]> git.ipfire.org Git - thirdparty/elfutils.git/commitdiff
Record new line table fields, export APIs to fetch them.
authorRoland McGrath <roland@redhat.com>
Sat, 19 Jun 2010 00:01:05 +0000 (17:01 -0700)
committerRoland McGrath <roland@redhat.com>
Sat, 19 Jun 2010 00:01:05 +0000 (17:01 -0700)
NEWS
libdw/ChangeLog
libdw/Makefile.am
libdw/dwarf_getsrclines.c
libdw/dwarf_linediscriminator.c [new file with mode: 0644]
libdw/dwarf_lineisa.c [new file with mode: 0644]
libdw/dwarf_lineop_index.c [new file with mode: 0644]
libdw/libdw.h
libdw/libdw.map
libdw/libdwP.h

diff --git a/NEWS b/NEWS
index 9fc203e8912250a84a4138c9ec3fda68cc7bdb65..01a33db94fee7252dfba8a636b38bb6123123583 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -1,8 +1,8 @@
 Version 0.148:
 
-libdw: Accept DWARF 4 format.
-
-libdw: New function dwarf_cfi_validate_fde.
+libdw: Accept DWARF 4 formats.
+       New functions dwarf_lineisa, dwarf_linediscriminator, dwarf_lineop_index.
+       New function dwarf_cfi_validate_fde.
 
 libdwfl: Fixes in core-file handling, support cores from PIEs.
         When working from build IDs, don't open a named file that mismatches.
index 5672082e713d1ae427d11bd00b6161674fb92973..277966bae09f2b36b574927e89d4d6d3e1395ee9 100644 (file)
@@ -1,3 +1,17 @@
+2010-06-17  Roland McGrath  <roland@redhat.com>
+
+       * libdwP.h (struct Dwarf_Line_s): Add members isa, discriminator, and
+       op_index.
+       * dwarf_getsrclines.c (dwarf_getsrclines): Move NEW_FILE macro guts
+       into an inner inline function.  Set new fields.  Check all fields for
+       overflow when setting.
+       * dwarf_lineisa.c: New file.
+       * dwarf_linediscriminator.c: New file.
+       * dwarf_lineop_index.c: New file.
+       * Makefile.am (libdw_a_SOURCES): Add them.
+       * libdw.map (ELFUTILS_0.148): Add them.
+       * libdw.h: Declare them.
+
 2010-06-16  Roland McGrath  <roland@redhat.com>
 
        * dwarf_next_cfi.c: Fix version 4 return_address_register decoding.
index 4bd0f2a8d117e6070126630fcbf6de11f7e6fdbc..0604ac28e270968726bb0b010f40136d71dc99d3 100644 (file)
@@ -63,6 +63,8 @@ libdw_a_SOURCES = dwarf_begin.c dwarf_begin_elf.c dwarf_end.c dwarf_getelf.c \
                  dwarf_linecol.c dwarf_linebeginstatement.c \
                  dwarf_lineendsequence.c dwarf_lineblock.c \
                  dwarf_lineprologueend.c dwarf_lineepiloguebegin.c \
+                 dwarf_lineisa.c dwarf_linediscriminator.c \
+                 dwarf_lineop_index.c \
                  dwarf_onesrcline.c dwarf_formblock.c \
                  dwarf_getsrcfiles.c dwarf_filesrc.c dwarf_getsrcdirs.c \
                  dwarf_getlocation.c dwarf_getstring.c dwarf_offabbrev.c \
index c3ba837bb6e82e17c54e803eaba830b61b8e3da0..afdf9dba7e6410f5e31071abca7c50f4c6fa8ef5 100644 (file)
@@ -86,34 +86,6 @@ compare_lines (const void *a, const void *b)
   return (*p1)->addr - (*p2)->addr;
 }
 
