X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=gdb%2Fi386-stub.c;h=6b91296291f2d4bafe46f2168bc904c704a12d3c;hb=aff410f1800950c650dc4fbaf32aff513e12cf54;hp=768f00c3c8e22414e42845171ee926d6f43e05ec;hpb=30727aa6d12fb866494020c0b62ab265a2bdcdfe;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/i386-stub.c b/gdb/i386-stub.c index 768f00c3c8..6b91296291 100644 --- a/gdb/i386-stub.c +++ b/gdb/i386-stub.c @@ -43,7 +43,6 @@ * 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 @@ -97,14 +96,10 @@ * * external low-level support routines */ -typedef void (*ExceptionHook)(int); /* pointer to function with int parm */ -typedef void (*Function)(); /* pointer to a function */ extern void putDebugChar(); /* write a single character */ extern int getDebugChar(); /* read and return a single char */ - -extern Function exceptionHandler(); /* assign an exception handler */ -extern ExceptionHook exceptionHook; /* hook variable for errors/exceptions */ +extern void exceptionHandler(); /* assign an exception handler */ /************************************************************************/ /* BUFMAX defines the maximum number of characters in inbound/outbound buffers*/ @@ -116,8 +111,6 @@ static char initialized; /* boolean flag. != 0 means we've been initialized */ int remote_debug; /* debug > 0 prints ill-formed commands in valid packets & checksum errors */ -void waitabit(); - static const char hexchars[]="0123456789abcdef"; /* Number of registers. */ @@ -140,14 +133,6 @@ int registers[NUMREGS]; int remcomStack[STACKSIZE/sizeof(int)]; static int* stackPtr = &remcomStack[STACKSIZE/sizeof(int) - 1]; -/* - * In many cases, the system will want to continue exception processing - * when a continue command is given. - * oldExceptionHook is a function to invoke in this case. - */ - -static ExceptionHook oldExceptionHook; - /*************************** ASSEMBLY CODE MACROS *************************/ /* */ @@ -444,125 +429,149 @@ asm(" movl _stackPtr, %esp"); /* move to remcom stack area */ asm(" pushl %eax"); /* push exception onto stack */ asm(" call _handle_exception"); /* this never returns */ -void _returnFromException() +void +_returnFromException () { return_to_prog (); } -int hex(ch) -char ch; +int +hex (ch) + 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); + 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); } +static char remcomInBuffer[BUFMAX]; +static char remcomOutBuffer[BUFMAX]; /* scan for the sequence $# */ -void getpacket(buffer) -char * buffer; + +unsigned char * +getpacket (void) { + unsigned char *buffer = &remcomInBuffer[0]; unsigned char checksum; unsigned char xmitcsum; - int i; - int count; + int count; 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 ((remote_debug ) && (checksum != xmitcsum)) { - fprintf (stderr ,"bad checksum. My count = 0x%x, sent=0x%x. buf=%s\n", - checksum,xmitcsum,buffer); - } - - 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 (1) + { + /* wait around for the start character, ignore all other characters */ + while ((ch = getDebugChar ()) != '$') + ; + + retry: + checksum = 0; + xmitcsum = -1; + count = 0; + + /* now, read until a # or end of buffer is found */ + while (count < BUFMAX - 1) + { + ch = getDebugChar (); + if (ch == '$') + goto retry; + if (ch == '#') + break; + checksum = checksum + ch; + buffer[count] = ch; + count = count + 1; + } + buffer[count] = 0; + + if (ch == '#') + { + ch = getDebugChar (); + xmitcsum = hex (ch) << 4; + ch = getDebugChar (); + xmitcsum += hex (ch); + + if (checksum != xmitcsum) + { + if (remote_debug) + { + fprintf (stderr, + "bad checksum. My count = 0x%x, sent=0x%x. buf=%s\n", + checksum, xmitcsum, buffer); + } + 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]); + + return &buffer[3]; + } + + return &buffer[0]; + } + } } - } while (checksum != xmitcsum); - } /* send the packet in buffer. */ - -void putpacket(buffer) -char * buffer; +void +putpacket (unsigned char *buffer) { unsigned char checksum; - int count; + int count; char ch; /* $#. */ - do { - putDebugChar('$'); - checksum = 0; - count = 0; - - while (ch=buffer[count]) { - putDebugChar(ch); - checksum += ch; - count += 1; - } + do + { + putDebugChar ('$'); + checksum = 0; + count = 0; - putDebugChar('#'); - putDebugChar(hexchars[checksum >> 4]); - putDebugChar(hexchars[checksum % 16]); + while (ch = buffer[count]) + { + putDebugChar (ch); + checksum += ch; + count += 1; + } - } while ((getDebugChar() & 0x7f) != '+'); + putDebugChar ('#'); + putDebugChar (hexchars[checksum >> 4]); + putDebugChar (hexchars[checksum % 16]); + } + while (getDebugChar () != '+'); } -char remcomInBuffer[BUFMAX]; -char remcomOutBuffer[BUFMAX]; -static short error; - - -void debug_error(format, parm) -char * format; -char * parm; +void +debug_error (format, parm) + char *format; + char *parm; { - if (remote_debug) fprintf (stderr,format,parm); + if (remote_debug) + fprintf (stderr, format, parm); } /* Address of a routine to RTE to if we get a memory fault. */ -static void (*volatile mem_fault_routine)() = NULL; +static void (*volatile mem_fault_routine) () = NULL; /* Indicate to caller of mem2hex or hex2mem that there has been an error. */ static volatile int mem_err = 0; void -set_mem_err () +set_mem_err (void) { mem_err = 1; } @@ -572,16 +581,13 @@ set_mem_err () to mem_fault, they won't get restored, so there better not be any saved). */ int -get_char (addr) - char *addr; +get_char (char *addr) { return *addr; } void -set_char (addr, val) - char *addr; - int val; +set_char (char *addr, int val) { *addr = val; } @@ -590,80 +596,115 @@ set_char (addr, val) /* return a pointer to the last char put in buf (null) */ /* If MAY_FAULT is non-zero, then we should set mem_err in response to a fault; if zero treat a fault like any other fault in the stub. */ -char* mem2hex(mem, buf, count, may_fault) -char* mem; -char* buf; -int count; -int may_fault; +char * +mem2hex (mem, buf, count, may_fault) + char *mem; + char *buf; + int count; + int may_fault; { - int i; - unsigned char ch; - - if (may_fault) - mem_fault_routine = set_mem_err; - for (i=0;i> 4]; - *buf++ = hexchars[ch % 16]; - } - *buf = 0; - if (may_fault) - mem_fault_routine = NULL; - return(buf); + int i; + unsigned char ch; + + if (may_fault) + mem_fault_routine = set_mem_err; + for (i = 0; i < count; i++) + { + ch = get_char (mem++); + if (may_fault && mem_err) + return (buf); + *buf++ = hexchars[ch >> 4]; + *buf++ = hexchars[ch % 16]; + } + *buf = 0; + if (may_fault) + mem_fault_routine = NULL; + 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 */ -char* hex2mem(buf, mem, count, may_fault) -char* buf; -char* mem; -int count; -int may_fault; +char * +hex2mem (buf, mem, count, may_fault) + char *buf; + char *mem; + int count; + int may_fault; { - int i; - unsigned char ch; - - if (may_fault) - mem_fault_routine = set_mem_err; - for (i=0;i=0) - { - *intValue = (*intValue <<4) | hexValue; - numChars ++; - } - else - break; - - (*ptr)++; + hexValue = hex (**ptr); + if (hexValue >= 0) + { + *intValue = (*intValue << 4) | hexValue; + numChars++; + } + else + break; + + (*ptr)++; } - return (numChars); + return (numChars); } /* * This function does all command procesing for interfacing to gdb. */ -void handle_exception(int exceptionVector) +void +handle_exception (int exceptionVector) { - int sigval; - int addr, length; - char * ptr; - int newPC; + int sigval, stepping; + int addr, length; + char *ptr; + int newPC; gdb_i386vector = exceptionVector; - if (remote_debug) printf("vector=%d, sr=0x%x, pc=0x%x\n", - exceptionVector, - registers[ PS ], - registers[ PC ]); + if (remote_debug) + { + printf ("vector=%d, sr=0x%x, pc=0x%x\n", + exceptionVector, registers[PS], registers[PC]); + } /* reply to host that an exception has occurred */ - sigval = computeSignal( exceptionVector ); - remcomOutBuffer[0] = 'S'; - remcomOutBuffer[1] = hexchars[sigval >> 4]; - remcomOutBuffer[2] = hexchars[sigval % 16]; - remcomOutBuffer[3] = 0; - - putpacket(remcomOutBuffer); - - while (1==1) { - error = 0; - 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' : remote_debug = !(remote_debug); /* toggle debug flag */ - break; - case 'g' : /* return the value of the CPU registers */ - mem2hex((char*) registers, remcomOutBuffer, NUMREGBYTES, 0); - break; - case 'G' : /* set the value of the CPU registers - return OK */ - hex2mem(&remcomInBuffer[1], (char*) registers, NUMREGBYTES, 0); - strcpy(remcomOutBuffer,"OK"); - break; - case 'P' : /* set the value of a single CPU register - return OK */ - { - int regno; - - ptr = &remcomInBuffer[1]; - if (hexToInt (&ptr, ®no) && *ptr++ == '=') - if (regno >= 0 && regno < NUMREGS) - { - hex2mem (ptr, (char *)®isters[regno], 4, 0); - strcpy(remcomOutBuffer,"OK"); - break; - } - - strcpy (remcomOutBuffer, "E01"); - break; - } - - /* mAA..AA,LLLL Read LLLL bytes at address AA..AA */ - case 'm' : - /* TRY TO READ %x,%x. IF SUCCEED, SET PTR = 0 */ - ptr = &remcomInBuffer[1]; - if (hexToInt(&ptr,&addr)) - if (*(ptr++) == ',') - if (hexToInt(&ptr,&length)) - { - ptr = 0; - mem_err = 0; - mem2hex((char*) addr, remcomOutBuffer, length, 1); - if (mem_err) { - strcpy (remcomOutBuffer, "E03"); - debug_error ("memory fault"); - } - } - - if (ptr) - { - strcpy(remcomOutBuffer,"E01"); - debug_error("malformed read memory command: %s",remcomInBuffer); - } - break; - - /* MAA..AA,LLLL: Write LLLL bytes at address AA.AA return OK */ - case 'M' : - /* TRY TO READ '%x,%x:'. IF SUCCEED, SET PTR = 0 */ - ptr = &remcomInBuffer[1]; - if (hexToInt(&ptr,&addr)) - if (*(ptr++) == ',') - if (hexToInt(&ptr,&length)) - if (*(ptr++) == ':') - { - mem_err = 0; - hex2mem(ptr, (char*) addr, length, 1); - - if (mem_err) { - strcpy (remcomOutBuffer, "E03"); - debug_error ("memory fault"); - } else { - strcpy(remcomOutBuffer,"OK"); - } - - ptr = 0; - } - if (ptr) - { - strcpy(remcomOutBuffer,"E02"); - debug_error("malformed write memory command: %s",remcomInBuffer); + sigval = computeSignal (exceptionVector); + + ptr = remcomOutBuffer; + + *ptr++ = 'T'; /* notify gdb with signo, PC, FP and SP */ + *ptr++ = hexchars[sigval >> 4]; + *ptr++ = hexchars[sigval & 0xf]; + + *ptr++ = hexchars[ESP]; + *ptr++ = ':'; + ptr = mem2hex((char *)®isters[ESP], ptr, 4, 0); /* SP */ + *ptr++ = ';'; + + *ptr++ = hexchars[EBP]; + *ptr++ = ':'; + ptr = mem2hex((char *)®isters[EBP], ptr, 4, 0); /* FP */ + *ptr++ = ';'; + + *ptr++ = hexchars[PC]; + *ptr++ = ':'; + ptr = mem2hex((char *)®isters[PC], ptr, 4, 0); /* PC */ + *ptr++ = ';'; + + *ptr = '\0' + + putpacket (remcomOutBuffer); + + stepping = 0; + + while (1 == 1) + { + remcomOutBuffer[0] = 0; + ptr = getpacket (); + + switch (*ptr++) + { + case '?': + remcomOutBuffer[0] = 'S'; + remcomOutBuffer[1] = hexchars[sigval >> 4]; + remcomOutBuffer[2] = hexchars[sigval % 16]; + remcomOutBuffer[3] = 0; + break; + case 'd': + remote_debug = !(remote_debug); /* toggle debug flag */ + break; + case 'g': /* return the value of the CPU registers */ + mem2hex ((char *) registers, remcomOutBuffer, NUMREGBYTES, 0); + break; + case 'G': /* set the value of the CPU registers - return OK */ + hex2mem (ptr, (char *) registers, NUMREGBYTES, 0); + strcpy (remcomOutBuffer, "OK"); + break; + case 'P': /* set the value of a single CPU register - return OK */ + { + int regno; + + if (hexToInt (&ptr, ®no) && *ptr++ == '=') + if (regno >= 0 && regno < NUMREGS) + { + hex2mem (ptr, (char *) ®isters[regno], 4, 0); + strcpy (remcomOutBuffer, "OK"); + break; + } + + strcpy (remcomOutBuffer, "E01"); + break; + } + + /* mAA..AA,LLLL Read LLLL bytes at address AA..AA */ + case 'm': + /* TRY TO READ %x,%x. IF SUCCEED, SET PTR = 0 */ + if (hexToInt (&ptr, &addr)) + if (*(ptr++) == ',') + if (hexToInt (&ptr, &length)) + { + ptr = 0; + mem_err = 0; + mem2hex ((char *) addr, remcomOutBuffer, length, 1); + if (mem_err) + { + strcpy (remcomOutBuffer, "E03"); + debug_error ("memory fault"); } - 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; - - newPC = registers[ PC]; - - /* clear the trace bit */ - registers[ PS ] &= 0xfffffeff; - - /* set the trace bit if we're stepping */ - if (remcomInBuffer[0] == 's') registers[ PS ] |= 0x100; - - /* - * If we found a match for the PC AND we are not returning - * as a result of a breakpoint (33), - * trace exception (9), nmi (31), jmp to - * the old exception handler as if this code never ran. - */ + } + + if (ptr) + { + strcpy (remcomOutBuffer, "E01"); + } + break; + + /* MAA..AA,LLLL: Write LLLL bytes at address AA.AA return OK */ + case 'M': + /* TRY TO READ '%x,%x:'. IF SUCCEED, SET PTR = 0 */ + if (hexToInt (&ptr, &addr)) + if (*(ptr++) == ',') + if (hexToInt (&ptr, &length)) + if (*(ptr++) == ':') + { + mem_err = 0; + hex2mem (ptr, (char *) addr, length, 1); + + if (mem_err) + { + strcpy (remcomOutBuffer, "E03"); + debug_error ("memory fault"); + } + else + { + strcpy (remcomOutBuffer, "OK"); + } + + ptr = 0; + } + if (ptr) + { + strcpy (remcomOutBuffer, "E02"); + } + break; + + /* cAA..AA Continue at address AA..AA(optional) */ + /* sAA..AA Step one instruction from AA..AA(optional) */ + case 's': + stepping = 1; + case 'c': + /* try to read optional parameter, pc unchanged if no parm */ + if (hexToInt (&ptr, &addr)) + registers[PC] = addr; + + newPC = registers[PC]; + + /* clear the trace bit */ + registers[PS] &= 0xfffffeff; + + /* set the trace bit if we're stepping */ + if (stepping) + registers[PS] |= 0x100; + + _returnFromException (); /* this is a jump */ + break; + + /* kill the program */ + case 'k': /* do nothing */ #if 0 - /* Don't really think we need this, except maybe for protection - exceptions. */ - /* - * invoke the previous handler. - */ - if (oldExceptionHook) - (*oldExceptionHook) (frame->exceptionVector); - newPC = registers[ PC ]; /* pc may have changed */ -#endif /* 0 */ - - _returnFromException(); /* this is a jump */ - - break; - - /* kill the program */ - case 'k' : /* do nothing */ -#if 0 - /* Huh? This doesn't look like "nothing". - m68k-stub.c and sparc-stub.c don't have it. */ - BREAKPOINT(); + /* Huh? This doesn't look like "nothing". + m68k-stub.c and sparc-stub.c don't have it. */ + BREAKPOINT (); #endif - break; - } /* switch */ + break; + } /* switch */ - /* reply to the request */ - putpacket(remcomOutBuffer); + /* reply to the request */ + putpacket (remcomOutBuffer); } } /* this function is used to set up exception handlers for tracing and breakpoints */ -void set_debug_traps() +void +set_debug_traps (void) { -extern void remcomHandler(); -int exception; - - stackPtr = &remcomStack[STACKSIZE/sizeof(int) - 1]; + stackPtr = &remcomStack[STACKSIZE / sizeof (int) - 1]; exceptionHandler (0, _catchException0); exceptionHandler (1, _catchException1); @@ -887,18 +936,7 @@ int exception; exceptionHandler (14, _catchException14); exceptionHandler (16, _catchException16); - if (exceptionHook != remcomHandler) - { - oldExceptionHook = exceptionHook; - exceptionHook = remcomHandler; - } - - /* In case GDB is started before us, ack any packets (presumably - "$?#xx") sitting there. */ - putDebugChar ('+'); - initialized = 1; - } /* This function will generate a breakpoint exception. It is used at the @@ -906,22 +944,9 @@ int exception; otherwise as a quick means to stop program execution and "break" into the debugger. */ -void breakpoint() -{ - if (initialized) -#if 0 - handle_exception(3); -#else - BREAKPOINT(); -#endif - waitabit(); -} - -int waitlimit = 1000000; - void -waitabit() +breakpoint (void) { - int i; - for (i = 0; i < waitlimit; i++) ; + if (initialized) + BREAKPOINT (); }