PERFORCE change 30557 for review

Marcel Moolenaar marcel at FreeBSD.org
Sun May 4 15:45:31 PDT 2003


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

Change 30557 by marcel at marcel_nfs on 2003/05/04 15:44:31

	Next round of fixes:
	o  Port alpha. gdb_singlestep has not been ported yet. I
	   noticed on i386 that step is implemented by setting
	   a breakpoint (Z packet), which we don't handle. If gdb
	   on alpha does the same, it won't work anyway...
	o  Slight tweaking of prototypes and macros now that we
	   have alpha ported as well.
	o  Fix decoding of packets.
	o  Implement the link map functionality. Note that booting
	   with -dg still produces a warning. I'd like to fix that
	   to even though it's not a regression.
	
	More to come...

Affected files ...

.. //depot/projects/sio/sys/alpha/alpha/db_interface.c#2 edit
.. //depot/projects/sio/sys/alpha/alpha/machdep.c#3 edit
.. //depot/projects/sio/sys/alpha/alpha/sio_machdep.c#2 edit
.. //depot/projects/sio/sys/alpha/include/db_machdep.h#2 edit
.. //depot/projects/sio/sys/ddb/db_gdb.c#4 edit
.. //depot/projects/sio/sys/ddb/db_main.c#2 edit
.. //depot/projects/sio/sys/ddb/ddb.h#4 edit
.. //depot/projects/sio/sys/i386/i386/db_interface.c#4 edit
.. //depot/projects/sio/sys/i386/include/db_machdep.h#5 edit
.. //depot/projects/sio/sys/ia64/ia64/db_interface.c#4 edit
.. //depot/projects/sio/sys/ia64/include/db_machdep.h#3 edit
.. //depot/projects/sio/sys/kern/link_elf.c#3 edit

Differences ...

==== //depot/projects/sio/sys/alpha/alpha/db_interface.c#2 (text+ko) ====

@@ -68,6 +68,7 @@
 #include <machine/db_machdep.h>
 #include <machine/pal.h>
 #include <machine/prom.h>
+#include <machine/reg.h>
 
 #include <alpha/alpha/db_instruction.h>
 
@@ -81,13 +82,6 @@
 static jmp_buf *db_nofault = 0;
 extern jmp_buf	db_jmpbuf;
 
-extern void	gdb_handle_exception(db_regs_t *, int, int);
-
-#if 0
-extern char *trap_type[];
-extern int trap_types;
-#endif
-
 int	db_active;
 
 void	ddbprinttrap(unsigned long, unsigned long, unsigned long,
@@ -578,3 +572,139 @@
 	db_printf("ipis         = 0x%lx\n", pc->pc_pending_ipis);
 	db_printf("next ASN     = %d\n", pc->pc_next_asn);
 }