-
-/* Adds a new line to the matrix.  We cannot define a function because
-   we want to use alloca.  */
-#define NEW_LINE(end_seq) \
-  do {                                                                       \
-    /* Add the new line.  */                                                 \
-    new_line = (struct linelist *) alloca (sizeof (struct linelist));        \
-                                                                             \
-    /* Set the line information.  */                                         \
-    new_line->line.addr = address;                                           \
-    /* new_line->line.op_index = op_index; */                                \
-    new_line->line.file = file;                                                      \
-    new_line->line.line = line;                                                      \
-    new_line->line.column = column;                                          \
-    new_line->line.is_stmt = is_stmt;                                        \
-    new_line->line.basic_block = basic_block;                                \
-    new_line->line.end_sequence = end_seq;                                   \
-    new_line->line.prologue_end = prologue_end;                                      \
-    new_line->line.epilogue_begin = epilogue_begin;                          \
-    /* new_line->line.isa = isa; */                                          \
-    /* new_line->line.discriminator = discriminator; */                              \
-                                                                             \
-    new_line->next = linelist;                                               \
-    linelist = new_line;                                                     \
-    ++nlinelist;                                                             \
-  } while (0)
-
-
 int
 dwarf_getsrclines (Dwarf_Die *cudie, Dwarf_Lines **lines, size_t *nlines)
 {
@@ -351,11 +323,11 @@ dwarf_getsrclines (Dwarf_Die *cudie, Dwarf_Lines **lines, size_t *nlines)
 
         /* We are about to process the statement program.  Initialize the
           state machine registers (see 6.2.2 in the v2.1 specification).  */
-      Dwarf_Word address = 0;
+      Dwarf_Word addr = 0;
       unsigned int op_index = 0;
-      size_t file = 1;
-      size_t line = 1;
-      size_t column = 0;
+      unsigned int file = 1;
+      int line = 1;
+      unsigned int column = 0;
       uint_fast8_t is_stmt = default_is_stmt;
       bool basic_block = false;
       bool prologue_end = false;
@@ -367,17 +339,61 @@ dwarf_getsrclines (Dwarf_Die *cudie, Dwarf_Lines **lines, size_t *nlines)
         or DW_LNS_advance_pc (as per DWARF4 6.2.5.1).  */
       inline void advance_pc (unsigned int op_advance)
       {
-       address += minimum_instr_len * ((op_index + op_advance)
-                                       / max_ops_per_instr);
+       addr += minimum_instr_len * ((op_index + op_advance)
+                                    / max_ops_per_instr);
        op_index = (op_index + op_advance) % max_ops_per_instr;
       }
 
       /* Process the instructions.  */
       struct linelist *linelist = NULL;
       unsigned int nlinelist = 0;
+
+      /* Adds a new line to the matrix.
+        We cannot simply define a function because we want to use alloca.  */
+#define NEW_LINE(end_seq)                                              \
+      do {                                                             \
+       if (unlikely (add_new_line (alloca (sizeof (struct linelist)),  \
+                                   end_seq)))                          \
+         goto invalid_data;                                            \
+      } while (0)
+
+      inline bool add_new_line (struct linelist *new_line, bool end_sequence)
+      {
+       /* Set the line information.  For some fields we use bitfields,
+          so we would lose information if the encoded values are too large.
+          Check just for paranoia, and call the data "invalid" if it
+          violates our assumptions on reasonable limits for the values.  */
+#define SET(field)                                                           \
+       do {                                                                  \
+         new_line->line.field = field;                                       \
+         if (unlikely (new_line->line.field != field))                       \
+           return true;                                                      \
+        } while (0)
+
+       SET (addr);
+       SET (op_index);
+       SET (file);
+       SET (line);
+       SET (column);
+       SET (is_stmt);
+       SET (basic_block);
+       SET (end_sequence);
+       SET (prologue_end);
+       SET (epilogue_begin);
+       SET (isa);
+       SET (discriminator);
+
+#undef SET
+
+       new_line->next = linelist;
+       linelist = new_line;
+       ++nlinelist;
+
+       return false;
+      }
+
       while (linep < lineendp)
        {
-         struct linelist *new_line;
          unsigned int opcode;
          unsigned int u128;
          int s128;
@@ -433,7 +449,7 @@ dwarf_getsrclines (Dwarf_Die *cudie, Dwarf_Lines **lines, size_t *nlines)
                  NEW_LINE (1);
 
                  /* Reset the registers.  */
-                 address = 0;
+                 addr = 0;
                  op_index = 0;
                  file = 1;
                  line = 1;
@@ -454,7 +470,7 @@ dwarf_getsrclines (Dwarf_Die *cudie, Dwarf_Lines **lines, size_t *nlines)
                  if (unlikely (lineendp - linep < cu->address_size))
                    goto invalid_data;
                  if (__libdw_read_address_inc (dbg, IDX_debug_line, &linep,
-                                               cu->address_size, &address))
+                                               cu->address_size, &addr))
                    goto out;
                  break;
 
