Method syscall_next_pc of struct arm_get_next_pcs_ops has an argument
PC, which is not necessary, because PC can be got from regcache in
'struct arm_get_next_pcs'. This patch removes the PC argument of
syscall_next_pc.
gdb:
2016-02-16 Yao Qi <yao.qi@linaro.org>
* arch/arm-get-next-pcs.h (struct arm_get_next_pcs_ops)
<syscall_next_pc>: Remove argument PC. Callers updated.
* arm-linux-tdep.c (arm_linux_get_next_pcs_syscall_next_pc):
Remove argument PC. Get pc from regcache_read_pc.
* arm-tdep.c (arm_get_next_pcs_syscall_next_pc): Remove
argument PC.
gdb/gdbserver:
2016-02-16 Yao Qi <yao.qi@linaro.org>
* linux-arm-low.c (get_next_pcs_syscall_next_pc): Remove argument
PC. Get pc from regcache_read_pc.
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.
Nowadays, get_next_pcs in linux_target_ops has two parameters PC
and REGCACHE. Parameter PC looks redundant because it can be go
from REGCACHE. The patch is to remove PC from the arguments for
various functions.
gdb:
2016-01-26 Yao Qi <yao.qi@linaro.org>
* arch/arm-get-next-pcs.c (thumb_deal_with_atomic_sequence_raw):
Remove argument pc. Get pc by regcache_read_pc. Callers updated.
(arm_deal_with_atomic_sequence_raw): Likewise.
(thumb_get_next_pcs_raw): Likewise.
(arm_get_next_pcs_raw): Likewise.
(arm_get_next_pcs): Remove argument pc. Callers updated.
* arch/arm-get-next-pcs.h (arm_get_next_pcs): Update declaration.
gdb/gdbserver:
2016-01-26 Yao Qi <yao.qi@linaro.org>
* linux-arm-low.c (arm_gdbserver_get_next_pcs): Remove argument pc.
* linux-low.c (install_software_single_step_breakpoints): Don't
call regcache_read_pc.
* linux-low.h (struct linux_target_ops) <get_next_pcs>: Remove
argument pc.
This patch makes thumb2_breakpoint static. When writing this patch,
I find the only reason we keep thumb2_breakpoint extern is that it
is used as an argument passed to arm_gdbserver_get_next_pcs. However,
field arm_thumb2_breakpoint is only used in a null check in
thumb_get_next_pcs_raw, so I wonder why do need to pass thumb2_breakpoint
to arm_gdbserver_get_next_pcs.
thumb2_breakpoint was added by Daniel Jacobowitz in order to support
single-step IT block
https://sourceware.org/ml/gdb-patches/2010-01/msg00624.html the logic
there was if we have 32-bit thumb-2 breakpoint defined, we can safely
single-step IT block, otherwise, we can't. Daniel didn't want to use
16-bit thumb BKPT instruction, because it triggers even on instruction
which should be executed. Secondly, using 16-bit thumb illegal
instruction on top of 32-bit thumb instruction may break the meaning of
original IT blocks, because the other 16-bit can be regarded as an
instruction. See more explanations from Daniel's kernel patch
http://www.spinics.net/lists/arm-kernel/msg80476.html
Let us back to this patch, GDB/GDBserver can safely single step
IT block if thumb2_breakpoint is defined, but the single step logic
doesn't have to know the thumb-2 breakpoint instruction. Only
breakpoint insertion mechanism decides to use which breakpoint
instruction. In the software single step code, instead of pass
thumb2_breakpoint, we can pass a boolean variable
has_thumb2_breakpoint indicate whether the target has thumb-2
breakpoint defined, which is equivalent to the original code.
Regression tested on arm-linux. No regression.
gdb:
2016-01-14 Yao Qi <yao.qi@linaro.org>
* arch/arm-get-next-pcs.c (arm_get_next_pcs_ctor): Change
argument arm_thumb2_breakpoint to has_thumb2_breakpoint.
(thumb_get_next_pcs_raw): Check has_thumb2_breakpoint
instead.
* arch/arm-get-next-pcs.h (struct arm_get_next_pcs)
<arm_thumb2_breakpoint>: Remove.
<has_thumb2_breakpoint>: New field.
(arm_get_next_pcs_ctor): Update declaration.
* arm-linux-tdep.c (arm_linux_software_single_step): Pass
1 to arm_get_next_pcs_ctor.
* arm-tdep.c (arm_software_single_step): Pass 0 to
arm_get_next_pcs_ctor.
gdb/gdbserver:
2016-01-14 Yao Qi <yao.qi@linaro.org>
* linux-aarch32-low.c (thumb2_breakpoint): Make it static.
* linux-aarch32-low.h (thumb2_breakpoint): Remove declaration.
* linux-arm-low.c (arm_gdbserver_get_next_pcs): Pass 1 to
arm_get_next_pcs_ctor.
When reading instruction, we should use byte_order_for_code instead
of byte_order.
gdb:
2016-01-13 Yao Qi <yao.qi@linaro.org>
* arch/arm-get-next-pcs.c (arm_get_next_pcs_raw): Use
byte_order_for_code to read instruction.
This patch makes arm_get_next_pcs_raw and thumb_get_next_pcs_raw
static.
gdb:
2016-01-06 Yao Qi <yao.qi@linaro.org>
* arch/arm-get-next-pcs.c (arm_get_next_pcs): Move it to some
lines below.
(thumb_get_next_pcs_raw): Make it static.
(arm_get_next_pcs_raw): Likewise.
* arch/arm-get-next-pcs.h (thumb_get_next_pcs_raw): Remove the
declaration.
(arm_get_next_pcs_raw): Likewise.
This patch teaches GDBServer how to software single step on ARM
linux by sharing code with GDB.
The arm_get_next_pcs function in GDB is now shared with GDBServer. So
that GDBServer can use the function to return the possible addresses of
the next PC.
A proper shared context was also needed so that we could share the code,
this context is described in the arm_get_next_pcs structure.
Testing :
No regressions, tested on ubuntu 14.04 ARMv7 and x86.
With gdbserver-{native,extended} / { -marm -mthumb }
gdb/ChangeLog:
* Makefile.in (ALL_TARGET_OBS): Append arm-get-next-pcs.o,
arm-linux.o.
(ALLDEPFILES): Append arm-get-next-pcs.c, arm-linux.c
(arm-linux.o): New rule.
(arm-get-next-pcs.o): New rule.
* arch/arm-get-next-pcs.c: New file.
* arch/arm-get-next-pcs.h: New file.
* arch/arm-linux.h: New file.
* arch/arm-linux.c: New file.
* arm.c: Include common-regcache.c.
(thumb_advance_itstate): Moved from arm-tdep.c.
(arm_instruction_changes_pc): Likewise.
(thumb_instruction_changes_pc): Likewise.
(thumb2_instruction_changes_pc): Likewise.
(shifted_reg_val): Likewise.
* arm.h (submask): Move macro from arm-tdep.h
(bit): Likewise.
(bits): Likewise.
(sbits): Likewise.
(BranchDest): Likewise.
(thumb_advance_itstate): Moved declaration from arm-tdep.h
(arm_instruction_changes_pc): Likewise.
(thumb_instruction_changes_pc): Likewise.
(thumb2_instruction_changes_pc): Likewise.
(shifted_reg_val): Likewise.
* arm-linux-tdep.c: Include arch/arm.h, arch/arm-get-next-pcs.h
arch/arm-linux.h.
(arm_linux_get_next_pcs_ops): New struct.
(ARM_SIGCONTEXT_R0, ARM_UCONTEXT_SIGCONTEXT,
ARM_OLD_RT_SIGFRAME_SIGINFO, ARM_OLD_RT_SIGFRAME_UCONTEXT,
ARM_NEW_RT_SIGFRAME_UCONTEXT, ARM_NEW_SIGFRAME_MAGIC): Move stack
layout defines to arch/arm-linux.h.
(arm_linux_sigreturn_next_pc_offset): Move to arch/arm-linux.c.
(arm_linux_software_single_step): Adjust for arm_get_next_pcs
implementation.
* arm-tdep.c: Include arch/arm-get-next-pcs.h.
(arm_get_next_pcs_ops): New struct.
(submask): Move macro to arm.h.
(bit): Likewise.
(bits): Likewise.
(sbits): Likewise.
(BranchDest): Likewise.
(thumb_instruction_changes_pc): Move to arm.c
(thumb2_instruction_changes_pc): Likewise.
(arm_instruction_changes_pc): Likewise.
(shifted_reg_val): Likewise.
(thumb_advance_itstate): Likewise.
(thumb_get_next_pc_raw): Move to arm-get-next-pcs.c.
(arm_get_next_pc_raw): Likewise.
(arm_get_next_pc): Likewise.
(thumb_deal_with_atomic_sequence_raw): Likewise.
(arm_deal_with_atomic_sequence_raw): Likewise.
(arm_deal_with_atomic_sequence): Likewise.
(arm_get_next_pcs_read_memory_unsigned_integer): New function.
(arm_get_next_pcs_addr_bits_remove): Likewise.
(arm_get_next_pcs_syscall_next_pc): Likewise.
(arm_get_next_pcs_is_thumb): Likewise.
(arm_software_single_step): Adjust for arm_get_next_pcs
implementation.
* arm-tdep.h: (arm_get_next_pc): Remove declaration.
(arm_get_next_pcs_read_memory_unsigned_integer):
New declaration.
(arm_get_next_pcs_addr_bits_remove): Likewise.
(arm_get_next_pcs_syscall_next_pc): Likewise.
(arm_get_next_pcs_is_thumb): Likewise.
(arm_deal_with_atomic_sequence: Remove declaration.
* common/gdb_vecs.h: Add CORE_ADDR vector definition.
* configure.tgt (aarch64*-*-linux): Add arm-get-next-pcs.o,
arm-linux.o.
(arm*-wince-pe): Add arm-get-next-pcs.o.
(arm*-*-linux*): Add arm-get-next-pcs.o, arm-linux.o,
arm-get-next-pcs.o
(arm*-*-netbsd*,arm*-*-knetbsd*-gnu): Add arm-get-next-pcs.o.
(arm*-*-openbsd*): Likewise.
(arm*-*-symbianelf*): Likewise.
(arm*-*-*): Likewise.
* symtab.h: Move CORE_ADDR vector definition to gdb_vecs.h.
gdb/gdbserver/ChangeLog:
* Makefile.in (SFILES): Append arch/arm-linux.c,
arch/arm-get-next-pcs.c.
(arm-linux.o): New rule.
(arm-get-next-pcs.o): New rule.
* configure.srv (arm*-*-linux*): Add arm-get-next-pcs.o,
arm-linux.o.
* linux-aarch32-low.c (arm_abi_breakpoint): Remove macro. Moved
to linux-aarch32-low.c.
(arm_eabi_breakpoint, arm_breakpoint): Likewise.
(arm_breakpoint_len, thumb_breakpoint): Likewise.
(thumb_breakpoint_len, thumb2_breakpoint): Likewise.
(thumb2_breakpoint_len): Likewise.
(arm_is_thumb_mode): Make non-static.
* linux-aarch32-low.h (arm_abi_breakpoint): New macro. Moved
from linux-aarch32-low.c.
(arm_eabi_breakpoint, arm_breakpoint): Likewise.
(arm_breakpoint_len, thumb_breakpoint): Likewise.
(thumb_breakpoint_len, thumb2_breakpoint): Likewise.
(thumb2_breakpoint_len): Likewise.
(arm_is_thumb_mode): New declaration.
* linux-arm-low.c: Include arch/arm-linux.h
aarch/arm-get-next-pcs.h, sys/syscall.h.
(get_next_pcs_ops): New struct.
(get_next_pcs_addr_bits_remove): New function.
(get_next_pcs_is_thumb): New function.
(get_next_pcs_read_memory_unsigned_integer): Likewise.
(arm_sigreturn_next_pc): Likewise.
(get_next_pcs_syscall_next_pc): Likewise.
(arm_gdbserver_get_next_pcs): Likewise.
(struct linux_target_ops) <arm_gdbserver_get_next_pcs>:
Initialize.
* linux-low.h: Move CORE_ADDR vector definition to gdb_vecs.h.
* server.h: Include gdb_vecs.h.