X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=binutils%2Faddr2line.c;h=846720fc81886dae7896c7aed38baeb49293c560;hb=refs%2Fheads%2Fconcurrent-displaced-stepping-2020-04-01;hp=1ece80aecd4ed6c0408fdb386497248f1440d589;hpb=877c169de7ff0b777dc72f1881b003b967c6553c;p=deliverable%2Fbinutils-gdb.git diff --git a/binutils/addr2line.c b/binutils/addr2line.c index 1ece80aecd..846720fc81 100644 --- a/binutils/addr2line.c +++ b/binutils/addr2line.c @@ -1,6 +1,5 @@ /* addr2line.c -- convert addresses to line number and function name - Copyright 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, - 2007, 2009 Free Software Foundation, Inc. + Copyright (C) 1997-2020 Free Software Foundation, Inc. Contributed by Ulrich Lauther This file is part of GNU Binutils. @@ -46,6 +45,9 @@ 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. */ +/* Flags passed to the name demangler. */ +static int demangle_flags = DMGL_PARAMS | DMGL_ANSI; + static int naddr; /* Number of addresses to process. */ static char **addr; /* Hex addresses to process. */ @@ -60,6 +62,10 @@ static struct option long_options[] = {"functions", no_argument, NULL, 'f'}, {"inlines", no_argument, NULL, 'i'}, {"pretty-print", no_argument, NULL, 'p'}, + {"recurse-limit", no_argument, NULL, 'R'}, + {"recursion-limit", no_argument, NULL, 'R'}, + {"no-recurse-limit", no_argument, NULL, 'r'}, + {"no-recursion-limit", no_argument, NULL, 'r'}, {"section", required_argument, NULL, 'j'}, {"target", required_argument, NULL, 'b'}, {"help", no_argument, NULL, 'H'}, @@ -92,6 +98,8 @@ usage (FILE *stream, int status) -s --basenames Strip directory names\n\ -f --functions Show function names\n\ -C --demangle[=style] Demangle function names\n\ + -R --recurse-limit Enable a limit on recursion whilst demangling. [Default]\n\ + -r --no-recurse-limit Disable a limit on recursion whilst demangling\n\ -h --help Display this information\n\ -v --version Display the program's version\n\ \n")); @@ -130,6 +138,25 @@ slurp_symtab (bfd *abfd) symcount = bfd_canonicalize_symtab (abfd, syms); if (symcount < 0) bfd_fatal (bfd_get_filename (abfd)); + + /* If there are no symbols left after canonicalization and + we have not tried the dynamic symbols then give them a go. */ + if (symcount == 0 + && ! dynamic + && (storage = bfd_get_dynamic_symtab_upper_bound (abfd)) > 0) + { + free (syms); + syms = xmalloc (storage); + symcount = bfd_canonicalize_dynamic_symtab (abfd, syms); + } + + /* PR 17512: file: 2a1d3b5b. + Do not pretend that we have some symbols when we don't. */ + if (symcount <= 0) + { + free (syms); + syms = NULL; + } } /* These global variables are used to pass information between @@ -139,6 +166,7 @@ static bfd_vma pc; static const char *filename; static const char *functionname; static unsigned int line; +static unsigned int discriminator; static bfd_boolean found; /* Look for an address in a section. This is called via @@ -154,19 +182,20 @@ find_address_in_section (bfd *abfd, asection *section, if (found) return; - if ((bfd_get_section_flags (abfd, section) & SEC_ALLOC) == 0) + if ((bfd_section_flags (section) & SEC_ALLOC) == 0) return; - vma = bfd_get_section_vma (abfd, section); + vma = bfd_section_vma (section); if (pc < vma) return; - size = bfd_get_section_size (section); + size = bfd_section_size (section); if (pc >= vma + size) return; - found = bfd_find_nearest_line (abfd, section, syms, pc - vma, - &filename, &functionname, &line); + found = bfd_find_nearest_line_discriminator (abfd, section, syms, pc - vma, + &filename, &functionname, + &line, &discriminator); } /* Look for an offset in a section. This is directly called. */ @@ -179,15 +208,16 @@ find_offset_in_section (bfd *abfd, asection *section) if (found) return; - if ((bfd_get_section_flags (abfd, section) & SEC_ALLOC) == 0) + if ((bfd_section_flags (section) & SEC_ALLOC) == 0) return; - size = bfd_get_section_size (section); + size = bfd_section_size (section); if (pc >= size) return; - found = bfd_find_nearest_line (abfd, section, syms, pc, - &filename, &functionname, &line); + found = bfd_find_nearest_line_discriminator (abfd, section, syms, pc, + &filename, &functionname, + &line, &discriminator); } /* Read hexadecimal addresses from stdin, translate into @@ -196,8 +226,6 @@ find_offset_in_section (bfd *abfd, asection *section) static void translate_addresses (bfd *abfd, asection *section) { - const struct elf_backend_data * bed; - int read_stdin = (naddr == 0); for (;;) @@ -218,11 +246,15 @@ translate_addresses (bfd *abfd, asection *section) pc = bfd_scan_vma (*addr++, NULL, 16); } - if (bfd_get_flavour (abfd) == bfd_target_elf_flavour - && (bed = get_elf_backend_data (abfd)) != NULL - && bed->sign_extend_vma - && (pc & (bfd_vma) 1 << (bed->s->arch_size - 1))) - pc |= ((bfd_vma) -1) << bed->s->arch_size; + if (bfd_get_flavour (abfd) == bfd_target_elf_flavour) + { + const struct elf_backend_data *bed = get_elf_backend_data (abfd); + bfd_vma sign = (bfd_vma) 1 << (bed->s->arch_size - 1); + + pc &= (sign << 1) - 1; + if (bed->sign_extend_vma) + pc = (pc ^ sign) - sign; + } if (with_addresses) { @@ -244,7 +276,12 @@ translate_addresses (bfd *abfd, asection *section) if (! found) { if (with_functions) - printf ("??\n"); + { + if (pretty_print) + printf ("?? "); + else + printf ("??\n"); + } printf ("??:0\n"); } else @@ -261,19 +298,23 @@ translate_addresses (bfd *abfd, asection *section) name = "??"; else if (do_demangle) { - alloc = bfd_demangle (abfd, name, DMGL_ANSI | DMGL_PARAMS); + alloc = bfd_demangle (abfd, name, demangle_flags); if (alloc != NULL) name = alloc; } printf ("%s", name); if (pretty_print) + /* Note for translators: This printf is used to join the + function name just printed above to the line number/ + file name pair that is about to be printed below. Eg: + + foo at 123:bar.c */ printf (_(" at ")); else printf ("\n"); - if (alloc != NULL) - free (alloc); + free (alloc); } if (base_names && filename != NULL) @@ -285,14 +326,30 @@ translate_addresses (bfd *abfd, asection *section) filename = h + 1; } - printf ("%s:%u\n", filename ? filename : "??", line); + printf ("%s:", filename ? filename : "??"); + if (line != 0) + { + if (discriminator != 0) + printf ("%u (discriminator %u)\n", line, discriminator); + else + printf ("%u\n", line); + } + else + printf ("?\n"); if (!unwind_inlines) found = FALSE; else - found = bfd_find_inliner_info (abfd, &filename, &functionname, &line); + found = bfd_find_inliner_info (abfd, &filename, &functionname, + &line); if (! found) break; if (pretty_print) + /* Note for translators: This printf is used to join the + line number/file name pair that has just been printed with + the line number/file name pair that is going to be printed + by the next iteration of the while loop. Eg: + + 123:bar.c (inlined by) 456:main.c */ printf (_(" (inlined by) ")); } } @@ -352,11 +409,8 @@ process_file (const char *file_name, const char *section_name, translate_addresses (abfd, section); - if (syms != NULL) - { - free (syms); - syms = NULL; - } + free (syms); + syms = NULL; bfd_close (abfd); @@ -382,16 +436,18 @@ main (int argc, char **argv) program_name = *argv; xmalloc_set_program_name (program_name); + bfd_set_error_program_name (program_name); expandargv (&argc, &argv); - bfd_init (); + if (bfd_init () != BFD_INIT_MAGIC) + fatal (_("fatal error: libbfd ABI mismatch")); set_default_bfd_target (); file_name = NULL; section_name = NULL; target = NULL; - while ((c = getopt_long (argc, argv, "ab:Ce:sfHhij:pVv", long_options, (int *) 0)) + while ((c = getopt_long (argc, argv, "ab:Ce:rRsfHhij:pVv", long_options, (int *) 0)) != EOF) { switch (c) @@ -418,6 +474,12 @@ main (int argc, char **argv) cplus_demangle_set_style (style); } break; + case 'r': + demangle_flags |= DMGL_NO_RECURSE_LIMIT; + break; + case 'R': + demangle_flags &= ~ DMGL_NO_RECURSE_LIMIT; + break; case 'e': file_name = optarg; break;