Subject: [PATCH] fix gdb-stub for kernel compiled with higher ISA level

From: Atsushi Nemoto <[email-masked]>
Date: Thu, 24 Nov 2005 16:50:43 +0900 (JST)

The modern gdb seems to require 64bit values in remote packet for
32bit kernel which is compiled with -march=mips3, etc.

Signed-off-by: Atsushi Nemoto <[email-masked]>

diff --git a/arch/mips/kernel/gdb-stub.c b/arch/mips/kernel/gdb-stub.c
index 96d18c4..9fedfa4 100644
--- a/arch/mips/kernel/gdb-stub.c
+++ b/arch/mips/kernel/gdb-stub.c
@@ -670,6 +670,13 @@ static void kgdb_wait(void *arg)
 }

+#if defined(CONFIG_32BIT) && \
+	(_MIPS_ISA == _MIPS_ISA_MIPS3 || \
+	 _MIPS_ISA == _MIPS_ISA_MIPS4 || \
+	 _MIPS_ISA == _MIPS_ISA_MIPS5 || \
+	 _MIPS_ISA == _MIPS_ISA_MIPS64)
+#define GDB_EXPECT_64BIT_REG
+#endif
 /*
  * This function does all command processing for interfacing to gdb.  It
  * returns 1 if you should skip the instruction at the trap address, 0
@@ -685,6 +692,9 @@ void handle_exception (struct gdb_regs *
 	unsigned long *stack;
 	int i;
 	int bflag = 0;
+#ifdef GDB_EXPECT_64BIT_REG
+	u64 tmp64;
+#endif
 
 	kgdb_started = 1;
 
@@ -762,7 +772,12 @@ void handle_exception (struct gdb_regs *
 	*ptr++ = hexchars[REG_EPC >> 4];
 	*ptr++ = hexchars[REG_EPC & 0xf];
 	*ptr++ = ':';
+#ifdef GDB_EXPECT_64BIT_REG
+	tmp64 = regs->cp0_epc;
+	ptr = mem2hex((char *)&tmp64, ptr, sizeof(u64), 0);
+#else
 	ptr = mem2hex((char *)&regs->cp0_epc, ptr, sizeof(long), 0);
+#endif
 	*ptr++ = ';';
 
 	/*
@@ -771,7 +786,12 @@ void handle_exception (struct gdb_regs *
 	*ptr++ = hexchars[REG_FP >> 4];
 	*ptr++ = hexchars[REG_FP & 0xf];
 	*ptr++ = ':';
+#ifdef GDB_EXPECT_64BIT_REG
+	tmp64 = regs->reg30;
+	ptr = mem2hex((char *)&tmp64, ptr, sizeof(u64), 0);
+#else
 	ptr = mem2hex((char *)&regs->reg30, ptr, sizeof(long), 0);
+#endif
 	*ptr++ = ';';
 
 	/*
@@ -780,7 +800,12 @@ void handle_exception (struct gdb_regs *
 	*ptr++ = hexchars[REG_SP >> 4];
 	*ptr++ = hexchars[REG_SP & 0xf];
 	*ptr++ = ':';
+#ifdef GDB_EXPECT_64BIT_REG
+	tmp64 = regs->reg29;
+	ptr = mem2hex((char *)&tmp64, ptr, sizeof(u64), 0);
+#else
 	ptr = mem2hex((char *)&regs->reg29, ptr, sizeof(long), 0);
+#endif
 	*ptr++ = ';';
 
 	*ptr++ = 0;
@@ -819,12 +844,19 @@ void handle_exception (struct gdb_regs *
 		 */
 		case 'g':
 			ptr = output_buffer;
+#ifdef GDB_EXPECT_64BIT_REG
+			for (i = 0; i < 32 + 6 + 32 + 2 + 2 + 16; i++) {
+				tmp64 = *(&regs->reg0 + i);
+				ptr = mem2hex((char *)&tmp64, ptr, sizeof(u64), 0);
+			}
+#else
 			ptr = mem2hex((char *)&regs->reg0, ptr, 32*sizeof(long), 0); /* r0...r31 */
 			ptr = mem2hex((char *)&regs->cp0_status, ptr, 6*sizeof(long), 0); /* cp0 */
 			ptr = mem2hex((char *)&regs->fpr0, ptr, 32*sizeof(long), 0); /* f0...31 */
 			ptr = mem2hex((char *)&regs->cp1_fsr, ptr, 2*sizeof(long), 0); /* cp1 */
 			ptr = mem2hex((char *)&regs->frame_ptr, ptr, 2*sizeof(long), 0); /* frp */
 			ptr = mem2hex((char *)&regs->cp0_index, ptr, 16*sizeof(long), 0); /* cp0 */
+#endif
 			break;
 
 		/*
@@ -833,6 +865,13 @@ void handle_exception (struct gdb_regs *
 		case 'G':
 		{
 			ptr = &input_buffer[1];
+#ifdef GDB_EXPECT_64BIT_REG
+			for (i = 0; i < 32 + 6 + 32 + 2 + 2 + 16; i++) {
+				hex2mem(ptr, (char *)&tmp64, sizeof(u64), 0, 0);
+				*(&regs->reg0 + i) = (long)tmp64;
+				ptr += 2*sizeof(u64);
+			}
+#else
 			hex2mem(ptr, (char *)&regs->reg0, 32*sizeof(long), 0, 0);
 			ptr += 32*(2*sizeof(long));
 			hex2mem(ptr, (char *)&regs->cp0_status, 6*sizeof(long), 0, 0);
@@ -844,6 +883,7 @@ void handle_exception (struct gdb_regs *
 			hex2mem(ptr, (char *)&regs->frame_ptr, 2*sizeof(long), 0, 0);
 			ptr += 2*(2*sizeof(long));
 			hex2mem(ptr, (char *)&regs->cp0_index, 16*sizeof(long), 0, 0);
+#endif
 			strcpy(output_buffer,"OK");
 		 }
 		break;

---

From: Daniel Jacobowitz <[email-masked]>
Date: Fri, 25 Nov 2005 14:27:42 -0500

> 32bit kernel which is compiled with -march=mips3, etc.

FYI, it is a known limitation in GDB that it can't cope with either
format, and I hope to fix it sometime soon.  It's definitely a bug that
it expects 64-bit registers for mips3 32-bit binaries; I think the
change in question was crazy...

You can "set architecture mips:isa32" before connecting to get around
this.

-- 
Daniel Jacobowitz
CodeSourcery, LLC

---

From: Atsushi Nemoto <[email-masked]>
Date: Sun, 27 Nov 2005 01:16:04 +0900 (JST)

>>>>> On Fri, 25 Nov 2005 14:27:42 -0500, Daniel Jacobowitz <[email-masked]> said:

dan> FYI, it is a known limitation in GDB that it can't cope with
dan> either format, and I hope to fix it sometime soon.  It's
dan> definitely a bug that it expects 64-bit registers for mips3
dan> 32-bit binaries; I think the change in question was crazy...

dan> You can "set architecture mips:isa32" before connecting to get
dan> around this.

Thank you for the information.  Then I revoke this patch.

Ralf, please ignore this patch.  (And please apply my another gdb-stub
patch which is just fix a build error ...)

---
Atsushi Nemoto