diff options
author | Yao Qi <yao.qi@linaro.org> | 2015-04-15 14:34:03 +0100 |
---|---|---|
committer | Yao Qi <yao.qi@linaro.org> | 2015-04-15 15:14:37 +0100 |
commit | 41f071ef337ac55b7bd5366ef003fe47b809cdee (patch) | |
tree | 615148aae0616f8f91761fafa39e31b180216fc8 | |
parent | 8cbc97c629061306efb30aa83440bec7380c584e (diff) | |
download | gdb-41f071ef337ac55b7bd5366ef003fe47b809cdee.zip gdb-41f071ef337ac55b7bd5366ef003fe47b809cdee.tar.gz gdb-41f071ef337ac55b7bd5366ef003fe47b809cdee.tar.bz2 |
[arm] Fix fails in gdb.base/disp-step-syscall.exp
Hi,
I see this fail on arm-linux target,
FAIL: gdb.base/disp-step-syscall.exp: fork: single step over fork final pc
which is caused by the PC isn't expected after displaced stepping the
svc instruction. The code is:
=> 0xb6ead9a4 <__libc_do_syscall+4>: svc 0
0xb6ead9a6 <__libc_do_syscall+6>: pop {r7, pc}
0xb6ead9a8: nop.w^M
0xb6ead9ac: nop.w
after single step svc instruction, pc should be 0xb6ead9a6, but the
actual value of pc is 0xb6ead9a8. The problem is illustrated by
turning on debug message of displaced stepping,
stepi^M
displaced: stepping Thread 12031 now^M
displaced: saved 0x8574: 02 bc 6a 46 04 b4 01 b4 df f8 10 c0 4d f8 04 cd 03 48 04 4b ff f7 d2 ef ff f7 e8 ef 0d 87 00 00 ^M
displaced: process thumb insn df00 at b6ead9a4^M
displaced: copying svc insn df00^M
displaced: read r7 value 00000078^M
displaced: sigreturn/rt_sigreturn SVC call not in signal trampoline frame^M
displaced: writing insn df00 at 00008574^M
displaced: copy 0xb6ead9a4->0x8574: displaced: check mode of b6ead9a4 instead of 00008574^M
displaced: displaced pc to 0x8574^M
displaced: run 0x8574: 00 df 01 de ^M
displaced: restored Thread 12031 0x8574^M
displaced: PC is apparently 00008576 after SVC step (within scratch space)^M
displaced: writing pc b6ead9a8 <----- WRONG ADDRESS
GDB writes the wrong address back to pc because GDB thinks the
instruction size is 4, which isn't true for thumb instruction.
This patch is to replace 4 with dsc->insn_size.
gdb:
2015-04-15 Yao Qi <yao.qi@linaro.org>
* arm-linux-tdep.c (arm_linux_cleanup_svc): Use
dsc->insn_size instead of 4.
-rw-r--r-- | gdb/ChangeLog | 5 | ||||
-rw-r--r-- | gdb/arm-linux-tdep.c | 6 |
2 files changed, 8 insertions, 3 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog index acb408b..a97e720 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,8 @@ +2015-04-15 Yao Qi <yao.qi@linaro.org> + + * arm-linux-tdep.c (arm_linux_cleanup_svc): Use + dsc->insn_size instead of 4. + 2015-04-14 Gary Benson <gbenson@redhat.com> * jit.c (mem_bfd_iovec_stat): Zero supplied buffer. diff --git a/gdb/arm-linux-tdep.c b/gdb/arm-linux-tdep.c index f58da84..60266b5 100644 --- a/gdb/arm-linux-tdep.c +++ b/gdb/arm-linux-tdep.c @@ -939,7 +939,6 @@ arm_linux_cleanup_svc (struct gdbarch *gdbarch, struct regcache *regs, struct displaced_step_closure *dsc) { - CORE_ADDR from = dsc->insn_addr; ULONGEST apparent_pc; int within_scratch; @@ -960,7 +959,8 @@ arm_linux_cleanup_svc (struct gdbarch *gdbarch, } if (within_scratch) - displaced_write_reg (regs, dsc, ARM_PC_REGNUM, from + 4, BRANCH_WRITE_PC); + displaced_write_reg (regs, dsc, ARM_PC_REGNUM, + dsc->insn_addr + dsc->insn_size, BRANCH_WRITE_PC); } static int @@ -1027,7 +1027,7 @@ arm_linux_copy_svc (struct gdbarch *gdbarch, struct regcache *regs, /* Preparation: If we detect sigreturn, set momentary breakpoint at resume location, else nothing. Insn: unmodified svc. - Cleanup: if pc lands in scratch space, pc <- insn_addr + 4 + Cleanup: if pc lands in scratch space, pc <- insn_addr + insn_size else leave pc alone. */ |