PERFORCE change 30481 for review

Marcel Moolenaar marcel at FreeBSD.org
Sat May 3 15:13:00 PDT 2003


http://perforce.freebsd.org/chv.cgi?CH=30481

Change 30481 by marcel at marcel_nfs on 2003/05/03 15:12:53

	Get i386 to compile again. MD support functions for GDB
	support have been put in db_interface.c. This should have
	the MI framework mostly in good shape. The only real
	hardcoding is in the first packet: we assume there's a
	PC, FP and SP. Porting the other architectures should make
	it clear whether we can get away with it or not. I'll
	cross that bridge when I come to it.

Affected files ...

.. //depot/projects/sio/sys/ddb/db_gdb.c#2 edit
.. //depot/projects/sio/sys/i386/i386/db_interface.c#3 edit
.. //depot/projects/sio/sys/i386/include/db_machdep.h#3 edit

Differences ...

==== //depot/projects/sio/sys/ddb/db_gdb.c#2 (text+ko) ====

@@ -224,6 +224,94 @@
 static int encdecsz;
 
 static __inline void
+gdb_dec_begin(char *buf, int size)
+{
+	encdecp = buf;
+	encdecsz = size;
+}
+
+static __inline int
+gdb_dec_char(void)
+{
+	int c;
+	if (encdecsz > 0) {
+		c = *encdecp++;
+		encdecsz--;
+	} else
+		c = -1;
+	return (c);
+}
+
+static __inline int
+gdb_dec_int8(void)
+{
+	int h, l;
+	h = gdb_hex(gdb_dec_char());
+	l = gdb_hex(gdb_dec_char());
+	if (h != -1 && l != -1)
+		return ((h << 4) | (l & 0xf));
+	else
+		return (-1);
+}
+
+static __inline int
+gdb_dec_int16(void)
+{
+	int h, l;
+	h = gdb_dec_int8();
+	l = gdb_dec_int8();
+	if (h != -1 && l != -1)
+		return ((h << 8) | (l & 0xff));
+	else
+		return (-1);
+}
+
+static __inline int32_t
+gdb_dec_int32(void)
+{
+	int32_t h, l;
+	h = gdb_dec_int16();
+	l = gdb_dec_int16();
+	if (h != -1 && l != -1)
+		return ((h << 16) | (l & 0xffff));
+	else
+		return (-1);
+}
+
+static __inline uint64_t
+gdb_dec_int64(void)
+{
+	int64_t h, l;
+	h = gdb_dec_int32();
+	l = gdb_dec_int32();
+	if (h != -1 && l != -1)
+		return ((h << 32) | (l & 0xffffffff));
+	else
+		return (-1);
+}
+
+static __inline int
+gdb_dec_block(gdb_addr addr, int len)
+{
+	uint8_t *p = (void*)(intptr_t)addr;
+	int c;
+	while (len > 0) {
+		c = gdb_dec_int8();
+		if (c == -1)
+			return (-1);
+		*p++ = c;
+		len--;
+	}
+	return 0;
+}
+
+static __inline int
+gdb_dec_registers(struct gdb_registers *regs)
+{
+	return (gdb_dec_block((intptr_t)regs, sizeof(*regs)));
+}
+
+static __inline void
 gdb_enc_begin(char *buf, int size)
 {
 	encdecp = buf;
@@ -280,6 +368,20 @@
 	gdb_enc_int32(i & 0xffffffff);
 }
 
+static __inline void
+gdb_enc_block(gdb_addr addr, int len)
+{
+	uint8_t *p = (void*)(intptr_t)addr;
+	while (len > 0)
+		gdb_enc_int8(*p++), len--;
+}
+
+static __inline void
+gdb_enc_registers(struct gdb_registers *regs)
+{
+	gdb_enc_block((intptr_t)regs, sizeof(*regs));
+}
+
 /*
  * gdb_handle_exception
  *
@@ -327,8 +429,12 @@
 int
 gdb_handle_exception(db_regs_t *raw_regs, int type)
 {
-	char *ptr;
-	int addr, error, length, regno;
+	struct gdb_registers regs;
+	gdb_addr addr;
+	gdb_reg reg;
+	int c, error, len, regno;
+
+	gdb_getregs(&regs, raw_regs);
 
 	/* "TxxPC:xxxxxxxx;FP:xxxxxxxx;SP:xxxxxxxx;" */
 	gdb_enc_begin(gdb_buffer, sizeof(gdb_buffer));
