X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=binutils%2Faddr2line.c;h=31e0b2f370db120b791711c6064e07219c633eb9;hb=aa8698122b7460cede3dc17abe499fd77ef10883;hp=72707c20bbb6cc871e293e8ab63311112f81687e;hpb=abd8680d6efd97e7ba848a6392ee3ad72be18cd0;p=deliverable%2Fbinutils-gdb.git diff --git a/binutils/addr2line.c b/binutils/addr2line.c index 72707c20bb..31e0b2f370 100644 --- a/binutils/addr2line.c +++ b/binutils/addr2line.c @@ -1,6 +1,7 @@ /* addr2line.c -- convert addresses to line number and function name - Copyright 1997, 1998, 1999 Free Software Foundation, Inc. - Contributed by Ulrich Lauther + Copyright 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004 + Free Software Foundation, Inc. + Contributed by Ulrich Lauther This file is part of GNU Binutils. @@ -18,17 +19,16 @@ along with this program; if not, write to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* Derived from objdump.c and nm.c by Ulrich.Lauther@zfe.siemens.de +/* Derived from objdump.c and nm.c by Ulrich.Lauther@mchp.siemens.de - Usage: + Usage: addr2line [options] addr addr ... or - addr2line [options] + addr2line [options] both forms write results to stdout, the second form reads addresses to be converted from stdin. */ -#include #include #include "bfd.h" @@ -36,12 +36,11 @@ #include "libiberty.h" #include "demangle.h" #include "bucomm.h" +#include "budemang.h" -extern char *program_version; - -static boolean with_functions; /* -f, show function names. */ -static boolean do_demangle; /* -C, demangle names. */ -static boolean base_names; /* -s, strip directory names. */ +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. */ static int naddr; /* Number of addresses to process. */ static char **addr; /* Hex addresses to process. */ @@ -51,7 +50,7 @@ static asymbol **syms; /* Symbol table. */ static struct option long_options[] = { {"basenames", no_argument, NULL, 's'}, - {"demangle", no_argument, NULL, 'C'}, + {"demangle", optional_argument, NULL, 'C'}, {"exe", required_argument, NULL, 'e'}, {"functions", no_argument, NULL, 'f'}, {"target", required_argument, NULL, 'b'}, @@ -60,49 +59,51 @@ static struct option long_options[] = {0, no_argument, 0, 0} }; -static void usage PARAMS ((FILE *, int)); -static void slurp_symtab PARAMS ((bfd *)); -static void find_address_in_section PARAMS ((bfd *, asection *, PTR)); -static void translate_addresses PARAMS ((bfd *)); -static void process_file PARAMS ((const char *, const char *)); +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 *); /* Print a usage message to STREAM and exit with STATUS. */ static void -usage (stream, status) - FILE *stream; - int status; +usage (FILE *stream, int status) { - fprintf (stream, _("\ -Usage: %s [-CfsHV] [-b bfdname] [--target=bfdname]\n\ - [-e executable] [--exe=executable] [--demangle]\n\ - [--basenames] [--functions] [addr addr ...]\n"), - program_name); + fprintf (stream, _("Usage: %s [option(s)] [addr(s)]\n"), program_name); + fprintf (stream, _(" Convert addresses into line number/file name pairs.\n")); + fprintf (stream, _(" If no addresses are specified on the command line, they will be read from stdin\n")); + 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\ + -s --basenames Strip directory names\n\ + -f --functions Show function names\n\ + -C --demangle[=style] Demangle function names\n\ + -h --help Display this information\n\ + -v --version Display the program's version\n\ +\n")); + list_supported_targets (program_name, stream); if (status == 0) - fprintf (stream, _("Report bugs to bug-gnu-utils@gnu.org\n")); + fprintf (stream, _("Report bugs to %s\n"), REPORT_BUGS_TO); exit (status); } /* Read in the symbol table. */ static void -slurp_symtab (abfd) - bfd *abfd; +slurp_symtab (bfd *abfd) { - long storage; long symcount; + unsigned int size; if ((bfd_get_file_flags (abfd) & HAS_SYMS) == 0) return; - storage = bfd_get_symtab_upper_bound (abfd); - if (storage < 0) - bfd_fatal (bfd_get_filename (abfd)); - - syms = (asymbol **) xmalloc (storage); + symcount = bfd_read_minisymbols (abfd, FALSE, (void *) &syms, &size); + if (symcount == 0) + symcount = bfd_read_minisymbols (abfd, TRUE /* dynamic */, (void *) &syms, &size); - symcount = bfd_canonicalize_symtab (abfd, syms); if (symcount < 0) bfd_fatal (bfd_get_filename (abfd)); } @@ -114,16 +115,14 @@ static bfd_vma pc; static const char *filename; static const char *functionname; static unsigned int line; -static boolean found; +static bfd_boolean found; /* Look for an address in a section. This is called via bfd_map_over_sections. */ static void -find_address_in_section (abfd, section, data) - bfd *abfd; - asection *section; - PTR data ATTRIBUTE_UNUSED; +find_address_in_section (bfd *abfd, asection *section, + void *data ATTRIBUTE_UNUSED) { bfd_vma vma; bfd_size_type size; @@ -138,7 +137,7 @@ find_address_in_section (abfd, section, data) if (pc < vma) return; - size = bfd_get_section_size_before_reloc (section); + size = bfd_get_section_size (section); if (pc >= vma + size) return; @@ -150,8 +149,7 @@ find_address_in_section (abfd, section, data) file_name:line_number and optionally function name. */ static void -translate_addresses (abfd) - bfd *abfd; +translate_addresses (bfd *abfd) { int read_stdin = (naddr == 0); @@ -173,8 +171,8 @@ translate_addresses (abfd) pc = bfd_scan_vma (*addr++, NULL, 16); } - found = false; - bfd_map_over_sections (abfd, find_address_in_section, (PTR) NULL); + found = FALSE; + bfd_map_over_sections (abfd, find_address_in_section, NULL); if (! found) { @@ -186,23 +184,22 @@ translate_addresses (abfd) { if (with_functions) { - if (functionname == NULL || *functionname == '\0') - printf ("??\n"); - else if (! do_demangle) - printf ("%s\n", functionname); - else + const char *name; + char *alloc = NULL; + + name = functionname; + if (name == NULL || *name == '\0') + name = "??"; + else if (do_demangle) { - char *res; - - res = cplus_demangle (functionname, DMGL_ANSI | DMGL_PARAMS); - if (res == NULL) - printf ("%s\n", functionname); - else - { - printf ("%s\n", res); - free (res); - } + alloc = demangle (abfd, name); + name = alloc; } + + printf ("%s\n", name); + + if (alloc != NULL) + free (alloc); } if (base_names && filename != NULL) @@ -228,19 +225,20 @@ translate_addresses (abfd) /* Process a file. */ static void -process_file (filename, target) - const char *filename; - const char *target; +process_file (const char *file_name, const char *target) { bfd *abfd; char **matching; - abfd = bfd_openr (filename, target); + if (get_file_size (file_name) < 1) + return; + + abfd = bfd_openr (file_name, target); if (abfd == NULL) - bfd_fatal (filename); + bfd_fatal (file_name); if (bfd_check_format (abfd, bfd_archive)) - fatal (_("%s: can not get addresses from archive"), filename); + fatal (_("%s: can not get addresses from archive"), file_name); if (! bfd_check_format_matches (abfd, bfd_object, &matching)) { @@ -266,17 +264,20 @@ process_file (filename, target) bfd_close (abfd); } +int main (int, char **); + int -main (argc, argv) - int argc; - char **argv; +main (int argc, char **argv) { - char *filename; + const char *file_name; char *target; int c; #if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES) setlocale (LC_MESSAGES, ""); +#endif +#if defined (HAVE_SETLOCALE) + setlocale (LC_CTYPE, ""); #endif bindtextdomain (PACKAGE, LOCALEDIR); textdomain (PACKAGE); @@ -287,33 +288,46 @@ main (argc, argv) bfd_init (); set_default_bfd_target (); - filename = NULL; + file_name = NULL; target = NULL; - while ((c = getopt_long (argc, argv, "b:Ce:sfHV", long_options, (int *) 0)) + while ((c = getopt_long (argc, argv, "b:Ce:sfHhVv", long_options, (int *) 0)) != EOF) { switch (c) { case 0: - break; /* we've been given a long option */ + break; /* We've been given a long option. */ case 'b': target = optarg; break; case 'C': - do_demangle = true; + do_demangle = TRUE; + if (optarg != NULL) + { + enum demangling_styles style; + + style = cplus_demangle_name_to_style (optarg); + if (style == unknown_demangling) + fatal (_("unknown demangling style `%s'"), + optarg); + + cplus_demangle_set_style (style); + } break; case 'e': - filename = optarg; + file_name = optarg; break; case 's': - base_names = true; + base_names = TRUE; break; case 'f': - with_functions = true; + with_functions = TRUE; break; + case 'v': case 'V': print_version ("addr2line"); break; + case 'h': case 'H': usage (stdout, 0); break; @@ -323,13 +337,13 @@ main (argc, argv) } } - if (filename == NULL) - filename = "a.out"; + if (file_name == NULL) + file_name = "a.out"; addr = argv + optind; naddr = argc - optind; - process_file (filename, target); + process_file (file_name, target); return 0; }