libdw/
authorRoland McGrath <roland@redhat.com>
Mon, 15 Aug 2005 09:53:04 +0000 (09:53 +0000)
committerRoland McGrath <roland@redhat.com>
Mon, 15 Aug 2005 09:53:04 +0000 (09:53 +0000)
2005-08-15  Roland McGrath  <roland@redhat.com>

* dwarf_func_inline.c: New file.
* Makefile.am (libdw_a_SOURCES): Add it.
* libdw.h: Declare dwarf_func_inline, dwarf_func_inline_instances.
* libdw.map: Add them.

* dwarf_func_die.c: New file.
* Makefile.am (libdw_a_SOURCES): Add it.
* libdw.h: Declare dwarf_func_die.
* libdw.map: Add it.  Bump version to ELFUTILS_0.114.

tests/
2005-08-15  Roland McGrath  <roland@redhat.com>

* dwflmodtest.c (print_instance, print_inline): New functions.
(print_func): Call print_inline.
(options, parse_opt): Grok -i/--inlines.

libdw/ChangeLog
libdw/Makefile.am
libdw/libdw.h
libdw/libdw.map
libdw/libdwP.h
tests/ChangeLog
tests/dwflmodtest.c

index c5d1503..17b8b3e 100644 (file)
@@ -1,3 +1,15 @@
+2005-08-15  Roland McGrath  <roland@redhat.com>
+
+       * dwarf_func_inline.c: New file.
+       * Makefile.am (libdw_a_SOURCES): Add it.
+       * libdw.h: Declare dwarf_func_inline, dwarf_func_inline_instances.
+       * libdw.map: Add them.
+
+       * dwarf_func_die.c: New file.
+       * Makefile.am (libdw_a_SOURCES): Add it.
+       * libdw.h: Declare dwarf_func_die.
+       * libdw.map: Add it.  Bump version to ELFUTILS_0.114.
+
 2005-08-10  Ulrich Drepper  <drepper@redhat.com>
 
        * dwarf_getsrclines.c (dwarf_getsrclines): Correct fallout of renaming
index 097ec3a..ad6b28a 100644 (file)
@@ -62,8 +62,10 @@ libdw_a_SOURCES = dwarf_begin.c dwarf_begin_elf.c dwarf_end.c dwarf_getelf.c \
                  dwarf_macro_param2.c dwarf_addrdie.c \
                  dwarf_getfuncs.c dwarf_func_name.c dwarf_func_lowpc.c \
                  dwarf_func_highpc.c dwarf_func_entrypc.c dwarf_func_file.c \
-                 dwarf_func_line.c dwarf_func_col.c dwarf_getsrc_file.c \
-                 libdw_findcu.c libdw_form.c libdw_alloc.c memory-access.c
+                 dwarf_func_line.c dwarf_func_col.c dwarf_func_die.c \
+                 dwarf_func_inline.c dwarf_getsrc_file.c \
+                 libdw_findcu.c libdw_form.c libdw_alloc.c memory-access.c \
+                 libdw_visit_scopes.c
 
 
 if !MUDFLAP
index 786be22..e6b3059 100644 (file)
@@ -508,6 +508,19 @@ extern int dwarf_func_line (Dwarf_Func *func, int *linep)
 extern int dwarf_func_col (Dwarf_Func *func, int *colp)
      __nonnull_attribute__ (2);
 
+/* Get definition DIE of given function.  */
+extern Dwarf_Die *dwarf_func_die (Dwarf_Func *func, Dwarf_Die *die_mem)
+    __nonnull_attribute__ (2);
+
+/* Return nonzero if given function is an abstract inline definition.  */
+extern int dwarf_func_inline (Dwarf_Func *func);
+
+/* Find each concrete inlined instance of the abstract inline definition.  */
+extern int dwarf_func_inline_instances (Dwarf_Func *func,
+                                       int (*callback) (Dwarf_Die *, void *),
+                                       void *arg);
+
+
 
 /* Call callback function for each of the macro information entry for
    the CU.  */
index fb4a62d..b54dea3 100644 (file)
@@ -1,5 +1,5 @@
 ELFUTILS_0 { };
