From 1ca618fcaaceb511247bd2e0f2fa6ae4587a9599 Mon Sep 17 00:00:00 2001 From: Marcel Moolenaar Date: Sun, 11 Jul 2004 01:47:26 +0000 Subject: [PATCH] Remove the now unused GDB stubs. See src/sys/gdb/* for the new KDB backend. --- sys/alpha/alpha/alpha-gdbstub.c | 746 -------------------------------- sys/amd64/amd64/amd64-gdbstub.c | 614 -------------------------- sys/i386/i386/i386-gdbstub.c | 612 -------------------------- sys/ia64/ia64/ia64-gdbstub.c | 580 ------------------------- 4 files changed, 2552 deletions(-) delete mode 100644 sys/alpha/alpha/alpha-gdbstub.c delete mode 100644 sys/amd64/amd64/amd64-gdbstub.c delete mode 100644 sys/i386/i386/i386-gdbstub.c delete mode 100644 sys/ia64/ia64/ia64-gdbstub.c diff --git a/sys/alpha/alpha/alpha-gdbstub.c b/sys/alpha/alpha/alpha-gdbstub.c deleted file mode 100644 index 1be2c26eed66..000000000000 --- a/sys/alpha/alpha/alpha-gdbstub.c +++ /dev/null @@ -1,746 +0,0 @@ -/**************************************************************************** - - THIS SOFTWARE IS NOT COPYRIGHTED - - HP offers the following for use in the public domain. HP makes no - warranty with regard to the software or its performance and the - user accepts the software "AS IS" with all faults. - - HP DISCLAIMS ANY WARRANTIES, EXPRESS OR IMPLIED, WITH REGARD - TO THIS SOFTWARE INCLUDING BUT NOT LIMITED TO THE WARRANTIES - OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. - -****************************************************************************/ - -/**************************************************************************** - * Header: remcom.c,v 1.34 91/03/09 12:29:49 glenne Exp $ - * - * Module name: remcom.c $ - * Revision: 1.34 $ - * Date: 91/03/09 12:29:49 $ - * Contributor: Lake Stevens Instrument Division$ - * - * Description: low level support for gdb debugger. $ - * - * Considerations: only works on target hardware $ - * - * Written by: Glenn Engel $ - * ModuleState: Experimental $ - * - * NOTES: See Below $ - * - * Modified for FreeBSD by Stu Grossman. - * - * To enable debugger support, two things need to happen. One, a - * call to set_debug_traps() is necessary in order to allow any breakpoints - * or error conditions to be properly intercepted and reported to gdb. - * Two, a breakpoint needs to be generated to begin communication. This - * is most easily accomplished by a call to breakpoint(). Breakpoint() - * simulates a breakpoint by executing a trap #1. - * - * The external function exceptionHandler() is - * used to attach a specific handler to a specific 386 vector number. - * It should use the same privilege level it runs at. It should - * install it as an interrupt gate so that interrupts are masked - * while the handler runs. - * Also, need to assign exceptionHook and oldExceptionHook. - * - * Because gdb will sometimes write to the stack area to execute function - * calls, this program cannot rely on using the supervisor stack so it - * uses its own stack area reserved in the int array remcomStack. - * - ************* - * - * The following gdb commands are supported: - * - * command function Return value - * - * g return the value of the CPU registers hex data or ENN - * G set the value of the CPU registers OK or ENN - * - * mAA..AA,LLLL Read LLLL bytes at address AA..AA hex data or ENN - * MAA..AA,LLLL: Write LLLL bytes at address AA.AA OK or ENN - * - * c Resume at current address SNN ( signal NN) - * cAA..AA Continue at address AA..AA SNN - * - * s Step one instruction SNN - * sAA..AA Step one instruction from AA..AA SNN - * - * k kill - * - * ? What was the last sigval ? SNN (signal NN) - * - * D detach OK - * - * All commands and responses are sent with a packet which includes a - * checksum. A packet consists of - * - * $#. - * - * where - * :: - * :: < two hex digits computed as modulo 256 sum of > - * - * When a packet is received, it is first acknowledged with either '+' or '-'. - * '+' indicates a successful transfer. '-' indicates a failed transfer. - * - * Example: - * - * Host: Reply: - * $m0,10#2a +$00010203040506070809101112131415#42 - * - ****************************************************************************/ - -#include -__FBSDID("$FreeBSD$"); - -#include "opt_ddb.h" - -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include - -/************************************************************************/ - -void gdb_handle_exception (db_regs_t *, int, int); - -extern jmp_buf db_jmpbuf; - -/************************************************************************/ -/* BUFMAX defines the maximum number of characters in inbound/outbound buffers*/ -/* at least NUMREGBYTES*2 are needed for register packets */ -#define BUFMAX 1500 - -/* Create private copies of common functions used by the stub. This prevents - nasty interactions between app code and the stub (for instance if user steps - into strlen, etc..) */ -/* XXX this is fairly bogus. strlen() and strcpy() should be reentrant, - and are reentrant under FreeBSD. In any case, our versions should not - be named the same as the standard versions, so that the address `strlen' - is unambiguous... */ - -#define strlen gdb_strlen -#define strcpy gdb_strcpy - -static int -strlen (const char *s) -{ - const char *s1 = s; - - while (*s1++ != '\000'); - - return s1 - s; -} - -static char * -strcpy (char *dst, const char *src) -{ - char *retval = dst; - - while ((*dst++ = *src++) != '\000'); - - return retval; -} - -static int -putDebugChar (int c) /* write a single character */ -{ - if (gdb_arg == NULL) - return 0; - (*gdb_putc)(gdb_arg, c); - return 1; -} - -static int -getDebugChar (void) /* read and return a single char */ -{ - if (gdb_arg == NULL) - return -1; - return (*gdb_getc)(gdb_arg); -} - -static const char hexchars[]="0123456789abcdef"; - -static int -hex(char ch) -{ - if ((ch >= 'a') && (ch <= 'f')) return (ch-'a'+10); - if ((ch >= '0') && (ch <= '9')) return (ch-'0'); - if ((ch >= 'A') && (ch <= 'F')) return (ch-'A'+10); - return (-1); -} - -/* scan for the sequence $# */ -static void -getpacket (char *buffer) -{ - unsigned char checksum; - unsigned char xmitcsum; - int i; - int count; - unsigned char ch; - - do - { - /* wait around for the start character, ignore all other characters */ - - while ((ch = (getDebugChar () & 0x7f)) != '$'); - - checksum = 0; - xmitcsum = -1; - - count = 0; - - /* now, read until a # or end of buffer is found */ - - while (count < BUFMAX) - { - ch = getDebugChar () & 0x7f; - if (ch == '#') - break; - checksum = checksum + ch; - buffer[count] = ch; - count = count + 1; - } - buffer[count] = 0; - - if (ch == '#') - { - xmitcsum = hex (getDebugChar () & 0x7f) << 4; - xmitcsum += hex (getDebugChar () & 0x7f); - - if (checksum != xmitcsum) - putDebugChar ('-'); /* failed checksum */ - else - { - putDebugChar ('+'); /* successful transfer */ - /* if a sequence char is present, reply the sequence ID */ - if (buffer[2] == ':') - { - putDebugChar (buffer[0]); - putDebugChar (buffer[1]); - - /* remove sequence chars from buffer */ - - count = strlen (buffer); - for (i=3; i <= count; i++) - buffer[i-3] = buffer[i]; - } - } - } - } - while (checksum != xmitcsum); - - if (strlen(buffer) >= BUFMAX) - panic("kgdb: buffer overflow"); -} - -/* send the packet in buffer. */ - -static void -putpacket (char *buffer) -{ - unsigned char checksum; - int count; - unsigned char ch; - - if (strlen(buffer) >= BUFMAX) - panic("kgdb: buffer overflow"); - - /* $#. */ - do - { -/* - * This is a non-standard hack to allow use of the serial console for - * operation as well as debugging. Simply turn on 'remotechat' in gdb. - * - * This extension is not part of the Cygnus protocol, is kinda gross, - * but gets the job done. - */ -#ifdef GDB_REMOTE_CHAT - putDebugChar ('|'); - putDebugChar ('|'); - putDebugChar ('|'); - putDebugChar ('|'); -#endif - putDebugChar ('$'); - checksum = 0; - count = 0; - - while ((ch=buffer[count]) != 0) - { - putDebugChar (ch); - checksum += ch; - count += 1; - } - - putDebugChar ('#'); - putDebugChar (hexchars[checksum >> 4]); - putDebugChar (hexchars[checksum & 0xf]); - } - while ((getDebugChar () & 0x7f) != '+'); -} - -static char remcomInBuffer[BUFMAX]; -static char remcomOutBuffer[BUFMAX]; - -static int -get_char (vm_offset_t addr) -{ - char data; - - if (setjmp (db_jmpbuf)) - return -1; - - db_read_bytes (addr, 1, &data); - - return data & 0xff; -} - -static int -set_char (vm_offset_t addr, int val) -{ - char data; - - if (setjmp (db_jmpbuf)) - return -1; - - data = val; - - db_write_bytes (addr, 1, &data); - return 0; -} - -/* convert the memory pointed to by mem into hex, placing result in buf */ -/* return a pointer to the last char put in buf (null) */ - -static char * -mem2hex (vm_offset_t mem, char *buf, int count) -{ - int i; - int ch; - - for (i=0;i> 4]; - *buf++ = hexchars[ch % 16]; - } - *buf = 0; - return(buf); -} - -/* convert the hex array pointed to by buf into binary to be placed in mem */ -/* return a pointer to the character AFTER the last byte written */ -static char * -hex2mem (char *buf, vm_offset_t mem, int count) -{ - int i; - int ch; - int rv; - - for (i=0;i=0) - { - *intValue = (*intValue <<4) | hexValue; - numChars ++; - } - else - break; - - (*ptr)++; - } - - return (numChars); -} - -static enum { - NONE, - NORMAL, - BRANCH -} ss_mode = NONE; - -struct ss_bpt { - int active; - vm_offset_t addr; - u_int32_t contents; -}; - -static struct ss_bpt ss_bp1, ss_bp2; - -static int -set_bpt(struct ss_bpt* bp) -{ - u_int32_t bp_ins = BKPT_INST; - if (bp->active) return 0; - if (badaddr((caddr_t)bp->addr, 4)) - return 0; - db_read_bytes(bp->addr, 4, (caddr_t) &bp->contents); - db_write_bytes(bp->addr, 4, (caddr_t) &bp_ins); - bp->active = 1; - return 1; -} - -static void -clear_bpt(struct ss_bpt* bp) -{ - if (!bp->active) return; - if (badaddr((caddr_t) bp->addr, 4)) - return; - db_write_bytes(bp->addr, 4, (caddr_t) &bp->contents); - bp->active = 0; -} - -static int -set_single_step(db_regs_t* regs) -{ - u_int32_t ins; - vm_offset_t pc = regs->tf_regs[FRAME_PC]; - - if (ss_mode != NONE) { - printf("single_step botch\n"); - return 0; - } - - if (badaddr((caddr_t) pc, 4)) - return 0; - db_read_bytes(pc, 4, (caddr_t) &ins); - ss_bp1.addr = pc + 4; - if (db_inst_branch(ins)) { - ss_bp2.addr = db_branch_taken(ins, pc, regs); - if (!set_bpt(&ss_bp1)) - return 0; - if (!set_bpt(&ss_bp2)) { - clear_bpt(&ss_bp1); - return 0; - } - ss_mode = BRANCH; - } else { - if (!set_bpt(&ss_bp1)) - return 0; - ss_mode = NORMAL; - } - - return 1; -} - -static void -clear_single_step(db_regs_t* regs) -{ - /* if we hit one of the step breakpoints, adjust pc */ - if (ss_mode == BRANCH) - { - /* remove in reverse order in case they are at the same address */ - if (regs->tf_regs[FRAME_PC] == ss_bp1.addr + 4 - || regs->tf_regs[FRAME_PC] == ss_bp2.addr + 4) - regs->tf_regs[FRAME_PC] -= 4; - clear_bpt(&ss_bp2); - clear_bpt(&ss_bp1); - } - else if (ss_mode == NORMAL) - { - if (regs->tf_regs[FRAME_PC] == ss_bp1.addr + 4) - regs->tf_regs[FRAME_PC] -= 4; - clear_bpt(&ss_bp1); - } - ss_mode = NONE; -} - -#define NUMREGBYTES (sizeof registers) -#define PC 64 -#define SP 30 -#define FP 15 -#define VFP 65 -#define NUM_REGS 66 - -/* - * 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[NUM_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, -}; - -/* - * This function does all command procesing for interfacing to gdb. - */ -void -gdb_handle_exception (db_regs_t *raw_regs, int type, int code) -{ - int sigval; - long addr, length; - char * ptr; - struct alpharegs { - u_int64_t r[32]; - u_int64_t f[32]; - u_int64_t pc, vfp; - }; - static struct alpharegs registers; - int i; - - clear_single_step(raw_regs); - - bzero(®isters, sizeof registers); - - /* - * Map trapframe to registers. - * Ignore float regs for now. - */ - for (i = 0; i < FRAME_SIZE; i++) - if (tf2gdb[i] >= 0) - registers.r[tf2gdb[i]] = raw_regs->tf_regs[i]; - registers.pc = raw_regs->tf_regs[FRAME_PC]; - - /* reply to host that an exception has occurred */ - sigval = computeSignal (type, code); - ptr = remcomOutBuffer; - - *ptr++ = 'T'; - *ptr++ = hexchars[sigval >> 4]; - *ptr++ = hexchars[sigval & 0xf]; - - *ptr++ = hexchars[PC >> 4]; - *ptr++ = hexchars[PC & 0xf]; - *ptr++ = ':'; - ptr = mem2hex ((vm_offset_t)®isters.pc, ptr, 8); - *ptr++ = ';'; - - *ptr++ = hexchars[FP >> 4]; - *ptr++ = hexchars[FP & 0xf]; - *ptr++ = ':'; - ptr = mem2hex ((vm_offset_t)®isters.r[FP], ptr, 8); - *ptr++ = ';'; - - *ptr++ = hexchars[SP >> 4]; - *ptr++ = hexchars[SP & 0xf]; - *ptr++ = ':'; - ptr = mem2hex ((vm_offset_t)®isters.r[SP], ptr, 8); - *ptr++ = ';'; - - *ptr++ = 0; - - putpacket (remcomOutBuffer); - - while (1) - { - if (gdb_arg == NULL) /* somebody's removed it */ - return; /* get out of here */ - remcomOutBuffer[0] = 0; - - getpacket (remcomInBuffer); - switch (remcomInBuffer[0]) - { - case '?': - remcomOutBuffer[0] = 'S'; - remcomOutBuffer[1] = hexchars[sigval >> 4]; - remcomOutBuffer[2] = hexchars[sigval % 16]; - remcomOutBuffer[3] = 0; - break; - - case 'D': /* detach; say OK and turn off gdb */ - putpacket(remcomOutBuffer); - boothowto &= ~RB_GDB; - return; - - case 'k': - prom_halt(1); - /*NOTREACHED*/ - break; - - case 'g': /* return the value of the CPU registers */ - mem2hex ((vm_offset_t)®isters, remcomOutBuffer, NUMREGBYTES); - break; - - case 'G': /* set the value of the CPU registers - return OK */ - hex2mem (&remcomInBuffer[1], (vm_offset_t)®isters, NUMREGBYTES); - strcpy (remcomOutBuffer, "OK"); - break; - - case 'P': /* Set the value of one register */ - { - long regno; - - ptr = &remcomInBuffer[1]; - - if (hexToInt (&ptr, ®no) - && *ptr++ == '=' - && regno < NUM_REGS) - { - hex2mem (ptr, (vm_offset_t)®isters + regno * 8, 8); - strcpy(remcomOutBuffer,"OK"); - } - else - strcpy (remcomOutBuffer, "P01"); - break; - } - case 'm': /* mAA..AA,LLLL Read LLLL bytes at address AA..AA */ - /* Try to read %x,%x. */ - - ptr = &remcomInBuffer[1]; - - if (hexToInt (&ptr, &addr) - && *(ptr++) == ',' - && hexToInt (&ptr, &length)) - { - if (mem2hex((vm_offset_t) addr, remcomOutBuffer, length) == NULL) - strcpy (remcomOutBuffer, "E03"); - break; - } - else - strcpy (remcomOutBuffer, "E01"); - break; - - case 'M': /* MAA..AA,LLLL: Write LLLL bytes at address AA.AA return OK */ - - /* Try to read '%x,%x:'. */ - - ptr = &remcomInBuffer[1]; - - if (hexToInt(&ptr,&addr) - && *(ptr++) == ',' - && hexToInt(&ptr, &length) - && *(ptr++) == ':') - { - if (hex2mem(ptr, (vm_offset_t) addr, length) == NULL) - strcpy (remcomOutBuffer, "E03"); - else - strcpy (remcomOutBuffer, "OK"); - } - else - strcpy (remcomOutBuffer, "E02"); - break; - - /* cAA..AA Continue at address AA..AA(optional) */ - /* sAA..AA Step one instruction from AA..AA(optional) */ - case 'c' : - case 's' : - /* try to read optional parameter, pc unchanged if no parm */ - - ptr = &remcomInBuffer[1]; - if (hexToInt(&ptr,&addr)) - registers.pc = addr; - - /* - * Map gdb registers back to trapframe (ignoring fp regs). - */ - for (i = 0; i < NUM_REGS; i++) - if (gdb2tf[i] >= 0) - raw_regs->tf_regs[gdb2tf[i]] = registers.r[i]; - raw_regs->tf_regs[FRAME_PC] = registers.pc; - - if (remcomInBuffer[0] == 's') - if (!set_single_step(raw_regs)) - printf("Can't set single step breakpoint\n"); - - return; - - } /* switch */ - - /* reply to the request */ - putpacket (remcomOutBuffer); - } -} diff --git a/sys/amd64/amd64/amd64-gdbstub.c b/sys/amd64/amd64/amd64-gdbstub.c deleted file mode 100644 index ac001cdc406d..000000000000 --- a/sys/amd64/amd64/amd64-gdbstub.c +++ /dev/null @@ -1,614 +0,0 @@ -/**************************************************************************** - - THIS SOFTWARE IS NOT COPYRIGHTED - - HP offers the following for use in the public domain. HP makes no - warranty with regard to the software or its performance and the - user accepts the software "AS IS" with all faults. - - HP DISCLAIMS ANY WARRANTIES, EXPRESS OR IMPLIED, WITH REGARD - TO THIS SOFTWARE INCLUDING BUT NOT LIMITED TO THE WARRANTIES - OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. - -****************************************************************************/ - -#include -__FBSDID("$FreeBSD$"); - -/**************************************************************************** - * Header: remcom.c,v 1.34 91/03/09 12:29:49 glenne Exp $ - * - * Module name: remcom.c $ - * Revision: 1.34 $ - * Date: 91/03/09 12:29:49 $ - * Contributor: Lake Stevens Instrument Division$ - * - * Description: low level support for gdb debugger. $ - * - * Considerations: only works on target hardware $ - * - * Written by: Glenn Engel $ - * ModuleState: Experimental $ - * - * NOTES: See Below $ - * - * Modified for FreeBSD by Stu Grossman. - * - * To enable debugger support, two things need to happen. One, a - * call to set_debug_traps() is necessary in order to allow any breakpoints - * or error conditions to be properly intercepted and reported to gdb. - * Two, a breakpoint needs to be generated to begin communication. This - * is most easily accomplished by a call to breakpoint(). Breakpoint() - * simulates a breakpoint by executing a trap #1. - * - * The external function exceptionHandler() is - * used to attach a specific handler to a specific 386 vector number. - * It should use the same privilege level it runs at. It should - * install it as an interrupt gate so that interrupts are masked - * while the handler runs. - * Also, need to assign exceptionHook and oldExceptionHook. - * - * Because gdb will sometimes write to the stack area to execute function - * calls, this program cannot rely on using the supervisor stack so it - * uses its own stack area reserved in the int array remcomStack. - * - ************* - * - * The following gdb commands are supported: - * - * command function Return value - * - * g return the value of the CPU registers hex data or ENN - * G set the value of the CPU registers OK or ENN - * - * mAA..AA,LLLL Read LLLL bytes at address AA..AA hex data or ENN - * MAA..AA,LLLL: Write LLLL bytes at address AA.AA OK or ENN - * - * c Resume at current address SNN ( signal NN) - * cAA..AA Continue at address AA..AA SNN - * - * s Step one instruction SNN - * sAA..AA Step one instruction from AA..AA SNN - * - * k kill - * - * ? What was the last sigval ? SNN (signal NN) - * - * D detach OK - * - * All commands and responses are sent with a packet which includes a - * checksum. A packet consists of - * - * $#. - * - * where - * :: - * :: < two hex digits computed as modulo 256 sum of > - * - * When a packet is received, it is first acknowledged with either '+' or '-'. - * '+' indicates a successful transfer. '-' indicates a failed transfer. - * - * Example: - * - * Host: Reply: - * $m0,10#2a +$00010203040506070809101112131415#42 - * - ****************************************************************************/ - -#include -#include -#include -#include - -#include - -#include - -#include "opt_ddb.h" - -int gdb_handle_exception (db_regs_t *, int, int); - -/************************************************************************/ - -extern jmp_buf db_jmpbuf; - -/************************************************************************/ -/* BUFMAX defines the maximum number of characters in inbound/outbound buffers*/ -/* at least NUMREGBYTES*2 are needed for register packets */ -#define BUFMAX 400 - -/* Create private copies of common functions used by the stub. This prevents - nasty interactions between app code and the stub (for instance if user steps - into strlen, etc..) */ - -static int -gdb_strlen (const char *s) -{ - const char *s1 = s; - - while (*s1++ != '\000'); - - return s1 - s; -} - -static char * -gdb_strcpy (char *dst, const char *src) -{ - char *retval = dst; - - while ((*dst++ = *src++) != '\000'); - - return retval; -} - -static int -putDebugChar (int c) /* write a single character */ -{ - if (gdb_arg == NULL) - return 0; - (*gdb_putc)(gdb_arg, c); - return 1; -} - -static int -getDebugChar (void) /* read and return a single char */ -{ - if (gdb_arg == NULL) - return -1; - return (*gdb_getc)(gdb_arg); -} - -static const char hexchars[]="0123456789abcdef"; - -static int -hex(char ch) -{ - if ((ch >= 'a') && (ch <= 'f')) return (ch-'a'+10); - if ((ch >= '0') && (ch <= '9')) return (ch-'0'); - if ((ch >= 'A') && (ch <= 'F')) return (ch-'A'+10); - return (-1); -} - -/* scan for the sequence $# */ -static void -getpacket (char *buffer) -{ - unsigned char checksum; - unsigned char xmitcsum; - int i; - int count; - unsigned char ch; - - do - { - /* wait around for the start character, ignore all other characters */ - - while ((ch = (getDebugChar () & 0x7f)) != '$'); - - checksum = 0; - xmitcsum = -1; - - count = 0; - - /* now, read until a # or end of buffer is found */ - - while (count < BUFMAX) - { - ch = getDebugChar () & 0x7f; - if (ch == '#') - break; - checksum = checksum + ch; - buffer[count] = ch; - count = count + 1; - } - buffer[count] = 0; - - if (ch == '#') - { - xmitcsum = hex (getDebugChar () & 0x7f) << 4; - xmitcsum += hex (getDebugChar () & 0x7f); - - if (checksum != xmitcsum) - putDebugChar ('-'); /* failed checksum */ - else - { - putDebugChar ('+'); /* successful transfer */ - /* if a sequence char is present, reply the sequence ID */ - if (buffer[2] == ':') - { - putDebugChar (buffer[0]); - putDebugChar (buffer[1]); - - /* remove sequence chars from buffer */ - - count = gdb_strlen (buffer); - for (i=3; i <= count; i++) - buffer[i-3] = buffer[i]; - } - } - } - } - while (checksum != xmitcsum); -} - -/* send the packet in buffer. */ - -static void -putpacket (char *buffer) -{ - unsigned char checksum; - int count; - unsigned char ch; - - /* $#. */ - do - { -/* - * This is a non-standard hack to allow use of the serial console for - * operation as well as debugging. Simply turn on 'remotechat' in gdb. - * - * This extension is not part of the Cygnus protocol, is kinda gross, - * but gets the job done. - */ -#ifdef GDB_REMOTE_CHAT - putDebugChar ('|'); - putDebugChar ('|'); - putDebugChar ('|'); - putDebugChar ('|'); -#endif - putDebugChar ('$'); - checksum = 0; - count = 0; - - while ((ch=buffer[count]) != 0) - { - putDebugChar (ch); - checksum += ch; - count += 1; - } - - putDebugChar ('#'); - putDebugChar (hexchars[checksum >> 4]); - putDebugChar (hexchars[checksum & 0xf]); - } - while ((getDebugChar () & 0x7f) != '+'); -} - -static char remcomInBuffer[BUFMAX]; -static char remcomOutBuffer[BUFMAX]; - -static int -get_char (vm_offset_t addr) -{ - char data; - - if (setjmp (db_jmpbuf)) - return -1; - - db_read_bytes (addr, 1, &data); - - return data & 0xff; -} - -static int -set_char (vm_offset_t addr, int val) -{ - char data; - - if (setjmp (db_jmpbuf)) - return -1; - - data = val; - - db_write_bytes (addr, 1, &data); - return 0; -} - -/* convert the memory pointed to by mem into hex, placing result in buf */ -/* return a pointer to the last char put in buf (null) */ - -static char * -mem2hex (vm_offset_t mem, char *buf, int count) -{ - int i; - int ch; - - for (i=0;i> 4]; - *buf++ = hexchars[ch % 16]; - } - *buf = 0; - return(buf); -} - -/* convert the hex array pointed to by buf into binary to be placed in mem */ -/* return a pointer to the character AFTER the last byte written */ -static char * -hex2mem (char *buf, vm_offset_t mem, int count) -{ - int i; - int ch; - int rv; - - for (i=0;i=0) - { - *intValue = (*intValue <<4) | hexValue; - numChars ++; - } - else - break; - - (*ptr)++; - } - - return (numChars); -} - -#define NUMREGBYTES (sizeof registers) -#define PC 8 -#define SP 4 -#define FP 5 -#define NUM_REGS 14 - -/* - * This function does all command procesing for interfacing to gdb. - */ -int -gdb_handle_exception (db_regs_t *raw_regs, int type, int code) -{ - int sigval; - int addr, length; - char * ptr; - struct i386regs { - unsigned int rax; - unsigned int rcx; - unsigned int rdx; - unsigned int rbx; - unsigned int rsp; - unsigned int rbp; - unsigned int rsi; - unsigned int rdi; - unsigned int rip; - unsigned int rflags; - unsigned int cs; - unsigned int ss; - unsigned int ds; - unsigned int es; - }; - struct i386regs registers; - - registers.rax = raw_regs->tf_rax; - registers.rbx = raw_regs->tf_rbx; - registers.rcx = raw_regs->tf_rcx; - registers.rdx = raw_regs->tf_rdx; - - registers.rsp = raw_regs->tf_rsp; - registers.rbp = raw_regs->tf_rbp; - registers.rsi = raw_regs->tf_rsi; - registers.rdi = raw_regs->tf_rdi; - - registers.rip = raw_regs->tf_rip; - registers.rflags = raw_regs->tf_rflags; - - registers.cs = raw_regs->tf_cs; - registers.ss = raw_regs->tf_ss; - registers.ds = 0; /* XXX rds() */ - registers.es = 0; /* XXX res() */ - - /* reply to host that an exception has occurred */ - sigval = computeSignal (type); - ptr = remcomOutBuffer; - - *ptr++ = 'T'; - *ptr++ = hexchars[sigval >> 4]; - *ptr++ = hexchars[sigval & 0xf]; - - *ptr++ = hexchars[PC >> 4]; - *ptr++ = hexchars[PC & 0xf]; - *ptr++ = ':'; - ptr = mem2hex ((vm_offset_t)®isters.rip, ptr, 4); - *ptr++ = ';'; - - *ptr++ = hexchars[FP >> 4]; - *ptr++ = hexchars[FP & 0xf]; - *ptr++ = ':'; - ptr = mem2hex ((vm_offset_t)®isters.rbp, ptr, 4); - *ptr++ = ';'; - - *ptr++ = hexchars[SP >> 4]; - *ptr++ = hexchars[SP & 0xf]; - *ptr++ = ':'; - ptr = mem2hex ((vm_offset_t)®isters.rsp, ptr, 4); - *ptr++ = ';'; - - *ptr++ = 0; - - putpacket (remcomOutBuffer); - - while (1) - { - if (gdb_arg == NULL) - return 1; /* somebody has removed the gdb device */ - remcomOutBuffer[0] = 0; - - getpacket (remcomInBuffer); - switch (remcomInBuffer[0]) - { - case '?': - remcomOutBuffer[0] = 'S'; - remcomOutBuffer[1] = hexchars[sigval >> 4]; - remcomOutBuffer[2] = hexchars[sigval % 16]; - remcomOutBuffer[3] = 0; - break; - - case 'D': /* detach; say OK and turn off gdb */ - putpacket(remcomOutBuffer); - boothowto &= ~RB_GDB; - return 0; - - case 'g': /* return the value of the CPU registers */ - mem2hex ((vm_offset_t)®isters, remcomOutBuffer, NUMREGBYTES); - break; - - case 'G': /* set the value of the CPU registers - return OK */ - hex2mem (&remcomInBuffer[1], (vm_offset_t)®isters, NUMREGBYTES); - gdb_strcpy (remcomOutBuffer, "OK"); - break; - - case 'P': /* Set the value of one register */ - { - int regno; - - ptr = &remcomInBuffer[1]; - - if (hexToInt (&ptr, ®no) - && *ptr++ == '=' - && regno < NUM_REGS) - { - hex2mem (ptr, (vm_offset_t)®isters + regno * 4, 4); - gdb_strcpy(remcomOutBuffer,"OK"); - } - else - gdb_strcpy (remcomOutBuffer, "P01"); - break; - } - case 'm': /* mAA..AA,LLLL Read LLLL bytes at address AA..AA */ - /* Try to read %x,%x. */ - - ptr = &remcomInBuffer[1]; - - if (hexToInt (&ptr, &addr) - && *(ptr++) == ',' - && hexToInt (&ptr, &length)) - { - if (mem2hex((vm_offset_t) addr, remcomOutBuffer, length) == NULL) - gdb_strcpy (remcomOutBuffer, "E03"); - break; - } - else - gdb_strcpy (remcomOutBuffer, "E01"); - break; - - case 'M': /* MAA..AA,LLLL: Write LLLL bytes at address AA.AA return OK */ - - /* Try to read '%x,%x:'. */ - - ptr = &remcomInBuffer[1]; - - if (hexToInt(&ptr,&addr) - && *(ptr++) == ',' - && hexToInt(&ptr, &length) - && *(ptr++) == ':') - { - if (hex2mem(ptr, (vm_offset_t) addr, length) == NULL) - gdb_strcpy (remcomOutBuffer, "E03"); - else - gdb_strcpy (remcomOutBuffer, "OK"); - } - else - gdb_strcpy (remcomOutBuffer, "E02"); - break; - - /* cAA..AA Continue at address AA..AA(optional) */ - /* sAA..AA Step one instruction from AA..AA(optional) */ - case 'c' : - case 's' : - /* try to read optional parameter, pc unchanged if no parm */ - - ptr = &remcomInBuffer[1]; - if (hexToInt(&ptr,&addr)) - registers.rip = addr; - - - /* set the trace bit if we're stepping */ - if (remcomInBuffer[0] == 's') - registers.rflags |= PSL_T; - else - registers.rflags &= ~PSL_T; - - raw_regs->tf_rax = registers.rax; - raw_regs->tf_rbx = registers.rbx; - raw_regs->tf_rcx = registers.rcx; - raw_regs->tf_rdx = registers.rdx; - - raw_regs->tf_rsp = registers.rsp; - raw_regs->tf_rbp = registers.rbp; - raw_regs->tf_rsi = registers.rsi; - raw_regs->tf_rdi = registers.rdi; - - raw_regs->tf_rip = registers.rip; - raw_regs->tf_rflags = registers.rflags; - - raw_regs->tf_cs = registers.cs; - raw_regs->tf_ss = registers.ss; -#if 0 - raw_regs->tf_ds = registers.ds; - raw_regs->tf_es = registers.es; -#endif - return 0; - - } /* switch */ - - /* reply to the request */ - putpacket (remcomOutBuffer); - } - return 0; -} diff --git a/sys/i386/i386/i386-gdbstub.c b/sys/i386/i386/i386-gdbstub.c deleted file mode 100644 index 330a46a54f92..000000000000 --- a/sys/i386/i386/i386-gdbstub.c +++ /dev/null @@ -1,612 +0,0 @@ -/**************************************************************************** - - THIS SOFTWARE IS NOT COPYRIGHTED - - HP offers the following for use in the public domain. HP makes no - warranty with regard to the software or its performance and the - user accepts the software "AS IS" with all faults. - - HP DISCLAIMS ANY WARRANTIES, EXPRESS OR IMPLIED, WITH REGARD - TO THIS SOFTWARE INCLUDING BUT NOT LIMITED TO THE WARRANTIES - OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. - -****************************************************************************/ - -#include -__FBSDID("$FreeBSD$"); - -/**************************************************************************** - * Header: remcom.c,v 1.34 91/03/09 12:29:49 glenne Exp $ - * - * Module name: remcom.c $ - * Revision: 1.34 $ - * Date: 91/03/09 12:29:49 $ - * Contributor: Lake Stevens Instrument Division$ - * - * Description: low level support for gdb debugger. $ - * - * Considerations: only works on target hardware $ - * - * Written by: Glenn Engel $ - * ModuleState: Experimental $ - * - * NOTES: See Below $ - * - * Modified for FreeBSD by Stu Grossman. - * - * To enable debugger support, two things need to happen. One, a - * call to set_debug_traps() is necessary in order to allow any breakpoints - * or error conditions to be properly intercepted and reported to gdb. - * Two, a breakpoint needs to be generated to begin communication. This - * is most easily accomplished by a call to breakpoint(). Breakpoint() - * simulates a breakpoint by executing a trap #1. - * - * The external function exceptionHandler() is - * used to attach a specific handler to a specific 386 vector number. - * It should use the same privilege level it runs at. It should - * install it as an interrupt gate so that interrupts are masked - * while the handler runs. - * Also, need to assign exceptionHook and oldExceptionHook. - * - * Because gdb will sometimes write to the stack area to execute function - * calls, this program cannot rely on using the supervisor stack so it - * uses its own stack area reserved in the int array remcomStack. - * - ************* - * - * The following gdb commands are supported: - * - * command function Return value - * - * g return the value of the CPU registers hex data or ENN - * G set the value of the CPU registers OK or ENN - * - * mAA..AA,LLLL Read LLLL bytes at address AA..AA hex data or ENN - * MAA..AA,LLLL: Write LLLL bytes at address AA.AA OK or ENN - * - * c Resume at current address SNN ( signal NN) - * cAA..AA Continue at address AA..AA SNN - * - * s Step one instruction SNN - * sAA..AA Step one instruction from AA..AA SNN - * - * k kill - * - * ? What was the last sigval ? SNN (signal NN) - * - * D detach OK - * - * All commands and responses are sent with a packet which includes a - * checksum. A packet consists of - * - * $#. - * - * where - * :: - * :: < two hex digits computed as modulo 256 sum of > - * - * When a packet is received, it is first acknowledged with either '+' or '-'. - * '+' indicates a successful transfer. '-' indicates a failed transfer. - * - * Example: - * - * Host: Reply: - * $m0,10#2a +$00010203040506070809101112131415#42 - * - ****************************************************************************/ - -#include -#include -#include -#include - -#include - -#include - -#include "opt_ddb.h" - -int gdb_handle_exception (db_regs_t *, int, int); - -/************************************************************************/ - -extern jmp_buf db_jmpbuf; - -/************************************************************************/ -/* BUFMAX defines the maximum number of characters in inbound/outbound buffers*/ -/* at least NUMREGBYTES*2 are needed for register packets */ -#define BUFMAX 400 - -/* Create private copies of common functions used by the stub. This prevents - nasty interactions between app code and the stub (for instance if user steps - into strlen, etc..) */ - -static int -gdb_strlen (const char *s) -{ - const char *s1 = s; - - while (*s1++ != '\000'); - - return s1 - s; -} - -static char * -gdb_strcpy (char *dst, const char *src) -{ - char *retval = dst; - - while ((*dst++ = *src++) != '\000'); - - return retval; -} - -static int -putDebugChar (int c) /* write a single character */ -{ - if (gdb_arg == NULL) - return 0; - (*gdb_putc)(gdb_arg, c); - return 1; -} - -static int -getDebugChar (void) /* read and return a single char */ -{ - if (gdb_arg == NULL) - return -1; - return (*gdb_getc)(gdb_arg); -} - -static const char hexchars[]="0123456789abcdef"; - -static int -hex(char ch) -{ - if ((ch >= 'a') && (ch <= 'f')) return (ch-'a'+10); - if ((ch >= '0') && (ch <= '9')) return (ch-'0'); - if ((ch >= 'A') && (ch <= 'F')) return (ch-'A'+10); - return (-1); -} - -/* scan for the sequence $# */ -static void -getpacket (char *buffer) -{ - unsigned char checksum; - unsigned char xmitcsum; - int i; - int count; - unsigned char ch; - - do - { - /* wait around for the start character, ignore all other characters */ - - while ((ch = (getDebugChar () & 0x7f)) != '$'); - - checksum = 0; - xmitcsum = -1; - - count = 0; - - /* now, read until a # or end of buffer is found */ - - while (count < BUFMAX) - { - ch = getDebugChar () & 0x7f; - if (ch == '#') - break; - checksum = checksum + ch; - buffer[count] = ch; - count = count + 1; - } - buffer[count] = 0; - - if (ch == '#') - { - xmitcsum = hex (getDebugChar () & 0x7f) << 4; - xmitcsum += hex (getDebugChar () & 0x7f); - - if (checksum != xmitcsum) - putDebugChar ('-'); /* failed checksum */ - else - { - putDebugChar ('+'); /* successful transfer */ - /* if a sequence char is present, reply the sequence ID */ - if (buffer[2] == ':') - { - putDebugChar (buffer[0]); - putDebugChar (buffer[1]); - - /* remove sequence chars from buffer */ - - count = gdb_strlen (buffer); - for (i=3; i <= count; i++) - buffer[i-3] = buffer[i]; - } - } - } - } - while (checksum != xmitcsum); -} - -/* send the packet in buffer. */ - -static void -putpacket (char *buffer) -{ - unsigned char checksum; - int count; - unsigned char ch; - - /* $#. */ - do - { -/* - * This is a non-standard hack to allow use of the serial console for - * operation as well as debugging. Simply turn on 'remotechat' in gdb. - * - * This extension is not part of the Cygnus protocol, is kinda gross, - * but gets the job done. - */ -#ifdef GDB_REMOTE_CHAT - putDebugChar ('|'); - putDebugChar ('|'); - putDebugChar ('|'); - putDebugChar ('|'); -#endif - putDebugChar ('$'); - checksum = 0; - count = 0; - - while ((ch=buffer[count]) != 0) - { - putDebugChar (ch); - checksum += ch; - count += 1; - } - - putDebugChar ('#'); - putDebugChar (hexchars[checksum >> 4]); - putDebugChar (hexchars[checksum & 0xf]); - } - while ((getDebugChar () & 0x7f) != '+'); -} - -static char remcomInBuffer[BUFMAX]; -static char remcomOutBuffer[BUFMAX]; - -static int -get_char (vm_offset_t addr) -{ - char data; - - if (setjmp (db_jmpbuf)) - return -1; - - db_read_bytes (addr, 1, &data); - - return data & 0xff; -} - -static int -set_char (vm_offset_t addr, int val) -{ - char data; - - if (setjmp (db_jmpbuf)) - return -1; - - data = val; - - db_write_bytes (addr, 1, &data); - return 0; -} - -/* convert the memory pointed to by mem into hex, placing result in buf */ -/* return a pointer to the last char put in buf (null) */ - -static char * -mem2hex (vm_offset_t mem, char *buf, int count) -{ - int i; - int ch; - - for (i=0;i> 4]; - *buf++ = hexchars[ch % 16]; - } - *buf = 0; - return(buf); -} - -/* convert the hex array pointed to by buf into binary to be placed in mem */ -/* return a pointer to the character AFTER the last byte written */ -static char * -hex2mem (char *buf, vm_offset_t mem, int count) -{ - int i; - int ch; - int rv; - - for (i=0;i=0) - { - *intValue = (*intValue <<4) | hexValue; - numChars ++; - } - else - break; - - (*ptr)++; - } - - return (numChars); -} - -#define NUMREGBYTES (sizeof registers) -#define PC 8 -#define SP 4 -#define FP 5 -#define NUM_REGS 14 - -/* - * This function does all command procesing for interfacing to gdb. - */ -int -gdb_handle_exception (db_regs_t *raw_regs, int type, int code) -{ - int sigval; - int addr, length; - char * ptr; - struct i386regs { - unsigned int eax; - unsigned int ecx; - unsigned int edx; - unsigned int ebx; - unsigned int esp; - unsigned int ebp; - unsigned int esi; - unsigned int edi; - unsigned int eip; - unsigned int eflags; - unsigned int cs; - unsigned int ss; - unsigned int ds; - unsigned int es; - }; - struct i386regs registers; - - registers.eax = raw_regs->tf_eax; - registers.ebx = raw_regs->tf_ebx; - registers.ecx = raw_regs->tf_ecx; - registers.edx = raw_regs->tf_edx; - - registers.esp = raw_regs->tf_esp; - registers.ebp = raw_regs->tf_ebp; - registers.esi = raw_regs->tf_esi; - registers.edi = raw_regs->tf_edi; - - registers.eip = raw_regs->tf_eip; - registers.eflags = raw_regs->tf_eflags; - - registers.cs = raw_regs->tf_cs; - registers.ss = raw_regs->tf_ss; - registers.ds = raw_regs->tf_ds; - registers.es = raw_regs->tf_es; - - /* reply to host that an exception has occurred */ - sigval = computeSignal (type); - ptr = remcomOutBuffer; - - *ptr++ = 'T'; - *ptr++ = hexchars[sigval >> 4]; - *ptr++ = hexchars[sigval & 0xf]; - - *ptr++ = hexchars[PC >> 4]; - *ptr++ = hexchars[PC & 0xf]; - *ptr++ = ':'; - ptr = mem2hex ((vm_offset_t)®isters.eip, ptr, 4); - *ptr++ = ';'; - - *ptr++ = hexchars[FP >> 4]; - *ptr++ = hexchars[FP & 0xf]; - *ptr++ = ':'; - ptr = mem2hex ((vm_offset_t)®isters.ebp, ptr, 4); - *ptr++ = ';'; - - *ptr++ = hexchars[SP >> 4]; - *ptr++ = hexchars[SP & 0xf]; - *ptr++ = ':'; - ptr = mem2hex ((vm_offset_t)®isters.esp, ptr, 4); - *ptr++ = ';'; - - *ptr++ = 0; - - putpacket (remcomOutBuffer); - - while (1) - { - if (gdb_arg == NULL) - return 1; /* somebody has removed the gdb device */ - remcomOutBuffer[0] = 0; - - getpacket (remcomInBuffer); - switch (remcomInBuffer[0]) - { - case '?': - remcomOutBuffer[0] = 'S'; - remcomOutBuffer[1] = hexchars[sigval >> 4]; - remcomOutBuffer[2] = hexchars[sigval % 16]; - remcomOutBuffer[3] = 0; - break; - - case 'D': /* detach; say OK and turn off gdb */ - putpacket(remcomOutBuffer); - boothowto &= ~RB_GDB; - return 0; - - case 'g': /* return the value of the CPU registers */ - mem2hex ((vm_offset_t)®isters, remcomOutBuffer, NUMREGBYTES); - break; - - case 'G': /* set the value of the CPU registers - return OK */ - hex2mem (&remcomInBuffer[1], (vm_offset_t)®isters, NUMREGBYTES); - gdb_strcpy (remcomOutBuffer, "OK"); - break; - - case 'P': /* Set the value of one register */ - { - int regno; - - ptr = &remcomInBuffer[1]; - - if (hexToInt (&ptr, ®no) - && *ptr++ == '=' - && regno < NUM_REGS) - { - hex2mem (ptr, (vm_offset_t)®isters + regno * 4, 4); - gdb_strcpy(remcomOutBuffer,"OK"); - } - else - gdb_strcpy (remcomOutBuffer, "P01"); - break; - } - case 'm': /* mAA..AA,LLLL Read LLLL bytes at address AA..AA */ - /* Try to read %x,%x. */ - - ptr = &remcomInBuffer[1]; - - if (hexToInt (&ptr, &addr) - && *(ptr++) == ',' - && hexToInt (&ptr, &length)) - { - if (mem2hex((vm_offset_t) addr, remcomOutBuffer, length) == NULL) - gdb_strcpy (remcomOutBuffer, "E03"); - break; - } - else - gdb_strcpy (remcomOutBuffer, "E01"); - break; - - case 'M': /* MAA..AA,LLLL: Write LLLL bytes at address AA.AA return OK */ - - /* Try to read '%x,%x:'. */ - - ptr = &remcomInBuffer[1]; - - if (hexToInt(&ptr,&addr) - && *(ptr++) == ',' - && hexToInt(&ptr, &length) - && *(ptr++) == ':') - { - if (hex2mem(ptr, (vm_offset_t) addr, length) == NULL) - gdb_strcpy (remcomOutBuffer, "E03"); - else - gdb_strcpy (remcomOutBuffer, "OK"); - } - else - gdb_strcpy (remcomOutBuffer, "E02"); - break; - - /* cAA..AA Continue at address AA..AA(optional) */ - /* sAA..AA Step one instruction from AA..AA(optional) */ - case 'c' : - case 's' : - /* try to read optional parameter, pc unchanged if no parm */ - - ptr = &remcomInBuffer[1]; - if (hexToInt(&ptr,&addr)) - registers.eip = addr; - - - /* set the trace bit if we're stepping */ - if (remcomInBuffer[0] == 's') - registers.eflags |= PSL_T; - else - registers.eflags &= ~PSL_T; - - raw_regs->tf_eax = registers.eax; - raw_regs->tf_ebx = registers.ebx; - raw_regs->tf_ecx = registers.ecx; - raw_regs->tf_edx = registers.edx; - - raw_regs->tf_esp = registers.esp; - raw_regs->tf_ebp = registers.ebp; - raw_regs->tf_esi = registers.esi; - raw_regs->tf_edi = registers.edi; - - raw_regs->tf_eip = registers.eip; - raw_regs->tf_eflags = registers.eflags; - - raw_regs->tf_cs = registers.cs; - raw_regs->tf_ss = registers.ss; - raw_regs->tf_ds = registers.ds; - raw_regs->tf_es = registers.es; - return 0; - - } /* switch */ - - /* reply to the request */ - putpacket (remcomOutBuffer); - } - return 0; -} diff --git a/sys/ia64/ia64/ia64-gdbstub.c b/sys/ia64/ia64/ia64-gdbstub.c deleted file mode 100644 index 139d02396958..000000000000 --- a/sys/ia64/ia64/ia64-gdbstub.c +++ /dev/null @@ -1,580 +0,0 @@ -/* $FreeBSD$ */ -/**************************************************************************** - - THIS SOFTWARE IS NOT COPYRIGHTED - - HP offers the following for use in the public domain. HP makes no - warranty with regard to the software or its performance and the - user accepts the software "AS IS" with all faults. - - HP DISCLAIMS ANY WARRANTIES, EXPRESS OR IMPLIED, WITH REGARD - TO THIS SOFTWARE INCLUDING BUT NOT LIMITED TO THE WARRANTIES - OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. - -****************************************************************************/ - -/**************************************************************************** - * Header: remcom.c,v 1.34 91/03/09 12:29:49 glenne Exp $ - * - * Module name: remcom.c $ - * Revision: 1.34 $ - * Date: 91/03/09 12:29:49 $ - * Contributor: Lake Stevens Instrument Division$ - * - * Description: low level support for gdb debugger. $ - * - * Considerations: only works on target hardware $ - * - * Written by: Glenn Engel $ - * ModuleState: Experimental $ - * - * NOTES: See Below $ - * - * Modified for FreeBSD by Stu Grossman. - * - * To enable debugger support, two things need to happen. One, a - * call to set_debug_traps() is necessary in order to allow any breakpoints - * or error conditions to be properly intercepted and reported to gdb. - * Two, a breakpoint needs to be generated to begin communication. This - * is most easily accomplished by a call to breakpoint(). Breakpoint() - * simulates a breakpoint by executing a trap #1. - * - * The external function exceptionHandler() is - * used to attach a specific handler to a specific 386 vector number. - * It should use the same privilege level it runs at. It should - * install it as an interrupt gate so that interrupts are masked - * while the handler runs. - * Also, need to assign exceptionHook and oldExceptionHook. - * - * Because gdb will sometimes write to the stack area to execute function - * calls, this program cannot rely on using the supervisor stack so it - * uses its own stack area reserved in the int array remcomStack. - * - ************* - * - * The following gdb commands are supported: - * - * command function Return value - * - * g return the value of the CPU registers hex data or ENN - * G set the value of the CPU registers OK or ENN - * - * mAA..AA,LLLL Read LLLL bytes at address AA..AA hex data or ENN - * MAA..AA,LLLL: Write LLLL bytes at address AA.AA OK or ENN - * - * c Resume at current address SNN ( signal NN) - * cAA..AA Continue at address AA..AA SNN - * - * s Step one instruction SNN - * sAA..AA Step one instruction from AA..AA SNN - * - * k kill - * - * ? What was the last sigval ? SNN (signal NN) - * - * D detach OK - * - * All commands and responses are sent with a packet which includes a - * checksum. A packet consists of - * - * $#. - * - * where - * :: - * :: < two hex digits computed as modulo 256 sum of > - * - * When a packet is received, it is first acknowledged with either '+' or '-'. - * '+' indicates a successful transfer. '-' indicates a failed transfer. - * - * Example: - * - * Host: Reply: - * $m0,10#2a +$00010203040506070809101112131415#42 - * - ****************************************************************************/ - -#include -#include -#include -#include -#include - -#include - -#include - -#include - -#include "opt_ddb.h" - -/************************************************************************/ - -void gdb_handle_exception (db_regs_t *, int); - -#if 0 -extern jmp_buf db_jmpbuf; - -/************************************************************************/ -/* BUFMAX defines the maximum number of characters in inbound/outbound buffers*/ -/* at least NUMREGBYTES*2 are needed for register packets */ -#define BUFMAX 1500 - -/* Create private copies of common functions used by the stub. This prevents - nasty interactions between app code and the stub (for instance if user steps - into strlen, etc..) */ - -#define strlen gdb_strlen -#define strcpy gdb_strcpy - -static int -strlen (const char *s) -{ - const char *s1 = s; - - while (*s1++ != '\000'); - - return s1 - s; -} - -static char * -strcpy (char *dst, const char *src) -{ - char *retval = dst; - - while ((*dst++ = *src++) != '\000'); - - return retval; -} - -/* XXX sio always uses its major with minor 0 no matter what we specify. */ -#define REMOTE_DEV 0 - -static int -putDebugChar (int c) /* write a single character */ -{ - return 1; -} - -static int -getDebugChar (void) /* read and return a single char */ -{ - return 0; -} - -static const char hexchars[]="0123456789abcdef"; - -static int -hex(char ch) -{ - if ((ch >= 'a') && (ch <= 'f')) return (ch-'a'+10); - if ((ch >= '0') && (ch <= '9')) return (ch-'0'); - if ((ch >= 'A') && (ch <= 'F')) return (ch-'A'+10); - return (-1); -} - -/* scan for the sequence $# */ -static void -getpacket (char *buffer) -{ - unsigned char checksum; - unsigned char xmitcsum; - int i; - int count; - unsigned char ch; - - do - { - /* wait around for the start character, ignore all other characters */ - - while ((ch = (getDebugChar () & 0x7f)) != '$'); - - checksum = 0; - xmitcsum = -1; - - count = 0; - - /* now, read until a # or end of buffer is found */ - - while (count < BUFMAX) - { - ch = getDebugChar () & 0x7f; - if (ch == '#') - break; - checksum = checksum + ch; - buffer[count] = ch; - count = count + 1; - } - buffer[count] = 0; - - if (ch == '#') - { - xmitcsum = hex (getDebugChar () & 0x7f) << 4; - xmitcsum += hex (getDebugChar () & 0x7f); - - if (checksum != xmitcsum) - putDebugChar ('-'); /* failed checksum */ - else - { - putDebugChar ('+'); /* successful transfer */ - /* if a sequence char is present, reply the sequence ID */ - if (buffer[2] == ':') - { - putDebugChar (buffer[0]); - putDebugChar (buffer[1]); - - /* remove sequence chars from buffer */ - - count = strlen (buffer); - for (i=3; i <= count; i++) - buffer[i-3] = buffer[i]; - } - } - } - } - while (checksum != xmitcsum); - - if (strlen(buffer) >= BUFMAX) - panic("kgdb: buffer overflow"); -} - -/* send the packet in buffer. */ - -static void -putpacket (char *buffer) -{ - unsigned char checksum; - int count; - unsigned char ch; - - if (strlen(buffer) >= BUFMAX) - panic("kgdb: buffer overflow"); - - /* $#. */ - do - { -/* - * This is a non-standard hack to allow use of the serial console for - * operation as well as debugging. Simply turn on 'remotechat' in gdb. - * - * This extension is not part of the Cygnus protocol, is kinda gross, - * but gets the job done. - */ -#ifdef GDB_REMOTE_CHAT - putDebugChar ('|'); - putDebugChar ('|'); - putDebugChar ('|'); - putDebugChar ('|'); -#endif - putDebugChar ('$'); - checksum = 0; - count = 0; - - while ((ch=buffer[count]) != 0) - { - putDebugChar (ch); - checksum += ch; - count += 1; - } - - putDebugChar ('#'); - putDebugChar (hexchars[checksum >> 4]); - putDebugChar (hexchars[checksum & 0xf]); - } - while ((getDebugChar () & 0x7f) != '+'); -} - -static char remcomInBuffer[BUFMAX]; -static char remcomOutBuffer[BUFMAX]; - -static int -get_char (vm_offset_t addr) -{ - char data; - - if (setjmp (db_jmpbuf)) - return -1; - - db_read_bytes (addr, 1, &data); - - return data & 0xff; -} - -static int -set_char (vm_offset_t addr, int val) -{ - char data; - - if (setjmp (db_jmpbuf)) - return -1; - - data = val; - - db_write_bytes (addr, 1, &data); - return 0; -} - -/* convert the memory pointed to by mem into hex, placing result in buf */ -/* return a pointer to the last char put in buf (null) */ - -static char * -mem2hex (vm_offset_t mem, char *buf, int count) -{ - int i; - int ch; - - for (i=0;i> 4]; - *buf++ = hexchars[ch % 16]; - } - *buf = 0; - return(buf); -} - -/* convert the hex array pointed to by buf into binary to be placed in mem */ -/* return a pointer to the character AFTER the last byte written */ -static char * -hex2mem (char *buf, vm_offset_t mem, int count) -{ - int i; - int ch; - int rv; - - for (i=0;i=0) - { - *intValue = (*intValue <<4) | hexValue; - numChars ++; - } - else - break; - - (*ptr)++; - } - - return (numChars); -} - -#define NUMREGBYTES (sizeof registers) -#define PC 64 -#define SP 30 -#define FP 15 -#define VFP 65 -#define NUM_REGS 66 - -#endif - -/* - * This function does all command procesing for interfacing to gdb. - */ -void -gdb_handle_exception (db_regs_t *raw_regs, int vector) -{ -#if 0 - int sigval; - long addr, length; - char * ptr; - struct alpharegs { - u_int64_t r[32]; - u_int64_t f[32]; - u_int64_t pc, vfp; - }; - static struct alpharegs registers; - int i; - - clear_single_step(raw_regs); - - bzero(®isters, sizeof registers); - - /* - * Map trapframe to registers. - * Ignore float regs for now. - */ - for (i = 0; i < FRAME_SIZE; i++) - if (tf2gdb[i] >= 0) - registers.r[tf2gdb[i]] = raw_regs->tf_regs[i]; - registers.pc = raw_regs->tf_regs[FRAME_PC]; - - /* reply to host that an exception has occurred */ - sigval = computeSignal (type, code); - ptr = remcomOutBuffer; - - *ptr++ = 'T'; - *ptr++ = hexchars[sigval >> 4]; - *ptr++ = hexchars[sigval & 0xf]; - - *ptr++ = hexchars[PC >> 4]; - *ptr++ = hexchars[PC & 0xf]; - *ptr++ = ':'; - ptr = mem2hex ((vm_offset_t)®isters.pc, ptr, 8); - *ptr++ = ';'; - - *ptr++ = hexchars[FP >> 4]; - *ptr++ = hexchars[FP & 0xf]; - *ptr++ = ':'; - ptr = mem2hex ((vm_offset_t)®isters.r[FP], ptr, 8); - *ptr++ = ';'; - - *ptr++ = hexchars[SP >> 4]; - *ptr++ = hexchars[SP & 0xf]; - *ptr++ = ':'; - ptr = mem2hex ((vm_offset_t)®isters.r[SP], ptr, 8); - *ptr++ = ';'; - - *ptr++ = 0; - - putpacket (remcomOutBuffer); - - while (1) - { - remcomOutBuffer[0] = 0; - - getpacket (remcomInBuffer); - switch (remcomInBuffer[0]) - { - case '?': - remcomOutBuffer[0] = 'S'; - remcomOutBuffer[1] = hexchars[sigval >> 4]; - remcomOutBuffer[2] = hexchars[sigval % 16]; - remcomOutBuffer[3] = 0; - break; - - case 'D': /* detach; say OK and turn off gdb */ - putpacket(remcomOutBuffer); - boothowto &= ~RB_GDB; - return; - - case 'k': - prom_halt(); - /*NOTREACHED*/ - break; - - case 'g': /* return the value of the CPU registers */ - mem2hex ((vm_offset_t)®isters, remcomOutBuffer, NUMREGBYTES); - break; - - case 'G': /* set the value of the CPU registers - return OK */ - hex2mem (&remcomInBuffer[1], (vm_offset_t)®isters, NUMREGBYTES); - strcpy (remcomOutBuffer, "OK"); - break; - - case 'P': /* Set the value of one register */ - { - long regno; - - ptr = &remcomInBuffer[1]; - - if (hexToInt (&ptr, ®no) - && *ptr++ == '=' - && regno < NUM_REGS) - { - hex2mem (ptr, (vm_offset_t)®isters + regno * 8, 8); - strcpy(remcomOutBuffer,"OK"); - } - else - strcpy (remcomOutBuffer, "P01"); - break; - } - case 'm': /* mAA..AA,LLLL Read LLLL bytes at address AA..AA */ - /* Try to read %x,%x. */ - - ptr = &remcomInBuffer[1]; - - if (hexToInt (&ptr, &addr) - && *(ptr++) == ',' - && hexToInt (&ptr, &length)) - { - if (mem2hex((vm_offset_t) addr, remcomOutBuffer, length) == NULL) - strcpy (remcomOutBuffer, "E03"); - break; - } - else - strcpy (remcomOutBuffer, "E01"); - break; - - case 'M': /* MAA..AA,LLLL: Write LLLL bytes at address AA.AA return OK */ - - /* Try to read '%x,%x:'. */ - - ptr = &remcomInBuffer[1]; - - if (hexToInt(&ptr,&addr) - && *(ptr++) == ',' - && hexToInt(&ptr, &length) - && *(ptr++) == ':') - { - if (hex2mem(ptr, (vm_offset_t) addr, length) == NULL) - strcpy (remcomOutBuffer, "E03"); - else - strcpy (remcomOutBuffer, "OK"); - } - else - strcpy (remcomOutBuffer, "E02"); - break; - - /* cAA..AA Continue at address AA..AA(optional) */ - /* sAA..AA Step one instruction from AA..AA(optional) */ - case 'c' : - case 's' : - /* try to read optional parameter, pc unchanged if no parm */ - - ptr = &remcomInBuffer[1]; - if (hexToInt(&ptr,&addr)) - registers.pc = addr; - - /* - * Map gdb registers back to trapframe (ignoring fp regs). - */ - for (i = 0; i < NUM_REGS; i++) - if (gdb2tf[i] >= 0) - raw_regs->tf_regs[gdb2tf[i]] = registers.r[i]; - raw_regs->tf_regs[FRAME_PC] = registers.pc; - - if (remcomInBuffer[0] == 's') - if (!set_single_step(raw_regs)) - printf("Can't set single step breakpoint\n"); - - return; - - } /* switch */ - - /* reply to the request */ - putpacket (remcomOutBuffer); - } -#endif -}