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(®, 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(®s, 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(®s, 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(®s, 0);
+ error = gdb_dec_hex(&addr);
+ if (!error)
+ gdb_setreg(®s, GDB_REGNUM_PC, addr);
+ gdb_setregs(®s, 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(®s, 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(®s, 0);
- addr = gdb_dec_addr();
- if (addr != ~0U)
- gdb_setreg(®s, GDB_REGNUM_PC, addr);
- gdb_setregs(®s, raw_regs);
- return (0);
+ case 'P':
+ /* Set the value of one register */
+ error = gdb_dec_hex(®no);
+ error = (!error) ? gdb_dec_skip('=') : error;
+ error = (!error) ? gdb_dec_hex(®) : error;
+ if (!error) {
+ gdb_setreg(®s, regno, reg);
+ gdb_putpacket("OK");
+ } else
+ gdb_putpacket("E01");
+ break;
case 's' :
/* sAA..AA Step one instruction from AA..AA (opt) */
gdb_singlestep(®s, 1);
- addr = gdb_dec_addr();
- if (addr != ~0U)
+ error = gdb_dec_hex(&addr);
+ if (!error)
gdb_setreg(®s, GDB_REGNUM_PC, addr);
gdb_setregs(®s, 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