[ARM] Fixup PC in software single step
authorYao Qi <yao.qi@linaro.org>
Mon, 8 Feb 2016 16:05:31 +0000 (16:05 +0000)
committerYao Qi <yao.qi@linaro.org>
Fri, 12 Feb 2016 15:58:52 +0000 (15:58 +0000)
commited443b61e1f6e4eb7919fe9122dd947d1e87e767
treecf064d4acb7896b89336b7dc9c0c11a3d34dd2c5
parent020ecd38e74681cb14987baf1a4d3c3ee3be0006
[ARM] Fixup PC in software single step

When I exercise GDBserver software single step, I see the following
error, which has been already handled by GDB properly.

In GDBserver log, we can see, GDBserver tries to single step instruction
on 0xb6e0a6e4, and destination address is 0xffff0fe0,

 stop pc is 0xb6e0a6e4
 Writing f001f0e7 to 0xffff0fe0 in process 7132
 Failed to insert breakpoint at 0xffff0fe0 (Input/output error).
 Failed to insert breakpoint at 0xffff0fe0 (-1).

(gdb) disassemble __aeabi_read_tp,+8
Dump of assembler code from 0xb6e0a6e0 to 0xb6e0a6e8:
   0xb6e0a6e0 <__aeabi_read_tp+0>: mvn r0, #61440 ; 0xf000
   0xb6e0a6e4 <__aeabi_read_tp+4>: sub pc, r0, #31

however, it fails inserting breakpoint there.  This problem has already
fixed by GDB, see comments in arm-linux-tdep.c:arm_linux_software_single_step

      /* The Linux kernel offers some user-mode helpers in a high page.  We can
 not read this page (as of 2.6.23), and even if we could then we
 couldn't set breakpoints in it, and even if we could then the atomic
 operations would fail when interrupted.  They are all called as
 functions and return to the address in LR, so step to there
 instead.  */

so we need to do the same thing in GDB side as well.  This patch adds
a new field fixup in arm_get_next_pcs_ops, so that we can fix up PC
for arm-linux target.  In this way, both GDB and GDBserver can single
step instructions going to kernel helpers.

gdb:

2016-02-12  Yao Qi  <yao.qi@linaro.org>

* arch/arm-get-next-pcs.c (arm_get_next_pcs): Call
self->ops->fixup if it isn't NULL.
* arch/arm-get-next-pcs.h: Include gdb_vecs.h.
(struct arm_get_next_pcs_ops) <fixup>: New field.
* arch/arm-linux.c: Include common-regcache.h and
arch/arm-get-next-pcs.h.
(arm_linux_get_next_pcs_fixup): New function.
* arch/arm-linux.h (arm_linux_get_next_pcs_fixup): Declare.
* arm-linux-tdep.c (arm_linux_get_next_pcs_ops): Initialize
it with arm_linux_get_next_pcs_fixup.
(arm_linux_software_single_step): Move code to
arm_linux_get_next_pcs_fixup.
* arm-tdep.c (arm_get_next_pcs_ops): Initialize it.

gdb/gdbserver:

2016-02-12  Yao Qi  <yao.qi@linaro.org>

* linux-arm-low.c (get_next_pcs_ops): Initialize it with
arm_linux_get_next_pcs_fixup.
gdb/ChangeLog
gdb/arch/arm-get-next-pcs.c
gdb/arch/arm-get-next-pcs.h
gdb/arch/arm-linux.c
gdb/arch/arm-linux.h
gdb/arm-linux-tdep.c
gdb/arm-tdep.c
gdb/gdbserver/ChangeLog
gdb/gdbserver/linux-arm-low.c