summaryrefslogtreecommitdiffstats
path: root/c/src/lib/libbsp/i386/shared/comm/i386-stub.c
diff options
context:
space:
mode:
Diffstat (limited to 'c/src/lib/libbsp/i386/shared/comm/i386-stub.c')
-rw-r--r--c/src/lib/libbsp/i386/shared/comm/i386-stub.c68
1 files changed, 60 insertions, 8 deletions
diff --git a/c/src/lib/libbsp/i386/shared/comm/i386-stub.c b/c/src/lib/libbsp/i386/shared/comm/i386-stub.c
index d4fd60ad9b..8764d7b27a 100644
--- a/c/src/lib/libbsp/i386/shared/comm/i386-stub.c
+++ b/c/src/lib/libbsp/i386/shared/comm/i386-stub.c
@@ -124,8 +124,15 @@ void waitabit ();
static const char hexchars[] = "0123456789abcdef";
+/* Number of registers. */
+#define NUMREGS 16
+
+/* Number of bytes per register. */
+#define REGBYTES 4
+
/* Number of bytes of registers. */
-#define NUMREGBYTES 64
+#define NUMREGBYTES (NUMREGS * REGBYTES)
+
enum regnames
{
EAX, ECX, EDX, EBX, ESP, EBP, ESI, EDI,
@@ -137,7 +144,7 @@ enum regnames
/*
* these should not be static cuz they can be used outside this module
*/
-int registers[NUMREGBYTES / 4];
+int registers[NUMREGS];
#define STACKSIZE 10000
int remcomStack[STACKSIZE / sizeof (int)];
@@ -741,7 +748,7 @@ void
handle_exception (int exceptionVector)
{
int sigval;
- int addr, length;
+ int addr, length, reg;
char *ptr;
int newPC;
@@ -753,12 +760,33 @@ handle_exception (int exceptionVector)
registers[PS],
registers[PC]);
- /* reply to host that an exception has occurred */
+ /* Reply to host that an exception has occurred. Always return the
+ PC, SP, and FP, since gdb always wants them. */
+ ptr = remcomOutBuffer;
+ *ptr++ = 'T';
sigval = computeSignal (exceptionVector);
- remcomOutBuffer[0] = 'S';
- remcomOutBuffer[1] = hexchars[sigval >> 4];
- remcomOutBuffer[2] = hexchars[sigval % 16];
- remcomOutBuffer[3] = 0;
+ *ptr++ = hexchars[sigval >> 4];
+ *ptr++ = hexchars[sigval % 16];
+
+ *ptr++ = hexchars[ESP];
+ *ptr++ = ':';
+ mem2hex ((char *) &registers[ESP], ptr, REGBYTES, 0);
+ ptr += REGBYTES * 2;
+ *ptr++ = ';';
+
+ *ptr++ = hexchars[EBP];
+ *ptr++ = ':';
+ mem2hex ((char *) &registers[EBP], ptr, REGBYTES, 0);
+ ptr += REGBYTES * 2;
+ *ptr++ = ';';
+
+ *ptr++ = hexchars[PC];
+ *ptr++ = ':';
+ mem2hex ((char *) &registers[PC], ptr, REGBYTES, 0);
+ ptr += REGBYTES * 2;
+ *ptr++ = ';';
+
+ *ptr = '\0';
putpacket (remcomOutBuffer);
@@ -786,6 +814,22 @@ handle_exception (int exceptionVector)
strcpy (remcomOutBuffer, "OK");
break;
+ case 'P': /* Set specific register */
+ ptr = &remcomInBuffer[1];
+ if (hexToInt (&ptr, &reg)
+ && *ptr++ == '=')
+ {
+ hex2mem (ptr, (char *) &registers[reg], REGBYTES, 0);
+ strcpy (remcomOutBuffer, "OK");
+ }
+ else
+ {
+ strcpy (remcomOutBuffer, "E01");
+ debug_error ("malformed register set command; %s",
+ remcomInBuffer);
+ }
+ break;
+
/* mAA..AA,LLLL Read LLLL bytes at address AA..AA */
case 'm':
/* TRY TO READ %x,%x. IF SUCCEED, SET PTR = 0 */
@@ -864,6 +908,14 @@ handle_exception (int exceptionVector)
break;
+ /* Detach. */
+ case 'D':
+ putpacket (remcomOutBuffer);
+ registers[PS] &= 0xfffffeff;
+ _returnFromException (); /* this is a jump */
+
+ break;
+
/* kill the program */
case 'k': /* do nothing */
break;