Author: dgorbachev Date: Mon Jun 22 15:32:25 2009 New Revision: 41533
URL: http://svn.reactos.org/svn/reactos?rev=41533&view=rev Log: Change GDB stub.
Modified: trunk/reactos/ntoskrnl/kd/wrappers/gdbstub.c
Modified: trunk/reactos/ntoskrnl/kd/wrappers/gdbstub.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/kd/wrappers/gdbstu... ============================================================================== --- trunk/reactos/ntoskrnl/kd/wrappers/gdbstub.c [iso-8859-1] (original) +++ trunk/reactos/ntoskrnl/kd/wrappers/gdbstub.c [iso-8859-1] Mon Jun 22 15:32:25 2009 @@ -11,76 +11,17 @@ OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
****************************************************************************/ - /**************************************************************************** - * Header: remcom.c,v 1.34 91/03/09 12:29:49 glenne Exp $ - * - * Module name: remcom.c $ - * Revision: 1.34 $ - * Date: 91/03/09 12:29:49 $ * Contributor: Lake Stevens Instrument Division$ * * Description: low level support for gdb debugger. $ * - * Considerations: only works on target hardware $ - * * Written by: Glenn Engel $ * ModuleState: Experimental $ - * - * NOTES: See Below $ * * Modified for 386 by Jim Kingdon, Cygnus Support. * Modified for ReactOS by Casper S. Hornstrup chorns@users.sourceforge.net * - * To enable debugger support, two things need to happen. One, setting - * up a routine so that it is in the exception path, is necessary in order - * to allow any breakpoints or error conditions to be properly intercepted - * and reported to gdb. - * Two, a breakpoint needs to be generated to begin communication. - * - * Because gdb will sometimes write to the stack area to execute function - * calls, this program cannot rely on using the supervisor stack so it - * uses it's own stack area. - * - ************* - * - * The following gdb commands are supported: - * - * command function Return value - * - * g return the value of the CPU Registers hex data or ENN - * G set the value of the CPU Registers OK or ENN - * - * mAA..AA,LLLL Read LLLL bytes at address AA..AA hex data or ENN - * MAA..AA,LLLL: Write LLLL bytes at address AA.AA OK or ENN - * - * c Resume at current address SNN ( signal NN) - * cAA..AA Continue at address AA..AA SNN - * - * s Step one instruction SNN - * sAA..AA Step one instruction from AA..AA SNN - * - * k kill - * - * ? What was the last sigval ? SNN (signal NN) - * - * All commands and responses are sent with a packet which includes a - * Checksum. A packet consists of - * - * $<packet info>#<Checksum>. - * - * where - * <packet info> :: <characters representing the command or response> - * <Checksum> :: < two hex digits computed as modulo 256 sum of <packetinfo>> - * - * When a packet is received, it is first acknowledged with either '+' or '-'. - * '+' indicates a successful transfer. '-' indicates a failed transfer. - * - * Example: - * - * Host: Reply: - * $m0,10#2a +$00010203040506070809101112131415#42 - * ****************************************************************************/
#include <ntoskrnl.h> @@ -88,12 +29,8 @@ #include <debug.h>
/************************************************************************/ -/* BUFMAX defines the maximum number of characters in inbound/outbound buffers*/ -/* at least NUMREGBYTES*2 are needed for register packets */ -#define BUFMAX 1000
static BOOLEAN GspInitialized; - static BOOLEAN GspRemoteDebug;
static CONST CHAR HexChars[]="0123456789abcdef"; @@ -105,7 +42,12 @@ static FAST_MUTEX GspLock;
extern LIST_ENTRY PsActiveProcessHead; -KD_PORT_INFORMATION GdbPortInfo = { 2, 115200, 0 }; /* FIXME hardcoded for COM2, 115200 baud */ + +/* FIXME hardcoded for COM2, 115200 baud */ +KD_PORT_INFORMATION GdbPortInfo = { 2, 115200, 0 }; + +static CHAR GspInBuffer[1000]; +static CHAR GspOutBuffer[1000];
/* Number of Registers. */ #define NUMREGS 16 @@ -178,8 +120,6 @@ return -1; }
-static CHAR GspInBuffer[BUFMAX]; -static CHAR GspOutBuffer[BUFMAX];
VOID GdbPutChar(UCHAR Value) @@ -199,7 +139,6 @@ }
/* scan for the sequence $<data>#<Checksum> */ - PCHAR GspGetPacket() { @@ -221,7 +160,7 @@ Count = 0;
/* now, read until a # or end of Buffer is found */ - while (Count < BUFMAX) + while (Count < sizeof(GspInBuffer) - 1) { ch = GdbGetChar(); if (ch == '$') @@ -260,7 +199,6 @@ }
/* send the packet in Buffer. */ - VOID GspPutPacket(PCHAR Buffer) { @@ -314,17 +252,23 @@ GdbPutChar(HexChars[Checksum & 0xf]); }
-/* Indicate to caller of GspMem2Hex or GspHex2Mem that there has been an - error. */ +/* Indicate to caller of GspMem2Hex or GspHex2Mem that there has been an error. */ static volatile BOOLEAN GspMemoryError = FALSE; -static volatile void *GspAccessLocation = NULL;
static CHAR GspReadMemSafe(PCHAR Address) { - CHAR ch; - KdpSafeReadMemory((ULONG_PTR)Address, 1, &ch); + CHAR ch = 0; + if (!KdpSafeReadMemory((ULONG_PTR)Address, 1, &ch)) + GspMemoryError = TRUE; return ch; +} + +static void +GspWriteMemSafe(PCHAR Address, CHAR Ch) +{ + if (!KdpSafeWriteMemory((ULONG_PTR)Address, 1, Ch)) + GspMemoryError = TRUE; }
/* Convert the memory pointed to by Address into hex, placing result in Buffer */ @@ -375,7 +319,6 @@ ULONG CountInPage; ULONG i; CHAR ch; - ULONG OldProt = 0;
Current = Address; while (Current < Address + Count) @@ -391,30 +334,24 @@ /* Flows into next page, handle only current page in this iteration */ CountInPage = PAGE_SIZE - (Address - Page); } + + for (i = 0; i < CountInPage && ! GspMemoryError; i++) + { + ch = (*GetContent)(Context, Current - Address); + + if (MayFault) + { + GspWriteMemSafe(Current, ch); + } + else + { + *Current = ch; + } + + Current++; + } if (MayFault) { - OldProt = MmGetPageProtect(NULL, Address); - MmSetPageProtect(NULL, Address, PAGE_EXECUTE_READWRITE); - } - - for (i = 0; i < CountInPage && ! GspMemoryError; i++) - { - ch = (*GetContent)(Context, Current - Address); - - if (MayFault) - { - GspAccessLocation = Current; - } - *Current = ch; - if (MayFault) - { - GspAccessLocation = NULL; - } - Current++; - } - if (MayFault) - { - MmSetPageProtect(NULL, Page, OldProt); if (GspMemoryError) { return Current - Address; @@ -432,8 +369,8 @@ HexValue(*((PCHAR) Context + 2 * Offset + 1))); }
-/* 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 */ +/* 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 */ static PCHAR GspHex2Mem(PCHAR Buffer, PCHAR Address, @@ -444,49 +381,6 @@
return Buffer + 2 * Count; } - -static void -GspWriteMemSafe(PCHAR Address, - CHAR Ch) -{ - KdpSafeWriteMemory((ULONG_PTR)Address, 1, Ch); -} - - -/* This function takes the 386 exception vector and attempts to - translate this number into a unix compatible signal value */ -ULONG -GspComputeSignal(NTSTATUS ExceptionCode) -{ - ULONG SigVal; - - switch (ExceptionCode) - { - case STATUS_INTEGER_DIVIDE_BY_ZERO: - SigVal = 8; /* divide by zero */ - break; - case STATUS_SINGLE_STEP: - case STATUS_BREAKPOINT: - SigVal = 5; /* breakpoint */ - break; - case STATUS_INTEGER_OVERFLOW: - case STATUS_ARRAY_BOUNDS_EXCEEDED: - SigVal = 16; /* bound instruction */ - break; - case STATUS_ILLEGAL_INSTRUCTION: - SigVal = 4; /* Invalid opcode */ - break; - case STATUS_STACK_OVERFLOW: - case STATUS_DATATYPE_MISALIGNMENT: - case STATUS_ACCESS_VIOLATION: - SigVal = 11; /* access violation */ - break; - default: - SigVal = 7; /* "software generated" */ - } - return SigVal; -} -
/**********************************************/ /* WHILE WE FIND NICE HEX CHARS, BUILD A LONG */ @@ -932,6 +826,15 @@ GspMem2Hex(Buffer, &GspOutBuffer[0], strlen(Buffer), FALSE); } } + else if (strncmp(Request, "Supported", 9) == 0) + { + /* tell maximum incoming packet size */ + sprintf(GspOutBuffer, "PacketSize=%u", sizeof(GspInBuffer) - 1); + } + else if (strncmp(Request, "Rcmd,", 5) == 0) + { + ; + } }
VOID @@ -954,6 +857,8 @@ GspOutBuffer[1] = '\0'; } } + +#define DR6_BS 0x00004000 /* Single step */
#define DR7_L0 0x00000001 /* Local breakpoint 0 enable */ #define DR7_G0 0x00000002 /* Global breakpoint 0 enable */ @@ -1011,7 +916,6 @@ #define MAX_SW_BREAKPOINTS 64 static unsigned GspSwBreakpointCount = 0; static GSPSWBREAKPOINT GspSwBreakpoints[MAX_SW_BREAKPOINTS]; -static CHAR GspSwBreakpointsInstructions[MAX_SW_BREAKPOINTS];
static void GspSetHwBreakpoint(ULONG Type, ULONG_PTR Address, ULONG Length) @@ -1085,6 +989,21 @@ strcpy(GspOutBuffer, "E22"); }
+static BOOLEAN +GspFindSwBreakpoint(ULONG_PTR Address, PULONG PIndex) +{ + ULONG Index; + + for (Index = 0; Index < GspSwBreakpointCount; Index++) + if (GspSwBreakpoints[Index].Address == Address) + { + if (PIndex) *PIndex = Index; + return TRUE; + } + + return FALSE; +} + static void GspSetSwBreakpoint(ULONG_PTR Address) { @@ -1094,61 +1013,44 @@ { DPRINT1("Trying to set too many software breakpoints\n"); strcpy(GspOutBuffer, "E22"); - } - else - { - unsigned Index; - - for (Index = 0; Index < GspSwBreakpointCount; Index++) - { - if (GspSwBreakpoints[Index].Address == Address) - { - strcpy(GspOutBuffer, "E22"); - return; - } - } - - DPRINT("Stored at index %u\n", GspSwBreakpointCount); - GspSwBreakpoints[GspSwBreakpointCount].Address = Address; - GspSwBreakpoints[GspSwBreakpointCount].Active = FALSE; - GspSwBreakpointsInstructions[GspSwBreakpointCount] = - GspReadMemSafe((PCHAR )Address); - GspWriteMemSafe((PCHAR )Address, 0xCC); - GspSwBreakpointCount++; - strcpy(GspOutBuffer, "OK"); - } + return; + } + + if (GspFindSwBreakpoint(Address, NULL)) + { + strcpy(GspOutBuffer, "E22"); + return; + } + + DPRINT("Stored at index %u\n", GspSwBreakpointCount); + GspSwBreakpoints[GspSwBreakpointCount].Address = Address; + GspSwBreakpoints[GspSwBreakpointCount].Active = FALSE; + GspSwBreakpointCount++; + strcpy(GspOutBuffer, "OK"); }
static void GspRemoveSwBreakpoint(ULONG_PTR Address) { - unsigned Index; + ULONG Index;
DPRINT("GspRemoveSwBreakpoint(0x%p)\n", Address); - for (Index = 0; Index < GspSwBreakpointCount; Index++) - { - if (GspSwBreakpoints[Index].Address == Address) - { - DPRINT("Found match at index %u\n", Index); - ASSERT(! GspSwBreakpoints[Index].Active); - - GspWriteMemSafe((PCHAR )Address, - GspSwBreakpointsInstructions[Index]); - - if (Index + 1 < GspSwBreakpointCount) - { - memmove(GspSwBreakpoints + Index, - GspSwBreakpoints + (Index + 1), - (GspSwBreakpointCount - Index - 1) * - sizeof(GSPSWBREAKPOINT)); - memmove(GspSwBreakpointsInstructions + Index, - GspSwBreakpointsInstructions + (Index + 1), - (GspSwBreakpointCount - Index - 1) * sizeof(CHAR)); - } - GspSwBreakpointCount--; - strcpy(GspOutBuffer, "OK"); - return; - } + + if (GspFindSwBreakpoint(Address, &Index)) + { + DPRINT("Found match at index %u\n", Index); + ASSERT(! GspSwBreakpoints[Index].Active); + + if (Index + 1 < GspSwBreakpointCount) + { + memmove(GspSwBreakpoints + Index, + GspSwBreakpoints + (Index + 1), + (GspSwBreakpointCount - Index - 1) * + sizeof(GSPSWBREAKPOINT)); + } + GspSwBreakpointCount--; + strcpy(GspOutBuffer, "OK"); + return; }
DPRINT1("Not found\n"); @@ -1195,6 +1097,28 @@ }
static void +GspLoadSwBreakpoint(ULONG Index) +{ + GspMemoryError = FALSE; + GspSwBreakpoints[Index].PrevContent = GspReadMemSafe((PCHAR) GspSwBreakpoints[Index].Address); + if (! GspMemoryError) + { + GspWriteMemSafe((PCHAR) GspSwBreakpoints[Index].Address, I386_OPCODE_INT3); + } + GspSwBreakpoints[Index].Active = ! GspMemoryError; + if (GspMemoryError) + { + DPRINT1("Failed to set software breakpoint at 0x%p\n", + GspSwBreakpoints[Index].Address); + } + else + { + DPRINT("Successfully set software breakpoint at 0x%p\n", + GspSwBreakpoints[Index].Address); + } +} + +static void GspLoadBreakpoints(PKTRAP_FRAME TrapFrame) { unsigned Index; @@ -1202,6 +1126,7 @@
DPRINT("GspLoadBreakpoints\n"); DPRINT("DR7 on entry: 0x%08x\n", TrapFrame->Dr7); + /* Remove all breakpoints */ TrapFrame->Dr7 &= ~(DR7_L0 | DR7_L1 | DR7_L2 | DR7_L3 | DR7_G0 | DR7_G1 | DR7_G2 | DR7_G3 | @@ -1235,47 +1160,22 @@
for (Index = 0; Index < GspSwBreakpointCount; Index++) { - if (GspHwBreakpointCount + Index < MAX_HW_BREAKPOINTS) - { - DPRINT("Implementing software interrupt using hardware register\n"); - GspLoadHwBreakpoint(TrapFrame, GspHwBreakpointCount + Index, - GspSwBreakpoints[Index].Address, 0, - I386_BP_TYPE_EXECUTE); - GspSwBreakpoints[Index].Active = FALSE; - } - else - { - DPRINT("Using real software breakpoint\n"); - GspMemoryError = FALSE; - GspSwBreakpoints[Index].PrevContent = GspReadMemSafe((PCHAR) GspSwBreakpoints[Index].Address); - if (! GspMemoryError) - { - GspWriteMemSafe((PCHAR) GspSwBreakpoints[Index].Address, I386_OPCODE_INT3); - } - GspSwBreakpoints[Index].Active = ! GspMemoryError; - if (GspMemoryError) - { - DPRINT1("Failed to set software breakpoint at 0x%p\n", - GspSwBreakpoints[Index].Address); - } - else - { - DPRINT("Successfully set software breakpoint at 0x%p\n", - GspSwBreakpoints[Index].Address); - DPRINT1("Successfully set software breakpoint at 0x%p\n", GspSwBreakpoints[Index].Address); - } - } + DPRINT("Using real software breakpoint\n"); + GspLoadSwBreakpoint(Index); }
DPRINT("Final DR7 value 0x%08x\n", TrapFrame->Dr7); }
static void -GspUnloadBreakpoints(PKTRAP_FRAME TrapFrame) +GspUnloadBreakpoints(void) { unsigned Index;
- DPRINT("GspUnloadHwBreakpoints\n"); + DPRINT("GspUnloadBreakpoints\n"); + + /* Disable hardware debugging while we are inside the stub */ + Ke386SetDr7(0);
for (Index = 0; Index < GspSwBreakpointCount; Index++) { @@ -1299,9 +1199,67 @@ } }
-static BOOLEAN gdb_attached_yet = FALSE; +static void +GspStopReply(NTSTATUS ExceptionCode, PKTRAP_FRAME TrapFrame) +{ + PCHAR ptr = GspOutBuffer; + ULONG SigVal; + LONG Esp; + + switch (ExceptionCode) + { + case STATUS_INTEGER_DIVIDE_BY_ZERO: + SigVal = 8; /* divide by zero */ + break; + case STATUS_SINGLE_STEP: + case STATUS_BREAKPOINT: + SigVal = 5; /* breakpoint */ + break; + case STATUS_INTEGER_OVERFLOW: + case STATUS_ARRAY_BOUNDS_EXCEEDED: + SigVal = 16; /* bound instruction */ + break; + case STATUS_ILLEGAL_INSTRUCTION: + SigVal = 4; /* Invalid opcode */ + break; + case STATUS_STACK_OVERFLOW: + case STATUS_DATATYPE_MISALIGNMENT: + case STATUS_ACCESS_VIOLATION: + SigVal = 11; /* access violation */ + break; + default: + SigVal = 7; /* "software generated" */ + } + + 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'; +} + + /* - * This function does all command procesing for interfacing to gdb. + * This function does all command procesing for interfacing to GDB. */ KD_CONTINUE_TYPE NTAPI @@ -1309,34 +1267,23 @@ PCONTEXT Context, PKTRAP_FRAME TrapFrame) { - BOOLEAN Stepping; - LONG Address; - LONG Length; - LONG SigVal = 0; - LONG NewPC; - PCHAR ptr; - - /* FIXME: Stop on other CPUs too */ - - if (STATUS_ACCESS_VIOLATION == (NTSTATUS) ExceptionRecord->ExceptionCode && - NULL != GspAccessLocation && - (ULONG_PTR) GspAccessLocation == - (ULONG_PTR) ExceptionRecord->ExceptionInformation[1]) - { - GspAccessLocation = NULL; - GspMemoryError = TRUE; - Context->Eip += 3; - } - else - { - DPRINT("Thread %p entering stub\n", PsGetCurrentThread()); + static BOOLEAN GdbAttached = FALSE; + BOOLEAN Stepping = FALSE; + NTSTATUS ExceptionCode; + LONG Address; + LONG Length; + PCHAR ptr; + + /* FIXME: Stop on other CPUs too */ + + DPRINT("Thread %p entering stub\n", PsGetCurrentThread()); + ExceptionCode = (NTSTATUS) ExceptionRecord->ExceptionCode; + /* Can only debug 1 thread at a time... */ ExAcquireFastMutex(&GspLock); DPRINT("Thread %p acquired mutex\n", PsGetCurrentThread());
- /* Disable hardware debugging while we are inside the stub */ - Ke386SetDr7(0); - GspUnloadBreakpoints(TrapFrame); + GspUnloadBreakpoints();
/* Make sure we're debugging the current thread. */ if (NULL != GspDbgThread) @@ -1346,67 +1293,29 @@ GspDbgThread = NULL; }
- /* 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]); - /* DPRINT("------- replied status: (%s) -------\n", GspOutBuffer); */ + if (GdbAttached) + { + GspStopReply(ExceptionCode, TrapFrame); + GspPutPacket(GspOutBuffer); + // DbgPrint(">>> (%s) >>>\n", GspOutBuffer); } else { - gdb_attached_yet = 1; - } - - Stepping = FALSE; + GdbAttached = TRUE; + }
while (TRUE) { /* Zero the buffer now so we don't have to worry about the terminating zero character */ - memset(GspOutBuffer, 0, sizeof(GspInBuffer)); + memset(GspOutBuffer, 0, sizeof(GspOutBuffer)); ptr = GspGetPacket(); - /* DPRINT("------- Get (%s) command -------\n", ptr); */ + // DbgPrint("<<< (%s) <<<\n", 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]; - GspOutBuffer[3] = 0; + GspStopReply(ExceptionCode, TrapFrame); break; case 'd': GspRemoteDebug = !GspRemoteDebug; /* toggle debug flag */ @@ -1478,7 +1387,7 @@ if (GspMemoryError) { strcpy(GspOutBuffer, "E03"); - DPRINT("Fault during memory read\n"); + DPRINT1("Fault during memory read\n"); } }
@@ -1514,7 +1423,7 @@ if (GspMemoryError) { strcpy(GspOutBuffer, "E03"); - DPRINT("Fault during memory write\n"); + DPRINT1("Fault during memory write\n"); } else { @@ -1537,55 +1446,49 @@ case 'c': { ULONG BreakpointNumber; - ULONG dr6_; - - /* try to read optional parameter, pc unchanged if no parm */ + ULONG Dr6; + + /* try to read optional parameter, pc changed if param */ if (GspHex2Long (&ptr, &Address)) { Context->Eip = Address; } - - NewPC = Context->Eip; + else if (ExceptionCode == STATUS_BREAKPOINT) + { + if (GspReadMemSafe((PCHAR) Context->Eip) == (CHAR) I386_OPCODE_INT3) + { + Context->Eip++; + } + }
/* clear the trace bit */ - Context->EFlags &= 0xfffffeff; + Context->EFlags &= ~EFLAGS_TF;
/* set the trace bit if we're Stepping */ if (Stepping) { - Context->EFlags |= 0x100; + Context->EFlags |= EFLAGS_TF; }
-#if defined(__GNUC__) - asm volatile ("movl %%db6, %0\n" : "=r" (dr6_) : ); -#elif defined(_MSC_VER) - __asm mov eax, dr6 __asm mov dr6_, eax; -#else -#error Unknown compiler for inline assembler -#endif - if (!(dr6_ & 0x4000)) + Dr6 = Ke386GetDr6(); + if (!(Dr6 & DR6_BS)) { - for (BreakpointNumber = 0; BreakpointNumber < 4; ++BreakpointNumber) + for (BreakpointNumber = 0; BreakpointNumber < MAX_HW_BREAKPOINTS; ++BreakpointNumber) { - if (dr6_ & (1 << BreakpointNumber)) + if (Dr6 & (1 << BreakpointNumber)) { - if (GspHwBreakpoints[BreakpointNumber].Type == 0) + if (GspHwBreakpoints[BreakpointNumber].Type == I386_BP_TYPE_EXECUTE) { /* Set restore flag */ - Context->EFlags |= 0x10000; + Context->EFlags |= EFLAGS_RF; break; } } } } + GspLoadBreakpoints(TrapFrame); -#if defined(__GNUC__) - asm volatile ("movl %0, %%db6\n" : : "r" (0)); -#elif defined(_MSC_VER) - __asm mov eax, 0 __asm mov dr6, eax; -#else -#error Unknown compiler for inline assembler -#endif + Ke386SetDr6(0);
if (NULL != GspDbgThread) { @@ -1596,14 +1499,19 @@ DPRINT("Thread %p releasing mutex\n", PsGetCurrentThread()); ExReleaseFastMutex(&GspLock); DPRINT("Thread %p leaving stub\n", PsGetCurrentThread()); - return kdContinue; - break; + + if (ExceptionCode == STATUS_BREAKPOINT || + ExceptionCode == STATUS_SINGLE_STEP) + { + return kdContinue; + } + + return kdHandleException; }
case 'k': /* kill the program */ strcpy(GspOutBuffer, "OK"); break; - /* kill the program */
case 'H': /* Set thread */ GspSetThread(ptr); @@ -1630,11 +1538,11 @@ GspHex2Long(&ptr, &Length); if (0 == Type) { - GspSetSwBreakpoint((ULONG_PTR) Address); + GspSetSwBreakpoint((ULONG_PTR) Address); } else { - GspSetHwBreakpoint(Type, (ULONG_PTR) Address, Length); + GspSetHwBreakpoint(Type, (ULONG_PTR) Address, Length); } break; } @@ -1652,11 +1560,11 @@ GspHex2Long(&ptr, &Length); if (0 == Type) { - GspRemoveSwBreakpoint((ULONG_PTR) Address); + GspRemoveSwBreakpoint((ULONG_PTR) Address); } else { - GspRemoveHwBreakpoint(Type, (ULONG_PTR) Address, Length); + GspRemoveHwBreakpoint(Type, (ULONG_PTR) Address, Length); } break; } @@ -1667,20 +1575,8 @@
/* reply to the request */ GspPutPacket(GspOutBuffer); - /* DPRINT("------- reply command (%s) -------\n", GspOutBuffer); */ - } - - /* not reached */ - ASSERT(0); - } - - if (NULL != GspDbgThread) - { - ObDereferenceObject(GspDbgThread); - GspDbgThread = NULL; - } - - return kdContinue; + // DbgPrint(">>> (%s) >>>\n", GspOutBuffer); + } }
@@ -1754,8 +1650,6 @@
/* Initialize the Port */ KdPortInitializeEx(&GdbPortInfo, 0, 0); - - KdpPort = GdbPortInfo.ComPort; } else if (BootPhase == 1) {