aboutsummaryrefslogtreecommitdiff
path: root/opcodes/arm-dis.c
diff options
context:
space:
mode:
authorDaniel Jacobowitz <drow@false.org>2004-11-17 17:50:28 +0000
committerDaniel Jacobowitz <drow@false.org>2004-11-17 17:50:28 +0000
commitb7693d02137c80845e6878f5efea94f7162bd77b (patch)
treec5cb392f78908c476f9201c8eca2d64463a41b0d /opcodes/arm-dis.c
parente2cb164148ad40db646a7ce8d0d02beb981ed915 (diff)
downloadgdb-b7693d02137c80845e6878f5efea94f7162bd77b.zip
gdb-b7693d02137c80845e6878f5efea94f7162bd77b.tar.gz
gdb-b7693d02137c80845e6878f5efea94f7162bd77b.tar.bz2
bfd/
* elf32-arm.c (PLT_THUMB_STUB_SIZE): Define. (elf32_arm_plt_thumb_stub): New. (struct elf32_arm_link_hash_entry): Add plt_thumb_refcount and plt_got_offset. (elf32_arm_link_hash_traverse): Fix typo. (elf32_arm_link_hash_table): Add obfd. (elf32_arm_link_hash_newfunc): Initialize new fields. (elf32_arm_copy_indirect_symbol): Copy plt_thumb_refcount. (elf32_arm_link_hash_table_create): Initialize obfd. (record_arm_to_thumb_glue): Mark the glue as a local ARM function. (record_thumb_to_arm_glue): Mark the glue as a local Thumb function. (bfd_elf32_arm_get_bfd_for_interworking): Verify that the interworking BFD is not dynamic. (bfd_elf32_arm_process_before_allocation): Handle R_ARM_PLT32. Do not emit glue for PLT references. (elf32_arm_final_link_relocate): Handle Thumb functions. Do not emit glue for PLT references. Support the Thumb PLT prefix. (elf32_arm_gc_sweep_hook): Handle R_ARM_THM_PC22 and plt_thumb_refcount. (elf32_arm_check_relocs): Likewise. (elf32_arm_adjust_dynamic_symbol): Handle Thumb functions and plt_thumb_refcount. (allocate_dynrelocs): Handle Thumb PLT references. (elf32_arm_finish_dynamic_symbol): Likewise. (elf32_arm_symbol_processing): New function. (elf_backend_symbol_processing): Define. opcodes/ * arm-dis.c (WORD_ADDRESS): Define. (print_insn): Use it. Correct big-endian end-of-section handling. gas/testsuite/ * gas/arm/mapping.d: Expect F markers for Thumb code. * gas/arm/unwind.d: Update big-endian pattern. ld/ * emultempl/armelf.em (arm_elf_set_bfd_for_interworking): Don't use a dynamic object for stubs. ld/testsuite/ * ld-arm/mixed-app.d, ld-arm/mixed-app.r, ld-arm/mixed-app.s, ld-arm/mixed-app.sym, ld-arm/mixed-lib.d, ld-arm/mixed-lib.r, ld-arm/mixed-lib.s, ld-arm/mixed-lib.sym, ld-arm/arm-dyn.ld, ld-arm/arm-lib.ld: New files. * ld-arm/arm-app-abs32.d, ld-arm/arm-app-abs32.r, ld-arm/arm-app.d, ld-arm/arm-app.r, ld-arm/arm-lib-plt32.d, ld-arm/arm-lib-plt32.r, ld-arm/arm-lib.d, ld-arm/arm-lib.r, ld-arm/arm-static-app.d, ld-arm/arm-static-app.r: Update for big-endian. * ld-arm/arm-elf.exp: Run the new tests.
Diffstat (limited to 'opcodes/arm-dis.c')
-rw-r--r--opcodes/arm-dis.c26
1 files changed, 16 insertions, 10 deletions
diff --git a/opcodes/arm-dis.c b/opcodes/arm-dis.c
index 44cdeac..b598739 100644
--- a/opcodes/arm-dis.c
+++ b/opcodes/arm-dis.c
@@ -46,6 +46,8 @@
#define NUM_ELEM(a) (sizeof (a) / sizeof (a)[0])
#endif
+#define WORD_ADDRESS(pc) ((pc) & ~0x3)
+
static char * arm_conditional[] =
{"eq", "ne", "cs", "cc", "mi", "pl", "vs", "vc",
"hi", "ls", "ge", "lt", "gt", "le", "", "nv"};
@@ -1253,7 +1255,7 @@ print_insn (pc, info, little)
unsigned char b[4];
long given;
int status;
- int is_thumb;
+ int is_thumb, second_half_valid = 1;
if (info->disassembler_options)
{
@@ -1299,6 +1301,7 @@ print_insn (pc, info, little)
if (status != 0 && is_thumb)
{
info->bytes_per_chunk = 2;
+ second_half_valid = 0;
status = info->read_memory_func (pc, (bfd_byte *) b, 2, info);
b[3] = b[2] = 0;
@@ -1315,10 +1318,10 @@ print_insn (pc, info, little)
else
{
status = info->read_memory_func
- (pc & ~ 0x3, (bfd_byte *) &b[0], 4, info);
+ (WORD_ADDRESS (pc), (bfd_byte *) &b[0], 4, info);
if (status != 0)
{
- info->memory_error_func (status, pc, info);
+ info->memory_error_func (status, WORD_ADDRESS (pc), info);
return -1;
}
@@ -1329,14 +1332,11 @@ print_insn (pc, info, little)
given = (b[2] << 8) | b[3];
status = info->read_memory_func
- ((pc + 4) & ~ 0x3, (bfd_byte *) b, 4, info);
+ (WORD_ADDRESS (pc + 4), (bfd_byte *) b, 4, info);
if (status != 0)
- {
- info->memory_error_func (status, pc + 4, info);
- return -1;
- }
-
- given |= (b[0] << 24) | (b[1] << 16);
+ second_half_valid = 0;
+ else
+ given |= (b[0] << 24) | (b[1] << 16);
}
else
given = (b[0] << 8) | b[1] | (b[2] << 24) | (b[3] << 16);
@@ -1358,6 +1358,12 @@ print_insn (pc, info, little)
else
status = print_insn_arm (pc, info, given);
+ if (is_thumb && status == 4 && second_half_valid == 0)
+ {
+ info->memory_error_func (status, WORD_ADDRESS (pc + 4), info);
+ return -1;
+ }
+
return status;
}