aboutsummaryrefslogtreecommitdiff
path: root/binutils
diff options
context:
space:
mode:
authorAlan Modra <amodra@gmail.com>2021-04-06 19:03:35 +0930
committerAlan Modra <amodra@gmail.com>2021-04-09 16:56:43 +0930
commitc3f72de4f53bc3e5f13762633d78d8a7efb8dd79 (patch)
treed1be8ec3633ed86a3451c392d0202444f9a72f6e /binutils
parent39178037a1cd78fed67b82aeec0313817c079c2a (diff)
downloadgdb-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/ChangeLog7
-rw-r--r--binutils/objdump.c56
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);
}