From: Yao Qi Date: Thu, 7 Apr 2011 03:42:51 +0000 (+0000) Subject: * arm-tdep.c (cleanup_branch): Set a correct return address in X-Git-Url: http://drtracing.org/?a=commitdiff_plain;h=8c8dba6d3d8f6509729107b34385d98e3301621e;p=deliverable%2Fbinutils-gdb.git * arm-tdep.c (cleanup_branch): Set a correct return address in LR for ARM and Thumb. --- diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 349e47e155..42b8b93f24 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,8 @@ +2011-04-07 Yao Qi + + * arm-tdep.c (cleanup_branch): Set a correct return address in + LR for ARM and Thumb. + 2011-04-06 Jan Kratochvil Code cleanup. diff --git a/gdb/arm-tdep.c b/gdb/arm-tdep.c index bb52ad4255..024191b9b3 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);