From ce04548af9eafaa2034f081247a21ff3fcfede15 Mon Sep 17 00:00:00 2001 From: Nick Clifton Date: Tue, 1 Mar 2005 15:18:44 +0000 Subject: [PATCH] objdump.c: Fix coding for DISASSEMBLER_NEEDS_RELOC: (struct objdump_disasm_info): Add 'reloc' field. (disassemble_bytes): Fix check for when an insn has a reloc associated with it. Improve comment explaining why the use of octets is wrong. Set the 'reloc' field in objdump_disasm_info structure. (objdump_print_addr): Use new 'reloc' field to lookup the correct address for the symbol associated with the current instruction's relocation. (disassemble_info): Initialise 'reloc' field. gas/arm/inst.d: Allow for ARM ports which decode the reloc associated with branches and so show the exact symbolic destination address rather than an offset from the start of the section. gas/arm/pic.d: Likewise. --- binutils/ChangeLog | 14 ++++++++ binutils/objdump.c | 79 +++++++++++++++++++++++++++++++++++++------- gas/testsuite/ChangeLog | 9 +++++ gas/testsuite/gas/arm/inst.d | 8 ++--- gas/testsuite/gas/arm/pic.d | 2 +- 5 files changed, 95 insertions(+), 17 deletions(-) diff --git a/binutils/ChangeLog b/binutils/ChangeLog index 96cd194..0899afc 100644 --- a/binutils/ChangeLog +++ b/binutils/ChangeLog @@ -1,3 +1,17 @@ +2005-03-01 Stig Petter Olsroed + Nick Clifton + + * objdump.c: Fix coding for DISASSEMBLER_NEEDS_RELOC: + (struct objdump_disasm_info): Add 'reloc' field. + (disassemble_bytes): Fix check for when an insn has a reloc + associated with it. Improve comment explaining why the use of + octets is wrong. Set the 'reloc' field in objdump_disasm_info + structure. + (objdump_print_addr): Use new 'reloc' field to lookup the correct + address for the symbol associated with the current instruction's + relocation. + (disassemble_info): Initialise 'reloc' field. + 2005-02-28 Jakub Jelinek * readelf.c (get_file_type, get_machine_name, get_osabi_name, diff --git a/binutils/objdump.c b/binutils/objdump.c index f63e298..a336089 100644 --- a/binutils/objdump.c +++ b/binutils/objdump.c @@ -128,6 +128,9 @@ struct objdump_disasm_info arelent ** dynrelbuf; long dynrelcount; disassembler_ftype disassemble_fn; +#ifdef DISASSEMBLER_NEEDS_RELOCS + arelent * reloc; +#endif }; /* Architecture to disassemble for, or default if NULL. */ @@ -852,6 +855,9 @@ objdump_print_addr (bfd_vma vma, { struct objdump_disasm_info *aux; asymbol *sym; +#ifdef DISASSEMBLER_NEEDS_RELOCS + bfd_boolean skip_find = FALSE; +#endif if (sorted_symcount < 1) { @@ -861,7 +867,25 @@ objdump_print_addr (bfd_vma vma, } aux = (struct objdump_disasm_info *) info->application_data; - sym = find_symbol_for_address (vma, info, NULL); + +#ifdef DISASSEMBLER_NEEDS_RELOCS + if (aux->reloc != NULL + && aux->reloc->sym_ptr_ptr != NULL + && * aux->reloc->sym_ptr_ptr != NULL) + { + sym = * aux->reloc->sym_ptr_ptr; + + /* Adjust the vma to the reloc. */ + vma += bfd_asymbol_value (sym); + + if (bfd_is_und_section (bfd_get_section (sym))) + skip_find = TRUE; + } + + if (!skip_find) +#endif + sym = find_symbol_for_address (vma, info, NULL); + objdump_print_addr_with_sym (aux->abfd, aux->sec, sym, vma, info, skip_zeroes); } @@ -1238,6 +1262,7 @@ disassemble_bytes (struct disassemble_info * info, unsigned int opb = info->octets_per_byte; unsigned int skip_zeroes = info->skip_zeroes; unsigned int skip_zeroes_at_end = info->skip_zeroes_at_end; + int octets = opb; SFILE sfile; aux = (struct objdump_disasm_info *) info->application_data; @@ -1282,8 +1307,14 @@ disassemble_bytes (struct disassemble_info * info, while (addr_offset < stop_offset) { bfd_vma z; - int octets = 0; bfd_boolean need_nl = FALSE; +#ifdef DISASSEMBLER_NEEDS_RELOCS + int previous_octets; + + /* Remember the length of the previous instruction. */ + previous_octets = octets; +#endif + octets = 0; /* If we see more than SKIP_ZEROES octets of zeroes, we just print `...'. */ @@ -1348,19 +1379,40 @@ disassemble_bytes (struct disassemble_info * info, info->stream = (FILE *) &sfile; info->bytes_per_line = 0; info->bytes_per_chunk = 0; + info->flags = 0; #ifdef DISASSEMBLER_NEEDS_RELOCS - /* FIXME: This is wrong. It tests the number of octets - in the last instruction, not the current one. */ - if (*relppp < relppend - && (**relppp)->address >= rel_offset + addr_offset - && ((**relppp)->address - < rel_offset + addr_offset + octets / opb)) - info->flags = INSN_HAS_RELOC; - else + if (*relppp < relppend) + { + bfd_signed_vma distance_to_rel; + + distance_to_rel = (**relppp)->address + - (rel_offset + addr_offset); + + /* Check to see if the current reloc is associated with + the instruction that we are about to disassemble. */ + if (distance_to_rel == 0 + /* FIXME: This is wrong. We are trying to catch + relocs that are addressed part way through the + current instruction, as might happen with a packed + VLIW instruction. Unfortunately we do not know the + length of the current instruction since we have not + disassembled it yet. Instead we take a guess based + upon the length of the previous instruction. The + proper solution is to have a new target-specific + disassembler function which just returns the length + of an instruction at a given address without trying + to display its disassembly. */ + || (distance_to_rel > 0 + && distance_to_rel < (bfd_signed_vma) (previous_octets/ opb))) + { + info->flags = INSN_HAS_RELOC; + aux->reloc = **relppp; + } + else + aux->reloc = NULL; + } #endif - info->flags = 0; - octets = (*disassemble_fn) (section->vma + addr_offset, info); info->fprintf_func = (fprintf_ftype) fprintf; info->stream = stdout; @@ -1817,6 +1869,9 @@ disassemble_data (bfd *abfd) aux.require_sec = FALSE; aux.dynrelbuf = NULL; aux.dynrelcount = 0; +#ifdef DISASSEMBLER_NEEDS_RELOCS + aux.reloc = NULL; +#endif disasm_info.print_address_func = objdump_print_address; disasm_info.symbol_at_address_func = objdump_symbol_at_address; diff --git a/gas/testsuite/ChangeLog b/gas/testsuite/ChangeLog index 12cf4aa..87bef55 100644 --- a/gas/testsuite/ChangeLog +++ b/gas/testsuite/ChangeLog @@ -1,3 +1,12 @@ +2005-03-01 Stig Petter Olsroed + Nick Clifton + + * gas/arm/inst.d: Allow for ARM ports which decode the reloc + associated with branches and so show the exact symbolic + destination address rather than an offset from the start of the + section. + * gas/arm/pic.d: Likewise. + 2005-03-01 Alan Modra * gas/m68k/mcf-emac.d: Allow for 64-bit addresses. diff --git a/gas/testsuite/gas/arm/inst.d b/gas/testsuite/gas/arm/inst.d index 6067fe9..1b35684 100644 --- a/gas/testsuite/gas/arm/inst.d +++ b/gas/testsuite/gas/arm/inst.d @@ -159,13 +159,13 @@ Disassembly of section .text: 0+254 <[^>]*> e9c40300 ? stmib r4, {r8, r9}\^ 0+258 <[^>]*> ef123456 ? swi 0x00123456 0+25c <[^>]*> 2f000033 ? swics 0x00000033 -0+260 <[^>]*> ebfffffe ? bl 0+260 <[^>]*> +0+260 <[^>]*> ebfffffe ? bl 0[0123456789abcdef]+ <[^>]*> [ ]*260:.*_wombat.* -0+264 <[^>]*> 5bfffffe ? blpl 0+264 <[^>]*> +0+264 <[^>]*> 5bfffffe ? blpl 0[0123456789abcdef]+ <[^>]*> [ ]*264:.*ARM.*hohum -0+268 <[^>]*> eafffffe ? b 0+268 <[^>]*> +0+268 <[^>]*> eafffffe ? b 0[0123456789abcdef]+ <[^>]*> [ ]*268:.*_wibble.* -0+26c <[^>]*> dafffffe ? ble 0+26c <[^>]*> +0+26c <[^>]*> dafffffe ? ble 0[0123456789abcdef]+ <[^>]*> [ ]*26c:.*testerfunc.* 0+270 <[^>]*> e1a01102 ? mov r1, r2, lsl #2 0+274 <[^>]*> e1a01002 ? mov r1, r2 diff --git a/gas/testsuite/gas/arm/pic.d b/gas/testsuite/gas/arm/pic.d index 2697136..5db6a61 100644 --- a/gas/testsuite/gas/arm/pic.d +++ b/gas/testsuite/gas/arm/pic.d @@ -8,7 +8,7 @@ Disassembly of section .text: 00+0 <[^>]*> ebfffffe bl 00+0 <[^>]*> 0: R_ARM_PC24 foo -00+4 <[^>]*> ebfffffe bl 00+4 <[^>]*> +00+4 <[^>]*> ebfffffe bl 0[0123456789abcdef]+ <[^>]*> 4: R_ARM_PLT32 foo \.\.\. 8: R_ARM_ABS32 sym -- 2.7.4