-ELFUTILS_0.111 {
+ELFUTILS_0.114 {
   global:
     dwarf_abbrevhaschildren;
     dwarf_addrdie;
@@ -29,9 +29,12 @@ ELFUTILS_0.111 {
     dwarf_formstring;
     dwarf_formudata;
     dwarf_func_col;
+    dwarf_func_die;
     dwarf_func_entrypc;
     dwarf_func_file;
     dwarf_func_highpc;
+    dwarf_func_inline;
+    dwarf_func_inline_instances;
     dwarf_func_line;
     dwarf_func_lowpc;
     dwarf_func_name;
index 062b3dc..5f15cf9 100644 (file)
@@ -342,6 +342,13 @@ extern unsigned char *__libdw_find_attr (Dwarf_Die *die,
 extern int __libdw_func_intval (Dwarf_Func *func, int *linep, int attval)
      __nonnull_attribute__ (1, 2) internal_function;
 
+/* Helper function to walk scopes.  */
+extern int __libdw_visit_scopes (unsigned int depth, Dwarf_Die *root,
+                                int (*visit) (unsigned int depth,
+                                              Dwarf_Die *die, void *arg),
+                                void *arg)
+  __nonnull_attribute__ (2, 3) internal_function;
+
 /* Return error code of last failing function call.  This value is kept
    separately for each thread.  */
 extern int __dwarf_errno_internal (void);
index ee83376..ec7a22c 100644 (file)
@@ -1,3 +1,9 @@
+2005-08-15  Roland McGrath  <roland@redhat.com>
+
+       * dwflmodtest.c (print_instance, print_inline): New functions.
+       (print_func): Call print_inline.
+       (options, parse_opt): Grok -i/--inlines.
+
 2005-08-07  Roland McGrath  <roland@redhat.com>
 
        * dwflmodtest.c: Print function details only if -f flag is given.
index e2b7d3c..5155f6c 100644 (file)
 #include <locale.h>
 #include <argp.h>
 #include <libdwfl.h>
+#include <dwarf.h>
 
+static bool show_inlines;
+
+struct info
+{
+  Dwarf_Die *cudie;
+  Dwarf_Addr dwbias;
+};
 
 static int
-print_func (Dwarf_Func *func, void *arg)
+print_instance (Dwarf_Die *instance, void *arg)
 {
-  const Dwarf_Addr dwbias = *(Dwarf_Addr *) arg;
+  const struct info *info = arg;
 
-  const char *file = dwarf_func_file (func);
-  int line = -1;
-  dwarf_func_line (func, &line);
-  const char *fct = dwarf_func_name (func);
+  printf ("    inlined");
 
-  printf ("  %s:%d: %s:", file, line, fct);
+  Dwarf_Files *files;
+  if (dwarf_getsrcfiles (info->cudie, &files, NULL) == 0)
+    {
+      Dwarf_Attribute attr_mem;
+      Dwarf_Word val;
+      if (dwarf_formudata (dwarf_attr (instance, DW_AT_call_file,
+                                      &attr_mem), &val) == 0)
+       {
+         const char *file = dwarf_filesrc (files, val, NULL, NULL);
+         int lineno = 0, colno = 0;
+         if (dwarf_formudata (dwarf_attr (instance, DW_AT_call_line,
+                                          &attr_mem), &val) == 0)
+           lineno = val;
+         if (dwarf_formudata (dwarf_attr (instance, DW_AT_call_column,
+                                          &attr_mem), &val) == 0)
+           colno = val;
+         if (lineno == 0)
+           {
+             if (file != NULL)
+               printf (" from %s", file);
+           }
+         else if (colno == 0)
+           printf (" at %s:%u", file, lineno);
+         else
+           printf (" at %s:%u:%u", file, lineno, colno);
+       }
+    }
 
   Dwarf_Addr lo = -1, hi = -1, entry = -1;
-  if (dwarf_func_lowpc (func, &lo) == 0)
-    lo += dwbias;
+  if (dwarf_lowpc (instance, &lo) == 0)
+    lo += info->dwbias;
   else
     printf (" (lowpc => %s)", dwarf_errmsg (-1));
-  if (dwarf_func_highpc (func, &hi) == 0)
-    hi += dwbias;
+  if (dwarf_highpc (instance, &hi) == 0)
+    hi += info->dwbias;
   else
     printf (" (highpc => %s)", dwarf_errmsg (-1));
-  if (dwarf_func_entrypc (func, &entry) == 0)
-    entry += dwbias;
-  else
-    printf (" (entrypc => %s)", dwarf_errmsg (-1));
 
-  if (lo != (Dwarf_Addr) -1 || hi != (Dwarf_Addr) -1
-      || entry != (Dwarf_Addr) -1)
-    printf (" %#" PRIx64 "..%#" PRIx64 " => %#" PRIx64 "\n",
-           lo, hi, entry);
+  Dwarf_Attribute attr_mem;
+  Dwarf_Attribute *attr = INTUSE(dwarf_attr) (instance, DW_AT_entry_pc,
+                                             &attr_mem);
+  if (attr != NULL)
+    {
+      if (INTUSE(dwarf_formaddr) (attr, &entry) == 0)
+       entry += info->dwbias;
+      else
+       printf (" (entrypc => %s)", dwarf_errmsg (-1));
+    }
+
+  if (lo != (Dwarf_Addr) -1 || hi != (Dwarf_Addr) -1)
+    printf (" %#" PRIx64 "..%#" PRIx64, lo, hi);
+  if (entry != (Dwarf_Addr) -1)
+    printf (" => %#" PRIx64 "\n", entry);
   else
     puts ("");
 
   return DWARF_CB_OK;
 }
 
+static void
+print_inline (Dwarf_Func *func, void *arg)
+{
+  if (dwarf_func_inline_instances (func, &print_instance, arg) != 0)
+    printf ("  error finding instances: %s\n", dwarf_errmsg (-1));
+}
+
+static int
+print_func (Dwarf_Func *func, void *arg)
+{
+  const struct info *info = arg;
+
+  const char *file = dwarf_func_file (func);
+  int line = -1;
+  dwarf_func_line (func, &line);
+  const char *fct = dwarf_func_name (func);
+
+  printf ("  %s:%d: %s:", file, line, fct);
+
+  if (dwarf_func_inline (func))
+    {
+      puts (" inline function");
+      if (show_inlines)
+       print_inline (func, arg);
+    }
+  else
+    {
+      Dwarf_Addr lo = -1, hi = -1, entry = -1;
+      if (dwarf_func_lowpc (func, &lo) == 0)
+       lo += info->dwbias;
+      else
+       printf (" (lowpc => %s)", dwarf_errmsg (-1));
+      if (dwarf_func_highpc (func, &hi) == 0)
+       hi += info->dwbias;
+      else
+       printf (" (highpc => %s)", dwarf_errmsg (-1));
+      if (dwarf_func_entrypc (func, &entry) == 0)
+       entry += info->dwbias;
+      else
+       printf (" (entrypc => %s)", dwarf_errmsg (-1));
+
+      if (lo != (Dwarf_Addr) -1 || hi != (Dwarf_Addr) -1
+         || entry != (Dwarf_Addr) -1)
+       printf (" %#" PRIx64 "..%#" PRIx64 " => %#" PRIx64 "\n",
+               lo, hi, entry);
+      else
+       puts ("");
+    }
+
+  return DWARF_CB_OK;
+}
+
 static int
 print_module (Dwfl_Module *mod __attribute__ ((unused)),
              void **userdata __attribute__ ((unused)),
@@ -80,9 +170,8 @@ print_module (Dwfl_Module *mod __attribute__ ((unused)),
       while (dwarf_nextcu (dw, off, &noff, &cuhl, NULL, NULL, NULL) == 0)
        {
          Dwarf_Die die_mem;
-         Dwarf_Die *die = dwarf_offdie (dw, off + cuhl, &die_mem);
-
-         (void) dwarf_getfuncs (die, print_func, &bias, 0);
+         struct info info = { dwarf_offdie (dw, off + cuhl, &die_mem), bias };
+         (void) dwarf_getfuncs (info.cudie, print_func, &info, 0);
 
          off = noff;
        }
@@ -95,7 +184,8 @@ static bool show_functions;
 
 static const struct argp_option options[] =
   {
-    { "functions", 'f', NULL, 0, N_("Additional show function names"), 0 },
+    { "functions", 'f', NULL, 0, N_("Additionally show function names"), 0 },
+    { "inlines", 'i', NULL, 0, N_("Show instances of inlined functions"), 0 },
     { NULL, 0, NULL, 0, NULL, 0 }
   };
 
@@ -113,6 +203,10 @@ parse_opt (int key, char *arg __attribute__ ((unused)),
       show_functions = true;
       break;
 
+    case 'i':
+      show_inlines = show_functions = true;
+      break;
+
     default:
       return ARGP_ERR_UNKNOWN;
     }