aboutsummaryrefslogtreecommitdiff
path: root/gdb/arm-tdep.c
diff options
context:
space:
mode:
authorDaniel Jacobowitz <drow@false.org>2007-09-27 18:48:33 +0000
committerDaniel Jacobowitz <drow@false.org>2007-09-27 18:48:33 +0000
commitdaddc3c15f2b1e2d39bddea8e055a0e329b4035e (patch)
tree92ca8568bd6a3281c3ad02d2efec37a9bc1eef21 /gdb/arm-tdep.c
parent7c52e0e8658a0ea03067c301a15e793cf9f1c208 (diff)
downloadgdb-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.c31
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"));