libdw/
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.
diff --git a/libdw/ChangeLog b/libdw/ChangeLog
index c5d1503..17b8b3e 100644
--- a/libdw/ChangeLog
+++ b/libdw/ChangeLog
@@ -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
diff --git a/libdw/Makefile.am b/libdw/Makefile.am
index 097ec3a..ad6b28a 100644
--- a/libdw/Makefile.am
+++ b/libdw/Makefile.am
@@ -62,8 +62,10 @@
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
diff --git a/libdw/libdw.h b/libdw/libdw.h
index 786be22..e6b3059 100644
--- a/libdw/libdw.h
+++ b/libdw/libdw.h
@@ -508,6 +508,19 @@
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. */
diff --git a/libdw/libdw.map b/libdw/libdw.map
index fb4a62d..b54dea3 100644
--- a/libdw/libdw.map
+++ b/libdw/libdw.map
@@ -1,5 +1,5 @@
ELFUTILS_0 { };
-ELFUTILS_0.111 {
+ELFUTILS_0.114 {
global:
dwarf_abbrevhaschildren;
dwarf_addrdie;
@@ -29,9 +29,12 @@
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;
diff --git a/libdw/libdwP.h b/libdw/libdwP.h
index 062b3dc..5f15cf9 100644
--- a/libdw/libdwP.h
+++ b/libdw/libdwP.h
@@ -342,6 +342,13 @@
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);
diff --git a/tests/ChangeLog b/tests/ChangeLog
index ee83376..ec7a22c 100644
--- a/tests/ChangeLog
+++ b/tests/ChangeLog
@@ -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.
diff --git a/tests/dwflmodtest.c b/tests/dwflmodtest.c
index e2b7d3c..5155f6c 100644
--- a/tests/dwflmodtest.c
+++ b/tests/dwflmodtest.c
@@ -23,12 +23,93 @@
#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_instance (Dwarf_Die *instance, void *arg)
+{
+ const struct info *info = arg;
+
+ printf (" inlined");
+
+ 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_lowpc (instance, &lo) == 0)
+ lo += info->dwbias;
+ else
+ printf (" (lowpc => %s)", dwarf_errmsg (-1));
+ if (dwarf_highpc (instance, &hi) == 0)
+ hi += info->dwbias;
+ else
+ printf (" (highpc => %s)", dwarf_errmsg (-1));
+
+ 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 Dwarf_Addr dwbias = *(Dwarf_Addr *) arg;
+ const struct info *info = arg;
const char *file = dwarf_func_file (func);
int line = -1;
@@ -37,26 +118,35 @@
printf (" %s:%d: %s:", file, line, fct);
- Dwarf_Addr lo = -1, hi = -1, entry = -1;
- if (dwarf_func_lowpc (func, &lo) == 0)
- lo += dwbias;
+ if (dwarf_func_inline (func))
+ {
+ puts (" inline function");
+ if (show_inlines)
+ print_inline (func, arg);
+ }
else
- printf (" (lowpc => %s)", dwarf_errmsg (-1));
- if (dwarf_func_highpc (func, &hi) == 0)
- hi += dwbias;
- else
- printf (" (highpc => %s)", dwarf_errmsg (-1));
- if (dwarf_func_entrypc (func, &entry) == 0)
- entry += dwbias;
- else
- printf (" (entrypc => %s)", dwarf_errmsg (-1));
+ {
+ 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 ("");
+ 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;
}
@@ -80,9 +170,8 @@
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 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 @@
show_functions = true;
break;
+ case 'i':
+ show_inlines = show_functions = true;
+ break;
+
default:
return ARGP_ERR_UNKNOWN;
}