[try 2nd 1/8] Fix cleanup_branch to take Thumb into account

Yao Qi
2011-03-24T13:45:09Z

[-- Attachment #1: Type: text/plain, Size: 214 bytes --]

When writing LR register in cleanup_branch, Thumb mode is not
considered, so `pc - 4' is not value of LR. Since insn_size and
insn_addr has been in `dsc', it can be easier to calculate LR.

--
Yao (é½å°§)

[-- Attachment #2: 0001-generic-fix-to-cleanup_branch.patch --]
[-- Type: text/x-patch, Size: 1150 bytes --]

2011-03-24 Yao Qi <yao@codesourcery.com>

* 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