+
+/*
+ * Remote GDB support.
+ */
+
+/*
+ * Map trapframe indices into gdb (integer) register indices.
+ * Entries not in integer register set are set to -1.
+ */
+static int tf2gdb[FRAME_SIZE] = {
+/*0*/	R_V0,	R_T0,	R_T1,	R_T2,	R_T3,	R_T4,	R_T5,	R_T6,
+/*8*/	R_T7,	R_S0,	R_S1,	R_S2,	R_S3,	R_S4,	R_S5,	R_S6,
+/*16*/	R_A3,	R_A4,	R_A5,	R_T8,	R_T9,	R_T10,	R_T11,	R_RA,
+/*24*/	R_T12,	R_AT,	R_SP,	-1,	-1,	-1,	-1,	-1,
+/*32*/	-1,	R_GP,	R_A0,	R_A1,	R_A2,
+};
+
+/*
+ * Map gdb register indices back to trapframe.
+ * Entries not in trapframe are set to -1.
+ */
+static int gdb2tf[GDB_REGS] = {
+	/* integer registers */
+	FRAME_V0,	FRAME_T0,	FRAME_T1,	FRAME_T2,
+	FRAME_T3,	FRAME_T4,	FRAME_T5,	FRAME_T6,
+	FRAME_T7,	FRAME_S0,	FRAME_S1,	FRAME_S2,
+	FRAME_S3,	FRAME_S4,	FRAME_S5,	FRAME_S6,
+	FRAME_A0,	FRAME_A1,	FRAME_A2,	FRAME_A3,
+	FRAME_A4,	FRAME_A5,	FRAME_T8,	FRAME_T9,
+	FRAME_T10,	FRAME_T11,	FRAME_RA,	FRAME_T12,
+	FRAME_AT,	FRAME_GP,	FRAME_SP,	-1,
+	/* float registers */
+	-1,		-1,		-1,		-1,
+	-1,		-1,		-1,		-1,
+	-1,		-1,		-1,		-1,
+	-1,		-1,		-1,		-1,
+	-1,		-1,		-1,		-1,
+	-1,		-1,		-1,		-1,
+	-1,		-1,		-1,		-1,
+	-1,		-1,		-1,		-1,
+	/* misc registers */
+	FRAME_PC,	-1,
+};
+
+int
+gdb_signal(int type, int code)
+{
+
+	switch (type) {
+	case ALPHA_KENTRY_INT:
+	case ALPHA_KENTRY_ARITH:
+		return (SIGILL);		/* ? can this happen? */
+	case ALPHA_KENTRY_MM:
+		switch (code) {
+		case ALPHA_MMCSR_INVALTRANS:
+			return (SIGSEGV);
+		case ALPHA_MMCSR_ACCESS:
+		case ALPHA_MMCSR_FOR:
+		case ALPHA_MMCSR_FOE:
+		case ALPHA_MMCSR_FOW:
+			return (SIGBUS);
+		}
+		break;
+	case ALPHA_KENTRY_IF:
+		switch (code) {
+		case ALPHA_IF_CODE_BUGCHK:
+		case ALPHA_IF_CODE_BPT:
+			return (SIGTRAP);
+		case ALPHA_IF_CODE_GENTRAP:
+		case ALPHA_IF_CODE_FEN:
+		case ALPHA_IF_CODE_OPDEC:
+			return (SIGILL);
+		}
+		break;
+	case ALPHA_KENTRY_UNA:
+		return (SIGSEGV);
+	case ALPHA_KENTRY_SYS:
+		return (SIGILL);
+	}
+        return (SIGILL);
+}
+
+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)
+{
+	int i;
+
+	bzero(regs, sizeof(*regs));
+
+	/* Map trapframe to registers. Ignore float regs for now. */
+	for (i = 0; i < FRAME_SIZE; i++) {
+		if (tf2gdb[i] >= 0)
+			regs->r[tf2gdb[i]] = raw_regs->tf_regs[i];
+	}
+	regs->r[GDB_REGNUM_PC] = raw_regs->tf_regs[FRAME_PC];
+}
+
+void
+gdb_setregs(struct gdb_registers *regs, db_regs_t *raw_regs)
+{
+	int i;
+
+	/* Map gdb registers back to trapframe (ignoring fp regs). */
+	for (i = 0; i < GDB_REGS; i++) {
+		if (gdb2tf[i] >= 0)
+			raw_regs->tf_regs[gdb2tf[i]] = regs->r[i];
+	}
+	raw_regs->tf_regs[FRAME_PC] = regs->r[GDB_REGNUM_PC];
+}
+
+void
+gdb_singlestep(struct gdb_registers *regs, int set)
+{
+}

==== //depot/projects/sio/sys/alpha/alpha/machdep.c#3 (text+ko) ====

@@ -1001,7 +1001,7 @@
 	 * Initialize debuggers, and break into them if appropriate.
 	 */
 #ifdef DDB
