This is the mail archive of the
gdb-patches@sourceware.org
mailing list for the GDB project.
[try 2nd 1/8] Fix cleanup_branch to take Thumb into account
- From: Yao Qi <yao at codesourcery dot com>
- To: gdb-patches at sourceware dot org
- Date: Thu, 24 Mar 2011 21:44:54 +0800
- Subject: [try 2nd 1/8] Fix cleanup_branch to take Thumb into account
- References: <4D15F9B8.5070705@codesourcery.com> <4D8B4947.1000000@codesourcery.com>
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 (éå)
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