From c5f8c3881a54348a45b3bb27fd3251e00177859b Mon Sep 17 00:00:00 2001 From: Eric Botcazou Date: Wed, 5 Apr 2006 16:12:01 +0000 Subject: * addr2line.c (long_options): Add new option 'section'. (usage): Document new -j/--section option. (find_offset_in_section): New function. (translate_addresses): Add 'section' parameter. If it is non-null, call find_offset_in_section on it. (process_file): Add 'section_name' parameter. If it is non-null, look for the section in the BFD object. Pass the section to translate_addresses. (main): Handle new -j option. Pass the section name to process_file. * doc/binutils.texi (addr2line): Document new -j/--section option. --- binutils/ChangeLog | 14 ++++++++++ binutils/addr2line.c | 67 +++++++++++++++++++++++++++++++++++++--------- binutils/doc/binutils.texi | 18 ++++++++----- 3 files changed, 80 insertions(+), 19 deletions(-) diff --git a/binutils/ChangeLog b/binutils/ChangeLog index 92a732b..da81bd5 100644 --- a/binutils/ChangeLog +++ b/binutils/ChangeLog @@ -1,3 +1,17 @@ +2006-04-05 Eric Botcazou + + * addr2line.c (long_options): Add new option 'section'. + (usage): Document new -j/--section option. + (find_offset_in_section): New function. + (translate_addresses): Add 'section' parameter. + If it is non-null, call find_offset_in_section on it. + (process_file): Add 'section_name' parameter. + If it is non-null, look for the section in the BFD object. + Pass the section to translate_addresses. + (main): Handle new -j option. + Pass the section name to process_file. + * doc/binutils.texi (addr2line): Document new -j/--section option. + 2006-03-29 Ben Elliston * resbin.c: Avoid duplicating constants in calls to reswr_alloc. diff --git a/binutils/addr2line.c b/binutils/addr2line.c index aae69ca..7cd67bc 100644 --- a/binutils/addr2line.c +++ b/binutils/addr2line.c @@ -1,5 +1,5 @@ /* addr2line.c -- convert addresses to line number and function name - Copyright 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004 + Copyright 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2006 Free Software Foundation, Inc. Contributed by Ulrich Lauther @@ -56,6 +56,7 @@ static struct option long_options[] = {"exe", required_argument, NULL, 'e'}, {"functions", no_argument, NULL, 'f'}, {"inlines", no_argument, NULL, 'i'}, + {"section", required_argument, NULL, 'j'}, {"target", required_argument, NULL, 'b'}, {"help", no_argument, NULL, 'H'}, {"version", no_argument, NULL, 'V'}, @@ -65,8 +66,9 @@ static struct option long_options[] = static void usage (FILE *, int); static void slurp_symtab (bfd *); static void find_address_in_section (bfd *, asection *, void *); -static void translate_addresses (bfd *); -static void process_file (const char *, const char *); +static void find_offset_in_section (bfd *, asection *); +static void translate_addresses (bfd *, asection *); +static void process_file (const char *, const char *, const char *); /* Print a usage message to STREAM and exit with STATUS. */ @@ -80,7 +82,8 @@ usage (FILE *stream, int status) @ Read options from \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\ + -i --inlines Unwind inlined functions\n\ + -j --section= Read section-relative offsets instead of addresses\n\ -s --basenames Strip directory names\n\ -f --functions Show function names\n\ -C --demangle[=style] Demangle function names\n\ @@ -150,11 +153,32 @@ find_address_in_section (bfd *abfd, asection *section, &filename, &functionname, &line); } +/* Look for an offset in a section. This is directly called. */ + +static void +find_offset_in_section (bfd *abfd, asection *section) +{ + bfd_size_type size; + + if (found) + return; + + if ((bfd_get_section_flags (abfd, section) & SEC_ALLOC) == 0) + return; + + size = bfd_get_section_size (section); + if (pc >= size) + return; + + found = bfd_find_nearest_line (abfd, section, syms, pc, + &filename, &functionname, &line); +} + /* Read hexadecimal addresses from stdin, translate into file_name:line_number and optionally function name. */ static void -translate_addresses (bfd *abfd) +translate_addresses (bfd *abfd, asection *section) { int read_stdin = (naddr == 0); @@ -177,7 +201,10 @@ translate_addresses (bfd *abfd) } found = FALSE; - bfd_map_over_sections (abfd, find_address_in_section, NULL); + if (section) + find_offset_in_section (abfd, section); + else + bfd_map_over_sections (abfd, find_address_in_section, NULL); if (! found) { @@ -237,9 +264,11 @@ translate_addresses (bfd *abfd) /* Process a file. */ static void -process_file (const char *file_name, const char *target) +process_file (const char *file_name, const char *section_name, + const char *target) { bfd *abfd; + asection *section; char **matching; if (get_file_size (file_name) < 1) @@ -250,7 +279,7 @@ process_file (const char *file_name, const char *target) bfd_fatal (file_name); if (bfd_check_format (abfd, bfd_archive)) - fatal (_("%s: can not get addresses from archive"), file_name); + fatal (_("%s: cannot get addresses from archive"), file_name); if (! bfd_check_format_matches (abfd, bfd_object, &matching)) { @@ -263,9 +292,18 @@ process_file (const char *file_name, const char *target) xexit (1); } + if (section_name != NULL) + { + section = bfd_get_section_by_name (abfd, section_name); + if (section == NULL) + fatal (_("%s: cannot find section %s"), file_name, section_name); + } + else + section = NULL; + slurp_symtab (abfd); - translate_addresses (abfd); + translate_addresses (abfd, section); if (syms != NULL) { @@ -276,12 +314,11 @@ process_file (const char *file_name, const char *target) bfd_close (abfd); } -int main (int, char **); - int main (int argc, char **argv) { const char *file_name; + const char *section_name; char *target; int c; @@ -303,8 +340,9 @@ main (int argc, char **argv) set_default_bfd_target (); file_name = NULL; + section_name = NULL; target = NULL; - while ((c = getopt_long (argc, argv, "b:Ce:sfHhiVv", long_options, (int *) 0)) + while ((c = getopt_long (argc, argv, "b:Ce:sfHhij:Vv", long_options, (int *) 0)) != EOF) { switch (c) @@ -348,6 +386,9 @@ main (int argc, char **argv) case 'i': unwind_inlines = TRUE; break; + case 'j': + section_name = optarg; + break; default: usage (stderr, 1); break; @@ -360,7 +401,7 @@ main (int argc, char **argv) addr = argv + optind; naddr = argc - optind; - process_file (file_name, target); + process_file (file_name, section_name, target); return 0; } diff --git a/binutils/doc/binutils.texi b/binutils/doc/binutils.texi index 3249106..c7d30d5 100644 --- a/binutils/doc/binutils.texi +++ b/binutils/doc/binutils.texi @@ -2601,6 +2601,7 @@ addr2line [@option{-b} @var{bfdname}|@option{--target=}@var{bfdname}] [@option{-e} @var{filename}|@option{--exe=}@var{filename}] [@option{-f}|@option{--functions}] [@option{-s}|@option{--basename}] [@option{-i}|@option{--inlines}] + [@option{-j}|@option{--section=}@var{name}] [@option{-H}|@option{--help}] [@option{-V}|@option{--version}] [addr addr @dots{}] @c man end @@ -2608,13 +2609,14 @@ addr2line [@option{-b} @var{bfdname}|@option{--target=}@var{bfdname}] @c man begin DESCRIPTION addr2line -@command{addr2line} translates program addresses into file names and line -numbers. Given an address and an executable, it uses the debugging -information in the executable to figure out which file name and line -number are associated with a given address. +@command{addr2line} translates addresses into file names and line numbers. +Given an address in an executable or an offset in a section of a relocatable +object, it uses the debugging information to figure out which file name and +line number are associated with it. -The executable to use is specified with the @option{-e} option. The -default is the file @file{a.out}. +The executable or relocatable object to use is specified with the @option{-e} +option. The default is the file @file{a.out}. The section in the relocatable +object to use is specified with the @option{-j} option. @command{addr2line} has two modes of operation. @@ -2682,6 +2684,10 @@ 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. + +@item -j +@itemx --section +Read offsets relative to the specified section instead of absolute addresses. @end table @c man end -- cgit v1.1