aboutsummaryrefslogtreecommitdiff
path: root/gdb/arm-tdep.c
diff options
context:
space:
mode:
authorYao Qi <yao@codesourcery.com>2011-04-07 03:42:51 +0000
committerYao Qi <yao@codesourcery.com>2011-04-07 03:42:51 +0000
commit8c8dba6d3d8f6509729107b34385d98e3301621e (patch)
treec4641be4079306425bf8278f9e13ee458b1b7cac /gdb/arm-tdep.c
parent91db4c57cf01b45479dac0c0b5388d1fce9a61ac (diff)
downloadgdb-8c8dba6d3d8f6509729107b34385d98e3301621e.zip
gdb-8c8dba6d3d8f6509729107b34385d98e3301621e.tar.gz
gdb-8c8dba6d3d8f6509729107b34385d98e3301621e.tar.bz2
* arm-tdep.c (cleanup_branch): Set a correct return address in
LR for ARM and Thumb.
Diffstat (limited to 'gdb/arm-tdep.c')
-rw-r--r--gdb/arm-tdep.c12
1 files changed, 10 insertions, 2 deletions
diff --git a/gdb/arm-tdep.c b/gdb/arm-tdep.c
index bb52ad4..024191b 100644
--- a/gdb/arm-tdep.c
+++ b/gdb/arm-tdep.c
@@ -5493,8 +5493,16 @@ cleanup_branch (struct gdbarch *gdbarch, struct regcache *regs,
if (dsc->u.branch.link)
{
- ULONGEST pc = displaced_read_reg (regs, dsc, ARM_PC_REGNUM);
- displaced_write_reg (regs, dsc, ARM_LR_REGNUM, pc - 4, CANNOT_WRITE_PC);
+ /* The value of LR should be the next insn of current one. In order
+ not to confuse logic hanlding later insn `bx lr', if current insn mode
+ is Thumb, the bit 0 of LR value should be set to 1. */
+ ULONGEST next_insn_addr = dsc->insn_addr + dsc->insn_size;
+
+ if (dsc->is_thumb)
+ next_insn_addr |= 0x1;
+
+ displaced_write_reg (regs, dsc, ARM_LR_REGNUM, next_insn_addr,
+ CANNOT_WRITE_PC);
}
displaced_write_reg (regs, dsc, ARM_PC_REGNUM, dsc->u.branch.dest, write_pc);