@@ -336,19 +442,18 @@
 	gdb_enc_int8(gdb_signal(type));
 	gdb_enc_int8(GDB_REGNUM_PC);
 	gdb_enc_char(':');
-	gdb_enc_register(raw_regs->eip);
+	gdb_enc_reg(gdb_getreg(&regs, GDB_REGNUM_PC));
 	gdb_enc_char(';');
 	gdb_enc_int8(GDB_REGNUM_FP);
 	gdb_enc_char(':');
-	gdb_enc_register(raw_regs->ebp);
+	gdb_enc_reg(gdb_getreg(&regs, GDB_REGNUM_FP));
 	gdb_enc_char(';');
 	gdb_enc_int8(GDB_REGNUM_SP);
 	gdb_enc_char(':');
-	gdb_enc_register(raw_regs->esp);
+	gdb_enc_reg(gdb_getreg(&regs, GDB_REGNUM_SP));
 	gdb_enc_char(';');
-	error = gdb_enc_end();
-	if (!error)
-		error = gdb_putpacket(gdb_buffer);
+	gdb_enc_end();
+	error = gdb_putpacket(gdb_buffer);
 	if (error)
 		return (error);
 
@@ -356,7 +461,8 @@
 		error = gdb_getpacket(gdb_buffer);
 		if (error)
 			return (error);
