diff mbox series

[v2,22/38] gdbserver: test endian when it is required

Message ID 20220329154931.493851-23-npiggin@gmail.com
State New
Headers show
Series gdbserver multi-threaded debugging and POWER9/10 support | expand

Commit Message

Nicholas Piggin March 29, 2022, 3:49 p.m. UTC
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 if a processor switches endian after the gdbserver is
started.

Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
---
 src/pdbgproxy.c | 30 ++++++++++++++----------------
 1 file changed, 14 insertions(+), 16 deletions(-)
diff mbox series

Patch

diff --git a/src/pdbgproxy.c b/src/pdbgproxy.c
index 1843517..29ba52a 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");
 		data = attn_opcode;
 
@@ -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)