@@ -609,7 +625,7 @@ dwarf_getsrclines (Dwarf_Die *cudie, Dwarf_Lines **lines, size_t *nlines)
                      || unlikely (lineendp - linep < 2))
                    goto invalid_data;
 
-                 address += read_2ubyte_unaligned_inc (dbg, linep);
+                 addr += read_2ubyte_unaligned_inc (dbg, linep);
                  op_index = 0;
                  break;
 
diff --git a/libdw/dwarf_linediscriminator.c b/libdw/dwarf_linediscriminator.c
new file mode 100644 (file)
index 0000000..d17a99f
--- /dev/null
@@ -0,0 +1,66 @@
+/* Return code path discriminator in line record.
+   Copyright (C) 2010 Red Hat, Inc.
+   This file is part of Red Hat elfutils.
+
+   Red Hat elfutils is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by the
+   Free Software Foundation; version 2 of the License.
+
+   Red Hat elfutils is distributed in the hope that it will be useful, but
+   WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   General Public License for more details.
+
+   You should have received a copy of the GNU General Public License along
+   with Red Hat elfutils; if not, write to the Free Software Foundation,
+   Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA.
+
+   In addition, as a special exception, Red Hat, Inc. gives You the
+   additional right to link the code of Red Hat elfutils with code licensed
+   under any Open Source Initiative certified open source license
+   (http://www.opensource.org/licenses/index.php) which requires the
+   distribution of source code with any binary distribution and to
+   distribute linked combinations of the two.  Non-GPL Code permitted under
+   this exception must only link to the code of Red Hat elfutils through
+   those well defined interfaces identified in the file named EXCEPTION
+   found in the source code files (the "Approved Interfaces").  The files
+   of Non-GPL Code may instantiate templates or use macros or inline
+   functions from the Approved Interfaces without causing the resulting
+   work to be covered by the GNU General Public License.  Only Red Hat,
+   Inc. may make changes or additions to the list of Approved Interfaces.
+   Red Hat's grant of this exception is conditioned upon your not adding
+   any new exceptions.  If you wish to add a new Approved Interface or
+   exception, please contact Red Hat.  You must obey the GNU General Public
+   License in all respects for all of the Red Hat elfutils code and other
+   code used in conjunction with Red Hat elfutils except the Non-GPL Code
+   covered by this exception.  If you modify this file, you may extend this
+   exception to your version of the file, but you are not obligated to do
+   so.  If you do not wish to provide this exception without modification,
+   you must delete this exception statement from your version and license
+   this file solely under the GPL without exception.
+
+   Red Hat elfutils is an included package of the Open Invention Network.
+   An included package of the Open Invention Network is a package for which
+   Open Invention Network licensees cross-license their patents.  No patent
+   license is granted, either expressly or impliedly, by designation as an
+   included package.  Should you wish to participate in the Open Invention
+   Network licensing program, please visit www.openinventionnetwork.com
+   <http://www.openinventionnetwork.com>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "libdwP.h"
+
+
+int
+dwarf_linediscriminator (Dwarf_Line *line, unsigned int *discp)
+{
+  if (line == NULL)
+    return -1;
+
+  *discp = line->discriminator;
+
+  return 0;
+}
diff --git a/libdw/dwarf_lineisa.c b/libdw/dwarf_lineisa.c
new file mode 100644 (file)
index 0000000..064761e
--- /dev/null
@@ -0,0 +1,66 @@
+/* Return ISA in line.
+   Copyright (C) 2010 Red Hat, Inc.
+   This file is part of Red Hat elfutils.
+
+   Red Hat elfutils is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by the
+   Free Software Foundation; version 2 of the License.
+
+   Red Hat elfutils is distributed in the hope that it will be useful, but
+   WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   General Public License for more details.
+
+   You should have received a copy of the GNU General Public License along
+   with Red Hat elfutils; if not, write to the Free Software Foundation,
+   Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA.
+
+   In addition, as a special exception, Red Hat, Inc. gives You the
+   additional right to link the code of Red Hat elfutils with code licensed
+   under any Open Source Initiative certified open source license
+   (http://www.opensource.org/licenses/index.php) which requires the
+   distribution of source code with any binary distribution and to
+   distribute linked combinations of the two.  Non-GPL Code permitted under
+   this exception must only link to the code of Red Hat elfutils through
+   those well defined interfaces identified in the file named EXCEPTION
+   found in the source code files (the "Approved Interfaces").  The files
+   of Non-GPL Code may instantiate templates or use macros or inline
+   functions from the Approved Interfaces without causing the resulting
+   work to be covered by the GNU General Public License.  Only Red Hat,
+   Inc. may make changes or additions to the list of Approved Interfaces.
+   Red Hat's grant of this exception is conditioned upon your not adding
+   any new exceptions.  If you wish to add a new Approved Interface or
+   exception, please contact Red Hat.  You must obey the GNU General Public
+   License in all respects for all of the Red Hat elfutils code and other
+   code used in conjunction with Red Hat elfutils except the Non-GPL Code
+   covered by this exception.  If you modify this file, you may extend this
+   exception to your version of the file, but you are not obligated to do
+   so.  If you do not wish to provide this exception without modification,
+   you must delete this exception statement from your version and license
+   this file solely under the GPL without exception.
+
+   Red Hat elfutils is an included package of the Open Invention Network.
+   An included package of the Open Invention Network is a package for which
+   Open Invention Network licensees cross-license their patents.  No patent
+   license is granted, either expressly or impliedly, by designation as an
+   included package.  Should you wish to participate in the Open Invention
+   Network licensing program, please visit www.openinventionnetwork.com
+   <http://www.openinventionnetwork.com>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "libdwP.h"
+
+
+int
+dwarf_lineisa (Dwarf_Line *line, unsigned int *isap)
+{
+  if (line == NULL)
+    return -1;
+
+  *isap = line->isa;
+
+  return 0;
+}
diff --git a/libdw/dwarf_lineop_index.c b/libdw/dwarf_lineop_index.c
new file mode 100644 (file)
index 0000000..3b43310
--- /dev/null
@@ -0,0 +1,66 @@
+/* Return line VLIW operation index.
+   Copyright (C) 2010 Red Hat, Inc.
+   This file is part of Red Hat elfutils.
+
+   Red Hat elfutils is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by the
+   Free Software Foundation; version 2 of the License.
+
+   Red Hat elfutils is distributed in the hope that it will be useful, but
+   WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   General Public License for more details.
+
+   You should have received a copy of the GNU General Public License along
+   with Red Hat elfutils; if not, write to the Free Software Foundation,
+   Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA.
+
+   In addition, as a special exception, Red Hat, Inc. gives You the
+   additional right to link the code of Red Hat elfutils with code licensed
+   under any Open Source Initiative certified open source license
+   (http://www.opensource.org/licenses/index.php) which requires the
+   distribution of source code with any binary distribution and to
+   distribute linked combinations of the two.  Non-GPL Code permitted under
+   this exception must only link to the code of Red Hat elfutils through
+   those well defined interfaces identified in the file named EXCEPTION
+   found in the source code files (the "Approved Interfaces").  The files
+   of Non-GPL Code may instantiate templates or use macros or inline
+   functions from the Approved Interfaces without causing the resulting
+   work to be covered by the GNU General Public License.  Only Red Hat,
+   Inc. may make changes or additions to the list of Approved Interfaces.
+   Red Hat's grant of this exception is conditioned upon your not adding
+   any new exceptions.  If you wish to add a new Approved Interface or
+   exception, please contact Red Hat.  You must obey the GNU General Public
+   License in all respects for all of the Red Hat elfutils code and other
+   code used in conjunction with Red Hat elfutils except the Non-GPL Code
+   covered by this exception.  If you modify this file, you may extend this
+   exception to your version of the file, but you are not obligated to do
+   so.  If you do not wish to provide this exception without modification,
+   you must delete this exception statement from your version and license
+   this file solely under the GPL without exception.
+
+   Red Hat elfutils is an included package of the Open Invention Network.
+   An included package of the Open Invention Network is a package for which
+   Open Invention Network licensees cross-license their patents.  No patent
+   license is granted, either expressly or impliedly, by designation as an
+   included package.  Should you wish to participate in the Open Invention
+   Network licensing program, please visit www.openinventionnetwork.com
+   <http://www.openinventionnetwork.com>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "libdwP.h"
+
+
+int
+dwarf_lineop_index (Dwarf_Line *line, unsigned int *idxp)
+{
+  if (line == NULL)
+    return -1;
+
+  *idxp = line->op_index;
+
+  return 0;
+}
index 75998e1a037992dd5c041d6a6cff9ae9b49b43b5..766aa7baecba72a9f8211a2a4c9a1f7ed4a8611d 100644 (file)
@@ -563,6 +563,9 @@ extern int dwarf_getsrc_file (Dwarf *dbg, const char *fname, int line, int col,
 /* Return line address.  */
 extern int dwarf_lineaddr (Dwarf_Line *line, Dwarf_Addr *addrp);
 
