#include <internal/module.h>
#include <internal/ldr.h>
-#define NDEBUG
+#undef NDEBUG
#include <internal/debug.h>
extern LIST_ENTRY PiThreadListHead;
{
DWORD Size;
DWORD OffsetInTF;
+ DWORD OffsetInContext;
+ BOOLEAN SetInContext;
} CPU_REGISTER, *PCPU_REGISTER;
#define KTRAP_FRAME_X86 KTRAP_FRAME
static CPU_REGISTER GspRegisters[NUMREGS] =
{
- { 4, FIELD_OFFSET (KTRAP_FRAME_X86, Eax) },
- { 4, FIELD_OFFSET (KTRAP_FRAME_X86, Ecx) },
- { 4, FIELD_OFFSET (KTRAP_FRAME_X86, Edx) },
- { 4, FIELD_OFFSET (KTRAP_FRAME_X86, Ebx) },
- { 4, FIELD_OFFSET (KTRAP_FRAME_X86, Esp) },
- { 4, FIELD_OFFSET (KTRAP_FRAME_X86, Ebp) },
- { 4, FIELD_OFFSET (KTRAP_FRAME_X86, Esi) },
- { 4, FIELD_OFFSET (KTRAP_FRAME_X86, Edi) },
- { 4, FIELD_OFFSET (KTRAP_FRAME_X86, Eip) },
- { 4, FIELD_OFFSET (KTRAP_FRAME_X86, Eflags) },
- { 4, FIELD_OFFSET (KTRAP_FRAME_X86, Cs) },
- { 4, FIELD_OFFSET (KTRAP_FRAME_X86, Ss) },
- { 4, FIELD_OFFSET (KTRAP_FRAME_X86, Ds) },
- { 4, FIELD_OFFSET (KTRAP_FRAME_X86, Es) },
- { 4, FIELD_OFFSET (KTRAP_FRAME_X86, Fs) },
- { 4, FIELD_OFFSET (KTRAP_FRAME_X86, Gs) }
+ { 4, FIELD_OFFSET (KTRAP_FRAME_X86, Eax), FIELD_OFFSET (CONTEXT, Eax), TRUE },
+ { 4, FIELD_OFFSET (KTRAP_FRAME_X86, Ecx), FIELD_OFFSET (CONTEXT, Ecx), TRUE },
+ { 4, FIELD_OFFSET (KTRAP_FRAME_X86, Edx), FIELD_OFFSET (CONTEXT, Edx), FALSE },
+ { 4, FIELD_OFFSET (KTRAP_FRAME_X86, Ebx), FIELD_OFFSET (CONTEXT, Ebx), TRUE },
+ { 4, FIELD_OFFSET (KTRAP_FRAME_X86, Esp), FIELD_OFFSET (CONTEXT, Esp), TRUE },
+ { 4, FIELD_OFFSET (KTRAP_FRAME_X86, Ebp), FIELD_OFFSET (CONTEXT, Ebp), TRUE },
+ { 4, FIELD_OFFSET (KTRAP_FRAME_X86, Esi), FIELD_OFFSET (CONTEXT, Esi), TRUE },
+ { 4, FIELD_OFFSET (KTRAP_FRAME_X86, Edi), FIELD_OFFSET (CONTEXT, Edi), TRUE },
+ { 4, FIELD_OFFSET (KTRAP_FRAME_X86, Eip), FIELD_OFFSET (CONTEXT, Eip), TRUE },
+ { 4, FIELD_OFFSET (KTRAP_FRAME_X86, Eflags), FIELD_OFFSET (CONTEXT, EFlags), TRUE },
+ { 4, FIELD_OFFSET (KTRAP_FRAME_X86, Cs), FIELD_OFFSET (CONTEXT, SegCs), TRUE },
+ { 4, FIELD_OFFSET (KTRAP_FRAME_X86, Ss), FIELD_OFFSET (CONTEXT, SegSs), TRUE },
+ { 4, FIELD_OFFSET (KTRAP_FRAME_X86, Ds), FIELD_OFFSET (CONTEXT, SegDs), TRUE },
+ { 4, FIELD_OFFSET (KTRAP_FRAME_X86, Es), FIELD_OFFSET (CONTEXT, SegEs), TRUE },
+ { 4, FIELD_OFFSET (KTRAP_FRAME_X86, Fs), FIELD_OFFSET (CONTEXT, SegFs), TRUE },
+ { 4, FIELD_OFFSET (KTRAP_FRAME_X86, Gs), FIELD_OFFSET (CONTEXT, SegGs), TRUE }
};
static PCHAR GspThreadStates[THREAD_STATE_MAX] =
KdPutChar (HexChars[Checksum & 0xf]);
}
-
-VOID
-GspDebugError(LPSTR Message)
-{
- DbgPrint ("%s\n", Message);
-}
-
-/* Address of a routine to RTE to if we get a memory fault. */
-static VOID (*volatile MemoryFaultRoutine) () = NULL;
-
/* Indicate to caller of GspMem2Hex or GspHex2Mem that there has been an
error. */
static volatile BOOLEAN GspMemoryError = FALSE;
-
-
-/* Currently not used */
-VOID
-GspSetMemoryError()
-{
- GspMemoryError = TRUE;
-}
-
-
-/* These are separate functions so that they are so short and sweet
- that the compiler won't save any Registers (if there is a fault
- to MemoryFaultRoutine, they won't get restored, so there better
- not be any saved). */
-CHAR
-GspGetChar (PCHAR Address)
-{
- return *Address;
-}
-
-
-VOID
-GspSetChar (PCHAR Address,
- CHAR Value)
-{
- *Address = Value;
-}
+static void *GspAccessLocation = NULL;
/* Convert the memory pointed to by Address into hex, placing result in Buffer */
ULONG i;
CHAR ch;
- if (MayFault)
- MemoryFaultRoutine = GspSetMemoryError;
for (i = 0; i < (ULONG) Count; i++)
{
- ch = GspGetChar (Address++);
+ if (MayFault)
+ GspAccessLocation = Address;
+ ch = *Address;
+ GspAccessLocation = NULL;
if (MayFault && GspMemoryError)
return (Buffer);
*Buffer++ = HexChars[(ch >> 4) & 0xf];
*Buffer++ = HexChars[ch & 0xf];
+ Address++;
}
*Buffer = 0;
- if (MayFault)
- MemoryFaultRoutine = NULL;
return (Buffer);
}
ULONG Count,
BOOLEAN MayFault)
{
+ PCHAR current;
+ PCHAR page;
+ ULONG countinpage;
ULONG i;
CHAR ch;
+ ULONG oldprot;
- if (MayFault)
- MemoryFaultRoutine = GspSetMemoryError;
- for (i = 0; i < Count; i++)
+ current = Address;
+ while ( current < Address + Count )
{
- ch = HexValue (*Buffer++) << 4;
- ch = ch + HexValue (*Buffer++);
- GspSetChar (Address++, ch);
- if (MayFault && GspMemoryError)
- return (Buffer);
+ page = (PCHAR)PAGE_ROUND_DOWN (current);
+ if (Address + Count <= page + PAGE_SIZE)
+ {
+ /* Fits in this page */
+ countinpage = Count;
+ }
+ else
+ {
+ /* Flows into next page, handle only current page in this iteration */
+ countinpage = PAGE_SIZE - (Address - page);
+ }
+ if (MayFault)
+ {
+ oldprot = MmGetPageProtect (NULL, Address);
+ MmSetPageProtect (NULL, Address, PAGE_EXECUTE_READWRITE);
+ }
+
+ for (i = 0; i < countinpage && ! GspMemoryError; i++)
+ {
+ ch = HexValue (*Buffer++) << 4;
+ ch = ch + HexValue (*Buffer++);
+
+ GspAccessLocation = Address;
+ *current = ch;
+ GspAccessLocation = NULL;
+ current++;
+ }
+ if (MayFault)
+ {
+ MmSetPageProtect (NULL, page, oldprot);
+ if (GspMemoryError)
+ return (Buffer);
+ }
}
- if (MayFault)
- MemoryFaultRoutine = NULL;
+
return (Buffer);
}
{
LONG Save;
- Save = (((Value >> 0) & 0xf) << 24) |
- (((Value >> 8) & 0xf) << 16) |
- (((Value >> 16) & 0xf) << 8) |
- (((Value >> 24) & 0xf) << 0);
+ Save = (((Value >> 0) & 0xff) << 24) |
+ (((Value >> 8) & 0xff) << 16) |
+ (((Value >> 16) & 0xff) << 8) |
+ (((Value >> 24) & 0xff) << 0);
*Address = GspMem2Hex ((PCHAR) &Save, *Address, 4, FALSE);
}
+/*
+ * Esp is not stored in the trap frame, although there is a member with it's name.
+ * Instead, it was pointing to the location of the TrapFrame Esp member when the
+ * exception occured.
+ */
+static LONG
+GspGetEspFromTrapFrame(PKTRAP_FRAME TrapFrame)
+{
+ return (LONG) &TrapFrame->Esp;
+}
+
+
VOID
GspGetRegistersFromTrapFrame(PCHAR Address,
+ PCONTEXT Context,
PKTRAP_FRAME TrapFrame)
{
- PCPU_REGISTER Regs;
ULONG Value;
PCHAR Buffer;
PULONG p;
DWORD i;
Buffer = Address;
- Regs = &GspRegisters[0];
- for (i = 0; i < NUMREGS; i++)
+ for (i = 0; i < sizeof (GspRegisters) / sizeof (GspRegisters[0]); i++)
{
if (TrapFrame)
{
- p = (PULONG) ((ULONG_PTR) TrapFrame + Regs[i].OffsetInTF);
- Value = *p;
+ if (ESP == i)
+ {
+ Value = GspGetEspFromTrapFrame (TrapFrame);
+ }
+ else
+ {
+ p = (PULONG) ((ULONG_PTR) TrapFrame + GspRegisters[i].OffsetInTF);
+ Value = *p;
+ }
}
else if (i == EIP_REGNO)
- {
+ {
/*
* This thread has not been sheduled yet so assume it
* is still in PsBeginThreadWithContextInternal().
*/
Value = (ULONG) PsBeginThreadWithContextInternal;
- }
+ }
else
- {
+ {
Value = 0;
}
- Buffer = GspMem2Hex ((PCHAR) &Value, Buffer, Regs[i].Size, FALSE);
+ Buffer = GspMem2Hex ((PCHAR) &Value, Buffer, GspRegisters[i].Size, FALSE);
}
}
VOID
GspSetRegistersInTrapFrame(PCHAR Address,
+ PCONTEXT Context,
PKTRAP_FRAME TrapFrame)
{
- PCPU_REGISTER Regs;
ULONG Value;
PCHAR Buffer;
PULONG p;
return;
Buffer = Address;
- Regs = &GspRegisters[0];
for (i = 0; i < NUMREGS; i++)
{
- p = (PULONG) ((ULONG_PTR) TrapFrame + Regs[i].OffsetInTF);
+ if (GspRegisters[i].SetInContext)
+ p = (PULONG) ((ULONG_PTR) Context + GspRegisters[i].OffsetInContext);
+ else
+ p = (PULONG) ((ULONG_PTR) TrapFrame + GspRegisters[i].OffsetInTF);
Value = 0;
- Buffer = GspHex2Mem (Buffer, (PCHAR) &Value, Regs[i].Size, FALSE);
+ Buffer = GspHex2Mem (Buffer, (PCHAR) &Value, GspRegisters[i].Size, FALSE);
*p = Value;
}
}
VOID
GspSetSingleRegisterInTrapFrame(PCHAR Address,
LONG Number,
+ PCONTEXT Context,
PKTRAP_FRAME TrapFrame)
{
ULONG Value;
if (!TrapFrame)
return;
- p = (PULONG) ((ULONG_PTR) TrapFrame + GspRegisters[Number].OffsetInTF);
+ if (GspRegisters[Number].SetInContext)
+ p = (PULONG) ((ULONG_PTR) Context + GspRegisters[Number].OffsetInContext);
+ else
+ p = (PULONG) ((ULONG_PTR) TrapFrame + GspRegisters[Number].OffsetInTF);
Value = 0;
GspHex2Mem (Address, (PCHAR) &Value, GspRegisters[Number].Size, FALSE);
*p = Value;
/* Get current thread id */
GspOutBuffer[0] = 'Q';
GspOutBuffer[1] = 'C';
- Value = (ULONG) GspDbgThread->Cid.UniqueThread;
+ if (NULL != GspDbgThread)
+ {
+ Value = (ULONG) GspDbgThread->Cid.UniqueThread;
+ }
+ else
+ {
+ Value = (ULONG) PsGetCurrentThread()->Cid.UniqueThread;
+ }
GspLong2Hex (&ptr, Value);
}
else if (strncmp (Command, "fThreadInfo", 11) == 0)
ETHREAD, Tcb.ThreadListEntry);
Value = (ULONG) GspEnumThread->Cid.UniqueThread;
GspLong2Hex (&ptr, Value);
+DPRINT("fThreadInfo 0x%08x\n", (ULONG) GspEnumThread->Cid.UniqueThread);
}
else if (strncmp (Command, "sThreadInfo", 11) == 0)
{
GspOutBuffer[0] = 'm';
Value = (ULONG) GspEnumThread->Cid.UniqueThread;
GspLong2Hex (&ptr, Value);
+DPRINT("sThreadInfo 0x%08x\n", (ULONG) GspEnumThread->Cid.UniqueThread);
}
else
{
- GspOutBuffer[0] = '1';
+ GspOutBuffer[0] = 'l';
+DPRINT("End of threads\n");
}
}
else if (strncmp (Command, "ThreadExtraInfo", 15) == 0)
LONG SigVal;
LONG NewPC;
PCHAR ptr;
+ LONG Esp;
/* FIXME: Stop on other CPUs too */
/* Disable hardware debugging while we are inside the stub */
__asm__("movl %0,%%db7" : /* no output */ : "r" (0));
- /* reply to host that an exception has occurred */
- SigVal = GspComputeSignal (ExceptionRecord->ExceptionCode);
-
- ptr = &GspOutBuffer[0];
-
- *ptr++ = 'T'; /* notify gdb with signo, PC, FP and SP */
- *ptr++ = HexChars[(SigVal >> 4) & 0xf];
- *ptr++ = HexChars[SigVal & 0xf];
-
- *ptr++ = HexChars[ESP];
- *ptr++ = ':';
- ptr = GspMem2Hex ((PCHAR) &TrapFrame->Esp, ptr, 4, 0); /* SP */
- *ptr++ = ';';
-
- *ptr++ = HexChars[EBP];
- *ptr++ = ':';
- ptr = GspMem2Hex ((PCHAR) &TrapFrame->Ebp, ptr, 4, 0); /* FP */
- *ptr++ = ';';
-
- *ptr++ = HexChars[PC];
- *ptr++ = ':';
- ptr = GspMem2Hex((PCHAR) &TrapFrame->Eip, ptr, 4, 0); /* PC */
- *ptr++ = ';';
-
- *ptr = '\0';
-
- GspPutPacket (&GspOutBuffer[0]);
-
- Stepping = FALSE;
-
- while (TRUE)
+ if (NULL != GspAccessLocation &&
+ (ULONG_PTR) GspAccessLocation ==
+ (ULONG_PTR) ExceptionRecord->ExceptionInformation[1])
{
- /* Zero the buffer now so we don't have to worry about the terminating zero character */
- memset (GspOutBuffer, 0, sizeof (GspInBuffer));
- ptr = GspGetPacket ();
-
- switch (*ptr++)
- {
- case '?':
- GspOutBuffer[0] = 'S';
- GspOutBuffer[1] = HexChars[SigVal >> 4];
- GspOutBuffer[2] = HexChars[SigVal % 16];
- GspOutBuffer[3] = 0;
- break;
- case 'd':
- GspRemoteDebug = !GspRemoteDebug; /* toggle debug flag */
- break;
- case 'g': /* return the value of the CPU Registers */
- if (GspDbgThread)
- GspGetRegistersFromTrapFrame (&GspOutBuffer[0], GspDbgThread->Tcb.TrapFrame);
- else
- GspGetRegistersFromTrapFrame (&GspOutBuffer[0], TrapFrame);
- break;
- case 'G': /* set the value of the CPU Registers - return OK */
- if (GspDbgThread)
- GspSetRegistersInTrapFrame (ptr, GspDbgThread->Tcb.TrapFrame);
- else
- GspSetRegistersInTrapFrame (ptr, TrapFrame);
- strcpy (GspOutBuffer, "OK");
- break;
- case 'P': /* set the value of a single CPU register - return OK */
- {
- LONG Register;
-
- if ((GspHex2Long (&ptr, &Register)) && (*ptr++ == '='))
- if ((Register >= 0) && (Register < NUMREGS))
- {
- if (GspDbgThread)
- GspSetSingleRegisterInTrapFrame (ptr, Register,
- GspDbgThread->Tcb.TrapFrame);
- else
- GspSetSingleRegisterInTrapFrame (ptr, Register, TrapFrame);
- strcpy (GspOutBuffer, "OK");
- break;
- }
-
- strcpy (GspOutBuffer, "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 (GspHex2Long (&ptr, &Address))
- if (*(ptr++) == ',')
- if (GspHex2Long (&ptr, &Length))
- {
- ptr = 0;
- GspMemoryError = FALSE;
- GspMem2Hex ((PCHAR) Address, GspOutBuffer, Length, 1);
- if (GspMemoryError)
- {
- strcpy (GspOutBuffer, "E03");
- GspDebugError ("memory fault");
- }
- }
-
- if (ptr)
- {
- strcpy (GspOutBuffer, "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 (GspHex2Long (&ptr, &Address))
- if (*(ptr++) == ',')
- if (GspHex2Long (&ptr, &Length))
- if (*(ptr++) == ':')
- {
- GspMemoryError = FALSE;
- GspHex2Mem (ptr, (PCHAR) Address, Length, TRUE);
-
- if (GspMemoryError)
- {
- strcpy (GspOutBuffer, "E03");
- GspDebugError ("memory fault");
- }
- else
- {
- strcpy (GspOutBuffer, "OK");
- }
-
- ptr = NULL;
- }
- if (ptr)
- {
- strcpy (GspOutBuffer, "E02");
- }
- break;
-
- /* cAA..AA Continue at address AA..AA(optional) */
- /* sAA..AA Step one instruction from AA..AA(optional) */
- case 's':
- Stepping = TRUE;
- case 'c':
- {
- ULONG BreakpointNumber;
- ULONG dr6;
+ GspAccessLocation = NULL;
+ GspMemoryError = TRUE;
+ TrapFrame->Eip += 2;
+ }
+ else
+ {
+ /* reply to host that an exception has occurred */
+ SigVal = GspComputeSignal (ExceptionRecord->ExceptionCode);
- /* try to read optional parameter, pc unchanged if no parm */
- if (GspHex2Long (&ptr, &Address))
- Context->Eip = Address;
+ ptr = &GspOutBuffer[0];
- NewPC = Context->Eip;
+ *ptr++ = 'T'; /* notify gdb with signo, PC, FP and SP */
+ *ptr++ = HexChars[(SigVal >> 4) & 0xf];
+ *ptr++ = HexChars[SigVal & 0xf];
- /* clear the trace bit */
- Context->EFlags &= 0xfffffeff;
+ *ptr++ = HexChars[ESP];
+ *ptr++ = ':';
- /* set the trace bit if we're Stepping */
- if (Stepping)
- Context->EFlags |= 0x100;
+ Esp = GspGetEspFromTrapFrame (TrapFrame); /* SP */
+ ptr = GspMem2Hex ((PCHAR) &Esp, ptr, 4, 0);
+ *ptr++ = ';';
- asm volatile ("movl %%db6, %0\n" : "=r" (dr6) : );
- if (!(dr6 & 0x4000))
- {
- for (BreakpointNumber = 0; BreakpointNumber < 4; ++BreakpointNumber)
- {
- if (dr6 & (1 << BreakpointNumber))
- {
- if (GspBreakpoints[BreakpointNumber].Type == 0)
- {
- /* Set restore flag */
- Context->EFlags |= 0x10000;
- break;
- }
- }
- }
- }
- GspCorrectHwBreakpoint();
- asm volatile ("movl %0, %%db6\n" : : "r" (0));
+ *ptr++ = HexChars[EBP];
+ *ptr++ = ':';
+ ptr = GspMem2Hex ((PCHAR) &TrapFrame->Ebp, ptr, 4, 0); /* FP */
+ *ptr++ = ';';
- return kdHandleException;
- break;
- }
- case 'k': /* kill the program */
- strcpy (GspOutBuffer, "OK");
- break;
- /* kill the program */
- case 'H': /* Set thread */
- GspSetThread (ptr);
- break;
- case 'q': /* Query */
- GspQuery (ptr);
- break;
- case 'T': /* Query thread status */
- GspQueryThreadStatus (ptr);
- break;
- case 'Y':
- {
- ULONG Number;
- ULONG Length;
- ULONG Type;
- ULONG Address;
-
- ptr = &GspOutBuffer[1];
- GspHex2Long (&ptr, &Number);
- ptr++;
- GspHex2Long (&ptr, &Type);
- ptr++;
- GspHex2Long (&ptr, &Length);
- ptr++;
- GspHex2Long (&ptr, &Address);
- if (GspSetHwBreakpoint (Number & 0x3, Type & 0x3 , Length & 0x3, Address) == 0)
- {
- strcpy (GspOutBuffer, "OK");
- }
- else
- {
- strcpy (GspOutBuffer, "E");
- }
- break;
- /* Remove hardware breakpoint */
- }
- case 'y':
- {
- ULONG Number;
+ *ptr++ = HexChars[PC];
+ *ptr++ = ':';
+ ptr = GspMem2Hex((PCHAR) &TrapFrame->Eip, ptr, 4, 0); /* PC */
+ *ptr++ = ';';
- ptr = &GspOutBuffer[1];
- GspHex2Long(&ptr, &Number);
- if (GspRemoveHwBreakpoint (Number & 0x3) == 0)
- {
- strcpy (GspOutBuffer, "OK");
- }
- else
- {
- strcpy (GspOutBuffer, "E");
- }
- break;
- }
- default:
- break;
- } /* switch */
+ *ptr = '\0';
- /* reply to the request */
GspPutPacket (&GspOutBuffer[0]);
+
+ Stepping = FALSE;
+
+ while (TRUE)
+ {
+ /* Zero the buffer now so we don't have to worry about the terminating zero character */
+ memset (GspOutBuffer, 0, sizeof (GspInBuffer));
+ ptr = GspGetPacket ();
+
+ switch (*ptr++)
+ {
+ case '?':
+ GspOutBuffer[0] = 'S';
+ GspOutBuffer[1] = HexChars[SigVal >> 4];
+ GspOutBuffer[2] = HexChars[SigVal % 16];
+ GspOutBuffer[3] = 0;
+ break;
+ case 'd':
+ GspRemoteDebug = !GspRemoteDebug; /* toggle debug flag */
+ break;
+ case 'g': /* return the value of the CPU Registers */
+ if (GspDbgThread)
+{
+DPRINT("GspDbgThread active\n");
+ GspGetRegistersFromTrapFrame (&GspOutBuffer[0], Context, GspDbgThread->Tcb.TrapFrame);
+/*GspGetRegistersFromTrapFrame (&GspOutBuffer[0], Context, TrapFrame);*/
+}
+ else
+{
+DPRINT("GspDbgThread not active\n");
+ GspGetRegistersFromTrapFrame (&GspOutBuffer[0], Context, TrapFrame);
+}
+ break;
+ case 'G': /* set the value of the CPU Registers - return OK */
+ if (GspDbgThread)
+/* GspSetRegistersInTrapFrame (ptr, Context, GspDbgThread->Tcb.TrapFrame);*/
+GspSetRegistersInTrapFrame (ptr, Context, TrapFrame);
+ else
+ GspSetRegistersInTrapFrame (ptr, Context, TrapFrame);
+ strcpy (GspOutBuffer, "OK");
+ break;
+ case 'P': /* set the value of a single CPU register - return OK */
+ {
+ LONG Register;
+
+ if ((GspHex2Long (&ptr, &Register)) && (*ptr++ == '='))
+ if ((Register >= 0) && (Register < NUMREGS))
+ {
+ if (GspDbgThread)
+/* GspSetSingleRegisterInTrapFrame (ptr, Register,
+ Context, GspDbgThread->Tcb.TrapFrame);*/
+GspSetSingleRegisterInTrapFrame (ptr, Register, Context, TrapFrame);
+ else
+ GspSetSingleRegisterInTrapFrame (ptr, Register, Context, TrapFrame);
+ strcpy (GspOutBuffer, "OK");
+ break;
+ }
+
+ strcpy (GspOutBuffer, "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 (GspHex2Long (&ptr, &Address))
+ if (*(ptr++) == ',')
+ if (GspHex2Long (&ptr, &Length))
+ {
+ ptr = 0;
+ GspMemoryError = FALSE;
+ GspMem2Hex ((PCHAR) Address, GspOutBuffer, Length, 1);
+ if (GspMemoryError)
+ {
+ strcpy (GspOutBuffer, "E03");
+ DPRINT ("Fault during memory read\n");
+ }
+ }
+
+ if (ptr)
+ strcpy (GspOutBuffer, "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 (GspHex2Long (&ptr, &Address))
+ if (*(ptr++) == ',')
+ if (GspHex2Long (&ptr, &Length))
+ if (*(ptr++) == ':')
+ {
+ GspMemoryError = FALSE;
+ GspHex2Mem (ptr, (PCHAR) Address, Length, TRUE);
+
+ if (GspMemoryError)
+ {
+ strcpy (GspOutBuffer, "E03");
+ DPRINT ("Fault during memory write\n");
+ }
+ else
+ {
+ strcpy (GspOutBuffer, "OK");
+ }
+
+ ptr = NULL;
+ }
+ if (ptr)
+ strcpy (GspOutBuffer, "E02");
+ break;
+
+ /* cAA..AA Continue at address AA..AA(optional) */
+ /* sAA..AA Step one instruction from AA..AA(optional) */
+ case 's':
+ Stepping = TRUE;
+ case 'c':
+ {
+ ULONG BreakpointNumber;
+ ULONG dr6;
+
+ /* try to read optional parameter, pc unchanged if no parm */
+ if (GspHex2Long (&ptr, &Address))
+ Context->Eip = Address;
+
+ NewPC = Context->Eip;
+
+ /* clear the trace bit */
+ Context->EFlags &= 0xfffffeff;
+
+ /* set the trace bit if we're Stepping */
+ if (Stepping)
+ Context->EFlags |= 0x100;
+
+ asm volatile ("movl %%db6, %0\n" : "=r" (dr6) : );
+ if (!(dr6 & 0x4000))
+ {
+ for (BreakpointNumber = 0; BreakpointNumber < 4; ++BreakpointNumber)
+ {
+ if (dr6 & (1 << BreakpointNumber))
+ {
+ if (GspBreakpoints[BreakpointNumber].Type == 0)
+ {
+ /* Set restore flag */
+ Context->EFlags |= 0x10000;
+ break;
+ }
+ }
+ }
+ }
+ GspCorrectHwBreakpoint();
+ asm volatile ("movl %0, %%db6\n" : : "r" (0));
+
+ return kdHandleException;
+ break;
+ }
+
+ case 'k': /* kill the program */
+ strcpy (GspOutBuffer, "OK");
+ break;
+ /* kill the program */
+
+ case 'H': /* Set thread */
+ GspSetThread (ptr);
+ break;
+
+ case 'q': /* Query */
+ GspQuery (ptr);
+ break;
+
+ case 'T': /* Query thread status */
+ GspQueryThreadStatus (ptr);
+ break;
+
+ case 'Y':
+ {
+ ULONG Number;
+ ULONG Length;
+ ULONG Type;
+ ULONG Address;
+
+ ptr = &GspOutBuffer[1];
+ GspHex2Long (&ptr, &Number);
+ ptr++;
+ GspHex2Long (&ptr, &Type);
+ ptr++;
+ GspHex2Long (&ptr, &Length);
+ ptr++;
+ GspHex2Long (&ptr, &Address);
+ if (GspSetHwBreakpoint (Number & 0x3, Type & 0x3 , Length & 0x3, Address) == 0)
+ {
+ strcpy (GspOutBuffer, "OK");
+ }
+ else
+ {
+ strcpy (GspOutBuffer, "E");
+ }
+ break;
+ }
+
+ /* Remove hardware breakpoint */
+ case 'y':
+ {
+ ULONG Number;
+
+ ptr = &GspOutBuffer[1];
+ GspHex2Long(&ptr, &Number);
+ if (GspRemoveHwBreakpoint (Number & 0x3) == 0)
+ {
+ strcpy (GspOutBuffer, "OK");
+ }
+ else
+ {
+ strcpy (GspOutBuffer, "E");
+ }
+ break;
+ }
+
+ default:
+ break;
+ } /* switch */
+
+ /* reply to the request */
+ GspPutPacket (&GspOutBuffer[0]);
+ }
}
return kdDoNotHandleException;
GspInitialized = TRUE;
GspRunThread = PsGetCurrentThread();
- GspDbgThread = PsGetCurrentThread();
+/* GspDbgThread = PsGetCurrentThread(); */
+GspDbgThread = NULL;
GspEnumThread = NULL;
DbgBreakPointWithStatus (DBG_STATUS_CONTROL_C);