/* 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-2014 Free Software Foundation, Inc.
Contributed by Ulrich Lauther <Ulrich.Lauther@mchp.siemens.de>
This file is part of GNU Binutils.
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);
+ }
}
\f
/* These global variables are used to pass information between
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
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. */
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
static void
translate_addresses (bfd *abfd, asection *section)
{
- const struct elf_backend_data * bed;
-
int read_stdin = (naddr == 0);
for (;;)
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)
{
if (! found)
{
if (with_functions)
- printf ("??\n");
+ {
+ if (pretty_print)
+ printf ("?? ");
+ else
+ printf ("??\n");
+ }
printf ("??:0\n");
}
else
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");
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) "));
}
}