+/* Return line VLIW operation index.  */
+extern int dwarf_lineop_index (Dwarf_Line *line, unsigned int *op_indexp);
+
 /* Return line number.  */
 extern int dwarf_lineno (Dwarf_Line *line, int *linep)
      __nonnull_attribute__ (2);
@@ -591,6 +594,14 @@ extern int dwarf_lineprologueend (Dwarf_Line *line, bool *flagp)
 extern int dwarf_lineepiloguebegin (Dwarf_Line *line, bool *flagp)
      __nonnull_attribute__ (2);
 
+/* Return instruction-set architecture in this record.  */
+extern int dwarf_lineisa (Dwarf_Line *line, unsigned int *isap)
+     __nonnull_attribute__ (2);
+
+/* Return code path discriminator in this record.  */
+extern int dwarf_linediscriminator (Dwarf_Line *line, unsigned int *discp)
+     __nonnull_attribute__ (2);
+
 
 /* Find line information for address.  */
 extern const char *dwarf_linesrc (Dwarf_Line *line,
index 89897acdc1ebc56c0880d85b31a3bdd0e2400f3f..d1f486615ce85c62645f883ed55ea2317ccf81f9 100644 (file)
@@ -241,4 +241,8 @@ ELFUTILS_0.146 {
 ELFUTILS_0.148 {
   global:
     dwarf_cfi_validate_fde;
+
+    dwarf_lineisa;
+    dwarf_linediscriminator;
+    dwarf_lineop_index;
 } ELFUTILS_0.146;
index bfa8a4265307d7772c2230640f20fc502af2b686..ee4d368b960ce9c6fe250f4d537d74e8c30bec04 100644 (file)
@@ -240,6 +240,12 @@ struct Dwarf_Line_s
   unsigned int end_sequence:1;
   unsigned int prologue_end:1;
   unsigned int epilogue_begin:1;
+  /* The remaining bit fields are not flags, but hold values presumed to be
+     small.  All the flags and other bit fields should add up to 48 bits
+     to give the whole struct a nice round size.  */
+  unsigned int op_index:8;
+  unsigned int isa:8;
+  unsigned int discriminator:24;
 };
 
 struct Dwarf_Lines_s