diff options
Diffstat (limited to 'opcodes')
-rw-r--r-- | opcodes/ChangeLog | 7 | ||||
-rw-r--r-- | opcodes/vax-dis.c | 45 |
2 files changed, 45 insertions, 7 deletions
diff --git a/opcodes/ChangeLog b/opcodes/ChangeLog index 0596631..156a82a 100644 --- a/opcodes/ChangeLog +++ b/opcodes/ChangeLog @@ -1,3 +1,10 @@ +2009-06-16 Maciej W. Rozycki <macro@linux-mips.org> + + * vax-dis.c (is_function_entry): Return success for synthetic + symbols too. + (is_plt_tail): New function. + (print_insn_vax): Decode PLT entry offset longword. + 2009-06-15 Nick Clifton <nickc@redhat.com> PR 10186 diff --git a/opcodes/vax-dis.c b/opcodes/vax-dis.c index 8c47437..63884f6 100644 --- a/opcodes/vax-dis.c +++ b/opcodes/vax-dis.c @@ -171,21 +171,24 @@ free_entry_array (void) } } #endif -/* Check if the given address is a known function entry. Either there must - be a symbol of function type at this address, or the address must be - a forced entry point. The later helps in disassembling ROM images, because - there's no symbol table at all. Forced entry points can be given by - supplying several -M options to objdump: -M entry:0xffbb7730. */ +/* Check if the given address is a known function entry point. This is + the case if there is a symbol of the function type at this address. + We also check for synthetic symbols as these are used for PLT entries + (weak undefined symbols may not have the function type set). Finally + the address may have been forced to be treated as an entry point. The + latter helps in disassembling ROM images, because there's no symbol + table at all. Forced entry points can be given by supplying several + -M options to objdump: -M entry:0xffbb7730. */ static bfd_boolean is_function_entry (struct disassemble_info *info, bfd_vma addr) { unsigned int i; - /* Check if there's a BSF_FUNCTION symbol at our address. */ + /* Check if there's a function or PLT symbol at our address. */ if (info->symbols && info->symbols[0] - && (info->symbols[0]->flags & BSF_FUNCTION) + && (info->symbols[0]->flags & (BSF_FUNCTION | BSF_SYNTHETIC)) && addr == bfd_asymbol_value (info->symbols[0])) return TRUE; @@ -197,6 +200,22 @@ is_function_entry (struct disassemble_info *info, bfd_vma addr) return FALSE; } +/* Check if the given address is the last longword of a PLT entry. + This longword is data and depending on the value it may interfere + with disassembly of further PLT entries. We make use of the fact + PLT symbols are marked BSF_SYNTHETIC. */ +static bfd_boolean +is_plt_tail (struct disassemble_info *info, bfd_vma addr) +{ + if (info->symbols + && info->symbols[0] + && (info->symbols[0]->flags & BSF_SYNTHETIC) + && addr == bfd_asymbol_value (info->symbols[0]) + 8) + return TRUE; + + return FALSE; +} + static int print_insn_mode (const char *d, int size, @@ -412,6 +431,18 @@ print_insn_vax (bfd_vma memaddr, disassemble_info *info) return 2; } + /* Decode PLT entry offset longword. */ + if (is_plt_tail (info, memaddr)) + { + int offset; + + FETCH_DATA (info, buffer + 4); + offset = buffer[3] << 24 | buffer[2] << 16 | buffer[1] << 8 | buffer[0]; + (*info->fprintf_func) (info->stream, ".long 0x%08x", offset); + + return 4; + } + for (votp = &votstrs[0]; votp->name[0]; votp++) { vax_opcodeT opcode = votp->detail.code; |