diff options
author | Yao Qi <yao@codesourcery.com> | 2011-04-07 03:42:51 +0000 |
---|---|---|
committer | Yao Qi <yao@codesourcery.com> | 2011-04-07 03:42:51 +0000 |
commit | 8c8dba6d3d8f6509729107b34385d98e3301621e (patch) | |
tree | c4641be4079306425bf8278f9e13ee458b1b7cac /gdb/arm-tdep.c | |
parent | 91db4c57cf01b45479dac0c0b5388d1fce9a61ac (diff) | |
download | gdb-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.c | 12 |
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); |