* 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.
This commit is contained in:
Eric Botcazou
2006-04-05 16:12:01 +00:00
parent dfcffada0b
commit c5f8c3881a
3 changed files with 80 additions and 19 deletions

View File

@@ -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 <Ulrich.Lauther@mchp.siemens.de>
@@ -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)
@<file> Read options from <file>\n\
-b --target=<bfdname> Set the binary file format\n\
-e --exe=<executable> Set the input file name (default is a.out)\n\
-i --inlines Unwind inlined functions\n\
-i --inlines Unwind inlined functions\n\
-j --section=<name> 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;
}