From 0c552dc1882e1b7cfe81f27117631f04a92381bb Mon Sep 17 00:00:00 2001 From: Fred Fish Date: Mon, 23 May 2005 17:45:42 +0000 Subject: [PATCH] Approved by nickc@redhat.com: 2005-05-23 Fred Fish * addr2line.c (unwind_inlines): New flag for 'i' option. (usage): Document '-i' option. (long_options): Recognize '--inlines'. (translate_addresses): Loop, calling bfd_find_inliner_info as necessary and printing multiple output lines. (main): Handle 'i' option. * doc/binutils.texi (addr2line): Document '-i' option. * NEWS: Mention new addr2line '-i' option. --- binutils/ChangeLog | 11 +++++++ binutils/NEWS | 3 ++ binutils/addr2line.c | 63 +++++++++++++++++++++++--------------- binutils/doc/binutils.texi | 10 ++++++ 4 files changed, 62 insertions(+), 25 deletions(-) diff --git a/binutils/ChangeLog b/binutils/ChangeLog index 2140bd9250..1a6bc31cd1 100644 --- a/binutils/ChangeLog +++ b/binutils/ChangeLog @@ -1,3 +1,14 @@ +2005-05-23 Fred Fish + + * addr2line.c (unwind_inlines): New flag for 'i' option. + (usage): Document '-i' option. + (long_options): Recognize '--inlines'. + (translate_addresses): Loop, calling bfd_find_inliner_info as + necessary and printing multiple output lines. + (main): Handle 'i' option. + * doc/binutils.texi (addr2line): Document '-i' option. + * NEWS: Mention new addr2line '-i' option. + 2005-05-23 Nick Clifton * readelf.c (fetch_indirect_string): Display a warning message diff --git a/binutils/NEWS b/binutils/NEWS index c5b4e11e45..e9c5031624 100644 --- a/binutils/NEWS +++ b/binutils/NEWS @@ -1,5 +1,8 @@ -*- text -*- +* Add "-i/--inlines" to addr2line to print enclosing scope information + for inlined function chains, back to first non-inlined function. + * Add "-N/--full-section-name" to readelf to display full section name. * Add "-M entry:" switch to objdump to specify a function entry address diff --git a/binutils/addr2line.c b/binutils/addr2line.c index b4f48fc7fa..6464e37de0 100644 --- a/binutils/addr2line.c +++ b/binutils/addr2line.c @@ -39,6 +39,7 @@ #include "bucomm.h" #include "budemang.h" +static bfd_boolean unwind_inlines; /* -i, unwind inlined functions. */ static bfd_boolean with_functions; /* -f, show function names. */ static bfd_boolean do_demangle; /* -C, demangle names. */ static bfd_boolean base_names; /* -s, strip directory names. */ @@ -54,6 +55,7 @@ static struct option long_options[] = {"demangle", optional_argument, NULL, 'C'}, {"exe", required_argument, NULL, 'e'}, {"functions", no_argument, NULL, 'f'}, + {"inlines", no_argument, NULL, 'i'}, {"target", required_argument, NULL, 'b'}, {"help", no_argument, NULL, 'H'}, {"version", no_argument, NULL, 'V'}, @@ -77,6 +79,7 @@ usage (FILE *stream, int status) fprintf (stream, _(" The options are:\n\ -b --target= Set the binary file format\n\ -e --exe= Set the input file name (default is a.out)\n\ + -i --inlines Unwind inlined functions\n\ -s --basenames Strip directory names\n\ -f --functions Show function names\n\ -C --demangle[=style] Demangle function names\n\ @@ -183,36 +186,43 @@ translate_addresses (bfd *abfd) } else { - if (with_functions) - { - const char *name; - char *alloc = NULL; + do { + if (with_functions) + { + const char *name; + char *alloc = NULL; - name = functionname; - if (name == NULL || *name == '\0') - name = "??"; - else if (do_demangle) - { - alloc = demangle (abfd, name); - name = alloc; - } + name = functionname; + if (name == NULL || *name == '\0') + name = "??"; + else if (do_demangle) + { + alloc = demangle (abfd, name); + name = alloc; + } - printf ("%s\n", name); + printf ("%s\n", name); - if (alloc != NULL) - free (alloc); - } + if (alloc != NULL) + free (alloc); + } - if (base_names && filename != NULL) - { - char *h; + if (base_names && filename != NULL) + { + char *h; - h = strrchr (filename, '/'); - if (h != NULL) - filename = h + 1; - } + h = strrchr (filename, '/'); + if (h != NULL) + filename = h + 1; + } + + printf ("%s:%u\n", filename ? filename : "??", line); + if (!unwind_inlines) + found = FALSE; + else + found = bfd_find_inliner_info (abfd, &filename, &functionname, &line); + } while (found); - printf ("%s:%u\n", filename ? filename : "??", line); } /* fflush() is essential for using this command as a server @@ -291,7 +301,7 @@ main (int argc, char **argv) file_name = NULL; target = NULL; - while ((c = getopt_long (argc, argv, "b:Ce:sfHhVv", long_options, (int *) 0)) + while ((c = getopt_long (argc, argv, "b:Ce:sfHhiVv", long_options, (int *) 0)) != EOF) { switch (c) @@ -332,6 +342,9 @@ main (int argc, char **argv) case 'H': usage (stdout, 0); break; + case 'i': + unwind_inlines = TRUE; + break; default: usage (stderr, 1); break; diff --git a/binutils/doc/binutils.texi b/binutils/doc/binutils.texi index 5fe6e52bc7..c18b6a9514 100644 --- a/binutils/doc/binutils.texi +++ b/binutils/doc/binutils.texi @@ -2524,6 +2524,7 @@ addr2line [@option{-b} @var{bfdname}|@option{--target=}@var{bfdname}] [@option{-C}|@option{--demangle}[=@var{style}]] [@option{-e} @var{filename}|@option{--exe=}@var{filename}] [@option{-f}|@option{--functions}] [@option{-s}|@option{--basename}] + [@option{-i}|@option{--inlines}] [@option{-H}|@option{--help}] [@option{-V}|@option{--version}] [addr addr @dots{}] @c man end @@ -2596,6 +2597,15 @@ Display function names as well as file and line number information. @item -s @itemx --basenames Display only the base of each file name. + +@item -i +@itemx --inlines +If the address belongs to a function that was inlined, the source +information for all enclosing scopes back to the first non-inlined +function will also be printed. For example, if @code{main} inlines +@code{callee1} which inlines @code{callee2}, and address is from +@code{callee2}, the source information for @code{callee1} and @code{main} +will also be printed. @end table @c man end