diff --git a/binutils/ChangeLog b/binutils/ChangeLog index e3aef7d69a0..e295fcac74d 100644 --- a/binutils/ChangeLog +++ b/binutils/ChangeLog @@ -1,3 +1,13 @@ +2009-12-10 Tristan Gingold + + * addr2line.c (pretty_print): New variable. + (long_options): Add an entry for -p/--pretty-print. + (usage): Document -p/--pretty-print. + (translate_addresses): Handle pretty_print. Reindent. + (main): Handle option -p. + * doc/binutils.texi (addr2line): Document -p/--pretty-print. + * NEWS: Mention new feature. + 2009-12-09 Tristan Gingold * addr2line.c (translate_addresses): Display addresses diff --git a/binutils/NEWS b/binutils/NEWS index 25fee15912f..7f79edac016 100644 --- a/binutils/NEWS +++ b/binutils/NEWS @@ -6,6 +6,9 @@ * Add a new command line option -a / --addresses to addr2line to display the address before function name or source filename. +* Add a new command line option -p / --pretty-print to addr2line to have + a more human readable output. + Changes in 2.20: * Add support for delay importing to dlltool. Use the --output-delaylib diff --git a/binutils/addr2line.c b/binutils/addr2line.c index 2ecdbfa14ac..b49c43a4791 100644 --- a/binutils/addr2line.c +++ b/binutils/addr2line.c @@ -42,6 +42,7 @@ static bfd_boolean unwind_inlines; /* -i, unwind inlined functions. */ static bfd_boolean with_addresses; /* -a, show addresses. */ static bfd_boolean with_functions; /* -f, show function names. */ static bfd_boolean do_demangle; /* -C, demangle names. */ +static bfd_boolean pretty_print; /* -p, print on one line. */ static bfd_boolean base_names; /* -s, strip directory names. */ static int naddr; /* Number of addresses to process. */ @@ -57,6 +58,7 @@ static struct option long_options[] = {"exe", required_argument, NULL, 'e'}, {"functions", no_argument, NULL, 'f'}, {"inlines", no_argument, NULL, 'i'}, + {"pretty-print", no_argument, NULL, 'p'}, {"section", required_argument, NULL, 'j'}, {"target", required_argument, NULL, 'b'}, {"help", no_argument, NULL, 'H'}, @@ -85,6 +87,7 @@ usage (FILE *stream, int status) -e --exe= Set the input file name (default is a.out)\n\ -i --inlines Unwind inlined functions\n\ -j --section= Read section-relative offsets instead of addresses\n\ + -p --pretty-print Make the output easier to read for humans\n\ -s --basenames Strip directory names\n\ -f --functions Show function names\n\ -C --demangle[=style] Demangle function names\n\ @@ -216,7 +219,11 @@ translate_addresses (bfd *abfd, asection *section) { printf ("0x"); bfd_printf_vma (abfd, pc); - printf ("\n"); + + if (pretty_print) + printf (": "); + else + printf ("\n"); } found = FALSE; @@ -233,44 +240,52 @@ translate_addresses (bfd *abfd, asection *section) } else { - do { - if (with_functions) - { - const char *name; - char *alloc = NULL; + while (1) + { + if (with_functions) + { + const char *name; + char *alloc = NULL; - name = functionname; - if (name == NULL || *name == '\0') - name = "??"; - else if (do_demangle) - { - alloc = bfd_demangle (abfd, name, DMGL_ANSI | DMGL_PARAMS); - if (alloc != NULL) - name = alloc; - } + name = functionname; + if (name == NULL || *name == '\0') + name = "??"; + else if (do_demangle) + { + alloc = bfd_demangle (abfd, name, DMGL_ANSI | DMGL_PARAMS); + if (alloc != NULL) + name = alloc; + } - printf ("%s\n", name); + printf ("%s", name); + if (pretty_print) + printf (_(" at ")); + else + printf ("\n"); - 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; - } - - printf ("%s:%u\n", filename ? filename : "??", line); - if (!unwind_inlines) - found = FALSE; - else - found = bfd_find_inliner_info (abfd, &filename, &functionname, &line); - } while (found); + 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); + if (! found) + break; + if (pretty_print) + printf (_(" (inlined by) ")); + } } /* fflush() is essential for using this command as a server @@ -364,7 +379,7 @@ main (int argc, char **argv) file_name = NULL; section_name = NULL; target = NULL; - while ((c = getopt_long (argc, argv, "ab:Ce:sfHhij:Vv", long_options, (int *) 0)) + while ((c = getopt_long (argc, argv, "ab:Ce:sfHhij:pVv", long_options, (int *) 0)) != EOF) { switch (c) @@ -400,6 +415,9 @@ main (int argc, char **argv) case 'f': with_functions = TRUE; break; + case 'p': + pretty_print = TRUE; + break; case 'v': case 'V': print_version ("addr2line"); diff --git a/binutils/doc/binutils.texi b/binutils/doc/binutils.texi index a96ecace9de..fa4fa26436e 100644 --- a/binutils/doc/binutils.texi +++ b/binutils/doc/binutils.texi @@ -2912,6 +2912,7 @@ addr2line [@option{-a}|@option{--addresses}] [@option{-e} @var{filename}|@option{--exe=}@var{filename}] [@option{-f}|@option{--functions}] [@option{-s}|@option{--basename}] [@option{-i}|@option{--inlines}] + [@option{-p}|@option{--pretty-print}] [@option{-j}|@option{--section=}@var{name}] [@option{-H}|@option{--help}] [@option{-V}|@option{--version}] [addr addr @dots{}] @@ -3006,6 +3007,12 @@ will also be printed. @item -j @itemx --section Read offsets relative to the specified section instead of absolute addresses. + +@item -p +@itemx --pretty-print +Make the output more human friendly: each location are printed on one line. +If option @option{-i} is specified, lines for all enclosing scopes are +prefixed with @samp{(inlined by)}. @end table @c man end