From: Roland McGrath Date: Mon, 15 Aug 2005 09:53:04 +0000 (+0000) Subject: libdw/ X-Git-Tag: elfutils-0.120~114 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=1ecb606f5af22838bf42b50dcc581d2b0f9191fe;p=thirdparty%2Felfutils.git libdw/ 2005-08-15 Roland McGrath * 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 * 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 c5d1503c7..17b8b3e5d 100644 --- a/libdw/ChangeLog +++ b/libdw/ChangeLog @@ -1,3 +1,15 @@ +2005-08-15 Roland McGrath + + * 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 * dwarf_getsrclines.c (dwarf_getsrclines): Correct fallout of renaming diff --git a/libdw/Makefile.am b/libdw/Makefile.am index 097ec3a25..ad6b28a16 100644 --- a/libdw/Makefile.am +++ b/libdw/Makefile.am @@ -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 diff --git a/libdw/libdw.h b/libdw/libdw.h index 786be22ab..e6b305970 100644 --- a/libdw/libdw.h +++ b/libdw/libdw.h @@ -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. */ diff --git a/libdw/libdw.map b/libdw/libdw.map index fb4a62d17..b54dea3e3 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 @@ 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; diff --git a/libdw/libdwP.h b/libdw/libdwP.h index 062b3dce7..5f15cf9d3 100644 --- a/libdw/libdwP.h +++ b/libdw/libdwP.h @@ -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); diff --git a/tests/ChangeLog b/tests/ChangeLog index ee83376fc..ec7a22c74 100644 --- a/tests/ChangeLog +++ b/tests/ChangeLog @@ -1,3 +1,9 @@ +2005-08-15 Roland McGrath + + * dwflmodtest.c (print_instance, print_inline): New functions. + (print_func): Call print_inline. + (options, parse_opt): Grok -i/--inlines. + 2005-08-07 Roland McGrath * dwflmodtest.c: Print function details only if -f flag is given. diff --git a/tests/dwflmodtest.c b/tests/dwflmodtest.c index e2b7d3cf4..5155f6cb6 100644 --- a/tests/dwflmodtest.c +++ b/tests/dwflmodtest.c @@ -23,44 +23,134 @@ #include #include #include +#include +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; }