aboutsummaryrefslogtreecommitdiff
path: root/binutils
diff options
context:
space:
mode:
Diffstat (limited to 'binutils')
-rw-r--r--binutils/ChangeLog15
-rw-r--r--binutils/objdump.c81
2 files changed, 87 insertions, 9 deletions
diff --git a/binutils/ChangeLog b/binutils/ChangeLog
index 8512827..a4cbad6 100644
--- a/binutils/ChangeLog
+++ b/binutils/ChangeLog
@@ -1,3 +1,18 @@
+2016-10-11 Nick Clifton <nickc@redhat.com>
+
+ * objdump.c (is_significant_symbol_name): New function.
+ (remove_useless_symbols): Do not remove significanr symbols.
+ (find_symbol_for_address): If an exact match for the specified
+ address has not been found, try scanning the dynamic relocs to see
+ if one of these matches the address. If so, use the symbol
+ associated with the reloc.
+ (objdump_print_addr_with_symbol): Do not print offsets to symbols
+ with no value.
+ (disassemble_section): Only use dynamic relocs if the user
+ requested this.
+ (disassemble_data): Always load dynamic relocs if they are
+ available.
+
2016-10-06 Alan Modra <amodra@gmail.com>
* dlltool.c: Spell fall through comments consistently.
diff --git a/binutils/objdump.c b/binutils/objdump.c
index 2d2bddb..59abc11 100644
--- a/binutils/objdump.c
+++ b/binutils/objdump.c
@@ -615,6 +615,18 @@ slurp_dynamic_symtab (bfd *abfd)
return sy;
}
+/* Some symbol names are significant and should be kept in the
+ table of sorted symbol names, even if they are marked as
+ debugging/section symbols. */
+
+static bfd_boolean
+is_significant_symbol_name (const char * name)
+{
+ return strcmp (name, ".plt") == 0
+ || strcmp (name, ".got") == 0
+ || strcmp (name, ".plt.got") == 0;
+}
+
/* Filter out (in place) symbols that are useless for disassembly.
COUNT is the number of elements in SYMBOLS.
Return the number of useful symbols. */
@@ -630,7 +642,8 @@ remove_useless_symbols (asymbol **symbols, long count)
if (sym->name == NULL || sym->name[0] == '\0')
continue;
- if (sym->flags & (BSF_DEBUGGING | BSF_SECTION_SYM))
+ if ((sym->flags & (BSF_DEBUGGING | BSF_SECTION_SYM))
+ && ! is_significant_symbol_name (sym->name))
continue;
if (bfd_is_und_section (sym->section)
|| bfd_is_com_section (sym->section))
@@ -913,11 +926,14 @@ find_symbol_for_address (bfd_vma vma,
/* The symbol we want is now in min, the low end of the range we
were searching. If there are several symbols with the same
- value, we want the first one. */
+ value, we want the first (non-section/non-debugging) one. */
thisplace = min;
while (thisplace > 0
&& (bfd_asymbol_value (sorted_syms[thisplace])
- == bfd_asymbol_value (sorted_syms[thisplace - 1])))
+ == bfd_asymbol_value (sorted_syms[thisplace - 1]))
+ && ((sorted_syms[thisplace - 1]->flags
+ & (BSF_SECTION_SYM | BSF_DEBUGGING)) == 0)
+ )
--thisplace;
/* Prefer a symbol in the current section if we have multple symbols
@@ -1003,6 +1019,41 @@ find_symbol_for_address (bfd_vma vma,
return NULL;
}
+ /* If we have not found an exact match for the specified address
+ and we have dynamic relocations available, then we can produce
+ a better result by matching a relocation to the address and
+ using the symbol associated with that relocation. */
+ if (!want_section
+ && aux->dynrelbuf != NULL
+ && sorted_syms[thisplace]->value != vma
+ /* If we have matched a synthetic symbol, then stick with that. */
+ && (sorted_syms[thisplace]->flags & BSF_SYNTHETIC) == 0)
+ {
+ long rel_count;
+ arelent ** rel_pp;
+
+ for (rel_count = aux->dynrelcount, rel_pp = aux->dynrelbuf;
+ rel_count--;)
+ {
+ arelent * rel = rel_pp[rel_count];
+
+ if (rel->address == vma
+ && rel->sym_ptr_ptr != NULL
+ /* Absolute relocations do not provide a more helpful symbolic address. */
+ && ! bfd_is_abs_section ((* rel->sym_ptr_ptr)->section))
+ {
+ if (place != NULL)
+ * place = thisplace;
+ return * rel->sym_ptr_ptr;
+ }
+
+ /* We are scanning backwards, so if we go below the target address
+ we have failed. */
+ if (rel_pp[rel_count]->address < vma)
+ break;
+ }
+ }
+
if (place != NULL)
*place = thisplace;
@@ -1040,8 +1091,21 @@ objdump_print_addr_with_sym (bfd *abfd, asection *sec, asymbol *sym,
else
{
(*inf->fprintf_func) (inf->stream, " <");
+
objdump_print_symname (abfd, inf, sym);
- if (bfd_asymbol_value (sym) > vma)
+
+ if (bfd_asymbol_value (sym) == vma)
+ ;
+ /* Undefined symbols in an executables and dynamic objects do not have
+ a value associated with them, so it does not make sense to display
+ an offset relative to them. Normally we would not be provided with
+ this kind of symbol, but the target backend might choose to do so,
+ and the code in find_symbol_for_address might return an as yet
+ unresolved symbol associated with a dynamic reloc. */
+ else if ((bfd_get_file_flags (abfd) & (EXEC_P | DYNAMIC))
+ && bfd_is_und_section (sym->section))
+ ;
+ else if (bfd_asymbol_value (sym) > vma)
{
(*inf->fprintf_func) (inf->stream, "-0x");
objdump_print_value (bfd_asymbol_value (sym) - vma, inf, TRUE);
@@ -1051,6 +1115,7 @@ objdump_print_addr_with_sym (bfd *abfd, asection *sec, asymbol *sym,
(*inf->fprintf_func) (inf->stream, "+0x");
objdump_print_value (vma - bfd_asymbol_value (sym), inf, TRUE);
}
+
(*inf->fprintf_func) (inf->stream, ">");
}
@@ -2006,7 +2071,7 @@ disassemble_section (bfd *abfd, asection *section, void *inf)
/* Decide which set of relocs to use. Load them if necessary. */
paux = (struct objdump_disasm_info *) pinfo->application_data;
- if (paux->dynrelbuf)
+ if (paux->dynrelbuf && dump_dynamic_reloc_info)
{
rel_pp = paux->dynrelbuf;
rel_count = paux->dynrelcount;
@@ -2283,13 +2348,11 @@ disassemble_data (bfd *abfd)
/* Allow the target to customize the info structure. */
disassemble_init_for_target (& disasm_info);
- /* Pre-load the dynamic relocs if we are going
- to be dumping them along with the disassembly. */
- if (dump_dynamic_reloc_info)
+ /* Pre-load the dynamic relocs as we may need them during the disassembly. */
{
long relsize = bfd_get_dynamic_reloc_upper_bound (abfd);
- if (relsize < 0)
+ if (relsize < 0 && dump_dynamic_reloc_info)
bfd_fatal (bfd_get_filename (abfd));
if (relsize > 0)