From 8c8dba6d3d8f6509729107b34385d98e3301621e Mon Sep 17 00:00:00 2001 From: Yao Qi Date: Thu, 7 Apr 2011 03:42:51 +0000 Subject: [PATCH] * arm-tdep.c (cleanup_branch): Set a correct return address in LR for ARM and Thumb. --- gdb/ChangeLog | 5 +++++ gdb/arm-tdep.c | 12 ++++++++++-- 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 349e47e..42b8b93 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 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); -- 2.7.4