diff options
Diffstat (limited to 'binutils')
-rw-r--r-- | binutils/ChangeLog | 15 | ||||
-rw-r--r-- | binutils/objdump.c | 81 |
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) |