diff options
author | Daniel Jacobowitz <drow@false.org> | 2007-09-27 18:48:33 +0000 |
---|---|---|
committer | Daniel Jacobowitz <drow@false.org> | 2007-09-27 18:48:33 +0000 |
commit | daddc3c15f2b1e2d39bddea8e055a0e329b4035e (patch) | |
tree | 92ca8568bd6a3281c3ad02d2efec37a9bc1eef21 /gdb/arm-tdep.c | |
parent | 7c52e0e8658a0ea03067c301a15e793cf9f1c208 (diff) | |
download | gdb-daddc3c15f2b1e2d39bddea8e055a0e329b4035e.zip gdb-daddc3c15f2b1e2d39bddea8e055a0e329b4035e.tar.gz gdb-daddc3c15f2b1e2d39bddea8e055a0e329b4035e.tar.bz2 |
* arm-linux-tdep.c (arm_linux_software_single_step): New.
(arm_linux_init_abi): Use it.
* arm-tdep.c (arm_get_next_pc): Make global. Handle all-ones
condition correctly.
* arm-tdep.h (arm_get_next_pc): Declare.
* Makefile.in (arm-linux-tdep.o): Update.
Diffstat (limited to 'gdb/arm-tdep.c')
-rw-r--r-- | gdb/arm-tdep.c | 31 |
1 files changed, 25 insertions, 6 deletions
diff --git a/gdb/arm-tdep.c b/gdb/arm-tdep.c index b4d2211..325bd80 100644 --- a/gdb/arm-tdep.c +++ b/gdb/arm-tdep.c @@ -1664,7 +1664,7 @@ thumb_get_next_pc (struct frame_info *frame, CORE_ADDR pc) return nextpc; } -static CORE_ADDR +CORE_ADDR arm_get_next_pc (struct frame_info *frame, CORE_ADDR pc) { unsigned long pc_val; @@ -1680,7 +1680,30 @@ arm_get_next_pc (struct frame_info *frame, CORE_ADDR pc) status = get_frame_register_unsigned (frame, ARM_PS_REGNUM); nextpc = (CORE_ADDR) (pc_val + 4); /* Default case */ - if (condition_true (bits (this_instr, 28, 31), status)) + if (bits (this_instr, 28, 31) == INST_NV) + switch (bits (this_instr, 24, 27)) + { + case 0xa: + case 0xb: + { + /* Branch with Link and change to Thumb. */ + nextpc = BranchDest (pc, this_instr); + nextpc |= bit (this_instr, 24) << 1; + + nextpc = gdbarch_addr_bits_remove (current_gdbarch, nextpc); + if (nextpc == pc) + error (_("Infinite loop detected")); + break; + } + case 0xc: + case 0xd: + case 0xe: + /* Coprocessor register transfer. */ + if (bits (this_instr, 12, 15) == 15) + error (_("Invalid update to pc in instruction")); + break; + } + else if (condition_true (bits (this_instr, 28, 31), status)) { switch (bits (this_instr, 24, 27)) { @@ -1886,10 +1909,6 @@ arm_get_next_pc (struct frame_info *frame, CORE_ADDR pc) { nextpc = BranchDest (pc, this_instr); - /* BLX */ - if (bits (this_instr, 28, 31) == INST_NV) - nextpc |= bit (this_instr, 24) << 1; - nextpc = gdbarch_addr_bits_remove (current_gdbarch, nextpc); if (nextpc == pc) error (_("Infinite loop detected")); |