[Pdbg] [PATCH v2 23/39] gdbserver: breakpoint instruction test current host endian when it is required
Joel Stanley
joel at jms.id.au
Tue May 3 17:12:35 AEST 2022
On Wed, 20 Apr 2022 at 06:51, Nicholas Piggin <npiggin at gmail.com> wrote:
>
> Rather than testing endian once at start-up, test it when a breakpoint
> is being installed.
>
> This may give a bit better chance of the correct endian being used,
> because a processor can switch endian asynchronously and at any time
> (e.g., after the gdbserver has started).
>
> We don't support endian-agnostic breakpoints unfortunately because
> bswap32(attn) is an illegal instruction.
>
> Signed-off-by: Nicholas Piggin <npiggin at gmail.com>
Reviewed-by: Joel Stanley <joel at jms.id.au>
> ---
> src/pdbgproxy.c | 30 ++++++++++++++----------------
> 1 file changed, 14 insertions(+), 16 deletions(-)
>
> diff --git a/src/pdbgproxy.c b/src/pdbgproxy.c
> index d7ceac8d..4572c689 100644
> --- a/src/pdbgproxy.c
> +++ b/src/pdbgproxy.c
> @@ -47,7 +47,6 @@ static struct pdbg_target *adu_target;
> static struct timeval timeout;
> static int poll_interval = 100;
> static int fd = -1;
> -static int littleendian = 1;
> enum client_state {IDLE, SIGNAL_WAIT};
> static enum client_state state = IDLE;
>
> @@ -395,11 +394,6 @@ static void put_mem(uint64_t *stack, void *priv)
> uint8_t gdb_break_opcode[] = {0x7d, 0x82, 0x10, 0x08};
> int err = 0;
>
> - if (littleendian) {
> - attn_opcode[1] = 0x02;
> - attn_opcode[2] = 0x00;
> - }
> -
> addr = stack[0];
> len = stack[1];
> data = (uint8_t *)(unsigned long)stack[2];
> @@ -412,6 +406,19 @@ static void put_mem(uint64_t *stack, void *priv)
> }
>
> if (len == 4 && !memcmp(data, gdb_break_opcode, 4)) {
> + uint64_t msr;
> +
> + /* Check endianess in MSR */
> + err = thread_getmsr(thread_target, &msr);
> + if (err) {
> + PR_ERROR("Couldn't read the MSR. Are all threads on this chiplet quiesced?\n");
> + goto out;
> + }
> + if (msr & 1) { /* little endian */
> + attn_opcode[1] = 0x02;
> + attn_opcode[2] = 0x00;
> + }
> +
> /* According to linux-ppc-low.c gdb only uses this
> * op-code for sw break points so we replace it with
> * the correct attn opcode which is what we need for
> @@ -419,6 +426,7 @@ static void put_mem(uint64_t *stack, void *priv)
> *
> * TODO: Upstream a patch to gdb so that it uses the
> * right opcode for baremetal debug. */
> +
> PR_INFO("Breakpoint opcode detected, replacing with attn\n");
> memcpy(data, attn_opcode, 4);
>
> @@ -723,8 +731,6 @@ int gdbserver_start(struct pdbg_target *thread, struct pdbg_target *adu, uint16_
> static int gdbserver(uint16_t port)
> {
> struct pdbg_target *target, *adu, *thread = NULL;
> - uint64_t msr;
> - int rc;
>
> for_each_path_target_class("thread", target) {
> if (pdbg_target_probe(target) != PDBG_TARGET_ENABLED)
> @@ -758,14 +764,6 @@ static int gdbserver(uint16_t port)
> PR_WARNING("Breakpoints may cause host crashes on POWER9 and should not be used\n");
> }
>
> - /* Check endianess in MSR */
> - rc = thread_getmsr(thread, &msr);
> - if (rc) {
> - PR_ERROR("Couldn't read the MSR. Are all threads on this chiplet quiesced?\n");
> - return 1;
> - }
> - littleendian = 0x01 & msr;
> -
> /* Select ADU target */
> pdbg_for_each_class_target("mem", adu) {
> if (pdbg_target_probe(adu) == PDBG_TARGET_ENABLED)
> --
> 2.35.1
>
> --
> Pdbg mailing list
> Pdbg at lists.ozlabs.org
> https://lists.ozlabs.org/listinfo/pdbg
More information about the Pdbg
mailing list