mirror of
https://github.com/reactos/reactos.git
synced 2025-08-03 00:27:13 +00:00
[FORMATTING]
svn path=/trunk/; revision=41537
This commit is contained in:
parent
1fcd100e50
commit
d103f7f548
1 changed files with 935 additions and 1016 deletions
|
@ -100,27 +100,21 @@ static PCHAR GspThreadStates[DeferredReady+1] =
|
||||||
"DeferredReady"
|
"DeferredReady"
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
LONG
|
LONG
|
||||||
HexValue(CHAR ch)
|
HexValue(CHAR ch)
|
||||||
{
|
{
|
||||||
if ((ch >= '0') && (ch <= '9'))
|
if ((ch >= '0') && (ch <= '9'))
|
||||||
{
|
|
||||||
return (ch - '0');
|
return (ch - '0');
|
||||||
}
|
|
||||||
if ((ch >= 'a') && (ch <= 'f'))
|
if ((ch >= 'a') && (ch <= 'f'))
|
||||||
{
|
|
||||||
return (ch - 'a' + 10);
|
return (ch - 'a' + 10);
|
||||||
}
|
|
||||||
if ((ch >= 'A') && (ch <= 'F'))
|
if ((ch >= 'A') && (ch <= 'F'))
|
||||||
{
|
|
||||||
return (ch - 'A' + 10);
|
return (ch - 'A' + 10);
|
||||||
}
|
|
||||||
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
GdbPutChar(UCHAR Value)
|
GdbPutChar(UCHAR Value)
|
||||||
{
|
{
|
||||||
|
@ -164,13 +158,11 @@ GspGetPacket()
|
||||||
{
|
{
|
||||||
ch = GdbGetChar();
|
ch = GdbGetChar();
|
||||||
if (ch == '$')
|
if (ch == '$')
|
||||||
{
|
|
||||||
goto retry;
|
goto retry;
|
||||||
}
|
|
||||||
if (ch == '#')
|
if (ch == '#')
|
||||||
{
|
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
Checksum = Checksum + ch;
|
Checksum = Checksum + ch;
|
||||||
Buffer[Count] = ch;
|
Buffer[Count] = ch;
|
||||||
Count = Count + 1;
|
Count = Count + 1;
|
||||||
|
@ -191,7 +183,6 @@ GspGetPacket()
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
GdbPutChar('+'); /* successful transfer */
|
GdbPutChar('+'); /* successful transfer */
|
||||||
|
|
||||||
return &Buffer[0];
|
return &Buffer[0];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -227,7 +218,6 @@ GspPutPacket(PCHAR Buffer)
|
||||||
while (GdbGetChar() != '+');
|
while (GdbGetChar() != '+');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
GspPutPacketNoWait(PCHAR Buffer)
|
GspPutPacketNoWait(PCHAR Buffer)
|
||||||
{
|
{
|
||||||
|
@ -259,8 +249,10 @@ static CHAR
|
||||||
GspReadMemSafe(PCHAR Address)
|
GspReadMemSafe(PCHAR Address)
|
||||||
{
|
{
|
||||||
CHAR ch = 0;
|
CHAR ch = 0;
|
||||||
|
|
||||||
if (!KdpSafeReadMemory((ULONG_PTR)Address, 1, &ch))
|
if (!KdpSafeReadMemory((ULONG_PTR)Address, 1, &ch))
|
||||||
GspMemoryError = TRUE;
|
GspMemoryError = TRUE;
|
||||||
|
|
||||||
return ch;
|
return ch;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -271,15 +263,13 @@ GspWriteMemSafe(PCHAR Address, CHAR Ch)
|
||||||
GspMemoryError = TRUE;
|
GspMemoryError = TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Convert the memory pointed to by Address into hex, placing result in Buffer */
|
/* Convert the memory pointed to by Address into hex, placing result in Buffer
|
||||||
/* Return a pointer to the last char put in Buffer (null) */
|
* Return a pointer to the last char put in Buffer (null)
|
||||||
/* If MayFault is TRUE, then we should set GspMemoryError in response to
|
* 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. */
|
* a fault; if FALSE treat a fault like any other fault in the stub.
|
||||||
|
*/
|
||||||
static PCHAR
|
static PCHAR
|
||||||
GspMem2Hex(PCHAR Address,
|
GspMem2Hex(PCHAR Address, PCHAR Buffer, LONG Count, BOOLEAN MayFault)
|
||||||
PCHAR Buffer,
|
|
||||||
LONG Count,
|
|
||||||
BOOLEAN MayFault)
|
|
||||||
{
|
{
|
||||||
ULONG i;
|
ULONG i;
|
||||||
CHAR ch;
|
CHAR ch;
|
||||||
|
@ -290,10 +280,8 @@ GspMem2Hex(PCHAR Address,
|
||||||
{
|
{
|
||||||
ch = GspReadMemSafe(Address);
|
ch = GspReadMemSafe(Address);
|
||||||
if (GspMemoryError)
|
if (GspMemoryError)
|
||||||
{
|
|
||||||
return Buffer;
|
return Buffer;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ch = *Address;
|
ch = *Address;
|
||||||
|
@ -308,11 +296,8 @@ GspMem2Hex(PCHAR Address,
|
||||||
}
|
}
|
||||||
|
|
||||||
static ULONG
|
static ULONG
|
||||||
GspWriteMem(PCHAR Address,
|
GspWriteMem(PCHAR Address, ULONG Count, BOOLEAN MayFault,
|
||||||
ULONG Count,
|
CHAR (*GetContent)(PVOID Context, ULONG Offset), PVOID Context)
|
||||||
BOOLEAN MayFault,
|
|
||||||
CHAR (*GetContent)(PVOID Context, ULONG Offset),
|
|
||||||
PVOID Context)
|
|
||||||
{
|
{
|
||||||
PCHAR Current;
|
PCHAR Current;
|
||||||
PCHAR Page;
|
PCHAR Page;
|
||||||
|
@ -340,24 +325,18 @@ GspWriteMem(PCHAR Address,
|
||||||
ch = (*GetContent)(Context, Current - Address);
|
ch = (*GetContent)(Context, Current - Address);
|
||||||
|
|
||||||
if (MayFault)
|
if (MayFault)
|
||||||
{
|
|
||||||
GspWriteMemSafe(Current, ch);
|
GspWriteMemSafe(Current, ch);
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
|
||||||
*Current = ch;
|
*Current = ch;
|
||||||
}
|
|
||||||
|
|
||||||
Current++;
|
Current++;
|
||||||
}
|
}
|
||||||
if (MayFault)
|
if (MayFault)
|
||||||
{
|
{
|
||||||
if (GspMemoryError)
|
if (GspMemoryError)
|
||||||
{
|
|
||||||
return Current - Address;
|
return Current - Address;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
return Current - Address;
|
return Current - Address;
|
||||||
}
|
}
|
||||||
|
@ -372,13 +351,9 @@ GspHex2MemGetContent(PVOID Context, ULONG Offset)
|
||||||
/* Convert the hex array pointed to by Buffer into binary to be placed at Address
|
/* 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 */
|
* Return a pointer to the character AFTER the last byte read from Buffer */
|
||||||
static PCHAR
|
static PCHAR
|
||||||
GspHex2Mem(PCHAR Buffer,
|
GspHex2Mem(PCHAR Buffer, PCHAR Address, ULONG Count, BOOLEAN MayFault)
|
||||||
PCHAR Address,
|
|
||||||
ULONG Count,
|
|
||||||
BOOLEAN MayFault)
|
|
||||||
{
|
{
|
||||||
Count = GspWriteMem(Address, Count, MayFault, GspHex2MemGetContent, Buffer);
|
Count = GspWriteMem(Address, Count, MayFault, GspHex2MemGetContent, Buffer);
|
||||||
|
|
||||||
return Buffer + 2 * Count;
|
return Buffer + 2 * Count;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -387,8 +362,7 @@ GspHex2Mem(PCHAR Buffer,
|
||||||
/* RETURN NUMBER OF CHARS PROCESSED */
|
/* RETURN NUMBER OF CHARS PROCESSED */
|
||||||
/**********************************************/
|
/**********************************************/
|
||||||
LONG
|
LONG
|
||||||
GspHex2Long(PCHAR *Address,
|
GspHex2Long(PCHAR *Address, PLONG Value)
|
||||||
PLONG Value)
|
|
||||||
{
|
{
|
||||||
LONG NumChars = 0;
|
LONG NumChars = 0;
|
||||||
LONG Hex;
|
LONG Hex;
|
||||||
|
@ -414,21 +388,17 @@ GspHex2Long(PCHAR *Address,
|
||||||
return NumChars;
|
return NumChars;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
GspLong2Hex(PCHAR *Address,
|
GspLong2Hex(PCHAR *Address, LONG Value)
|
||||||
LONG Value)
|
|
||||||
{
|
{
|
||||||
LONG Save;
|
LONG Save;
|
||||||
|
|
||||||
Save = (((Value >> 0) & 0xff) << 24) |
|
Save = (((Value >> 0) & 0xff) << 24) | (((Value >> 8) & 0xff) << 16) |
|
||||||
(((Value >> 8) & 0xff) << 16) |
|
(((Value >> 16) & 0xff) << 8) | (((Value >> 24) & 0xff) << 0);
|
||||||
(((Value >> 16) & 0xff) << 8) |
|
|
||||||
(((Value >> 24) & 0xff) << 0);
|
|
||||||
*Address = GspMem2Hex((PCHAR)&Save, *Address, 4, FALSE);
|
*Address = GspMem2Hex((PCHAR)&Save, *Address, 4, FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* When coming from kernel mode, Esp is not stored in the trap frame.
|
* When coming from kernel mode, Esp is not stored in the trap frame.
|
||||||
* Instead, it was pointing to the location of the TrapFrame Esp member
|
* Instead, it was pointing to the location of the TrapFrame Esp member
|
||||||
|
@ -438,14 +408,12 @@ GspLong2Hex(PCHAR *Address,
|
||||||
static LONG
|
static LONG
|
||||||
GspGetEspFromTrapFrame(PKTRAP_FRAME TrapFrame)
|
GspGetEspFromTrapFrame(PKTRAP_FRAME TrapFrame)
|
||||||
{
|
{
|
||||||
return KeGetPreviousMode() == KernelMode
|
return KeGetPreviousMode() == KernelMode ?
|
||||||
? (LONG) &TrapFrame->HardwareEsp : (LONG)TrapFrame->HardwareEsp;
|
(LONG)&TrapFrame->HardwareEsp : (LONG)TrapFrame->HardwareEsp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static VOID
|
static VOID
|
||||||
GspGetRegisters(PCHAR Address,
|
GspGetRegisters(PCHAR Address, PKTRAP_FRAME TrapFrame)
|
||||||
PKTRAP_FRAME TrapFrame)
|
|
||||||
{
|
{
|
||||||
ULONG_PTR Value;
|
ULONG_PTR Value;
|
||||||
PULONG p;
|
PULONG p;
|
||||||
|
@ -498,8 +466,8 @@ GspGetRegisters(PCHAR Address,
|
||||||
Value = 0;
|
Value = 0;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
Address = GspMem2Hex((PCHAR) &Value, Address, GspRegisters[i].Size,
|
|
||||||
FALSE);
|
Address = GspMem2Hex((PCHAR)&Value, Address, GspRegisters[i].Size, FALSE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -514,8 +482,7 @@ GspGetRegisters(PCHAR Address,
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
p = (PULONG)((ULONG_PTR) TrapFrame +
|
p = (PULONG)((ULONG_PTR)TrapFrame + GspRegisters[i].OffsetInTF);
|
||||||
GspRegisters[i].OffsetInTF);
|
|
||||||
Value = *p;
|
Value = *p;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -531,17 +498,14 @@ GspGetRegisters(PCHAR Address,
|
||||||
{
|
{
|
||||||
Value = 0;
|
Value = 0;
|
||||||
}
|
}
|
||||||
Address = GspMem2Hex((PCHAR) &Value, Address,
|
|
||||||
GspRegisters[i].Size, FALSE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
Address = GspMem2Hex((PCHAR)&Value, Address, GspRegisters[i].Size, FALSE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
GspSetRegistersInTrapFrame(PCHAR Address,
|
GspSetRegistersInTrapFrame(PCHAR Address, PCONTEXT Context, PKTRAP_FRAME TrapFrame)
|
||||||
PCONTEXT Context,
|
|
||||||
PKTRAP_FRAME TrapFrame)
|
|
||||||
{
|
{
|
||||||
ULONG Value;
|
ULONG Value;
|
||||||
PCHAR Buffer;
|
PCHAR Buffer;
|
||||||
|
@ -549,9 +513,7 @@ GspSetRegistersInTrapFrame(PCHAR Address,
|
||||||
ULONG i;
|
ULONG i;
|
||||||
|
|
||||||
if (!TrapFrame)
|
if (!TrapFrame)
|
||||||
{
|
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
Buffer = Address;
|
Buffer = Address;
|
||||||
for (i = 0; i < NUMREGS; i++)
|
for (i = 0; i < NUMREGS; i++)
|
||||||
|
@ -564,26 +526,21 @@ GspSetRegistersInTrapFrame(PCHAR Address,
|
||||||
{
|
{
|
||||||
p = (PULONG)((ULONG_PTR)TrapFrame + GspRegisters[i].OffsetInTF);
|
p = (PULONG)((ULONG_PTR)TrapFrame + GspRegisters[i].OffsetInTF);
|
||||||
}
|
}
|
||||||
|
|
||||||
Value = 0;
|
Value = 0;
|
||||||
Buffer = GspHex2Mem(Buffer, (PCHAR)&Value, GspRegisters[i].Size, FALSE);
|
Buffer = GspHex2Mem(Buffer, (PCHAR)&Value, GspRegisters[i].Size, FALSE);
|
||||||
*p = Value;
|
*p = Value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
GspSetSingleRegisterInTrapFrame(PCHAR Address,
|
GspSetSingleRegisterInTrapFrame(PCHAR Address, LONG Number, PCONTEXT Context, PKTRAP_FRAME TrapFrame)
|
||||||
LONG Number,
|
|
||||||
PCONTEXT Context,
|
|
||||||
PKTRAP_FRAME TrapFrame)
|
|
||||||
{
|
{
|
||||||
ULONG Value;
|
ULONG Value;
|
||||||
PULONG p;
|
PULONG p;
|
||||||
|
|
||||||
if (!TrapFrame)
|
if (!TrapFrame)
|
||||||
{
|
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
if (GspRegisters[Number].SetInContext)
|
if (GspRegisters[Number].SetInContext)
|
||||||
{
|
{
|
||||||
|
@ -593,15 +550,14 @@ GspSetSingleRegisterInTrapFrame(PCHAR Address,
|
||||||
{
|
{
|
||||||
p = (PULONG)((ULONG_PTR)TrapFrame + GspRegisters[Number].OffsetInTF);
|
p = (PULONG)((ULONG_PTR)TrapFrame + GspRegisters[Number].OffsetInTF);
|
||||||
}
|
}
|
||||||
|
|
||||||
Value = 0;
|
Value = 0;
|
||||||
GspHex2Mem(Address, (PCHAR)&Value, GspRegisters[Number].Size, FALSE);
|
GspHex2Mem(Address, (PCHAR)&Value, GspRegisters[Number].Size, FALSE);
|
||||||
*p = Value;
|
*p = Value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
BOOLEAN
|
BOOLEAN
|
||||||
GspFindThread(PCHAR Data,
|
GspFindThread(PCHAR Data, PETHREAD *Thread)
|
||||||
PETHREAD *Thread)
|
|
||||||
{
|
{
|
||||||
PETHREAD ThreadInfo = NULL;
|
PETHREAD ThreadInfo = NULL;
|
||||||
|
|
||||||
|
@ -625,11 +581,11 @@ GspFindThread(PCHAR Data,
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
*Thread = ThreadInfo;
|
*Thread = ThreadInfo;
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
GspSetThread(PCHAR Request)
|
GspSetThread(PCHAR Request)
|
||||||
{
|
{
|
||||||
|
@ -645,20 +601,19 @@ GspSetThread(PCHAR Request)
|
||||||
GspOutBuffer[1] = 'K';
|
GspOutBuffer[1] = 'K';
|
||||||
|
|
||||||
if (NULL != GspRunThread)
|
if (NULL != GspRunThread)
|
||||||
{
|
|
||||||
ObDereferenceObject(GspRunThread);
|
ObDereferenceObject(GspRunThread);
|
||||||
}
|
|
||||||
GspRunThread = ThreadInfo;
|
GspRunThread = ThreadInfo;
|
||||||
|
|
||||||
if (NULL != GspRunThread)
|
if (NULL != GspRunThread)
|
||||||
{
|
|
||||||
ObReferenceObject(GspRunThread);
|
ObReferenceObject(GspRunThread);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
GspOutBuffer[0] = 'E';
|
GspOutBuffer[0] = 'E';
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'g': /* Debug thread */
|
case 'g': /* Debug thread */
|
||||||
if (GspFindThread(ptr, &ThreadInfo))
|
if (GspFindThread(ptr, &ThreadInfo))
|
||||||
{
|
{
|
||||||
|
@ -666,9 +621,7 @@ GspSetThread(PCHAR Request)
|
||||||
GspOutBuffer[1] = 'K';
|
GspOutBuffer[1] = 'K';
|
||||||
|
|
||||||
if (NULL != GspDbgThread)
|
if (NULL != GspDbgThread)
|
||||||
{
|
|
||||||
ObDereferenceObject(GspDbgThread);
|
ObDereferenceObject(GspDbgThread);
|
||||||
}
|
|
||||||
|
|
||||||
if (ThreadInfo == PsGetCurrentThread())
|
if (ThreadInfo == PsGetCurrentThread())
|
||||||
{
|
{
|
||||||
|
@ -685,12 +638,12 @@ GspSetThread(PCHAR Request)
|
||||||
GspOutBuffer[0] = 'E';
|
GspOutBuffer[0] = 'E';
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
GspQuery(PCHAR Request)
|
GspQuery(PCHAR Request)
|
||||||
{
|
{
|
||||||
|
@ -703,14 +656,12 @@ GspQuery(PCHAR Request)
|
||||||
/* Get current thread id */
|
/* Get current thread id */
|
||||||
GspOutBuffer[0] = 'Q';
|
GspOutBuffer[0] = 'Q';
|
||||||
GspOutBuffer[1] = 'C';
|
GspOutBuffer[1] = 'C';
|
||||||
|
|
||||||
if (NULL != GspDbgThread)
|
if (NULL != GspDbgThread)
|
||||||
{
|
|
||||||
Value = (ULONG)GspDbgThread->Cid.UniqueThread;
|
Value = (ULONG)GspDbgThread->Cid.UniqueThread;
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
|
||||||
Value = (ULONG)PsGetCurrentThread()->Cid.UniqueThread;
|
Value = (ULONG)PsGetCurrentThread()->Cid.UniqueThread;
|
||||||
}
|
|
||||||
GspLong2Hex(&ptr, Value);
|
GspLong2Hex(&ptr, Value);
|
||||||
}
|
}
|
||||||
else if (strncmp(Request, "fThreadInfo", 11) == 0)
|
else if (strncmp(Request, "fThreadInfo", 11) == 0)
|
||||||
|
@ -812,14 +763,14 @@ GspQuery(PCHAR Request)
|
||||||
Proc = (PEPROCESS)ThreadInfo->ThreadsProcess;
|
Proc = (PEPROCESS)ThreadInfo->ThreadsProcess;
|
||||||
|
|
||||||
Buffer[0] = '\0';
|
Buffer[0] = '\0';
|
||||||
|
|
||||||
if (NULL != Proc)
|
if (NULL != Proc)
|
||||||
{
|
sprintf(Buffer, "%s [%d:0x%x], ",
|
||||||
sprintf(Buffer, "%s [%d:0x%x], ", Proc->ImageFileName,
|
Proc->ImageFileName,
|
||||||
(int)Proc->UniqueProcessId,
|
(int)Proc->UniqueProcessId,
|
||||||
(int)ThreadInfo->Cid.UniqueThread);
|
(int)ThreadInfo->Cid.UniqueThread);
|
||||||
}
|
|
||||||
strcpy(Buffer + strlen(Buffer),
|
strcpy(Buffer + strlen(Buffer), GspThreadStates[ThreadInfo->Tcb.State]);
|
||||||
GspThreadStates[ThreadInfo->Tcb.State]);
|
|
||||||
|
|
||||||
ObDereferenceObject(ThreadInfo);
|
ObDereferenceObject(ThreadInfo);
|
||||||
|
|
||||||
|
@ -939,8 +890,7 @@ GspSetHwBreakpoint(ULONG Type, ULONG_PTR Address, ULONG Length)
|
||||||
}
|
}
|
||||||
else if (0 != (Address & (Length - 1)))
|
else if (0 != (Address & (Length - 1)))
|
||||||
{
|
{
|
||||||
DPRINT1("Invalid alignment for address 0x%p and length %d\n",
|
DPRINT1("Invalid alignment for address 0x%p and length %d\n", Address, Length);
|
||||||
Address, Length);
|
|
||||||
strcpy(GspOutBuffer, "E22");
|
strcpy(GspOutBuffer, "E22");
|
||||||
}
|
}
|
||||||
else if (MAX_HW_BREAKPOINTS == GspHwBreakpointCount)
|
else if (MAX_HW_BREAKPOINTS == GspHwBreakpointCount)
|
||||||
|
@ -973,12 +923,10 @@ GspRemoveHwBreakpoint(ULONG Type, ULONG_PTR Address, ULONG Length)
|
||||||
{
|
{
|
||||||
DPRINT("Found match at index %u\n", Index);
|
DPRINT("Found match at index %u\n", Index);
|
||||||
if (Index + 1 < GspHwBreakpointCount)
|
if (Index + 1 < GspHwBreakpointCount)
|
||||||
{
|
|
||||||
memmove(GspHwBreakpoints + Index,
|
memmove(GspHwBreakpoints + Index,
|
||||||
GspHwBreakpoints + (Index + 1),
|
GspHwBreakpoints + (Index + 1),
|
||||||
(GspHwBreakpointCount - Index - 1) *
|
(GspHwBreakpointCount - Index - 1) * sizeof(GSPHWBREAKPOINT));
|
||||||
sizeof(GSPHWBREAKPOINT));
|
|
||||||
}
|
|
||||||
GspHwBreakpointCount--;
|
GspHwBreakpointCount--;
|
||||||
strcpy(GspOutBuffer, "OK");
|
strcpy(GspOutBuffer, "OK");
|
||||||
return;
|
return;
|
||||||
|
@ -997,7 +945,8 @@ GspFindSwBreakpoint(ULONG_PTR Address, PULONG PIndex)
|
||||||
for (Index = 0; Index < GspSwBreakpointCount; Index++)
|
for (Index = 0; Index < GspSwBreakpointCount; Index++)
|
||||||
if (GspSwBreakpoints[Index].Address == Address)
|
if (GspSwBreakpoints[Index].Address == Address)
|
||||||
{
|
{
|
||||||
if (PIndex) *PIndex = Index;
|
if (PIndex)
|
||||||
|
*PIndex = Index;
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1042,12 +991,10 @@ GspRemoveSwBreakpoint(ULONG_PTR Address)
|
||||||
ASSERT(!GspSwBreakpoints[Index].Active);
|
ASSERT(!GspSwBreakpoints[Index].Active);
|
||||||
|
|
||||||
if (Index + 1 < GspSwBreakpointCount)
|
if (Index + 1 < GspSwBreakpointCount)
|
||||||
{
|
|
||||||
memmove(GspSwBreakpoints + Index,
|
memmove(GspSwBreakpoints + Index,
|
||||||
GspSwBreakpoints + (Index + 1),
|
GspSwBreakpoints + (Index + 1),
|
||||||
(GspSwBreakpointCount - Index - 1) *
|
(GspSwBreakpointCount - Index - 1) * sizeof(GSPSWBREAKPOINT));
|
||||||
sizeof(GSPSWBREAKPOINT));
|
|
||||||
}
|
|
||||||
GspSwBreakpointCount--;
|
GspSwBreakpointCount--;
|
||||||
strcpy(GspOutBuffer, "OK");
|
strcpy(GspOutBuffer, "OK");
|
||||||
return;
|
return;
|
||||||
|
@ -1058,14 +1005,11 @@ GspRemoveSwBreakpoint(ULONG_PTR Address)
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
GspLoadHwBreakpoint(PKTRAP_FRAME TrapFrame,
|
GspLoadHwBreakpoint(PKTRAP_FRAME TrapFrame, unsigned BpIndex,
|
||||||
unsigned BpIndex,
|
ULONG_PTR Address, ULONG Length, ULONG Type)
|
||||||
ULONG_PTR Address,
|
|
||||||
ULONG Length,
|
|
||||||
ULONG Type)
|
|
||||||
{
|
{
|
||||||
DPRINT("GspLoadHwBreakpoint(0x%p, %d, 0x%p, %d)\n", TrapFrame, BpIndex,
|
DPRINT("GspLoadHwBreakpoint(0x%p, %d, 0x%p, %d)\n",
|
||||||
Address, Type);
|
TrapFrame, BpIndex, Address, Type);
|
||||||
|
|
||||||
/* Set the DR7_Gx bit to globally enable the breakpoint */
|
/* Set the DR7_Gx bit to globally enable the breakpoint */
|
||||||
TrapFrame->Dr7 |= DR7_GLOBAL_ENABLE(BpIndex) |
|
TrapFrame->Dr7 |= DR7_GLOBAL_ENABLE(BpIndex) |
|
||||||
|
@ -1100,22 +1044,18 @@ static void
|
||||||
GspLoadSwBreakpoint(ULONG Index)
|
GspLoadSwBreakpoint(ULONG Index)
|
||||||
{
|
{
|
||||||
GspMemoryError = FALSE;
|
GspMemoryError = FALSE;
|
||||||
|
|
||||||
GspSwBreakpoints[Index].PrevContent = GspReadMemSafe((PCHAR)GspSwBreakpoints[Index].Address);
|
GspSwBreakpoints[Index].PrevContent = GspReadMemSafe((PCHAR)GspSwBreakpoints[Index].Address);
|
||||||
|
|
||||||
if (!GspMemoryError)
|
if (!GspMemoryError)
|
||||||
{
|
|
||||||
GspWriteMemSafe((PCHAR)GspSwBreakpoints[Index].Address, I386_OPCODE_INT3);
|
GspWriteMemSafe((PCHAR)GspSwBreakpoints[Index].Address, I386_OPCODE_INT3);
|
||||||
}
|
|
||||||
GspSwBreakpoints[Index].Active = !GspMemoryError;
|
GspSwBreakpoints[Index].Active = !GspMemoryError;
|
||||||
|
|
||||||
if (GspMemoryError)
|
if (GspMemoryError)
|
||||||
{
|
DPRINT1("Failed to set software breakpoint at 0x%p\n", GspSwBreakpoints[Index].Address);
|
||||||
DPRINT1("Failed to set software breakpoint at 0x%p\n",
|
|
||||||
GspSwBreakpoints[Index].Address);
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
DPRINT("Successfully set software breakpoint at 0x%p\n", GspSwBreakpoints[Index].Address);
|
||||||
DPRINT("Successfully set software breakpoint at 0x%p\n",
|
|
||||||
GspSwBreakpoints[Index].Address);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -1257,7 +1197,6 @@ GspStopReply(NTSTATUS ExceptionCode, PKTRAP_FRAME TrapFrame)
|
||||||
*ptr = '\0';
|
*ptr = '\0';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This function does all command procesing for interfacing to GDB.
|
* This function does all command procesing for interfacing to GDB.
|
||||||
*/
|
*/
|
||||||
|
@ -1317,23 +1256,24 @@ KdpGdbEnterDebuggerException(PEXCEPTION_RECORD ExceptionRecord,
|
||||||
/* a little hack to send more complete status information */
|
/* a little hack to send more complete status information */
|
||||||
GspStopReply(ExceptionCode, TrapFrame);
|
GspStopReply(ExceptionCode, TrapFrame);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'd':
|
case 'd':
|
||||||
GspRemoteDebug = !GspRemoteDebug; /* toggle debug flag */
|
GspRemoteDebug = !GspRemoteDebug; /* toggle debug flag */
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'g': /* return the value of the CPU Registers */
|
case 'g': /* return the value of the CPU Registers */
|
||||||
GspGetRegisters(GspOutBuffer, TrapFrame);
|
GspGetRegisters(GspOutBuffer, TrapFrame);
|
||||||
break;
|
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)
|
if (NULL != GspDbgThread)
|
||||||
{
|
|
||||||
GspSetRegistersInTrapFrame(ptr, Context, GspDbgThread->Tcb.TrapFrame);
|
GspSetRegistersInTrapFrame(ptr, Context, GspDbgThread->Tcb.TrapFrame);
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
|
||||||
GspSetRegistersInTrapFrame(ptr, Context, TrapFrame);
|
GspSetRegistersInTrapFrame(ptr, Context, TrapFrame);
|
||||||
}
|
|
||||||
strcpy(GspOutBuffer, "OK");
|
strcpy(GspOutBuffer, "OK");
|
||||||
break;
|
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;
|
LONG Register;
|
||||||
|
@ -1344,14 +1284,12 @@ KdpGdbEnterDebuggerException(PEXCEPTION_RECORD ExceptionRecord,
|
||||||
{
|
{
|
||||||
if (GspDbgThread)
|
if (GspDbgThread)
|
||||||
{
|
{
|
||||||
GspSetSingleRegisterInTrapFrame(ptr, Register,
|
GspSetSingleRegisterInTrapFrame(ptr, Register, Context,
|
||||||
Context,
|
|
||||||
GspDbgThread->Tcb.TrapFrame);
|
GspDbgThread->Tcb.TrapFrame);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
GspSetSingleRegisterInTrapFrame(ptr, Register,
|
GspSetSingleRegisterInTrapFrame(ptr, Register, Context, TrapFrame);
|
||||||
Context, TrapFrame);
|
|
||||||
}
|
}
|
||||||
strcpy(GspOutBuffer, "OK");
|
strcpy(GspOutBuffer, "OK");
|
||||||
break;
|
break;
|
||||||
|
@ -1364,10 +1302,9 @@ KdpGdbEnterDebuggerException(PEXCEPTION_RECORD ExceptionRecord,
|
||||||
|
|
||||||
/* mAA..AA,LLLL Read LLLL bytes at address AA..AA */
|
/* mAA..AA,LLLL Read LLLL bytes at address AA..AA */
|
||||||
case 'm':
|
case 'm':
|
||||||
|
{
|
||||||
/* TRY TO READ %x,%x. IF SUCCEED, SET PTR = 0 */
|
/* TRY TO READ %x,%x. IF SUCCEED, SET PTR = 0 */
|
||||||
if (GspHex2Long(&ptr, &Address) &&
|
if (GspHex2Long(&ptr, &Address) && *(ptr++) == ',' && GspHex2Long(&ptr, &Length))
|
||||||
*(ptr++) == ',' &&
|
|
||||||
GspHex2Long(&ptr, &Length))
|
|
||||||
{
|
{
|
||||||
PEPROCESS DbgProcess = NULL;
|
PEPROCESS DbgProcess = NULL;
|
||||||
|
|
||||||
|
@ -1378,12 +1315,13 @@ KdpGdbEnterDebuggerException(PEXCEPTION_RECORD ExceptionRecord,
|
||||||
DbgProcess = GspDbgThread->ThreadsProcess;
|
DbgProcess = GspDbgThread->ThreadsProcess;
|
||||||
KeAttachProcess(&DbgProcess->Pcb);
|
KeAttachProcess(&DbgProcess->Pcb);
|
||||||
}
|
}
|
||||||
|
|
||||||
GspMemoryError = FALSE;
|
GspMemoryError = FALSE;
|
||||||
GspMem2Hex((PCHAR)Address, GspOutBuffer, Length, 1);
|
GspMem2Hex((PCHAR)Address, GspOutBuffer, Length, 1);
|
||||||
|
|
||||||
if (NULL != DbgProcess)
|
if (NULL != DbgProcess)
|
||||||
{
|
|
||||||
KeDetachProcess();
|
KeDetachProcess();
|
||||||
}
|
|
||||||
if (GspMemoryError)
|
if (GspMemoryError)
|
||||||
{
|
{
|
||||||
strcpy(GspOutBuffer, "E03");
|
strcpy(GspOutBuffer, "E03");
|
||||||
|
@ -1392,19 +1330,18 @@ KdpGdbEnterDebuggerException(PEXCEPTION_RECORD ExceptionRecord,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (NULL != ptr)
|
if (NULL != ptr)
|
||||||
{
|
|
||||||
strcpy(GspOutBuffer, "E01");
|
strcpy(GspOutBuffer, "E01");
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
/* MAA..AA,LLLL: Write LLLL bytes at address AA.AA return OK */
|
/* MAA..AA,LLLL: Write LLLL bytes at address AA.AA return OK */
|
||||||
case 'M':
|
case 'M':
|
||||||
|
{
|
||||||
/* TRY TO READ '%x,%x:'. IF SUCCEED, SET PTR = 0 */
|
/* TRY TO READ '%x,%x:'. IF SUCCEED, SET PTR = 0 */
|
||||||
if (GspHex2Long(&ptr, &Address))
|
if (GspHex2Long(&ptr, &Address))
|
||||||
{
|
{
|
||||||
if (*(ptr++) == ',' &&
|
if (*(ptr++) == ',' && GspHex2Long(&ptr, &Length) && *(ptr++) == ':')
|
||||||
GspHex2Long(&ptr, &Length) &&
|
|
||||||
*(ptr++) == ':')
|
|
||||||
{
|
{
|
||||||
PEPROCESS DbgProcess = NULL;
|
PEPROCESS DbgProcess = NULL;
|
||||||
|
|
||||||
|
@ -1417,9 +1354,8 @@ KdpGdbEnterDebuggerException(PEXCEPTION_RECORD ExceptionRecord,
|
||||||
GspMemoryError = FALSE;
|
GspMemoryError = FALSE;
|
||||||
GspHex2Mem(ptr, (PCHAR)Address, Length, TRUE);
|
GspHex2Mem(ptr, (PCHAR)Address, Length, TRUE);
|
||||||
if (NULL != DbgProcess)
|
if (NULL != DbgProcess)
|
||||||
{
|
|
||||||
KeDetachProcess();
|
KeDetachProcess();
|
||||||
}
|
|
||||||
if (GspMemoryError)
|
if (GspMemoryError)
|
||||||
{
|
{
|
||||||
strcpy(GspOutBuffer, "E03");
|
strcpy(GspOutBuffer, "E03");
|
||||||
|
@ -1434,13 +1370,13 @@ KdpGdbEnterDebuggerException(PEXCEPTION_RECORD ExceptionRecord,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (NULL != ptr)
|
if (NULL != ptr)
|
||||||
{
|
|
||||||
strcpy(GspOutBuffer, "E02");
|
strcpy(GspOutBuffer, "E02");
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
/* cAA..AA Continue at address AA..AA(optional) */
|
break;
|
||||||
/* sAA..AA Step one instruction from AA..AA(optional) */
|
}
|
||||||
|
|
||||||
|
/* cAA..AA Continue at address AA..AA */
|
||||||
|
/* sAA..AA Step one instruction from AA..AA */
|
||||||
case 's':
|
case 's':
|
||||||
Stepping = TRUE;
|
Stepping = TRUE;
|
||||||
case 'c':
|
case 'c':
|
||||||
|
@ -1456,24 +1392,22 @@ KdpGdbEnterDebuggerException(PEXCEPTION_RECORD ExceptionRecord,
|
||||||
else if (ExceptionCode == STATUS_BREAKPOINT)
|
else if (ExceptionCode == STATUS_BREAKPOINT)
|
||||||
{
|
{
|
||||||
if (GspReadMemSafe((PCHAR)Context->Eip) == (CHAR)I386_OPCODE_INT3)
|
if (GspReadMemSafe((PCHAR)Context->Eip) == (CHAR)I386_OPCODE_INT3)
|
||||||
{
|
|
||||||
Context->Eip++;
|
Context->Eip++;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/* clear the trace bit */
|
/* clear the trace bit */
|
||||||
Context->EFlags &= ~EFLAGS_TF;
|
Context->EFlags &= ~EFLAGS_TF;
|
||||||
|
|
||||||
/* set the trace bit if we're Stepping */
|
/* set the trace bit if we're Stepping */
|
||||||
if (Stepping)
|
if (Stepping)
|
||||||
{
|
|
||||||
Context->EFlags |= EFLAGS_TF;
|
Context->EFlags |= EFLAGS_TF;
|
||||||
}
|
|
||||||
|
|
||||||
Dr6 = Ke386GetDr6();
|
Dr6 = Ke386GetDr6();
|
||||||
if (!(Dr6 & DR6_BS))
|
if (!(Dr6 & DR6_BS))
|
||||||
{
|
{
|
||||||
for (BreakpointNumber = 0; BreakpointNumber < MAX_HW_BREAKPOINTS; ++BreakpointNumber)
|
for (BreakpointNumber = 0;
|
||||||
|
BreakpointNumber < MAX_HW_BREAKPOINTS;
|
||||||
|
BreakpointNumber++)
|
||||||
{
|
{
|
||||||
if (Dr6 & (1 << BreakpointNumber))
|
if (Dr6 & (1 << BreakpointNumber))
|
||||||
{
|
{
|
||||||
|
@ -1502,9 +1436,7 @@ KdpGdbEnterDebuggerException(PEXCEPTION_RECORD ExceptionRecord,
|
||||||
|
|
||||||
if (ExceptionCode == STATUS_BREAKPOINT ||
|
if (ExceptionCode == STATUS_BREAKPOINT ||
|
||||||
ExceptionCode == STATUS_SINGLE_STEP)
|
ExceptionCode == STATUS_SINGLE_STEP)
|
||||||
{
|
|
||||||
return kdContinue;
|
return kdContinue;
|
||||||
}
|
|
||||||
|
|
||||||
return kdHandleException;
|
return kdHandleException;
|
||||||
}
|
}
|
||||||
|
@ -1536,14 +1468,12 @@ KdpGdbEnterDebuggerException(PEXCEPTION_RECORD ExceptionRecord,
|
||||||
GspHex2Long(&ptr, &Address);
|
GspHex2Long(&ptr, &Address);
|
||||||
ptr++;
|
ptr++;
|
||||||
GspHex2Long(&ptr, &Length);
|
GspHex2Long(&ptr, &Length);
|
||||||
|
|
||||||
if (0 == Type)
|
if (0 == Type)
|
||||||
{
|
|
||||||
GspSetSwBreakpoint((ULONG_PTR)Address);
|
GspSetSwBreakpoint((ULONG_PTR)Address);
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
|
||||||
GspSetHwBreakpoint(Type, (ULONG_PTR)Address, Length);
|
GspSetHwBreakpoint(Type, (ULONG_PTR)Address, Length);
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1558,14 +1488,12 @@ KdpGdbEnterDebuggerException(PEXCEPTION_RECORD ExceptionRecord,
|
||||||
GspHex2Long(&ptr, &Address);
|
GspHex2Long(&ptr, &Address);
|
||||||
ptr++;
|
ptr++;
|
||||||
GspHex2Long(&ptr, &Length);
|
GspHex2Long(&ptr, &Length);
|
||||||
|
|
||||||
if (0 == Type)
|
if (0 == Type)
|
||||||
{
|
|
||||||
GspRemoveSwBreakpoint((ULONG_PTR)Address);
|
GspRemoveSwBreakpoint((ULONG_PTR)Address);
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
|
||||||
GspRemoveHwBreakpoint(Type, (ULONG_PTR)Address, Length);
|
GspRemoveHwBreakpoint(Type, (ULONG_PTR)Address, Length);
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1579,11 +1507,9 @@ KdpGdbEnterDebuggerException(PEXCEPTION_RECORD ExceptionRecord,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
BOOLEAN
|
BOOLEAN
|
||||||
NTAPI
|
NTAPI
|
||||||
GspBreakIn(PKINTERRUPT Interrupt,
|
GspBreakIn(PKINTERRUPT Interrupt, PVOID ServiceContext)
|
||||||
PVOID ServiceContext)
|
|
||||||
{
|
{
|
||||||
PKTRAP_FRAME TrapFrame;
|
PKTRAP_FRAME TrapFrame;
|
||||||
BOOLEAN DoBreakIn;
|
BOOLEAN DoBreakIn;
|
||||||
|
@ -1597,15 +1523,11 @@ GspBreakIn(PKINTERRUPT Interrupt,
|
||||||
while (KdPortGetByteEx(&GdbPortInfo, &Value))
|
while (KdPortGetByteEx(&GdbPortInfo, &Value))
|
||||||
{
|
{
|
||||||
if (Value == 0x03)
|
if (Value == 0x03)
|
||||||
{
|
|
||||||
DoBreakIn = TRUE;
|
DoBreakIn = TRUE;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (!DoBreakIn)
|
if (!DoBreakIn)
|
||||||
{
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
|
||||||
|
|
||||||
KeRaiseIrql(HIGH_LEVEL, &OldIrql);
|
KeRaiseIrql(HIGH_LEVEL, &OldIrql);
|
||||||
|
|
||||||
|
@ -1631,13 +1553,10 @@ KdpGdbDebugPrint(PCH Message, ULONG Length)
|
||||||
/* Initialize the GDB stub */
|
/* Initialize the GDB stub */
|
||||||
VOID
|
VOID
|
||||||
NTAPI
|
NTAPI
|
||||||
KdpGdbStubInit(PKD_DISPATCH_TABLE WrapperTable,
|
KdpGdbStubInit(PKD_DISPATCH_TABLE WrapperTable, ULONG BootPhase)
|
||||||
ULONG BootPhase)
|
|
||||||
{
|
{
|
||||||
if (!KdDebuggerEnabled || !KdpDebugMode.Gdb)
|
if (!KdDebuggerEnabled || !KdpDebugMode.Gdb)
|
||||||
{
|
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
if (BootPhase == 0)
|
if (BootPhase == 0)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue