/****************************************************************************
- THIS SOFTWARE IS NOT COPYRIGHTED
+ 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 it's performance and the
#define BUFMAX 1000
static BOOLEAN GspInitialized;
-#if 0
-static PKINTERRUPT GspInterrupt;
-#endif
static BOOLEAN GspRemoteDebug;
static PETHREAD GspDbgThread;
static PETHREAD GspEnumThread;
+static FAST_MUTEX GspLock;
+
extern LIST_ENTRY PsActiveProcessHead;
KD_PORT_INFORMATION GdbPortInfo = { 2, 115200, 0 }; /* FIXME hardcoded for COM2, 115200 baud */
/* Number of Registers. */
-#define NUMREGS 16
+#define NUMREGS 16
enum REGISTER_NAMES
{
EAX, ECX, EDX, EBX, ESP, EBP, ESI, EDI,
- PC /* also known as eip */,
- PS /* also known as eflags */,
- CS, SS, DS, ES, FS, GS
+ PC /* also known as eip */,
+ PS /* also known as eflags */,
+ CS, SS, DS, ES, FS, GS
};
typedef struct _CPU_REGISTER
BOOLEAN SetInContext;
} CPU_REGISTER, *PCPU_REGISTER;
-#define KTRAP_FRAME_X86 KTRAP_FRAME
-
-#define EIP_REGNO 8
-
-typedef
-VOID
-STDCALL_FUNC
-(*PKSYSTEM_ROUTINE)(PKSTART_ROUTINE StartRoutine,
- PVOID StartContext);
-
-VOID
-STDCALL
-KiThreadStartup(PKSYSTEM_ROUTINE SystemRoutine,
- PKSTART_ROUTINE StartRoutine,
- PVOID StartContext,
- BOOLEAN UserThread,
- KTRAP_FRAME TrapFrame);
-
static CPU_REGISTER GspRegisters[NUMREGS] =
{
- { 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 }
+ { 4, FIELD_OFFSET(KTRAP_FRAME, Eax), FIELD_OFFSET(CONTEXT, Eax), TRUE },
+ { 4, FIELD_OFFSET(KTRAP_FRAME, Ecx), FIELD_OFFSET(CONTEXT, Ecx), TRUE },
+ { 4, FIELD_OFFSET(KTRAP_FRAME, Edx), FIELD_OFFSET(CONTEXT, Edx), FALSE },
+ { 4, FIELD_OFFSET(KTRAP_FRAME, Ebx), FIELD_OFFSET(CONTEXT, Ebx), TRUE },
+ { 4, FIELD_OFFSET(KTRAP_FRAME, Esp), FIELD_OFFSET(CONTEXT, Esp), TRUE },
+ { 4, FIELD_OFFSET(KTRAP_FRAME, DebugEbp), FIELD_OFFSET(CONTEXT, Ebp), TRUE },
+ { 4, FIELD_OFFSET(KTRAP_FRAME, Esi), FIELD_OFFSET(CONTEXT, Esi), TRUE },
+ { 4, FIELD_OFFSET(KTRAP_FRAME, Edi), FIELD_OFFSET(CONTEXT, Edi), TRUE },
+ { 4, FIELD_OFFSET(KTRAP_FRAME, DebugEip), FIELD_OFFSET(CONTEXT, Eip), TRUE },
+ { 4, FIELD_OFFSET(KTRAP_FRAME, Eflags), FIELD_OFFSET(CONTEXT, EFlags), TRUE },
+ { 4, FIELD_OFFSET(KTRAP_FRAME, Cs), FIELD_OFFSET(CONTEXT, SegCs), TRUE },
+ { 4, FIELD_OFFSET(KTRAP_FRAME, Ss), FIELD_OFFSET(CONTEXT, SegSs), TRUE },
+ { 4, FIELD_OFFSET(KTRAP_FRAME, Ds), FIELD_OFFSET(CONTEXT, SegDs), TRUE },
+ { 4, FIELD_OFFSET(KTRAP_FRAME, Es), FIELD_OFFSET(CONTEXT, SegEs), TRUE },
+ { 4, FIELD_OFFSET(KTRAP_FRAME, Fs), FIELD_OFFSET(CONTEXT, SegFs), TRUE },
+ { 4, FIELD_OFFSET(KTRAP_FRAME, Gs), FIELD_OFFSET(CONTEXT, SegGs), TRUE }
};
static PCHAR GspThreadStates[DeferredReady+1] =
-{ "Initialized",
+{
+ "Initialized",
"Ready",
"Running",
"Standby",
LONG
-HexValue (CHAR ch)
+HexValue(CHAR ch)
{
- 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);
- return (-1);
+ 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);
+ }
+
+ return -1;
}
static CHAR GspInBuffer[BUFMAX];
VOID
GdbPutChar(UCHAR Value)
{
- KdPortPutByteEx (&GdbPortInfo, Value);
+ KdPortPutByteEx(&GdbPortInfo, Value);
}
UCHAR
{
UCHAR Value;
- while (!KdPortGetByteEx (&GdbPortInfo, &Value));
+ while (!KdPortGetByteEx(&GdbPortInfo, &Value))
+ ;
return Value;
}
while (TRUE)
{
/* wait around for the start character, ignore all other characters */
- while ((ch = GdbGetChar ()) != '$');
+ while ((ch = GdbGetChar ()) != '$')
+ ;
retry:
Checksum = 0;
/* now, read until a # or end of Buffer is found */
while (Count < BUFMAX)
- {
- ch = GdbGetChar ();
- if (ch == '$')
- goto retry;
- if (ch == '#')
- break;
- Checksum = Checksum + ch;
- Buffer[Count] = ch;
- Count = Count + 1;
- }
+ {
+ ch = GdbGetChar();
+ if (ch == '$')
+ {
+ goto retry;
+ }
+ if (ch == '#')
+ {
+ break;
+ }
+ Checksum = Checksum + ch;
+ Buffer[Count] = ch;
+ Count = Count + 1;
+ }
Buffer[Count] = 0;
if (ch == '#')
- {
- ch = GdbGetChar ();
- XmitChecksum = (CHAR)(HexValue (ch) << 4);
- ch = GdbGetChar ();
- XmitChecksum += (CHAR)(HexValue (ch));
-
- if (Checksum != XmitChecksum)
- {
- GdbPutChar ('-'); /* failed checksum */
- }
- else
- {
- GdbPutChar ('+'); /* successful transfer */
-
- /* if a sequence char is present, reply the sequence ID */
- if (Buffer[2] == ':')
- {
- GdbPutChar (Buffer[0]);
- GdbPutChar (Buffer[1]);
-
- return &Buffer[3];
- }
-
- return &Buffer[0];
- }
- }
+ {
+ ch = GdbGetChar();
+ XmitChecksum = (CHAR)(HexValue(ch) << 4);
+ ch = GdbGetChar();
+ XmitChecksum += (CHAR)(HexValue(ch));
+
+ if (Checksum != XmitChecksum)
+ {
+ GdbPutChar('-'); /* failed checksum */
+ }
+ else
+ {
+ GdbPutChar('+'); /* successful transfer */
+
+ return &Buffer[0];
+ }
+ }
}
}
/* send the packet in Buffer. */
VOID
-GspPutPacket (PCHAR Buffer)
+GspPutPacket(PCHAR Buffer)
{
CHAR Checksum;
LONG Count;
/* $<packet info>#<Checksum>. */
do
{
- GdbPutChar ('$');
+ GdbPutChar('$');
Checksum = 0;
Count = 0;
while ((ch = Buffer[Count]))
- {
- GdbPutChar (ch);
- Checksum += ch;
- Count += 1;
- }
-
- GdbPutChar ('#');
- GdbPutChar (HexChars[(Checksum >> 4) & 0xf]);
- GdbPutChar (HexChars[Checksum & 0xf]);
+ {
+ GdbPutChar(ch);
+ Checksum += ch;
+ Count += 1;
+ }
+
+ GdbPutChar('#');
+ GdbPutChar(HexChars[(Checksum >> 4) & 0xf]);
+ GdbPutChar(HexChars[Checksum & 0xf]);
}
- while (GdbGetChar () != '+');
+ while (GdbGetChar() != '+');
}
VOID
-GspPutPacketNoWait (PCHAR Buffer)
+GspPutPacketNoWait(PCHAR Buffer)
{
CHAR Checksum;
LONG Count;
CHAR ch;
/* $<packet info>#<Checksum>. */
- GdbPutChar ('$');
+ GdbPutChar('$');
Checksum = 0;
Count = 0;
while ((ch = Buffer[Count]))
- {
- GdbPutChar (ch);
- Checksum += ch;
- Count += 1;
- }
-
- GdbPutChar ('#');
- GdbPutChar (HexChars[(Checksum >> 4) & 0xf]);
- GdbPutChar (HexChars[Checksum & 0xf]);
+ {
+ GdbPutChar(ch);
+ Checksum += ch;
+ Count += 1;
+ }
+
+ GdbPutChar('#');
+ GdbPutChar(HexChars[(Checksum >> 4) & 0xf]);
+ GdbPutChar(HexChars[Checksum & 0xf]);
}
/* Indicate to caller of GspMem2Hex or GspHex2Mem that there has been an
/* If MayFault is TRUE, then we should set GspMemoryError in response to
a fault; if FALSE treat a fault like any other fault in the stub. */
PCHAR
-GspMem2Hex (PCHAR Address,
+GspMem2Hex(PCHAR Address,
PCHAR Buffer,
LONG Count,
BOOLEAN MayFault)
for (i = 0; i < (ULONG) Count; i++)
{
if (MayFault)
- GspAccessLocation = Address;
+ {
+ GspAccessLocation = Address;
+ }
ch = *Address;
GspAccessLocation = NULL;
if (MayFault && GspMemoryError)
{
- return (Buffer);
+ return Buffer;
}
*Buffer++ = HexChars[(ch >> 4) & 0xf];
*Buffer++ = HexChars[ch & 0xf];
Address++;
}
*Buffer = 0;
- return (Buffer);
+ return Buffer;
}
/* Convert the hex array pointed to by Buffer into binary to be placed at Address */
/* Return a pointer to the character AFTER the last byte read from Buffer */
PCHAR
-GspHex2Mem (PCHAR Buffer,
+GspHex2Mem(PCHAR Buffer,
PCHAR Address,
ULONG Count,
BOOLEAN MayFault)
current = Address;
while ( current < Address + Count )
{
- page = (PCHAR)PAGE_ROUND_DOWN (current);
+ page = (PCHAR)PAGE_ROUND_DOWN(current);
if (Address + Count <= page + PAGE_SIZE)
{
/* Fits in this page */
}
if (MayFault)
{
- oldprot = MmGetPageProtect (NULL, Address);
- MmSetPageProtect (NULL, Address, PAGE_EXECUTE_READWRITE);
+ oldprot = MmGetPageProtect(NULL, Address);
+ MmSetPageProtect(NULL, Address, PAGE_EXECUTE_READWRITE);
}
for (i = 0; i < countinpage && ! GspMemoryError; i++)
{
- ch = (CHAR)(HexValue (*Buffer++) << 4);
- ch = (CHAR)(ch + HexValue (*Buffer++));
+ ch = (CHAR)(HexValue(*Buffer++) << 4);
+ ch = (CHAR)(ch + HexValue(*Buffer++));
GspAccessLocation = current;
*current = ch;
}
if (MayFault)
{
- MmSetPageProtect (NULL, page, oldprot);
+ MmSetPageProtect(NULL, page, oldprot);
if (GspMemoryError)
{
- return (Buffer);
+ return Buffer;
}
}
}
- return (Buffer);
+ return Buffer;
}
/* This function takes the 386 exception vector and attempts to
translate this number into a unix compatible signal value */
ULONG
-GspComputeSignal (NTSTATUS ExceptionCode)
+GspComputeSignal(NTSTATUS ExceptionCode)
{
ULONG SigVal;
switch (ExceptionCode)
{
case STATUS_INTEGER_DIVIDE_BY_ZERO:
- SigVal = 8;
- break; /* divide by zero */
+ SigVal = 8; /* divide by zero */
+ break;
case STATUS_SINGLE_STEP:
- /* debug exception */
case STATUS_BREAKPOINT:
- SigVal = 5;
- break; /* breakpoint */
+ SigVal = 5; /* breakpoint */
+ break;
case STATUS_INTEGER_OVERFLOW:
- /* into instruction (overflow) */
case STATUS_ARRAY_BOUNDS_EXCEEDED:
- SigVal = 16;
- break; /* bound instruction */
+ SigVal = 16; /* bound instruction */
+ break;
case STATUS_ILLEGAL_INSTRUCTION:
- SigVal = 4;
- break; /* Invalid opcode */
-#if 0
- case STATUS_FLT_INVALID_OPERATION:
- SigVal = 8;
- break; /* coprocessor not available */
-#endif
+ SigVal = 4; /* Invalid opcode */
+ break;
case STATUS_STACK_OVERFLOW:
- /* stack exception */
case STATUS_DATATYPE_MISALIGNMENT:
- /* page fault */
case STATUS_ACCESS_VIOLATION:
- SigVal = 11; /* access violation */
+ SigVal = 11; /* access violation */
break;
default:
- SigVal = 7; /* "software generated" */
+ SigVal = 7; /* "software generated" */
}
- return (SigVal);
+ return SigVal;
}
/* RETURN NUMBER OF CHARS PROCESSED */
/**********************************************/
LONG
-GspHex2Long (PCHAR *Address,
+GspHex2Long(PCHAR *Address,
PLONG Value)
{
LONG NumChars = 0;
while (**Address)
{
- Hex = HexValue (**Address);
+ Hex = HexValue(**Address);
if (Hex >= 0)
- {
- *Value = (*Value << 4) | Hex;
- NumChars++;
- }
- else
- break;
+ {
+ *Value = (*Value << 4) | Hex;
+ NumChars++;
+ }
+ else
+ {
+ break;
+ }
(*Address)++;
}
- return (NumChars);
+ return NumChars;
}
VOID
-GspLong2Hex (PCHAR *Address,
+GspLong2Hex(PCHAR *Address,
LONG Value)
{
LONG Save;
(((Value >> 8) & 0xff) << 16) |
(((Value >> 16) & 0xff) << 8) |
(((Value >> 24) & 0xff) << 0);
- *Address = GspMem2Hex ((PCHAR) &Save, *Address, 4, FALSE);
+ *Address = GspMem2Hex((PCHAR) &Save, *Address, 4, FALSE);
}
static LONG
GspGetEspFromTrapFrame(PKTRAP_FRAME TrapFrame)
{
-
return KeGetPreviousMode() == KernelMode
- ? (LONG) &TrapFrame->Esp : TrapFrame->Esp;
+ ? (LONG) &TrapFrame->Esp : (LONG)TrapFrame->Esp;
}
-VOID
-GspGetRegistersFromTrapFrame(PCHAR Address,
- PCONTEXT Context,
+static VOID
+GspGetRegisters(PCHAR Address,
PKTRAP_FRAME TrapFrame)
{
- ULONG Value;
- PCHAR Buffer;
+ ULONG_PTR Value;
PULONG p;
DWORD i;
+ PETHREAD Thread;
+ ULONG_PTR *KernelStack;
- Buffer = Address;
- for (i = 0; i < sizeof (GspRegisters) / sizeof (GspRegisters[0]); i++)
- {
- if (TrapFrame)
+ if (NULL == GspDbgThread)
{
- if (ESP == i)
- {
- Value = GspGetEspFromTrapFrame (TrapFrame);
- }
- else
- {
- p = (PULONG) ((ULONG_PTR) TrapFrame + GspRegisters[i].OffsetInTF);
- Value = *p;
- }
+ Thread = PsGetCurrentThread();
}
- else if (i == EIP_REGNO)
+ else
{
- /*
- * This thread has not been sheduled yet so assume it
- * is still in PsBeginThreadWithContextInternal().
- */
- Value = (ULONG)KiThreadStartup;
+ TrapFrame = GspDbgThread->Tcb.TrapFrame;
+ Thread = GspDbgThread;
}
- else
+
+ if (Waiting == Thread->Tcb.State)
{
- Value = 0;
+ KernelStack = Thread->Tcb.KernelStack;
+ for (i = 0; i < sizeof(GspRegisters) / sizeof(GspRegisters[0]); i++)
+ {
+ switch(i)
+ {
+ case EBP:
+ Value = KernelStack[3];
+ break;
+ case EDI:
+ Value = KernelStack[4];
+ break;
+ case ESI:
+ Value = KernelStack[5];
+ break;
+ case EBX:
+ Value = KernelStack[6];
+ break;
+ case PC:
+ Value = KernelStack[7];
+ break;
+ case ESP:
+ Value = (ULONG_PTR) (KernelStack + 8);
+ break;
+ case CS:
+ Value = KERNEL_CS;
+ break;
+ case DS:
+ Value = KERNEL_DS;
+ break;
+ default:
+ Value = 0;
+ break;
+ }
+ Address = GspMem2Hex((PCHAR) &Value, Address, GspRegisters[i].Size,
+ FALSE);
+ }
+ }
+ else
+ {
+ for (i = 0; i < sizeof(GspRegisters) / sizeof(GspRegisters[0]); i++)
+ {
+ if (TrapFrame)
+ {
+ if (ESP == i)
+ {
+ Value = GspGetEspFromTrapFrame(TrapFrame);
+ }
+ else
+ {
+ p = (PULONG)((ULONG_PTR) TrapFrame +
+ GspRegisters[i].OffsetInTF);
+ Value = *p;
+ }
+ }
+ else if (i == PC)
+ {
+ /*
+ * This thread has not been sheduled yet so assume it
+ * is still in PsBeginThreadWithContextInternal().
+ */
+ Value = (ULONG)KiThreadStartup;
+ }
+ else
+ {
+ Value = 0;
+ }
+ Address = GspMem2Hex((PCHAR) &Value, Address,
+ GspRegisters[i].Size, FALSE);
+ }
}
- Buffer = GspMem2Hex ((PCHAR) &Value, Buffer, GspRegisters[i].Size, FALSE);
- }
}
DWORD i;
if (!TrapFrame)
- return;
+ {
+ return;
+ }
Buffer = Address;
for (i = 0; i < NUMREGS; i++)
- {
- 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, GspRegisters[i].Size, FALSE);
- *p = Value;
- }
+ {
+ 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, GspRegisters[i].Size, FALSE);
+ *p = Value;
+ }
}
PULONG p;
if (!TrapFrame)
- return;
+ {
+ return;
+ }
if (GspRegisters[Number].SetInContext)
- p = (PULONG) ((ULONG_PTR) Context + GspRegisters[Number].OffsetInContext);
+ {
+ p = (PULONG) ((ULONG_PTR) Context + GspRegisters[Number].OffsetInContext);
+ }
else
- p = (PULONG) ((ULONG_PTR) TrapFrame + GspRegisters[Number].OffsetInTF);
+ {
+ p = (PULONG) ((ULONG_PTR) TrapFrame + GspRegisters[Number].OffsetInTF);
+ }
Value = 0;
- GspHex2Mem (Address, (PCHAR) &Value, GspRegisters[Number].Size, FALSE);
+ GspHex2Mem(Address, (PCHAR) &Value, GspRegisters[Number].Size, FALSE);
*p = Value;
}
/* All threads */
ThreadInfo = NULL;
}
- else
+ else
{
ULONG uThreadId;
HANDLE ThreadId;
PCHAR ptr = &Data[0];
- GspHex2Long (&ptr, (PLONG) &uThreadId);
+ GspHex2Long(&ptr, (PLONG) &uThreadId);
ThreadId = (HANDLE)uThreadId;
- if (!NT_SUCCESS (PsLookupThreadByThreadId (ThreadId, &ThreadInfo)))
- {
+ if (!NT_SUCCESS(PsLookupThreadByThreadId(ThreadId, &ThreadInfo)))
+ {
*Thread = NULL;
return FALSE;
}
switch (Request[0])
{
case 'c': /* Run thread */
- if (GspFindThread (ptr, &ThreadInfo))
+ if (GspFindThread(ptr, &ThreadInfo))
{
GspOutBuffer[0] = 'O';
GspOutBuffer[1] = 'K';
}
break;
case 'g': /* Debug thread */
- if (GspFindThread (ptr, &ThreadInfo))
- {
- GspOutBuffer[0] = 'O';
- GspOutBuffer[1] = 'K';
-
- if(GspDbgThread) ObDereferenceObject(GspDbgThread);
-
- GspDbgThread = ThreadInfo;
- }
- else
- {
- GspOutBuffer[0] = 'E';
- }
+ if (GspFindThread(ptr, &ThreadInfo))
+ {
+ GspOutBuffer[0] = 'O';
+ GspOutBuffer[1] = 'K';
+
+ if (NULL != GspDbgThread)
+ {
+ ObDereferenceObject(GspDbgThread);
+ }
+
+ if (ThreadInfo == PsGetCurrentThread())
+ {
+ GspDbgThread = NULL;
+ ObDereferenceObject(ThreadInfo);
+ }
+ else
+ {
+ GspDbgThread = ThreadInfo;
+ }
+ }
+ else
+ {
+ GspOutBuffer[0] = 'E';
+ }
break;
default:
break;
VOID
GspQuery(PCHAR Request)
{
- PCHAR Command;
ULONG Value;
- Command = strtok (Request, ",");
- if (strncmp (Command, "C", 1) == 0)
- {
- PCHAR ptr = &GspOutBuffer[2];
-
- /* Get current thread id */
- GspOutBuffer[0] = 'Q';
- GspOutBuffer[1] = 'C';
- if (NULL != GspDbgThread)
+ if (strncmp(Request, "C", 1) == 0)
{
- Value = (ULONG) GspDbgThread->Cid.UniqueThread;
- }
- else
- {
- Value = (ULONG) PsGetCurrentThread()->Cid.UniqueThread;
- }
- GspLong2Hex (&ptr, Value);
- }
- else if (strncmp (Command, "fThreadInfo", 11) == 0)
- {
- PEPROCESS Process;
- PLIST_ENTRY AThread, AProcess;
- PCHAR ptr = &GspOutBuffer[1];
-
- /* Get first thread id */
- GspEnumThread = NULL;
- AProcess = PsActiveProcessHead.Flink;
- while(AProcess != &PsActiveProcessHead)
- {
- Process = CONTAINING_RECORD(AProcess, EPROCESS, ActiveProcessLinks);
- AThread = Process->ThreadListHead.Flink;
- if(AThread != &Process->ThreadListHead)
- {
- GspEnumThread = CONTAINING_RECORD (Process->ThreadListHead.Flink,
- ETHREAD, ThreadListEntry);
- break;
- }
- AProcess = AProcess->Flink;
- }
- if(GspEnumThread != NULL)
- {
- GspOutBuffer[0] = 'm';
- Value = (ULONG) GspEnumThread->Cid.UniqueThread;
- GspLong2Hex (&ptr, Value);
+ PCHAR ptr = &GspOutBuffer[2];
+
+ /* Get current thread id */
+ GspOutBuffer[0] = 'Q';
+ GspOutBuffer[1] = 'C';
+ if (NULL != GspDbgThread)
+ {
+ Value = (ULONG) GspDbgThread->Cid.UniqueThread;
+ }
+ else
+ {
+ Value = (ULONG) PsGetCurrentThread()->Cid.UniqueThread;
+ }
+ GspLong2Hex(&ptr, Value);
}
- else
+ else if (strncmp(Request, "fThreadInfo", 11) == 0)
{
- /* FIXME - what to do here? This case should never happen though, there
- should always be at least one thread on the system... */
- /* GspOutBuffer[0] = 'l'; */
- }
- }
- else if (strncmp (Command, "sThreadInfo", 11) == 0)
- {
- PEPROCESS Process;
- PLIST_ENTRY AThread, AProcess;
- PCHAR ptr = &GspOutBuffer[1];
+ PEPROCESS Process;
+ PLIST_ENTRY AThread, AProcess;
+ PCHAR ptr = &GspOutBuffer[1];
- /* Get next thread id */
- if (GspEnumThread != NULL)
- {
- /* find the next thread */
- Process = GspEnumThread->ThreadsProcess;
- if(GspEnumThread->ThreadListEntry.Flink != &Process->ThreadListHead)
- {
- GspEnumThread = CONTAINING_RECORD (GspEnumThread->ThreadListEntry.Flink,
- ETHREAD, ThreadListEntry);
- }
- else
- {
- PETHREAD Thread = NULL;
- AProcess = Process->ActiveProcessLinks.Flink;
- while(AProcess != &PsActiveProcessHead)
+ /* Get first thread id */
+ GspEnumThread = NULL;
+ AProcess = PsActiveProcessHead.Flink;
+ while(AProcess != &PsActiveProcessHead)
{
Process = CONTAINING_RECORD(AProcess, EPROCESS, ActiveProcessLinks);
AThread = Process->ThreadListHead.Flink;
- if(AThread != &Process->ThreadListHead)
- {
- Thread = CONTAINING_RECORD (Process->ThreadListHead.Flink,
- ETHREAD, ThreadListEntry);
- break;
- }
+ if (AThread != &Process->ThreadListHead)
+ {
+ GspEnumThread = CONTAINING_RECORD(Process->ThreadListHead.Flink,
+ ETHREAD, ThreadListEntry);
+ break;
+ }
AProcess = AProcess->Flink;
}
- GspEnumThread = Thread;
- }
-
if(GspEnumThread != NULL)
- {
- /* return the ID */
- GspOutBuffer[0] = 'm';
- Value = (ULONG) GspEnumThread->Cid.UniqueThread;
- GspLong2Hex (&ptr, Value);
- }
+ {
+ GspOutBuffer[0] = 'm';
+ Value = (ULONG) GspEnumThread->Cid.UniqueThread;
+ GspLong2Hex(&ptr, Value);
+ }
else
- {
- GspOutBuffer[0] = 'l';
- }
+ {
+ /* FIXME - what to do here? This case should never happen though, there
+ should always be at least one thread on the system... */
+ /* GspOutBuffer[0] = 'l'; */
+ }
}
- else
+ else if (strncmp(Request, "sThreadInfo", 11) == 0)
{
- GspOutBuffer[0] = 'l';
+ PEPROCESS Process;
+ PLIST_ENTRY AThread, AProcess;
+ PCHAR ptr = &GspOutBuffer[1];
+
+ /* Get next thread id */
+ if (GspEnumThread != NULL)
+ {
+ /* find the next thread */
+ Process = GspEnumThread->ThreadsProcess;
+ if(GspEnumThread->ThreadListEntry.Flink != &Process->ThreadListHead)
+ {
+ GspEnumThread = CONTAINING_RECORD(GspEnumThread->ThreadListEntry.Flink,
+ ETHREAD, ThreadListEntry);
+ }
+ else
+ {
+ PETHREAD Thread = NULL;
+ AProcess = Process->ActiveProcessLinks.Flink;
+ while(AProcess != &PsActiveProcessHead)
+ {
+ Process = CONTAINING_RECORD(AProcess, EPROCESS, ActiveProcessLinks);
+ AThread = Process->ThreadListHead.Flink;
+ if (AThread != &Process->ThreadListHead)
+ {
+ Thread = CONTAINING_RECORD(Process->ThreadListHead.Flink,
+ ETHREAD, ThreadListEntry);
+ break;
+ }
+ AProcess = AProcess->Flink;
+ }
+ GspEnumThread = Thread;
+ }
+
+ if (GspEnumThread != NULL)
+ {
+ /* return the ID */
+ GspOutBuffer[0] = 'm';
+ Value = (ULONG) GspEnumThread->Cid.UniqueThread;
+ GspLong2Hex(&ptr, Value);
+ }
+ else
+ {
+ GspOutBuffer[0] = 'l';
+ }
+ }
+ else
+ {
+ GspOutBuffer[0] = 'l';
+ }
}
- }
- else if (strncmp (Command, "ThreadExtraInfo", 15) == 0)
- {
- PETHREAD ThreadInfo;
- PCHAR ptr = &Command[15];
+ else if (strncmp(Request, "ThreadExtraInfo", 15) == 0)
+ {
+ PETHREAD ThreadInfo;
- /* Get thread information */
- if (GspFindThread (ptr, &ThreadInfo))
- {
- PCHAR String = GspThreadStates[ThreadInfo->Tcb.State];
+ /* Get thread information */
+ if (GspFindThread(Request + 16, &ThreadInfo))
+ {
+ char Buffer[64];
+ PEPROCESS Proc;
- ObDereferenceObject(ThreadInfo);
+ Proc = (PEPROCESS) ThreadInfo->ThreadsProcess;
- GspMem2Hex (String, &GspOutBuffer[0], strlen (String), FALSE);
- }
- }
-#if 0
- else if (strncmp (Command, "L", 1) == 0)
- {
- PLIST_ENTRY CurrentEntry;
- PETHREAD Current;
- ULONG MaxThreads = 0;
- ULONG ThreadId = 0;
- ULONG ThreadCount = 0;
-
- /* List threads */
- GspHex2Mem (&Request[1], (PCHAR) &MaxThreads, 2, TRUE);
- GspHex2Mem (&Request[3], (PCHAR) &Value, 4, TRUE);
- GspHex2Mem (&Request[11], (PCHAR) &ThreadId, 4, TRUE);
-
- GspOutBuffer[0] = 'q';
- GspOutBuffer[1] = 'M';
- Value = 0;
- GspMem2Hex ((PCHAR) &Value, &GspOutBuffer[5], 4, TRUE);
- GspMem2Hex ((PCHAR) &ThreadId, &GspOutBuffer[13], 4, TRUE);
-
- CurrentEntry = PiThreadListHead.Flink;
- while ((CurrentEntry != &PiThreadListHead) && (ThreadCount < MaxThreads))
- {
- Current = CONTAINING_RECORD (CurrentEntry, ETHREAD, Tcb.ThreadListEntry);
- Value = 0;
- GspMem2Hex ((PCHAR) &Value, &GspOutBuffer[21+ThreadCount*16], 4, TRUE);
- Value = (ULONG) Current->Cid.UniqueThread;
- GspMem2Hex ((PCHAR) &Value, &GspOutBuffer[21+ThreadCount*16+8], 4, TRUE);
- CurrentEntry = CurrentEntry->Flink;
- ThreadCount++;
- }
-
- if (CurrentEntry != &PiThreadListHead)
- {
- GspOutBuffer[4] = '0';
- }
- else
- {
- GspOutBuffer[4] = '1';
- }
+ Buffer[0] = '\0';
+ if (NULL != Proc )
+ {
+ sprintf(Buffer, "%s [%d:0x%x], ", Proc->ImageFileName,
+ (int) Proc->UniqueProcessId,
+ (int) ThreadInfo->Cid.UniqueThread);
+ }
+ strcpy(Buffer + strlen(Buffer),
+ GspThreadStates[ThreadInfo->Tcb.State]);
- GspMem2Hex ((PCHAR) &ThreadCount, &GspOutBuffer[2], 1, TRUE);
- }
-#endif
- else if (strncmp (Command, "Offsets", 7) == 0)
- {
- strcpy (GspOutBuffer, "Text=0;Data=0;Bss=0");
- }
+ ObDereferenceObject(ThreadInfo);
+
+ GspMem2Hex(Buffer, &GspOutBuffer[0], strlen(Buffer), FALSE);
+ }
+ }
}
VOID
PETHREAD ThreadInfo;
PCHAR ptr = &Request[0];
- if (GspFindThread (ptr, &ThreadInfo))
- {
- ObDereferenceObject(ThreadInfo);
+ if (GspFindThread(ptr, &ThreadInfo))
+ {
+ ObDereferenceObject(ThreadInfo);
- GspOutBuffer[0] = 'O';
- GspOutBuffer[1] = 'K';
- GspOutBuffer[2] = '\0';
- }
+ GspOutBuffer[0] = 'O';
+ GspOutBuffer[1] = 'K';
+ GspOutBuffer[2] = '\0';
+ }
else
- {
- GspOutBuffer[0] = 'E';
- GspOutBuffer[1] = '\0';
- }
+ {
+ GspOutBuffer[0] = 'E';
+ GspOutBuffer[1] = '\0';
+ }
}
"=r" (addr2), "=r" (addr3) : );
} while (FALSE);
#elif defined(_MSC_VER)
- __asm
+ __asm
{
- mov eax, dr7; mov dr7_, eax;
- mov eax, dr0; mov addr0, eax;
- mov eax, dr1; mov addr1, eax;
- mov eax, dr2; mov addr2, eax;
- mov eax, dr3; mov addr3, eax;
+ mov eax, dr7; mov dr7_, eax;
+ mov eax, dr0; mov addr0, eax;
+ mov eax, dr1; mov addr1, eax;
+ mov eax, dr2; mov addr2, eax;
+ mov eax, dr3; mov addr3, eax;
}
#else
#error Unknown compiler for inline assembler
#endif
- CorrectIt = FALSE;
- for (BreakpointNumber = 0; BreakpointNumber < 3; BreakpointNumber++)
+ CorrectIt = FALSE;
+ for (BreakpointNumber = 0; BreakpointNumber < 3; BreakpointNumber++)
{
- Bit = 2 << (BreakpointNumber << 1);
- if (!(dr7_ & Bit) && GspBreakpoints[BreakpointNumber].Enabled) {
- CorrectIt = TRUE;
- dr7_ |= Bit;
- dr7_ &= ~(0xf0000 << (BreakpointNumber << 2));
- dr7_ |= (((GspBreakpoints[BreakpointNumber].Length << 2) |
- GspBreakpoints[BreakpointNumber].Type) << 16) << (BreakpointNumber << 2);
- switch (BreakpointNumber) {
+ Bit = 2 << (BreakpointNumber << 1);
+ if (!(dr7_ & Bit) && GspBreakpoints[BreakpointNumber].Enabled)
+ {
+ CorrectIt = TRUE;
+ dr7_ |= Bit;
+ dr7_ &= ~(0xf0000 << (BreakpointNumber << 2));
+ dr7_ |= (((GspBreakpoints[BreakpointNumber].Length << 2) |
+ GspBreakpoints[BreakpointNumber].Type) << 16) << (BreakpointNumber << 2);
+ switch (BreakpointNumber)
+ {
#if defined(__GNUC__)
- case 0:
- asm volatile ("movl %0, %%dr0\n"
- : : "r" (GspBreakpoints[BreakpointNumber].Address) );
- break;
-
- case 1:
- asm volatile ("movl %0, %%dr1\n"
- : : "r" (GspBreakpoints[BreakpointNumber].Address) );
- break;
-
- case 2:
- asm volatile ("movl %0, %%dr2\n"
- : : "r" (GspBreakpoints[BreakpointNumber].Address) );
- break;
-
- case 3:
- asm volatile ("movl %0, %%dr3\n"
- : : "r" (GspBreakpoints[BreakpointNumber].Address) );
- break;
+ case 0:
+ asm volatile ("movl %0, %%dr0\n"
+ : : "r" (GspBreakpoints[BreakpointNumber].Address) );
+ break;
+
+ case 1:
+ asm volatile ("movl %0, %%dr1\n"
+ : : "r" (GspBreakpoints[BreakpointNumber].Address) );
+ break;
+
+ case 2:
+ asm volatile ("movl %0, %%dr2\n"
+ : : "r" (GspBreakpoints[BreakpointNumber].Address) );
+ break;
+
+ case 3:
+ asm volatile ("movl %0, %%dr3\n"
+ : : "r" (GspBreakpoints[BreakpointNumber].Address) );
+ break;
#elif defined(_MSC_VER)
- case 0:
- {
- ULONG addr = GspBreakpoints[BreakpointNumber].Address;
- __asm mov eax, addr;
- __asm mov dr0, eax;
- }
- break;
- case 1:
- {
- ULONG addr = GspBreakpoints[BreakpointNumber].Address;
- __asm mov eax, addr;
- __asm mov dr1, eax;
- }
- break;
- case 2:
- {
- ULONG addr = GspBreakpoints[BreakpointNumber].Address;
- __asm mov eax, addr;
- __asm mov dr2, eax;
- }
- break;
- case 3:
- {
- ULONG addr = GspBreakpoints[BreakpointNumber].Address;
- __asm mov eax, addr;
- __asm mov dr3, eax;
- }
- break;
+ case 0:
+ {
+ ULONG addr = GspBreakpoints[BreakpointNumber].Address;
+ __asm mov eax, addr;
+ __asm mov dr0, eax;
+ }
+ break;
+ case 1:
+ {
+ ULONG addr = GspBreakpoints[BreakpointNumber].Address;
+ __asm mov eax, addr;
+ __asm mov dr1, eax;
+ }
+ break;
+ case 2:
+ {
+ ULONG addr = GspBreakpoints[BreakpointNumber].Address;
+ __asm mov eax, addr;
+ __asm mov dr2, eax;
+ }
+ break;
+ case 3:
+ {
+ ULONG addr = GspBreakpoints[BreakpointNumber].Address;
+ __asm mov eax, addr;
+ __asm mov dr3, eax;
+ }
+ break;
#else
#error Unknown compiler for inline assembler
#endif
- }
+ }
+ }
+ else if ((dr7_ & Bit) && !GspBreakpoints[BreakpointNumber].Enabled)
+ {
+ CorrectIt = TRUE;
+ dr7_ &= ~Bit;
+ dr7_ &= ~(0xf0000 << (BreakpointNumber << 2));
+ }
}
- else if ((dr7_ & Bit) && !GspBreakpoints[BreakpointNumber].Enabled)
- {
- CorrectIt = TRUE;
- dr7_ &= ~Bit;
- dr7_ &= ~(0xf0000 << (BreakpointNumber << 2));
- }
- }
if (CorrectIt)
{
#if defined(__GNUC__)
- asm volatile ( "movl %0, %%db7\n" : : "r" (dr7_));
+ asm volatile ( "movl %0, %%db7\n" : : "r" (dr7_));
#elif defined(_MSC_VER)
- __asm mov eax, dr7_;
- __asm mov dr7, eax;
+ __asm mov eax, dr7_;
+ __asm mov dr7, eax;
#else
#error Unknown compiler for inline assembler
#endif
ULONG
GspRemoveHwBreakpoint(ULONG BreakpointNumber)
{
- if (!GspBreakpoints[BreakpointNumber].Enabled)
+ if (!GspBreakpoints[BreakpointNumber].Enabled)
{
- return -1;
- }
- GspBreakpoints[BreakpointNumber].Enabled = 0;
- return 0;
+ return -1;
+ }
+ GspBreakpoints[BreakpointNumber].Enabled = 0;
+ return 0;
}
ULONG Length,
ULONG Address)
{
- if (GspBreakpoints[BreakpointNumber].Enabled)
- {
- return -1;
- }
- GspBreakpoints[BreakpointNumber].Enabled = TRUE;
- GspBreakpoints[BreakpointNumber].Type = Type;
- GspBreakpoints[BreakpointNumber].Length = Length;
- GspBreakpoints[BreakpointNumber].Address = Address;
- return 0;
+ if (GspBreakpoints[BreakpointNumber].Enabled)
+ {
+ return -1;
+ }
+ GspBreakpoints[BreakpointNumber].Enabled = TRUE;
+ GspBreakpoints[BreakpointNumber].Type = Type;
+ GspBreakpoints[BreakpointNumber].Length = Length;
+ GspBreakpoints[BreakpointNumber].Address = Address;
+ return 0;
}
+static BOOL gdb_attached_yet = FALSE;
/*
* This function does all command procesing for interfacing to gdb.
*/
BOOLEAN Stepping;
LONG Address;
LONG Length;
- LONG SigVal;
+ LONG SigVal = 0;
LONG NewPC;
PCHAR ptr;
- LONG Esp;
/* FIXME: Stop on other CPUs too */
/* Disable hardware debugging while we are inside the stub */
{
GspAccessLocation = NULL;
GspMemoryError = TRUE;
- TrapFrame->Eip += 2;
+ Context->Eip += 3;
}
else
{
- /* Don't switch threads */
+ /* Can only debug 1 thread at a time... */
+ ExAcquireFastMutex(&GspLock);
- /* Always use the current thread when entering the exception handler */
+ /* Make sure we're debugging the current thread. */
if (NULL != GspDbgThread)
{
+ DPRINT1("Internal error: entering stub with non-NULL GspDbgThread\n");
ObDereferenceObject(GspDbgThread);
GspDbgThread = NULL;
}
- /* 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++ = ':';
-
- Esp = GspGetEspFromTrapFrame (TrapFrame); /* SP */
- ptr = GspMem2Hex ((PCHAR) &Esp, ptr, 4, 0);
- *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]);
-
+ /* ugly hack to avoid attempting to send status at the very
+ * beginning, right when GDB is trying to query the stub */
+ if (gdb_attached_yet)
+ {
+ LONG Esp;
+
+ stop_reply:
+ /* reply to host that an exception has occurred */
+ SigVal = GspComputeSignal(ExceptionRecord->ExceptionCode);
+
+ ptr = GspOutBuffer;
+
+ *ptr++ = 'T'; /* notify gdb with signo, PC, FP and SP */
+ *ptr++ = HexChars[(SigVal >> 4) & 0xf];
+ *ptr++ = HexChars[SigVal & 0xf];
+
+ *ptr++ = HexChars[ESP];
+ *ptr++ = ':';
+
+ Esp = GspGetEspFromTrapFrame(TrapFrame); /* SP */
+ ptr = GspMem2Hex((PCHAR) &Esp, ptr, 4, 0);
+ *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]);
+ }
+ else
+ {
+ gdb_attached_yet = 1;
+ }
+
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 ();
+ memset(GspOutBuffer, 0, sizeof(GspInBuffer));
+ ptr = GspGetPacket();
- switch (*ptr++)
+ switch(*ptr++)
{
case '?':
+ /* a little hack to send more complete status information */
+ goto stop_reply;
GspOutBuffer[0] = 'S';
GspOutBuffer[1] = HexChars[SigVal >> 4];
GspOutBuffer[2] = HexChars[SigVal % 16];
case 'd':
GspRemoteDebug = !GspRemoteDebug; /* toggle debug flag */
break;
- case 'g': /* return the value of the CPU Registers */
- if (NULL != GspDbgThread)
- {
- GspGetRegistersFromTrapFrame (&GspOutBuffer[0], Context, GspDbgThread->Tcb.TrapFrame);
- }
- else
- {
- GspGetRegistersFromTrapFrame (&GspOutBuffer[0], Context, TrapFrame);
- }
+ case 'g': /* return the value of the CPU Registers */
+ GspGetRegisters(GspOutBuffer, TrapFrame);
break;
- case 'G': /* set the value of the CPU Registers - return OK */
+ case 'G': /* set the value of the CPU Registers - return OK */
if (NULL != GspDbgThread)
{
- GspSetRegistersInTrapFrame (ptr, Context, GspDbgThread->Tcb.TrapFrame);
+ GspSetRegistersInTrapFrame(ptr, Context, GspDbgThread->Tcb.TrapFrame);
}
else
{
- GspSetRegistersInTrapFrame (ptr, Context, TrapFrame);
+ GspSetRegistersInTrapFrame(ptr, Context, TrapFrame);
}
- strcpy (GspOutBuffer, "OK");
+ strcpy(GspOutBuffer, "OK");
break;
- case 'P': /* set the value of a single CPU register - return OK */
+ 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);
- }
- else
- {
- GspSetSingleRegisterInTrapFrame (ptr, Register, Context, TrapFrame);
- }
- strcpy (GspOutBuffer, "OK");
- break;
- }
+ if ((GspHex2Long(&ptr, &Register)) && (*ptr++ == '='))
+ {
+ if ((Register >= 0) && (Register < NUMREGS))
+ {
+ if (GspDbgThread)
+ {
+ GspSetSingleRegisterInTrapFrame(ptr, Register,
+ Context,
+ GspDbgThread->Tcb.TrapFrame);
+ }
+ else
+ {
+ GspSetSingleRegisterInTrapFrame(ptr, Register,
+ Context, TrapFrame);
+ }
+ strcpy(GspOutBuffer, "OK");
+ break;
+ }
+ }
- strcpy (GspOutBuffer, "E01");
+ 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))
+ if (GspHex2Long(&ptr, &Address) &&
+ *(ptr++) == ',' &&
+ GspHex2Long(&ptr, &Length))
+ {
+ PEPROCESS DbgProcess = NULL;
+
+ ptr = NULL;
+ if (NULL != GspDbgThread &&
+ PsGetCurrentProcess() != GspDbgThread->ThreadsProcess)
{
- ptr = 0;
- GspMemoryError = FALSE;
- GspMem2Hex ((PCHAR) Address, GspOutBuffer, Length, 1);
- if (GspMemoryError)
- {
- strcpy (GspOutBuffer, "E03");
- DPRINT ("Fault during memory read\n");
- }
+ DbgProcess = GspDbgThread->ThreadsProcess;
+ KeAttachProcess(&DbgProcess->Pcb);
}
+ GspMemoryError = FALSE;
+ GspMem2Hex((PCHAR) Address, GspOutBuffer, Length, 1);
+ if (NULL != DbgProcess)
+ {
+ KeDetachProcess();
+ }
+ if (GspMemoryError)
+ {
+ strcpy(GspOutBuffer, "E03");
+ DPRINT("Fault during memory read\n");
+ }
+ }
- if (ptr)
- strcpy (GspOutBuffer, "E01");
+ if (NULL != 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 (GspHex2Long(&ptr, &Address))
+ {
+ if (*(ptr++) == ',' &&
+ GspHex2Long(&ptr, &Length) &&
+ *(ptr++) == ':')
+ {
+ PEPROCESS DbgProcess = NULL;
- if (GspMemoryError)
- {
- strcpy (GspOutBuffer, "E03");
- DPRINT ("Fault during memory write\n");
- }
- else
- {
- strcpy (GspOutBuffer, "OK");
- }
+ if (NULL != GspDbgThread &&
+ PsGetCurrentProcess() != GspDbgThread->ThreadsProcess)
+ {
+ DbgProcess = GspDbgThread->ThreadsProcess;
+ KeAttachProcess(&DbgProcess->Pcb);
+ }
+ GspMemoryError = FALSE;
+ GspHex2Mem(ptr, (PCHAR) Address, Length, TRUE);
+ if (NULL != DbgProcess)
+ {
+ KeDetachProcess();
+ }
+ if (GspMemoryError)
+ {
+ strcpy(GspOutBuffer, "E03");
+ DPRINT("Fault during memory write\n");
+ }
+ else
+ {
+ strcpy(GspOutBuffer, "OK");
+ }
+ ptr = NULL;
+ }
+ }
- ptr = NULL;
- }
- if (ptr)
- strcpy (GspOutBuffer, "E02");
+ if (NULL != ptr)
+ {
+ strcpy(GspOutBuffer, "E02");
+ }
break;
/* cAA..AA Continue at address AA..AA(optional) */
/* try to read optional parameter, pc unchanged if no parm */
if (GspHex2Long (&ptr, &Address))
- Context->Eip = Address;
+ {
+ Context->Eip = Address;
+ }
NewPC = Context->Eip;
/* set the trace bit if we're Stepping */
if (Stepping)
- Context->EFlags |= 0x100;
+ {
+ Context->EFlags |= 0x100;
+ }
#if defined(__GNUC__)
asm volatile ("movl %%db6, %0\n" : "=r" (dr6_) : );
#error Unknown compiler for inline assembler
#endif
- KeContextToTrapFrame(Context, TrapFrame);
- return ((SigVal == 5) ? (kdContinue) : (kdHandleException));
+ if (NULL != GspDbgThread)
+ {
+ ObDereferenceObject(GspDbgThread);
+ GspDbgThread = NULL;
+ }
+
+ ExReleaseFastMutex(&GspLock);
+ return kdContinue;
break;
}
- case 'k': /* kill the program */
- strcpy (GspOutBuffer, "OK");
+ case 'k': /* kill the program */
+ strcpy(GspOutBuffer, "OK");
break;
/* kill the program */
- case 'H': /* Set thread */
- GspSetThread (ptr);
+ case 'H': /* Set thread */
+ GspSetThread(ptr);
break;
case 'q': /* Query */
- GspQuery (ptr);
+ GspQuery(ptr);
break;
case 'T': /* Query thread status */
- GspQueryThreadStatus (ptr);
+ GspQueryThreadStatus(ptr);
break;
case 'Y':
LONG Address;
ptr = &GspOutBuffer[1];
- GspHex2Long (&ptr, &Number);
+ GspHex2Long(&ptr, &Number);
ptr++;
- GspHex2Long (&ptr, &Type);
+ GspHex2Long(&ptr, &Type);
ptr++;
- GspHex2Long (&ptr, &Length);
+ GspHex2Long(&ptr, &Length);
ptr++;
- GspHex2Long (&ptr, &Address);
- if (GspSetHwBreakpoint (Number & 0x3, Type & 0x3 , Length & 0x3, Address) == 0)
+ GspHex2Long(&ptr, &Address);
+ if (GspSetHwBreakpoint(Number & 0x3, Type & 0x3 , Length & 0x3, Address) == 0)
{
- strcpy (GspOutBuffer, "OK");
+ strcpy(GspOutBuffer, "OK");
}
else
{
- strcpy (GspOutBuffer, "E");
+ strcpy(GspOutBuffer, "E");
}
break;
}
ptr = &GspOutBuffer[1];
GspHex2Long(&ptr, &Number);
- if (GspRemoveHwBreakpoint (Number & 0x3) == 0)
+ if (GspRemoveHwBreakpoint(Number & 0x3) == 0)
{
- strcpy (GspOutBuffer, "OK");
+ strcpy(GspOutBuffer, "OK");
}
else
{
- strcpy (GspOutBuffer, "E");
+ strcpy(GspOutBuffer, "E");
}
break;
}
default:
break;
- } /* switch */
+ }
/* reply to the request */
- GspPutPacket (&GspOutBuffer[0]);
+ GspPutPacket(&GspOutBuffer[0]);
}
/* not reached */
ASSERT(0);
}
- return kdDoNotHandleException;
+ if (NULL != GspDbgThread)
+ {
+ ObDereferenceObject(GspDbgThread);
+ GspDbgThread = NULL;
+ }
+
+ return kdContinue;
}
KIRQL OldIrql;
UCHAR Value;
- DPRINT ("Break In\n");
+ DPRINT("Break In\n");
DoBreakIn = FALSE;
- while (KdPortGetByteEx (&GdbPortInfo, &Value))
+ while (KdPortGetByteEx(&GdbPortInfo, &Value))
{
if (Value == 0x03)
- DoBreakIn = TRUE;
+ {
+ DoBreakIn = TRUE;
+ }
}
if (!DoBreakIn)
- return TRUE;
+ {
+ return TRUE;
+ }
- KeRaiseIrql (HIGH_LEVEL, &OldIrql);
+ KeRaiseIrql(HIGH_LEVEL, &OldIrql);
TrapFrame = PsGetCurrentThread()->Tcb.TrapFrame;
- KeTrapFrameToContext (TrapFrame, &Context);
+ KeTrapFrameToContext(TrapFrame, NULL, &Context);
- KdpGdbEnterDebuggerException (NULL, &Context, TrapFrame);
+ KdpGdbEnterDebuggerException(NULL, &Context, TrapFrame);
- KeContextToTrapFrame (&Context, TrapFrame);
+ KeContextToTrapFrame(&Context, NULL, TrapFrame, KernelMode);
- KeLowerIrql (OldIrql);
+ KeLowerIrql(OldIrql);
return TRUE;
}
-
-extern ULONG KdpPortIrq;
-
-
VOID
STDCALL
-KdpGdbDebugPrint(PCH Message)
+KdpGdbDebugPrint(PCH Message, ULONG Length)
{
-#if 0
- /* This can be quite annoying! */
- if (GspInitialized)
- {
- ULONG Length;
-
- GspOutBuffer[0] = 'O';
- GspOutBuffer[1] = '\0';
- strcat (&GspOutBuffer[0], Message);
- Length = strlen (Message);
- GspOutBuffer[2 + Length] = '\n';
- GspOutBuffer[3 + Length] = '\0';
- GspPutPacketNoWait (&GspOutBuffer[0]);
- }
-#endif
-}
-
-
-extern LIST_ENTRY ModuleListHead;
-
-VOID
-KdGdbListModules()
-{
- PLIST_ENTRY CurrentEntry;
- PMODULE_OBJECT Current;
- ULONG ModuleCount;
-
- DPRINT1("\n");
-
- ModuleCount = 0;
-
- CurrentEntry = ModuleListHead.Flink;
- while (CurrentEntry != (&ModuleListHead))
- {
- Current = CONTAINING_RECORD (CurrentEntry, MODULE_OBJECT, ListEntry);
-
- DbgPrint ("Module %S Base 0x%.08x Length 0x%.08x\n",
- Current->BaseName.Buffer, Current->Base, Current->Length);
-
- ModuleCount++;
- CurrentEntry = CurrentEntry->Flink;
- }
-
- DbgPrint ("%d modules listed\n", ModuleCount);
}
/* Initialize the GDB stub */
KdpGdbStubInit(PKD_DISPATCH_TABLE WrapperTable,
ULONG BootPhase)
{
- if (!KdDebuggerEnabled || !KdpDebugMode.Gdb) return;
+ if (!KdDebuggerEnabled || !KdpDebugMode.Gdb)
+ {
+ return;
+ }
- if (BootPhase == 0)
+ if (BootPhase == 0)
{
+ ExInitializeFastMutex(&GspLock);
+
/* Write out the functions that we support for now */
WrapperTable->KdpInitRoutine = KdpGdbStubInit;
WrapperTable->KdpPrintRoutine = KdpGdbDebugPrint;
/* Initialize the Port */
KdPortInitializeEx(&GdbPortInfo, 0, 0);
}
- else if (BootPhase == 1)
+ else if (BootPhase == 1)
{
GspInitialized = TRUE;
HalDisplayString("Waiting for GDB to attach\n");
DbgPrint("Module 'hal.dll' loaded at 0x%.08x.\n", LdrHalBase);
- DbgBreakPointWithStatus (DBG_STATUS_CONTROL_C);
+ DbgBreakPointWithStatus(DBG_STATUS_CONTROL_C);
}
- else if (BootPhase == 2)
+ else if (BootPhase == 2)
{
HalDisplayString("\n GDB debugging enabled\n\n");
}