diff options
author | Nick Clifton <nickc@redhat.com> | 2005-03-01 15:18:44 +0000 |
---|---|---|
committer | Nick Clifton <nickc@redhat.com> | 2005-03-01 15:18:44 +0000 |
commit | ce04548af9eafaa2034f081247a21ff3fcfede15 (patch) | |
tree | be5ab939f6d3c9eb1219b097fa1fa5ef177a3021 /binutils | |
parent | b15c27d7c12d8c8d500a4f96693f6a7cff86aeaa (diff) | |
download | gdb-ce04548af9eafaa2034f081247a21ff3fcfede15.zip gdb-ce04548af9eafaa2034f081247a21ff3fcfede15.tar.gz gdb-ce04548af9eafaa2034f081247a21ff3fcfede15.tar.bz2 |
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.
Diffstat (limited to 'binutils')
-rw-r--r-- | binutils/ChangeLog | 14 | ||||
-rw-r--r-- | binutils/objdump.c | 79 |
2 files changed, 81 insertions, 12 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 <stigpo@users.sourceforge.net> + Nick Clifton <nickc@redhat.com> + + * 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 <jakub@redhat.com> * 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; |