2011-03-24 Yao Qi * arm-tdep.c (cleanup_branch): Set a correct return address in LR for ARM and Thumb. --- 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 6e5f2ab..2ebafad 100644 --- a/gdb/arm-tdep.c +++ b/gdb/arm-tdep.c @@ -5485,8 +5485,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); -- 1.7.0.4