-		switch (*gdb_buffer) {
+		gdb_dec_begin(gdb_buffer, sizeof(gdb_buffer));
+		switch (gdb_dec_char()) {
 		case '?':
 			gdb_enc_begin(gdb_buffer, sizeof(gdb_buffer));
 			gdb_enc_char('S');
@@ -373,25 +479,25 @@
 
 		case 'g':
 			/* Return the value of the CPU registers */
-			mem2hex((vm_offset_t)&registers, gdb_buffer,
-			    NUMREGBYTES);
+			gdb_enc_begin(gdb_buffer, sizeof(gdb_buffer));
+			gdb_enc_registers(&regs);
+			gdb_enc_end();
 			gdb_putpacket(gdb_buffer);
 			break;
 
 		case 'G':
 			/* Set the value of the CPU registers - return OK */
-			hex2mem(gdb_buffer + 1, (vm_offset_t)&registers,
-			    NUMREGBYTES);
+			gdb_dec_registers(&regs);
 			gdb_putpacket("OK");
 			break;
 
 		case 'P':
 			/* Set the value of one register */
-			ptr = gdb_buffer + 1;
-			if (hexToInt(&ptr, &regno) && *ptr++ == '=' &&
-			    regno < NUM_REGS) {
-				hex2mem(ptr,
-				    (vm_offset_t)&registers + regno * 4, 4);
+			regno = gdb_dec_int32();
+			c = gdb_dec_char();
+			reg = gdb_dec_reg();
+			if (regno > 0 && c == '=') {
+				gdb_setreg(&regs, regno, reg);
 				gdb_putpacket("OK");
 			} else
 				gdb_putpacket("P01");
@@ -400,15 +506,15 @@
 		case 'm':
 			/* mAA..AA,LLLL  Read LLLL bytes at address AA..AA */
 			/* Try to read %x,%x.  */
-			ptr = gdb_buffer + 1;
-			if (hexToInt(&ptr, &addr) && *(ptr++) == ',' &&
-			    hexToInt (&ptr, &length)) {
-				if (mem2hex((vm_offset_t)addr,
-					gdb_buffer, length) == NULL)
-					gdb_putpacket("E03");
-				else
-					gdb_putpacket(gdb_buffer);
-				break;
+			addr = gdb_dec_addr();
+			c = gdb_dec_char();
+			len = gdb_dec_int32();
+			if (c == ',' && len > 0) {
+				gdb_enc_begin(gdb_buffer, sizeof(gdb_buffer));
+				gdb_enc_block(addr, len);
+				gdb_enc_end();
+				gdb_putpacket(gdb_buffer);
+				/* XXX return "E03" when encoding fails. */
 			} else
 				gdb_putpacket("E01");
 			break;
@@ -417,31 +523,34 @@
 			/* MAA..AA,LLLL: Write LLLL bytes at address AA.AA */
 			/* return OK */
 			/* Try to read '%x,%x:'. */
-			ptr = gdb_buffer + 1;
-			if (hexToInt(&ptr,&addr) && *(ptr++) == ',' &&
-			    hexToInt(&ptr, &length) && *(ptr++) == ':') {
-				if (hex2mem(ptr, (vm_offset_t)addr, length)
-				    == NULL)
-					gdb_putpacket("E03");
-				else
-					gdb_putpacket("OK");
+			addr = gdb_dec_addr();
+			c = gdb_dec_char();
+			len = gdb_dec_int32();
+			if (c == ',' && len > 0 && gdb_dec_char() == ':') {
+				gdb_dec_block(addr, len);
+				gdb_putpacket("OK");
+				/* XXX return "E03" when decoding fails. */
 			} else
 				gdb_putpacket("E02");
 			break;
 
 		case 'c' :
 			/* cAA..AA    Continue at address AA..AA (opt) */
-			/* FALLTHROUGH */
+			gdb_singlestep(&regs, 0);
+			addr = gdb_dec_addr();
+			if (addr != ~0U)
+				gdb_setreg(&regs, GDB_REGNUM_PC, addr);
+			gdb_setregs(&regs, raw_regs);
+			return (0);
+
 		case 's' :
 			/* sAA..AA   Step one instruction from AA..AA (opt) */
-			gdb_cpu_set_regs(&regs);
-			/* try to read optional parameter */
-			ptr = gdb_buffer + 1;
-			if (hexToInt(&ptr,&addr))
-				gdb_cpu_set_pc(addr);
-			/* set the trace bit if we're stepping */
-			gdb_cpu_singlestep((*gdb_buffer == 's') ? 1 : 0);
-			return 0;
+			gdb_singlestep(&regs, 1);
+			addr = gdb_dec_addr();
+			if (addr != ~0U)
+				gdb_setreg(&regs, GDB_REGNUM_PC, addr);
+			gdb_setregs(&regs, raw_regs);
+			return (0);
 		} /* switch */
 	}
 

==== //depot/projects/sio/sys/i386/i386/db_interface.c#3 (text+ko) ====

@@ -303,6 +303,100 @@
 	}
 }
 
+int
+gdb_signal(int vector)
+{
+	switch (vector & ~T_USER) {
+	case 0:  return (SIGFPE);	/* divide by zero */
+	case 1:  return (SIGTRAP);	/* debug exception */
+	case 3:  return (SIGTRAP);	/* breakpoint */
+	case 4:  return (SIGURG);	/* into instr (overflow) */
+	case 5:  return (SIGURG);	/* bound instruction */
+	case 6:  return (SIGILL);	/* Invalid opcode */
+	case 7:  return (SIGFPE);	/* npx not available */
+	case 8:  return (SIGEMT);	/* double fault */
+	case 9:  return (SIGSEGV);	/* npx segment overrun */
+	case 10: return (SIGTRAP);	/* Invalid TSS (also single-step) */
+	case 11: return (SIGSEGV);	/* Segment not present */
+	case 12: return (SIGSEGV);	/* stack exception */
+	case 13: return (SIGSEGV);	/* general protection */
+	case 14: return (SIGSEGV);	/* page fault */
+	case 16: return (SIGEMT);	/* coprocessor error */
+	}
+	return (SIGEMT);
+}
+
+gdb_reg
+gdb_getreg(struct gdb_registers *regs, int regnum)
+{
+	gdb_reg *regp;
+
+	regp = (void*)regs;
+	if ((void*)(regp + regnum) < (void*)(regs + 1))
+		return (regp[regnum]);
+	/* XXX complain. */
+	return (~0);
+}
+
+void
+gdb_setreg(struct gdb_registers *regs, int regnum, gdb_reg val)
+{
+	gdb_reg *regp;
+
+	regp = (void*)regs;
+	if ((void*)(regp + regnum) < (void*)(regs + 1))
+		regp[regnum] = val;
+}
+
+void
+gdb_getregs(struct gdb_registers *regs, db_regs_t *raw_regs)
+{
+
+	regs->eax = raw_regs->tf_eax;
+	regs->ebx = raw_regs->tf_ebx;
+	regs->ecx = raw_regs->tf_ecx;
+	regs->edx = raw_regs->tf_edx;
+	regs->esp = raw_regs->tf_esp;
+	regs->ebp = raw_regs->tf_ebp;
+	regs->esi = raw_regs->tf_esi;
+	regs->edi = raw_regs->tf_edi;
+	regs->eip = raw_regs->tf_eip;
+	regs->eflags = raw_regs->tf_eflags;
+	regs->cs = raw_regs->tf_cs;
+	regs->ss = raw_regs->tf_ss;
+	regs->ds = raw_regs->tf_ds;
+	regs->es = raw_regs->tf_es;
+}
+
+void
+gdb_setregs(struct gdb_registers *regs, db_regs_t *raw_regs)
+{
+
+	raw_regs->tf_eax = regs->eax;
+	raw_regs->tf_ebx = regs->ebx;
+	raw_regs->tf_ecx = regs->ecx;
+	raw_regs->tf_edx = regs->edx;
+	raw_regs->tf_esp = regs->esp;
+	raw_regs->tf_ebp = regs->ebp;
+	raw_regs->tf_esi = regs->esi;
+	raw_regs->tf_edi = regs->edi;
+	raw_regs->tf_eip = regs->eip;
+	raw_regs->tf_eflags = regs->eflags;
+	raw_regs->tf_cs = regs->cs;
+	raw_regs->tf_ss = regs->ss;
+	raw_regs->tf_ds = regs->ds;
+	raw_regs->tf_es = regs->es;
+}
+
+void
+gdb_singlestep(struct gdb_registers *regs, int set)
+{
+	if (set)
+		regs->eflags |= PSL_T;
+	else
+		regs->eflags &= ~PSL_T;
+}
+
 /*
  * XXX
  * Move this to machdep.c and allow it to be called if any debugger is

==== //depot/projects/sio/sys/i386/include/db_machdep.h#3 (text+ko) ====

@@ -97,9 +97,35 @@
 #define	GDB_REGNUM_FP		5
 #define	GDB_REGNUM_PC		8
 
-/* What size are registers? */
-#define	gdb_enc_register	gdb_enc_int32
+typedef uint32_t	gdb_reg;
+typedef uint32_t	gdb_addr;
+
+#define	gdb_dec_addr	gdb_dec_int32
+#define	gdb_dec_reg	gdb_dec_int32
+#define	gdb_enc_reg	gdb_enc_int32
+
+struct gdb_registers {
+	gdb_reg		eax;
+	gdb_reg		ecx;
+	gdb_reg		edx;
+	gdb_reg		ebx;
+	gdb_reg		esp;
+	gdb_reg		ebp;
+	gdb_reg		esi;
+	gdb_reg		edi;
+	gdb_reg		eip;
+	gdb_reg		eflags;
+	gdb_reg		cs;
+	gdb_reg		ss;
+	gdb_reg		ds;
+	gdb_reg		es;
+};
 
-int gdb_signal(int);
+gdb_reg	gdb_getreg(struct gdb_registers *, int);
+void	gdb_getregs(struct gdb_registers *, db_regs_t *);
+void	gdb_setreg(struct gdb_registers *, int, gdb_reg);
+void	gdb_setregs(struct gdb_registers *, db_regs_t *);
+void	gdb_singlestep(struct gdb_registers *, int);
+int	gdb_signal(int);
 
 #endif /* !_MACHINE_DB_MACHDEP_H_ */


More information about the p4-projects mailing list