Add dwfl_dwarf_line, addr2line -F to print out more line info bits.
authorRoland McGrath <roland@redhat.com>
Tue, 24 Aug 2010 22:38:42 +0000 (15:38 -0700)
committerRoland McGrath <roland@redhat.com>
Tue, 24 Aug 2010 22:39:12 +0000 (15:39 -0700)
NEWS
libdw/ChangeLog
libdw/libdw.map
libdwfl/ChangeLog
libdwfl/Makefile.am
libdwfl/libdwfl.h
src/addr2line.c

diff --git a/NEWS b/NEWS
index 975e294..599ea32 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -1,3 +1,9 @@
+Version 0.149:
+
+libdwfl: New function dwfl_dwarf_line.
+
+addr2line: New flag -F/--flags to print DWARF more line information details.
+
 Version 0.148:
 
 libdw: Accept DWARF 4 format: new functions dwarf_next_unit, dwarf_offdie_types.
index d0b54f3..dc1a7f3 100644 (file)
@@ -1,3 +1,7 @@
+2010-08-24  Roland McGrath  <roland@redhat.com>
+
+       * libdw.map (ELFUTILS_0.149): New set.  Add dwfl_dwarf_line.
+
 2010-07-27  Roland McGrath  <roland@redhat.com>
 
        * dwarf_formref_die.c: Fix sig8 hash insertion.
index 8e93dff..6d6b365 100644 (file)
@@ -247,3 +247,8 @@ ELFUTILS_0.148 {
     dwarf_next_unit;
     dwarf_offdie_types;
 } ELFUTILS_0.146;
+
+ELFUTILS_0.149 {
+  global:
+    dwfl_dwarf_line;
+} ELFUTILS_0.148;
index eb8aa8a..cc6dfb5 100644 (file)
@@ -1,3 +1,8 @@
+2010-08-24  Roland McGrath  <roland@redhat.com>
+
+       * dwfl_dwarf_line.c: New file.
+       * Makefile.am (libdwfl_a_SOURCES): Add it.
+
 2010-08-18  Roland McGrath  <roland@redhat.com>
 
        * link_map.c (report_r_debug): Use found name if we have no name,
index 8ec1f4f..65b3896 100644 (file)
@@ -53,7 +53,7 @@ libdwfl_a_SOURCES = dwfl_begin.c dwfl_end.c dwfl_error.c dwfl_version.c \
                    cu.c dwfl_module_nextcu.c dwfl_nextcu.c dwfl_cumodule.c \
                    dwfl_module_addrdie.c dwfl_addrdie.c \
                    lines.c dwfl_lineinfo.c dwfl_line_comp_dir.c \
-                   dwfl_linemodule.c dwfl_linecu.c \
+                   dwfl_linemodule.c dwfl_linecu.c dwfl_dwarf_line.c \
                    dwfl_getsrclines.c dwfl_onesrcline.c \
                    dwfl_module_getsrc.c dwfl_getsrc.c \
                    dwfl_module_getsrc_file.c \
index 51e9818..4ea2796 100644 (file)
@@ -527,6 +527,9 @@ extern const char *dwfl_lineinfo (Dwfl_Line *line, Dwarf_Addr *addr,
                                  int *linep, int *colp,
                                  Dwarf_Word *mtime, Dwarf_Word *length);
 
+  /* Return the equivalent Dwarf_Line and the bias to apply to its address.  */
+extern Dwarf_Line *dwfl_dwarf_line (Dwfl_Line *line, Dwarf_Addr *bias);
+
 /* Return the compilation directory (AT_comp_dir) from this line's CU.  */
 extern const char *dwfl_line_comp_dir (Dwfl_Line *line);
 
index 48f017b..2a3efb7 100644 (file)
@@ -69,6 +69,7 @@ static const struct argp_option options[] =
     N_("Show absolute file names using compilation directory"), 0 },
   { "functions", 'f', NULL, 0, N_("Also show function names"), 0 },
   { "symbols", 'S', NULL, 0, N_("Also show symbol or section names"), 0 },
+  { "flags", 'F', NULL, 0, N_("Also show line table flags"), 0 },
   { "section", 'j', "NAME", 0,
     N_("Treat addresses as offsets relative to NAME section."), 0 },
 
@@ -109,6 +110,9 @@ static bool only_basenames;
 /* True if absolute file names based on DW_AT_comp_dir should be shown.  */
 static bool use_comp_dir;
 
+/* True if line flags should be shown.  */
+static bool show_flags;
+
 /* True if function names should be shown.  */
 static bool show_functions;
 
@@ -219,6 +223,10 @@ parse_opt (int key, char *arg, struct argp_state *state)
       show_functions = true;
       break;
 
+    case 'F':
+      show_flags = true;
+      break;
+
     case 'S':
       show_symbols = true;
       break;
@@ -521,11 +529,41 @@ handle_address (const char *string, Dwfl *dwfl)
        }
 
       if (linecol != 0)
-       printf ("%s%s%s:%d:%d\n",
+       printf ("%s%s%s:%d:%d",
                comp_dir, comp_dir_sep, src, lineno, linecol);
       else
-       printf ("%s%s%s:%d\n",
+       printf ("%s%s%s:%d",
                comp_dir, comp_dir_sep, src, lineno);
+
+      if (show_flags)
+       {
+         Dwarf_Addr bias;
+         Dwarf_Line *info = dwfl_dwarf_line (line, &bias);
+         assert (info != NULL);
+
+         inline void show (int (*get) (Dwarf_Line *, bool *),
+                           const char *note)
+         {
+           bool flag;
+           if ((*get) (info, &flag) == 0 && flag)
+             fputs (note, stdout);
+         }
+         inline void show_int (int (*get) (Dwarf_Line *, unsigned int *),
+                               const char *name)
+         {
+           unsigned int val;
+           if ((*get) (info, &val) == 0 && val != 0)
+             printf (" (%s %u)", name, val);
+         }
+
+         show (&dwarf_linebeginstatement, " (is_stmt)");
+         show (&dwarf_lineblock, " (basic_block)");
+         show (&dwarf_lineprologueend, " (prologue_end)");
+         show (&dwarf_lineepiloguebegin, " (epilogue_begin)");
+         show_int (&dwarf_lineisa, "isa");
+         show_int (&dwarf_linediscriminator, "discriminator");
+       }
+      putchar ('\n');
     }
   else
     puts ("??:0");