-	kdb_init();
+	db_init();
 	if (boothowto & RB_KDB) {
 		printf("Boot flags requested debugger\n");
 		breakpoint();

==== //depot/projects/sio/sys/alpha/alpha/sio_machdep.c#2 (text+ko) ====

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2002 Marcel Moolenaar
+ * Copyright (c) 2002, 2003 Marcel Moolenaar
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -42,22 +42,63 @@
 #include <dev/sio/siovar.h>
 
 int
-sio_get_console(struct sio_consdata *cd)
+sio_get_console(struct sio_devdata *dd)
 {
 	struct ctb *ctb;
 
-	bzero(cd, sizeof(*cd));
+	bzero(dd, sizeof(*dd));
 
 	ctb = (struct ctb *)(((caddr_t)hwrpb) + hwrpb->rpb_ctb_off);
 	if (ctb->ctb_term_type != CTB_PRINTERPORT)
 		return (ENXIO);
 
 	boothowto |= RB_SERIAL;
-	cd->bsh = 0x3f8;
-	cd->bst = busspace_isa_io;
-	cd->baud = 9600;
-	cd->databits = 8;
-	cd->stopbits = 1;
-	cd->parity = 0;
+	dd->bsh = 0x3f8;
+	dd->bst = busspace_isa_io;
+	dd->baud = 9600;
+	dd->databits = 8;
+	dd->stopbits = 1;
+	dd->parity = 0;
 	return (0);
 }
+
+int
+sio_get_dbgport(struct sio_devdata *dd)
+{
+	unsigned int i, ivar;
+
+	bzero(dd, sizeof(*dd));
+
+	/*
+	 * Scan the hints. We only try units 0 to 3 (inclusive). This
+	 * covers the ISA legacy where 4 UARTs had their resources
+	 * predefined.
+	 */
+	for (i = 0; i < 4; i++) {
+		if (resource_int_value("sio", i, "flags", &ivar))
+			continue;
+		if (!COM_DEBUGGER(ivar))
+			continue;
+		/* We have a possible debug port. Make sure it's enabled. */
+		if (resource_int_value("sio", i, "disabled", &ivar) == 0 &&
+		    ivar != 0)
+			continue;
+		/* It's alive. Get the port. */
+		if (resource_int_value("sio", i, "port", &ivar) != 0 ||
+		    ivar == 0)
+			continue;
+		dd->bsh = ivar;
+		dd->bst = busspace_isa_io;
+		if (resource_int_value("sio", i, "baud", &ivar) != 0)
+			ivar = 0;
+		dd->baud = ivar;
+		dd->databits = 8;
+		dd->stopbits = 1;
+		dd->parity = 0;
+
+		printf("GDB: sio%d: debug port\n", i);
+		return (0);
+	}
+
+	return (ENXIO);
+}

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

@@ -113,4 +113,19 @@
  */
 #define	DB_ELFSIZE	64
 
+/*
+ * Remote GDB support.
+ */
+#define	GDB_REGNUM_FP	15
+#define	GDB_REGNUM_SP	30
+#define	GDB_REGNUM_PC	64
+#define	GDB_REGS	66
+
+typedef uint64_t	gdb_reg;
+typedef uint64_t	gdb_int;
+
+struct gdb_registers {
+	gdb_reg		r[GDB_REGS];
+};
+
 #endif	/* _ALPHA_DB_MACHDEP_H_ */

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

@@ -69,8 +69,15 @@
 #define	gdb_getc	dbgport->dbg_getc
 #define	gdb_putc	dbgport->dbg_putc
 
-static int
-gdb_hex(char ch)
+static __inline int
+ishex(int c)
+{
+	return ((c >= '0' && c <= '9') || (c >= 'A' && c <= 'F') ||
+	    (c >= 'a' && c <= 'f')) ? 1 : 0;
+}
+
+static __inline int
+tohex(char ch)
 {
 
 	if (ch >= 'a' && ch <= 'f')
@@ -85,7 +92,7 @@
 static int
 gdb_getpacket(char *buffer)
 {
-	int count, i;
+	int count;
 	unsigned char ch, checksum, xmitcsum;
 
 	if (dbgport == NULL)
@@ -93,7 +100,7 @@
 
 	do {
 		/* Wait for '$'. Ignore all other characters. */
-		while ((ch = gdb_getc()) != '$')
+		while (gdb_getc() != '$')
 			;
 
 		checksum = 0;
@@ -112,25 +119,13 @@
 			return (ENOMEM);
 
 		buffer[count] = 0;
-		xmitcsum = gdb_hex(gdb_getc()) << 4;
-		xmitcsum += gdb_hex(gdb_getc());
+		xmitcsum = tohex(gdb_getc()) << 4;
+		xmitcsum += tohex(gdb_getc());
 
-		if (checksum == xmitcsum) {
-			/* successful transfer */
+		if (checksum == xmitcsum)
 			gdb_putc('+');
-
-			/* If there's a sequence char, echo the sequence ID. */
-			if (buffer[2] == ':') {
-				gdb_putc(buffer[0]);
-				gdb_putc(buffer[1]);
-
-				/* remove sequence chars from buffer */
-				for (i = 3; i <= count; i++)
-					buffer[i - 3] = buffer[i];
-				count -= 3;
-			}
-		} else
-			gdb_putc('-');		/* failed checksum */
+		else
+			gdb_putc('-');
 	} while (checksum != xmitcsum);
 
 	return (0);
@@ -145,7 +140,7 @@
 	if (dbgport == NULL)
 		return (ENXIO);
 
-	/*  $<packet info>#<checksum>. */
+	/* $<packet info>#<checksum> */
 	do {
 #ifdef GDB_REMOTE_CHAT
 		/*
@@ -174,7 +169,7 @@
 		gdb_putc('#');
 		gdb_putc(hexchars[checksum >> 4]);
 		gdb_putc(hexchars[checksum & 0xf]);
-	} while ((gdb_getc() & 0x7f) != '+');
+	} while (gdb_getc() != '+');
 
 	return (0);
 }
@@ -185,7 +180,7 @@
 {
 
 	if (dbgport == NULL) {
-		db_printf("No gdb port enabled.\n");
+		db_printf("GDB: No debug port configured.\n");
 		return;
 	}
 
@@ -201,12 +196,10 @@
 	struct dbgdev *dd, **set;
 	int error;
 
-	printf("gdb_init called\n");
 	SET_FOREACH(set, dbgdev_set) {
 		dd = *set;
 		if (dd->dbg_probe == NULL)
 			continue;
-		printf("Probing device: %s\n", dd->dbg_devname);
 		error = dd->dbg_probe();
 		if (error)
 			continue;
@@ -243,63 +236,38 @@
 }
 
 static __inline int
-gdb_dec_int8(void)
+gdb_dec_skip(int c)
 {
-	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);
+	if (encdecsz > 0 && *encdecp == c) {
+		encdecsz--;
+		encdecp++;
+		return (0);
+	}
+	return (EINVAL);
 }
 
 static __inline int
-gdb_dec_int16(void)
+gdb_dec_hex(gdb_reg *resp)
 {
-	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);
+	gdb_reg res = 0;
+	if (encdecsz == 0 || !ishex(*encdecp))
+		return (ENOENT);
+	do {
+		res <<= 4;
+		res |= tohex(gdb_dec_char());
+	} while (encdecsz > 0 && ishex(*encdecp));
+	*resp = res;
+	return (0);
 }
 
 static __inline int
-gdb_dec_block(gdb_addr addr, int len)
+gdb_dec_block(gdb_int 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;
+	uint8_t v;
+	while (len > 0 && encdecsz > 1) {
+		v = (tohex(gdb_dec_char()) << 4) | tohex(gdb_dec_char());
+		*p++ = v;
 		len--;
 	}
 	return 0;
@@ -348,45 +316,36 @@
 }
 
 static __inline void
-gdb_enc_int16(uint16_t i)
+gdb_enc_block(void *addr, int len)
 {
-	gdb_enc_int8(i >> 8);
-	gdb_enc_int8(i & 0xff);
+	uint8_t *p = addr;
+	while (len > 0)
+		gdb_enc_int8(*p++), len--;
 }
 
 static __inline void
-gdb_enc_int32(uint32_t i)
+gdb_enc_reg(gdb_reg reg)
 {
-	gdb_enc_int16(i >> 16);
-	gdb_enc_int16(i & 0xffff);
-}
-
-static __inline void
-gdb_enc_int64(uint64_t i)
-{
-	gdb_enc_int32(i >> 32);
-	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--;
+	gdb_enc_block(&reg, sizeof(reg));
 }
 
 static __inline void
 gdb_enc_registers(struct gdb_registers *regs)
 {
-	gdb_enc_block((intptr_t)regs, sizeof(*regs));
+	gdb_enc_block(regs, sizeof(*regs));
 }
 
 /*
  * gdb_handle_exception
  *
- * This function does all command processing for interfacing to gdb. The
- * following gdb commands are supported:
+ * This function does all command processing for interfacing to gdb. All
+ * commands and responses (except for acknowledgements) are sent as
+ * packets. A packet is started with '$', followed by the actual data and
+ * terminated with '#' followed by a 2 (two) digit checksum:
+ *
+ *	$<packet-data>#<checksum>
+ *
+ * The following gdb commands are supported:
  *
  * command          function                               Return value
  *
@@ -408,15 +367,6 @@
  *
  *    D             detach                                 OK
  *
- * All commands and responses are sent with a packet which includes a
- * checksum.  A packet consists of
- *
- * $<packet info>#<checksum>.
- *
- * where
- * <packet info> = characters representing the command or response
- * <checksum>    = two hex digits computed as modulo 256 sum of <packet info>
- *
  * When a packet is received, it is first acknowledged with either '+' or '-'.
  * '+' indicates a successful transfer.  '-' indicates a failed transfer.
  *
@@ -427,12 +377,11 @@
  */
 
 int
-gdb_handle_exception(db_regs_t *raw_regs, int type)
+gdb_handle_exception(db_regs_t *raw_regs, int type, int code)
 {
 	struct gdb_registers regs;
-	gdb_addr addr;
-	gdb_reg reg;
-	int c, error, len, regno;
+	gdb_int addr, len, reg, regno;
+	int error;
 
 	if (dbgport == NULL) {
 		db_printf("GDB: No debug port configured.\n");
@@ -441,10 +390,9 @@
 
 	gdb_getregs(&regs, raw_regs);
 
-	/* "TxxPC:xxxxxxxx;FP:xxxxxxxx;SP:xxxxxxxx;" */
 	gdb_enc_begin(gdb_buffer, sizeof(gdb_buffer));
 	gdb_enc_char('T');
-	gdb_enc_int8(gdb_signal(type));
+	gdb_enc_int8(gdb_signal(type, code));
 	gdb_enc_int8(GDB_REGNUM_PC);
 	gdb_enc_char(':');
 	gdb_enc_reg(gdb_getreg(&regs, GDB_REGNUM_PC));
@@ -471,14 +419,21 @@
 		case '?':
 			gdb_enc_begin(gdb_buffer, sizeof(gdb_buffer));
 			gdb_enc_char('S');
-			gdb_enc_int8(gdb_signal(type));
+			gdb_enc_int8(gdb_signal(type, code));
 			gdb_enc_end();
 			gdb_putpacket(gdb_buffer);
 			break;
 
+		case 'c' :
+			/* cAA..AA    Continue at address AA..AA (opt) */
+			gdb_singlestep(&regs, 0);
+			error = gdb_dec_hex(&addr);
+			if (!error)
+				gdb_setreg(&regs, GDB_REGNUM_PC, addr);
+			gdb_setregs(&regs, raw_regs);
+			return (0);
+
 		case 'D':
-			/* Detach; say OK and turn off gdb */
-			gdb_putpacket("OK");
 			boothowto &= ~RB_GDB;
 			return (0);
 
@@ -496,27 +451,19 @@
 			gdb_putpacket("OK");
 			break;
 
-		case 'P':
-			/* Set the value of one register */
-			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");
-			break;
+		case 'k':
+			boothowto &= ~RB_GDB;
+			return (0);
 
 		case 'm':
 			/* mAA..AA,LLLL  Read LLLL bytes at address AA..AA */
 			/* Try to read %x,%x.  */
-			addr = gdb_dec_addr();
-			c = gdb_dec_char();
-			len = gdb_dec_int32();
-			if (c == ',' && len > 0) {
+			error = gdb_dec_hex(&addr);
+			error = (!error) ? gdb_dec_skip(',') : error;
+			error = (!error) ? gdb_dec_hex(&len) : error;
+			if (!error) {
 				gdb_enc_begin(gdb_buffer, sizeof(gdb_buffer));
-				gdb_enc_block(addr, len);
+				gdb_enc_block((void*)(intptr_t)addr, len);
 				gdb_enc_end();
 				gdb_putpacket(gdb_buffer);
 				/* XXX return "E03" when encoding fails. */
@@ -528,10 +475,11 @@
 			/* MAA..AA,LLLL: Write LLLL bytes at address AA.AA */
 			/* return OK */
 			/* Try to read '%x,%x:'. */
-			addr = gdb_dec_addr();
-			c = gdb_dec_char();
-			len = gdb_dec_int32();
-			if (c == ',' && len > 0 && gdb_dec_char() == ':') {
+			error = gdb_dec_hex(&addr);
+			error = (!error) ? gdb_dec_skip(',') : error;
+			error = (!error) ? gdb_dec_hex(&len) : error;
+			error = (!error) ? gdb_dec_skip(':') : error;
+			if (!error) {
 				gdb_dec_block(addr, len);
 				gdb_putpacket("OK");
 				/* XXX return "E03" when decoding fails. */
@@ -539,23 +487,34 @@
 				gdb_putpacket("E02");
 			break;
 
-		case 'c' :
-			/* cAA..AA    Continue at address AA..AA (opt) */
-			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 'P':
+			/* Set the value of one register */
+			error = gdb_dec_hex(&regno);
+			error = (!error) ? gdb_dec_skip('=') : error;
+			error = (!error) ? gdb_dec_hex(&reg) : error;
+			if (!error) {
+				gdb_setreg(&regs, regno, reg);
+				gdb_putpacket("OK");
+			} else
+				gdb_putpacket("E01");
+			break;
 
 		case 's' :
 			/* sAA..AA   Step one instruction from AA..AA (opt) */
 			gdb_singlestep(&regs, 1);
-			addr = gdb_dec_addr();
-			if (addr != ~0U)
+			error = gdb_dec_hex(&addr);
+			if (!error)
 				gdb_setreg(&regs, GDB_REGNUM_PC, addr);
 			gdb_setregs(&regs, raw_regs);
 			return (0);
+
+		default:
+			/*
+			 * Empty response. Tells GDB that we don't understand
+			 * the command.
+			 */
+			gdb_putpacket("");
+			break;
 		} /* switch */
 	}
 

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

@@ -30,10 +30,70 @@
 #include <sys/systm.h>
 #include <sys/types.h>
 #include <sys/linker.h>
+#include <sys/link_elf.h>
+#include <sys/malloc.h>
+#include <sys/queue.h>
 
 #include <ddb/ddb.h>
 #include <ddb/db_sym.h>
 
+#define GDB_STATE(s)	r_debug.r_state = s; r_debug_state(NULL, NULL);
+
+static struct r_debug r_debug;
+
+struct db_module {
+	STAILQ_ENTRY(db_module) link;
+	linker_file_t	file;
+	struct link_map map;
+};
+
+STAILQ_HEAD(db_module_list, db_module);
+
+static struct db_module_list db_modules = STAILQ_HEAD_INITIALIZER(db_modules);
+
+/*
+ * Function for the debugger to set a breakpoint on to gain control.
+ */
+static void
+r_debug_state(struct r_debug *a1 __unused, struct link_map *a2 __unused)
+{
+}
+
+static void
+gdb_add_link_map(struct link_map *l)
+{
+	struct link_map *prev;
+
+	l->l_next = NULL;
+
+	if (r_debug.r_map == NULL) {
+		/* Add first. */
+		l->l_prev = NULL;
+		r_debug.r_map = l;
+	} else {
+		/* Append to list. */
+		for (prev = r_debug.r_map; prev->l_next != NULL;
+		     prev = prev->l_next)
+			;
+		l->l_prev = prev;
+		prev->l_next = l;
+	}
+}
+
+static void
+gdb_delete_link_map(struct link_map *l)
+{
+	if (l->l_prev == NULL) {
+		/* Remove first. */
+		if ((r_debug.r_map = l->l_next) != NULL)
+			l->l_next->l_prev = NULL;
+	} else {
+		/* Remove any but first. */
+		if ((l->l_prev->l_next = l->l_next) != NULL)
+			l->l_next->l_prev = l->l_prev;
+	}
+}
+
 boolean_t
 X_db_line_at_pc(db_symtab_t *symtab, c_db_sym_t sym, char **filename,
     int *linenum, db_expr_t off)
@@ -71,18 +131,43 @@
  * Called by the linker to notify that a module has been loaded. This
  * function is called after any MD specific load actions.
  */
-void db_load_file(linker_file_t lf)
+void
+db_load_file(linker_file_t lf, void * base, void *dyn)
 {
-	printf("db_load_file called (module=%s)\n", lf->filename);
+	struct db_module *m;
+
+	GDB_STATE(RT_ADD);
+	m = malloc(sizeof(*m), M_TEMP, M_WAITOK|M_ZERO);
+	m->file = lf;
+	m->map.l_addr = base;
+	m->map.l_name = lf->filename;
+	m->map.l_ld = dyn;
+	STAILQ_INSERT_TAIL(&db_modules, m, link);
+	gdb_add_link_map(&m->map);
+	GDB_STATE(RT_CONSISTENT);
 }
 
 /*
  * Called by the linker to notify that a module is about to be unloaded.
  * This function is called prior to any MD specific unload actions.
  */
-void db_unload_file(linker_file_t lf)
+void
+db_unload_file(linker_file_t lf)
 {
-	printf("db_unload_file called (module=%s)\n", lf->filename);
+	struct db_module *m;
+
+	STAILQ_FOREACH(m, &db_modules, link) {
+                if (m->file == lf)
+			break;
+        }
+	if (m == NULL)
+		return;
+
+	GDB_STATE(RT_DELETE);
+	gdb_delete_link_map(&m->map);
+	STAILQ_REMOVE(&db_modules, m, db_module, link);
+	free(m, M_TEMP);
+	GDB_STATE(RT_CONSISTENT);
 }
 
 /*
@@ -93,18 +178,22 @@
  * pointer that needs to be updated, we know about the data that needs
  * to be maintained.
  */
-vm_offset_t db_debug_base(void)
+vm_offset_t
+db_debug_base(void)
 {
-	printf("db_debug_base called\n");
-	return (0);
+	return ((intptr_t)&r_debug);
 }
 
 /*
  * Called by MD initialization code (preferrably after initializing the
  * low-level console) to initialize the debugger.
  */
-void db_init(void)
+void
+db_init(void)
 {
 
+	r_debug.r_map = NULL;
+	r_debug.r_brk = r_debug_state;
+	r_debug.r_state = RT_CONSISTENT;
 	gdb_init();
 }

==== //depot/projects/sio/sys/ddb/ddb.h#4 (text+ko) ====

@@ -163,12 +163,12 @@
 
 gdb_reg gdb_getreg(struct gdb_registers *, int);
 void    gdb_getregs(struct gdb_registers *, db_regs_t *);
-int	gdb_handle_exception(db_regs_t *, int);
+int	gdb_handle_exception(db_regs_t *, int, int);
 void	gdb_init(void);
 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);
+int     gdb_signal(int, int);
 
 /* Scare the user with backtrace of curthread to console. */
 void		db_print_backtrace(void);
@@ -176,7 +176,7 @@
 /* Linker hooks. */
 struct linker_file;
 vm_offset_t	db_debug_base(void);
-void		db_load_file(struct linker_file *);
+void		db_load_file(struct linker_file *, void*, void*);
 void		db_unload_file(struct linker_file *);
 /*
  * Command table.

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

@@ -171,7 +171,7 @@
 	    cndbctl(FALSE);
 	} else {
 	    db_active = 1;
-	    gdb_handle_exception(&ddb_regs, type);
+	    gdb_handle_exception(&ddb_regs, type, code);
 	}
 	db_active = 0;
 
@@ -304,7 +304,7 @@
 }
 
 int
-gdb_signal(int vector)
+gdb_signal(int vector, int code __unused)
 {
 	switch (vector & ~T_USER) {
 	case 0:  return (SIGFPE);	/* divide by zero */
@@ -366,6 +366,8 @@
 	regs->ss = raw_regs->tf_ss;
 	regs->ds = raw_regs->tf_ds;
 	regs->es = raw_regs->tf_es;
+	regs->fs = raw_regs->tf_fs;
+	regs->gs = 0;
 }
 
 void
@@ -386,6 +388,7 @@
 	raw_regs->tf_ss = regs->ss;
 	raw_regs->tf_ds = regs->ds;
 	raw_regs->tf_es = regs->es;
+	raw_regs->tf_fs = regs->fs;
 }
 
 void

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

@@ -98,11 +98,7 @@
 #define	GDB_REGNUM_PC		8
 
 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
+typedef uint32_t	gdb_int;
 
 struct gdb_registers {
 	gdb_reg		eax;
@@ -119,6 +115,8 @@
 	gdb_reg		ss;
 	gdb_reg		ds;
 	gdb_reg		es;
+	gdb_reg		fs;
+	gdb_reg		gs;
 };
 
 #endif /* !_MACHINE_DB_MACHDEP_H_ */

==== //depot/projects/sio/sys/ia64/ia64/db_interface.c#4 (text+ko) ====

@@ -359,11 +359,11 @@
 	db_active++;
 
 	if (ddb_mode) {
-	    cndbctl(TRUE);	/* DDB active, unblank video */
-	    db_trap(vector, 0);	/* Where the work happens */
-	    cndbctl(FALSE);	/* DDB inactive */
+		cndbctl(TRUE);		/* DDB active, unblank video */
+		db_trap(vector, 0);	/* Where the work happens */
+		cndbctl(FALSE);		/* DDB inactive */
 	} else
-	    gdb_handle_exception(&ddb_regs, vector);
+		gdb_handle_exception(&ddb_regs, vector, 0);
 
 	db_active--;
 
@@ -394,7 +394,6 @@
 
 	intr_restore(s);
 
-

>>> TRUNCATED FOR MAIL (1000 lines) <<<


More information about the p4-projects mailing list