Date: Sun, 4 May 2003 15:45:28 -0700 (PDT) From: Marcel Moolenaar <marcel@FreeBSD.org> To: Perforce Change Reviews <perforce@freebsd.org> Subject: PERFORCE change 30557 for review Message-ID: <200305042245.h44MjSST096770@repoman.freebsd.org>
index | next in thread | raw e-mail
http://perforce.freebsd.org/chv.cgi?CH=30557 Change 30557 by marcel@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) <<<help
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200305042245.h44MjSST096770>
