diff options
author | Alan Modra <amodra@gmail.com> | 2021-04-06 19:03:35 +0930 |
---|---|---|
committer | Alan Modra <amodra@gmail.com> | 2021-04-09 16:56:43 +0930 |
commit | c3f72de4f53bc3e5f13762633d78d8a7efb8dd79 (patch) | |
tree | d1be8ec3633ed86a3451c392d0202444f9a72f6e /binutils | |
parent | 39178037a1cd78fed67b82aeec0313817c079c2a (diff) | |
download | gdb-c3f72de4f53bc3e5f13762633d78d8a7efb8dd79.zip gdb-c3f72de4f53bc3e5f13762633d78d8a7efb8dd79.tar.gz gdb-c3f72de4f53bc3e5f13762633d78d8a7efb8dd79.tar.bz2 |
PowerPC disassembly of pcrel references
This adds some annotation to Power10 pcrel instructions, displaying
the target address (ie. pc + D34 field) plus a symbol if there is one
at exactly that target address. pld from the .got or .plt will also
look up the entry and display it, symbolically if there is a dynamic
relocation on the entry.
include/
* dis-asm.h (struct disassemble_info): Add dynrelbuf and dynrelcount.
binutils/
* objdump.c (struct objdump_disasm_info): Delete dynrelbuf and
dynrelcount.
(find_symbol_for_address): Adjust for dynrelbuf and dynrelcount move.
(disassemble_section, disassemble_data): Likewise.
opcodes/
* ppc-dis.c (struct dis_private): Add "special".
(POWERPC_DIALECT): Delete. Replace uses with..
(private_data): ..this. New inline function.
(disassemble_init_powerpc): Init "special" names.
(skip_optional_operands): Add is_pcrel arg, set when detecting R
field of prefix instructions.
(bsearch_reloc, print_got_plt): New functions.
(print_insn_powerpc): For pcrel instructions, print target address
and symbol if known, and decode plt and got loads too.
gas/
* testsuite/gas/ppc/prefix-pcrel.d: Update expected output.
* testsuite/gas/ppc/prefix-reloc.d: Likewise.
* gas/testsuite/gas/ppc/vsx_32byte.d: Likewise.
ld/
* testsuite/ld-powerpc/inlinepcrel-1.d: Update expected output.
* testsuite/ld-powerpc/inlinepcrel-2.d: Likewise.
* testsuite/ld-powerpc/notoc2.d: Likewise.
* testsuite/ld-powerpc/notoc3.d: Likewise.
* testsuite/ld-powerpc/pcrelopt.d: Likewise.
* testsuite/ld-powerpc/startstop.d: Likewise.
* testsuite/ld-powerpc/tlsget.d: Likewise.
* testsuite/ld-powerpc/tlsget2.d: Likewise.
* testsuite/ld-powerpc/tlsld.d: Likewise.
* testsuite/ld-powerpc/weak1.d: Likewise.
* testsuite/ld-powerpc/weak1so.d: Likewise.
Diffstat (limited to 'binutils')
-rw-r--r-- | binutils/ChangeLog | 7 | ||||
-rw-r--r-- | binutils/objdump.c | 56 |
2 files changed, 33 insertions, 30 deletions
diff --git a/binutils/ChangeLog b/binutils/ChangeLog index 413757d..9e88373 100644 --- a/binutils/ChangeLog +++ b/binutils/ChangeLog @@ -1,3 +1,10 @@ +2021-04-09 Alan Modra <amodra@gmail.com> + + * objdump.c (struct objdump_disasm_info): Delete dynrelbuf and + dynrelcount. + (find_symbol_for_address): Adjust for dynrelbuf and dynrelcount move. + (disassemble_section, disassemble_data): Likewise. + 2021-04-06 Alan Modra <amodra@gmail.com> * objdump.c (objdump_symbol_at_address): Return asymbol*. diff --git a/binutils/objdump.c b/binutils/objdump.c index ea80a70..3e6bf72 100644 --- a/binutils/objdump.c +++ b/binutils/objdump.c @@ -153,8 +153,6 @@ struct objdump_disasm_info { bfd *abfd; bool require_sec; - arelent **dynrelbuf; - long dynrelcount; disassembler_ftype disassemble_fn; arelent *reloc; const char *symbol; @@ -1270,20 +1268,20 @@ find_symbol_for_address (bfd_vma vma, 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. */ - rel_count = aux->dynrelcount; + rel_count = inf->dynrelcount; if (!want_section && sorted_syms[thisplace]->value != vma && rel_count > 0 - && aux->dynrelbuf != NULL - && aux->dynrelbuf[0]->address <= vma - && aux->dynrelbuf[rel_count - 1]->address >= vma + && inf->dynrelbuf != NULL + && inf->dynrelbuf[0]->address <= vma + && inf->dynrelbuf[rel_count - 1]->address >= vma /* If we have matched a synthetic symbol, then stick with that. */ && (sorted_syms[thisplace]->flags & BSF_SYNTHETIC) == 0) { arelent ** rel_low; arelent ** rel_high; - rel_low = aux->dynrelbuf; + rel_low = inf->dynrelbuf; rel_high = rel_low + rel_count - 1; while (rel_low <= rel_high) { @@ -3116,10 +3114,10 @@ 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 && dump_dynamic_reloc_info) + if (pinfo->dynrelbuf && dump_dynamic_reloc_info) { - rel_pp = paux->dynrelbuf; - rel_count = paux->dynrelcount; + rel_pp = pinfo->dynrelbuf; + rel_count = pinfo->dynrelcount; /* Dynamic reloc addresses are absolute, non-dynamic are section relative. REL_OFFSET specifies the reloc address corresponding to the start of this section. */ @@ -3455,8 +3453,8 @@ disassemble_data (bfd *abfd) disasm_info.application_data = (void *) &aux; aux.abfd = abfd; aux.require_sec = false; - aux.dynrelbuf = NULL; - aux.dynrelcount = 0; + disasm_info.dynrelbuf = NULL; + disasm_info.dynrelcount = 0; aux.reloc = NULL; aux.symbol = disasm_sym; @@ -3519,33 +3517,31 @@ disassemble_data (bfd *abfd) disassemble_init_for_target (& disasm_info); /* Pre-load the dynamic relocs as we may need them during the disassembly. */ - { - long relsize = bfd_get_dynamic_reloc_upper_bound (abfd); + long relsize = bfd_get_dynamic_reloc_upper_bound (abfd); - if (relsize < 0 && dump_dynamic_reloc_info) - bfd_fatal (bfd_get_filename (abfd)); + if (relsize < 0 && dump_dynamic_reloc_info) + bfd_fatal (bfd_get_filename (abfd)); - if (relsize > 0) - { - aux.dynrelbuf = (arelent **) xmalloc (relsize); - aux.dynrelcount = bfd_canonicalize_dynamic_reloc (abfd, - aux.dynrelbuf, - dynsyms); - if (aux.dynrelcount < 0) - bfd_fatal (bfd_get_filename (abfd)); + if (relsize > 0) + { + disasm_info.dynrelbuf = (arelent **) xmalloc (relsize); + disasm_info.dynrelcount + = bfd_canonicalize_dynamic_reloc (abfd, disasm_info.dynrelbuf, dynsyms); + if (disasm_info.dynrelcount < 0) + bfd_fatal (bfd_get_filename (abfd)); - /* Sort the relocs by address. */ - qsort (aux.dynrelbuf, aux.dynrelcount, sizeof (arelent *), - compare_relocs); - } + /* Sort the relocs by address. */ + qsort (disasm_info.dynrelbuf, disasm_info.dynrelcount, sizeof (arelent *), + compare_relocs); } + disasm_info.symtab = sorted_syms; disasm_info.symtab_size = sorted_symcount; bfd_map_over_sections (abfd, disassemble_section, & disasm_info); - if (aux.dynrelbuf != NULL) - free (aux.dynrelbuf); + free (disasm_info.dynrelbuf); + disasm_info.dynrelbuf = NULL; free (sorted_syms); disassemble_free_target (&disasm_info); } |