https://git.reactos.org/?p=reactos.git;a=commitdiff;h=0e391eecd1d8ddecf5ce2…
commit 0e391eecd1d8ddecf5ce26898543466059861502
Author: Hervé Poussineau <hpoussin(a)reactos.org>
AuthorDate: Sat Mar 28 10:16:44 2020 +0100
Commit: Hervé Poussineau <hpoussin(a)reactos.org>
CommitDate: Mon Nov 16 08:55:02 2020 +0100
[NTOS:KD] Remove GDB stubs
drivers/base/kdgdb/ should be used instead.
---
ntoskrnl/include/internal/kd.h | 8 -
ntoskrnl/kd/amd64/kd.c | 23 -
ntoskrnl/kd/kdinit.c | 13 -
ntoskrnl/kd/wrappers/gdbstub.c | 1606 ------------------------------
ntoskrnl/kd/wrappers/gdbstub_powerpc.c | 1698 --------------------------------
ntoskrnl/ntos.cmake | 5 +-
6 files changed, 1 insertion(+), 3352 deletions(-)
diff --git a/ntoskrnl/include/internal/kd.h b/ntoskrnl/include/internal/kd.h
index ede52d82c57..6834cbc7e2b 100644
--- a/ntoskrnl/include/internal/kd.h
+++ b/ntoskrnl/include/internal/kd.h
@@ -6,7 +6,6 @@
// Kernel Debugger Port Definition
//
struct _KD_DISPATCH_TABLE;
-extern CPPORT GdbPortInfo;
BOOLEAN
NTAPI
@@ -161,12 +160,6 @@ KdpBochsInit(
ULONG BootPhase
);
-VOID
-NTAPI
-KdpGdbStubInit(
- struct _KD_DISPATCH_TABLE *DispatchTable,
- ULONG BootPhase);
-
VOID
NTAPI
KdpKdbgInit(
@@ -228,7 +221,6 @@ typedef struct _KDP_DEBUG_MODE
/* Currently Supported Wrappers */
UCHAR Pice :1;
- UCHAR Gdb :1;
};
/* Generic Value */
diff --git a/ntoskrnl/kd/amd64/kd.c b/ntoskrnl/kd/amd64/kd.c
deleted file mode 100644
index b8d592ad5a6..00000000000
--- a/ntoskrnl/kd/amd64/kd.c
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * PROJECT: ReactOS Kernel
- * LICENSE: GPL - See COPYING in the top level directory
- * FILE: ntoskrnl/kd/amd64/kd.c
- * PURPOSE: Routines for CPU-level support
- * PROGRAMMERS: Timo Kreuzer (timo.kreuzer(a)reactos.org)
- */
-
-/* INCLUDES ******************************************************************/
-
-#include <ntoskrnl.h>
-#define NDEBUG
-#include <debug.h>
-
-/* FUNCTIONS *****************************************************************/
-
-VOID
-NTAPI
-KdpGdbStubInit(PKD_DISPATCH_TABLE WrapperTable,
- ULONG BootPhase)
-{
- UNIMPLEMENTED;
-}
diff --git a/ntoskrnl/kd/kdinit.c b/ntoskrnl/kd/kdinit.c
index fddde5a5bfd..9c4e0447058 100644
--- a/ntoskrnl/kd/kdinit.c
+++ b/ntoskrnl/kd/kdinit.c
@@ -106,19 +106,6 @@ KdpGetDebugMode(PCHAR Currentp2)
p2 += 5;
KdpDebugMode.Bochs = TRUE;
}
- /* Check for GDB Debugging */
- else if (!_strnicmp(p2, "GDB", 3))
- {
- /* Enable it */
- p2 += 3;
- KdpDebugMode.Gdb = TRUE;
-
- /* Enable Debugging */
- KdDebuggerNotPresent = FALSE;
- KdDebuggerEnabled = TRUE;
- SharedUserData->KdDebuggerEnabled = TRUE;
- WrapperInitRoutine = KdpGdbStubInit;
- }
/* Check for PICE Debugging */
else if (!_strnicmp(p2, "PICE", 4))
{
diff --git a/ntoskrnl/kd/wrappers/gdbstub.c b/ntoskrnl/kd/wrappers/gdbstub.c
deleted file mode 100644
index 52497779078..00000000000
--- a/ntoskrnl/kd/wrappers/gdbstub.c
+++ /dev/null
@@ -1,1606 +0,0 @@
-/****************************************************************************
-
- 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
- user accepts the software "AS IS" with all faults.
-
- HP DISCLAIMS ANY WARRANTIES, EXPRESS OR IMPLIED, WITH REGARD
- TO THIS SOFTWARE INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
-
-****************************************************************************/
-/****************************************************************************
- * Contributor: Lake Stevens Instrument Division$
- *
- * Description: low level support for gdb debugger. $
- *
- * Written by: Glenn Engel $
- * ModuleState: Experimental $
- *
- * Modified for 386 by Jim Kingdon, Cygnus Support.
- * Modified for ReactOS by Casper S. Hornstrup <chorns(a)users.sourceforge.net>
- *
- ****************************************************************************/
-
-#include <ntoskrnl.h>
-#define NDEBUG
-#include <debug.h>
-
-/************************************************************************/
-
-static BOOLEAN GspInitialized;
-static BOOLEAN GspRemoteDebug;
-
-static CONST CHAR HexChars[] = "0123456789abcdef";
-
-static PETHREAD GspRunThread; /* NULL means run all threads */
-static PETHREAD GspDbgThread;
-static PETHREAD GspEnumThread;
-
-static FAST_MUTEX GspLock;
-
-extern LIST_ENTRY PsActiveProcessHead;
-
-/* FIXME hardcoded for COM2, 115200 baud */
-ULONG GdbPortNumber = DEFAULT_DEBUG_PORT;
-CPPORT GdbPortInfo = {0, DEFAULT_DEBUG_BAUD_RATE, 0};
-
-static CHAR GspInBuffer[1000];
-static CHAR GspOutBuffer[1000];
-
-/* Number of Registers. */
-#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
-};
-
-typedef struct _CPU_REGISTER
-{
- ULONG Size;
- ULONG OffsetInTF;
- ULONG OffsetInContext;
- BOOLEAN SetInContext;
-} CPU_REGISTER, *PCPU_REGISTER;
-
-static CPU_REGISTER GspRegisters[NUMREGS] =
-{
- { 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, HardwareEsp), FIELD_OFFSET(CONTEXT, Esp), TRUE },
- { 4, FIELD_OFFSET(KTRAP_FRAME, DbgEbp), 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, DbgEip), FIELD_OFFSET(CONTEXT, Eip), TRUE },
- { 4, FIELD_OFFSET(KTRAP_FRAME, EFlags), FIELD_OFFSET(CONTEXT, EFlags), TRUE },
- { 4, FIELD_OFFSET(KTRAP_FRAME, SegCs), FIELD_OFFSET(CONTEXT, SegCs), TRUE },
- { 4, FIELD_OFFSET(KTRAP_FRAME, HardwareSegSs), FIELD_OFFSET(CONTEXT, SegSs), TRUE },
- { 4, FIELD_OFFSET(KTRAP_FRAME, SegDs), FIELD_OFFSET(CONTEXT, SegDs), TRUE },
- { 4, FIELD_OFFSET(KTRAP_FRAME, SegEs), FIELD_OFFSET(CONTEXT, SegEs), TRUE },
- { 4, FIELD_OFFSET(KTRAP_FRAME, SegFs), FIELD_OFFSET(CONTEXT, SegFs), TRUE },
- { 4, FIELD_OFFSET(KTRAP_FRAME, SegGs), FIELD_OFFSET(CONTEXT, SegGs), TRUE }
-};
-
-static PCHAR GspThreadStates[DeferredReady + 1] =
-{
- "Initialized",
- "Ready",
- "Running",
- "Standby",
- "Terminated",
- "Waiting",
- "Transition",
- "DeferredReady"
-};
-
-LONG
-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;
-}
-
-VOID
-GdbPutChar(UCHAR Value)
-{
- KdPortPutByteEx(&GdbPortInfo, Value);
-}
-
-UCHAR
-GdbGetChar(VOID)
-{
- UCHAR Value;
-
- while (!KdPortGetByteEx(&GdbPortInfo, &Value)) ;
- return Value;
-}
-
-/* scan for the sequence $<data>#<Checksum> */
-PCHAR
-GspGetPacket(VOID)
-{
- PCHAR Buffer = &GspInBuffer[0];
- CHAR Checksum;
- CHAR XmitChecksum;
- ULONG Count;
- CHAR ch;
-
- while (TRUE)
- {
- /* wait around for the start character, ignore all other characters */
- while ((ch = GdbGetChar()) != '$') ;
-
-retry:
- Checksum = 0;
- XmitChecksum = -1;
- Count = 0;
-
- /* now, read until a # or end of Buffer is found */
- while (Count < sizeof(GspInBuffer) - 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 */
- return &Buffer[0];
- }
- }
- }
-}
-
-/* send the packet in Buffer. */
-VOID
-GspPutPacket(PCHAR Buffer)
-{
- CHAR Checksum;
- LONG Count;
- CHAR ch;
-
- /* $<packet info>#<Checksum>. */
- do
- {
- 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]);
- }
- while (GdbGetChar() != '+');
-}
-
-VOID
-GspPutPacketNoWait(PCHAR Buffer)
-{
- CHAR Checksum;
- LONG Count;
- CHAR ch;
-
- /* $<packet info>#<Checksum>. */
- 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]);
-}
-
-/* Indicate to caller of GspMem2Hex or GspHex2Mem that there has been an error. */
-static volatile BOOLEAN GspMemoryError = FALSE;
-
-static CHAR
-GspReadMemSafe(PCHAR Address)
-{
- CHAR Ch = 0;
-
-#if 0
- if (!NT_SUCCESS(KdpCopyMemoryChunks((ULONG64)(ULONG_PTR)Address, &Ch, 1,
- 0, MMDBG_COPY_UNSAFE, NULL)))
-#else
- if (!NT_SUCCESS(MmDbgCopyMemory((ULONG64)(ULONG_PTR)Address, &Ch, 1,
- MMDBG_COPY_UNSAFE)))
-#endif
- {
- GspMemoryError = TRUE;
- }
-
- return Ch;
-}
-
-static void
-GspWriteMemSafe(PCHAR Address, CHAR Ch)
-{
-#if 0
- if (!NT_SUCCESS(KdpCopyMemoryChunks((ULONG64)(ULONG_PTR)Address, &Ch, 1,
- 0, MMDBG_COPY_UNSAFE | MMDBG_COPY_WRITE, NULL)))
-#else
- if (!NT_SUCCESS(MmDbgCopyMemory((ULONG64)(ULONG_PTR)Address, &Ch, 1,
- MMDBG_COPY_UNSAFE | MMDBG_COPY_WRITE)))
-#endif
- {
- GspMemoryError = TRUE;
- }
-}
-
-/* Convert the memory pointed to by Address into hex, placing result in Buffer
- * Return a pointer to the last char put in Buffer (null)
- * 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.
- */
-static PCHAR
-GspMem2Hex(PCHAR Address, PCHAR Buffer, LONG Count, BOOLEAN MayFault)
-{
- ULONG i;
- CHAR ch;
-
- for (i = 0; i < (ULONG)Count; i++)
- {
- if (MayFault)
- {
- ch = GspReadMemSafe(Address);
- if (GspMemoryError)
- return Buffer;
- }
- else
- {
- ch = *Address;
- }
- *Buffer++ = HexChars[(ch >> 4) & 0xf];
- *Buffer++ = HexChars[ch & 0xf];
- Address++;
- }
-
- *Buffer = 0;
- return Buffer;
-}
-
-static ULONG
-GspWriteMem(PCHAR Address, ULONG Count, BOOLEAN MayFault,
- CHAR (*GetContent)(PVOID Context, ULONG Offset), PVOID Context)
-{
- PCHAR Current;
- PCHAR Page;
- ULONG CountInPage;
- ULONG i;
- CHAR ch;
-
- Current = Address;
- while (Current < Address + Count)
- {
- Page = (PCHAR)PAGE_ROUND_DOWN(Current);
- if (Address + Count <= Page + PAGE_SIZE)
- {
- /* Fits in this page */
- CountInPage = Count;
- }
- else
- {
- /* Flows into next page, handle only current page in this iteration */
- CountInPage = PAGE_SIZE - (Address - Page);
- }
-
- for (i = 0; i < CountInPage && !GspMemoryError; i++)
- {
- ch = (*GetContent)(Context, Current - Address);
-
- if (MayFault)
- GspWriteMemSafe(Current, ch);
- else
- *Current = ch;
-
- Current++;
- }
- if (MayFault)
- {
- if (GspMemoryError)
- return Current - Address;
- }
- }
-
- return Current - Address;
-}
-
-static CHAR
-GspHex2MemGetContent(PVOID Context, ULONG Offset)
-{
- return (CHAR)((HexValue(*((PCHAR)Context + 2 * Offset)) << 4) +
- 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 */
-static PCHAR
-GspHex2Mem(PCHAR Buffer, PCHAR Address, ULONG Count, BOOLEAN MayFault)
-{
- Count = GspWriteMem(Address, Count, MayFault, GspHex2MemGetContent, Buffer);
- return Buffer + 2 * Count;
-}
-
-/**********************************************/
-/* WHILE WE FIND NICE HEX CHARS, BUILD A LONG */
-/* RETURN NUMBER OF CHARS PROCESSED */
-/**********************************************/
-LONG
-GspHex2Long(PCHAR *Address, PLONG Value)
-{
- LONG NumChars = 0;
- LONG Hex;
-
- *Value = 0;
-
- while (**Address)
- {
- Hex = HexValue(**Address);
- if (Hex >= 0)
- {
- *Value = (*Value << 4) | Hex;
- NumChars++;
- }
- else
- {
- break;
- }
-
- (*Address)++;
- }
-
- return NumChars;
-}
-
-VOID
-GspLong2Hex(PCHAR *Address, LONG Value)
-{
- LONG Save;
-
- Save = (((Value >> 0) & 0xff) << 24) | (((Value >> 8) &
0xff) << 16) |
- (((Value >> 16) & 0xff) << 8) | (((Value >> 24) &
0xff) << 0);
-
- *Address = GspMem2Hex((PCHAR)&Save, *Address, 4, FALSE);
-}
-
-/*
- * 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
- * when the exception occured. When coming from user mode, Esp is just
- * stored in the TrapFrame Esp member.
- */
-static LONG
-GspGetEspFromTrapFrame(PKTRAP_FRAME TrapFrame)
-{
- return KeGetPreviousMode() == KernelMode ?
- (LONG)&TrapFrame->HardwareEsp : (LONG)TrapFrame->HardwareEsp;
-}
-
-static VOID
-GspGetRegisters(PCHAR Address, PKTRAP_FRAME TrapFrame)
-{
- ULONG_PTR Value;
- PULONG p;
- ULONG i;
- PETHREAD Thread;
- ULONG_PTR *KernelStack;
-
- if (NULL == GspDbgThread)
- {
- Thread = PsGetCurrentThread();
- }
- else
- {
- TrapFrame = GspDbgThread->Tcb.TrapFrame;
- Thread = GspDbgThread;
- }
-
- if (Waiting == Thread->Tcb.State)
- {
- 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 = KGDT_R0_CODE;
- break;
- case DS:
- Value = KGDT_R0_DATA;
- 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);
- }
- }
-}
-
-VOID
-GspSetRegistersInTrapFrame(PCHAR Address, PCONTEXT Context, PKTRAP_FRAME TrapFrame)
-{
- ULONG Value;
- PCHAR Buffer;
- PULONG p;
- ULONG i;
-
- if (!TrapFrame)
- 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;
- }
-}
-
-VOID
-GspSetSingleRegisterInTrapFrame(PCHAR Address, LONG Number, PCONTEXT Context,
PKTRAP_FRAME TrapFrame)
-{
- ULONG Value;
- PULONG p;
-
- if (!TrapFrame)
- return;
-
- if (GspRegisters[Number].SetInContext)
- {
- p = (PULONG)((ULONG_PTR)Context + GspRegisters[Number].OffsetInContext);
- }
- else
- {
- p = (PULONG)((ULONG_PTR)TrapFrame + GspRegisters[Number].OffsetInTF);
- }
-
- Value = 0;
- GspHex2Mem(Address, (PCHAR)&Value, GspRegisters[Number].Size, FALSE);
- *p = Value;
-}
-
-BOOLEAN
-GspFindThread(PCHAR Data, PETHREAD *Thread)
-{
- PETHREAD ThreadInfo = NULL;
-
- if (strcmp(Data, "-1") == 0)
- {
- /* All threads */
- ThreadInfo = NULL;
- }
- else
- {
- ULONG uThreadId;
- HANDLE ThreadId;
- PCHAR ptr = &Data[0];
-
- GspHex2Long(&ptr, (PLONG)&uThreadId);
- ThreadId = (HANDLE)uThreadId;
-
- if (!NT_SUCCESS(PsLookupThreadByThreadId(ThreadId, &ThreadInfo)))
- {
- *Thread = NULL;
- return FALSE;
- }
- }
-
- *Thread = ThreadInfo;
- return TRUE;
-}
-
-VOID
-GspSetThread(PCHAR Request)
-{
- PETHREAD ThreadInfo;
- PCHAR ptr = &Request[1];
-
- switch (Request[0])
- {
- case 'c': /* Run thread */
- if (GspFindThread(ptr, &ThreadInfo))
- {
- GspOutBuffer[0] = 'O';
- GspOutBuffer[1] = 'K';
-
- if (NULL != GspRunThread)
- ObDereferenceObject(GspRunThread);
-
- GspRunThread = ThreadInfo;
-
- if (NULL != GspRunThread)
- ObReferenceObject(GspRunThread);
- }
- else
- {
- GspOutBuffer[0] = 'E';
- }
- break;
-
- case 'g': /* Debug thread */
- 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)
-{
- ULONG Value;
-
- if (strncmp(Request, "C", 1) == 0)
- {
- 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 if (strncmp(Request, "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);
- }
- else
- {
- /* 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(Request, "sThreadInfo", 11) == 0)
- {
- 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(Request, "ThreadExtraInfo", 15) == 0)
- {
- PETHREAD ThreadInfo;
-
- /* Get thread information */
- if (GspFindThread(Request + 16, &ThreadInfo))
- {
- char Buffer[64];
- PEPROCESS Proc;
-
- Proc = (PEPROCESS)ThreadInfo->ThreadsProcess;
-
- 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]);
-
- ObDereferenceObject(ThreadInfo);
-
- 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
-GspQueryThreadStatus(PCHAR Request)
-{
- PETHREAD ThreadInfo;
- PCHAR ptr = &Request[0];
-
- if (GspFindThread(ptr, &ThreadInfo))
- {
- ObDereferenceObject(ThreadInfo);
-
- GspOutBuffer[0] = 'O';
- GspOutBuffer[1] = 'K';
- GspOutBuffer[2] = '\0';
- }
- else
- {
- GspOutBuffer[0] = 'E';
- 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 */
-#define DR7_L1 0x00000004 /* Local breakpoint 1 enable */
-#define DR7_G1 0x00000008 /* Global breakpoint 1 enable */
-#define DR7_L2 0x00000010 /* Local breakpoint 2 enable */
-#define DR7_G2 0x00000020 /* Global breakpoint 2 enable */
-#define DR7_L3 0x00000040 /* Local breakpoint 3 enable */
-#define DR7_G3 0x00000080 /* Global breakpoint 3 enable */
-#define DR7_LE 0x00000100 /* Local exact breakpoint enable (old) */
-#define DR7_GE 0x00000200 /* Global exact breakpoint enable (old) */
-#define DR7_GD 0x00002000 /* General detect enable */
-#define DR7_TYPE0_MASK 0x00030000 /* Breakpoint 0 condition */
-#define DR7_LEN0_MASK 0x000c0000 /* Breakpoint 0 length */
-#define DR7_TYPE1_MASK 0x00300000 /* Breakpoint 1 condition */
-#define DR7_LEN1_MASK 0x00c00000 /* Breakpoint 1 length */
-#define DR7_TYPE2_MASK 0x03000000 /* Breakpoint 2 condition */
-#define DR7_LEN2_MASK 0x0c000000 /* Breakpoint 2 length */
-#define DR7_TYPE3_MASK 0x30000000 /* Breakpoint 3 condition */
-#define DR7_LEN3_MASK 0xc0000000 /* Breakpoint 3 length */
-#define DR7_GLOBAL_ENABLE(Bp) (2 << (2 * (Bp)))
-#define DR7_TYPE(Bp, Type) ((Type) << (16 + 4 * (Bp)))
-#define DR7_LEN(Bp, Len) ((Len) << (18 + 4 * (Bp)))
-
-#define I386_BP_TYPE_EXECUTE 0
-#define I386_BP_TYPE_DATA_WRITE 1
-#define I386_BP_TYPE_DATA_READWRITE 3
-
-#define I386_OPCODE_INT3 0xcc
-
-#define GDB_ZTYPE_MEMORY_BREAKPOINT 0
-#define GDB_ZTYPE_HARDWARE_BREAKPOINT 1
-#define GDB_ZTYPE_WRITE_WATCHPOINT 2
-#define GDB_ZTYPE_READ_WATCHPOINT 3
-#define GDB_ZTYPE_ACCESS_WATCHPOINT 4
-
-typedef struct _GSPHWBREAKPOINT
-{
- ULONG Type;
- ULONG_PTR Address;
- ULONG Length;
-} GSPHWBREAKPOINT;
-
-#define MAX_HW_BREAKPOINTS 4
-static unsigned GspHwBreakpointCount = 0;
-static GSPHWBREAKPOINT GspHwBreakpoints[MAX_HW_BREAKPOINTS];
-
-typedef struct _GSPSWBREAKPOINT
-{
- ULONG_PTR Address;
- CHAR PrevContent;
- BOOLEAN Active;
-} GSPSWBREAKPOINT;
-
-#define MAX_SW_BREAKPOINTS 64
-static unsigned GspSwBreakpointCount = 0;
-static GSPSWBREAKPOINT GspSwBreakpoints[MAX_SW_BREAKPOINTS];
-
-static void
-GspSetHwBreakpoint(ULONG Type, ULONG_PTR Address, ULONG Length)
-{
- DPRINT("GspSetHwBreakpoint(%lu, 0x%p, %lu)\n", Type, Address, Length);
-
- if (GDB_ZTYPE_READ_WATCHPOINT == Type)
- {
- DPRINT1("Read watchpoint not supported\n");
- strcpy(GspOutBuffer, "E22");
- }
- else if (GDB_ZTYPE_HARDWARE_BREAKPOINT == Type && 1 != Length)
- {
- DPRINT1("Invalid length %lu for hardware breakpoint\n", Length);
- strcpy(GspOutBuffer, "E22");
- }
- else if (1 != Length && 2 != Length && 4 != Length)
- {
- DPRINT1("Invalid length %lu for GDB Z type %lu\n", Length, Type);
- strcpy(GspOutBuffer, "E22");
- }
- else if (0 != (Address & (Length - 1)))
- {
- DPRINT1("Invalid alignment for address 0x%p and length %d\n", Address,
Length);
- strcpy(GspOutBuffer, "E22");
- }
- else if (MAX_HW_BREAKPOINTS == GspHwBreakpointCount)
- {
- DPRINT1("Trying to set too many hardware breakpoints\n");
- strcpy(GspOutBuffer, "E22");
- }
- else
- {
- DPRINT("Stored at index %u\n", GspHwBreakpointCount);
- GspHwBreakpoints[GspHwBreakpointCount].Type = Type;
- GspHwBreakpoints[GspHwBreakpointCount].Address = Address;
- GspHwBreakpoints[GspHwBreakpointCount].Length = Length;
- GspHwBreakpointCount++;
- strcpy(GspOutBuffer, "OK");
- }
-}
-
-static void
-GspRemoveHwBreakpoint(ULONG Type, ULONG_PTR Address, ULONG Length)
-{
- unsigned Index;
-
- DPRINT("GspRemoveHwBreakpoint(%lu, 0x%p, %lu)\n", Type, Address, Length);
- for (Index = 0; Index < GspHwBreakpointCount; Index++)
- {
- if (GspHwBreakpoints[Index].Type == Type &&
- GspHwBreakpoints[Index].Address == Address &&
- GspHwBreakpoints[Index].Length == Length)
- {
- DPRINT("Found match at index %u\n", Index);
- if (Index + 1 < GspHwBreakpointCount)
- memmove(GspHwBreakpoints + Index,
- GspHwBreakpoints + (Index + 1),
- (GspHwBreakpointCount - Index - 1) * sizeof(GSPHWBREAKPOINT));
-
- GspHwBreakpointCount--;
- strcpy(GspOutBuffer, "OK");
- return;
- }
- }
-
- DPRINT1("Not found\n");
- 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)
-{
- DPRINT("GspSetSwBreakpoint(0x%p)\n", Address);
-
- if (MAX_SW_BREAKPOINTS == GspSwBreakpointCount)
- {
- DPRINT1("Trying to set too many software breakpoints\n");
- strcpy(GspOutBuffer, "E22");
- 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)
-{
- ULONG Index;
-
- DPRINT("GspRemoveSwBreakpoint(0x%p)\n", Address);
-
- 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");
- strcpy(GspOutBuffer, "E22");
-}
-
-static void
-GspLoadHwBreakpoint(PKTRAP_FRAME TrapFrame, unsigned BpIndex,
- ULONG_PTR Address, ULONG Length, ULONG Type)
-{
- DPRINT("GspLoadHwBreakpoint(0x%p, %d, 0x%p, %d)\n",
- TrapFrame, BpIndex, Address, Type);
-
- /* Set the DR7_Gx bit to globally enable the breakpoint */
- TrapFrame->Dr7 |= DR7_GLOBAL_ENABLE(BpIndex) |
- DR7_LEN(BpIndex, Length) |
- DR7_TYPE(BpIndex, Type);
-
- switch (BpIndex)
- {
- case 0:
- DPRINT("Setting DR0 to 0x%p\n", Address);
- TrapFrame->Dr0 = Address;
- break;
-
- case 1:
- DPRINT("Setting DR1 to 0x%p\n", Address);
- TrapFrame->Dr1 = Address;
- break;
-
- case 2:
- DPRINT("Setting DR2 to 0x%p\n", Address);
- TrapFrame->Dr2 = Address;
- break;
-
- case 3:
- DPRINT("Setting DR3 to 0x%p\n", Address);
- TrapFrame->Dr3 = Address;
- break;
- }
-}
-
-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;
- ULONG i386Type;
-
- 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 |
- DR7_TYPE0_MASK | DR7_LEN0_MASK |
- DR7_TYPE1_MASK | DR7_LEN1_MASK |
- DR7_TYPE2_MASK | DR7_LEN2_MASK |
- DR7_TYPE3_MASK | DR7_LEN3_MASK);
-
- for (Index = 0; Index < GspHwBreakpointCount; Index++)
- {
- switch (GspHwBreakpoints[Index].Type)
- {
- case GDB_ZTYPE_HARDWARE_BREAKPOINT:
- i386Type = I386_BP_TYPE_EXECUTE;
- break;
- case GDB_ZTYPE_WRITE_WATCHPOINT:
- i386Type = I386_BP_TYPE_DATA_WRITE;
- break;
- case GDB_ZTYPE_ACCESS_WATCHPOINT:
- i386Type = I386_BP_TYPE_DATA_READWRITE;
- break;
- default:
- ASSERT(FALSE);
- i386Type = I386_BP_TYPE_EXECUTE;
- break;
- }
-
- GspLoadHwBreakpoint(TrapFrame, Index, GspHwBreakpoints[Index].Address,
- GspHwBreakpoints[Index].Length - 1, i386Type);
- }
-
- for (Index = 0; Index < GspSwBreakpointCount; Index++)
- {
- DPRINT("Using real software breakpoint\n");
- GspLoadSwBreakpoint(Index);
- }
-
- DPRINT("Final DR7 value 0x%08x\n", TrapFrame->Dr7);
-}
-
-static void
-GspUnloadBreakpoints(void)
-{
- unsigned Index;
-
- DPRINT("GspUnloadBreakpoints\n");
-
- /* Disable hardware debugging while we are inside the stub */
- __writedr(7, 0);
-
- for (Index = 0; Index < GspSwBreakpointCount; Index++)
- {
- if (GspSwBreakpoints[Index].Active)
- {
- GspMemoryError = FALSE;
- GspWriteMemSafe((PCHAR)GspSwBreakpoints[Index].Address,
- GspSwBreakpoints[Index].PrevContent);
- GspSwBreakpoints[Index].Active = FALSE;
- if (GspMemoryError)
- {
- DPRINT1("Failed to remove software breakpoint from 0x%p\n",
- GspSwBreakpoints[Index].Address);
- }
- else
- {
- DPRINT("Successfully removed software breakpoint from 0x%p\n",
- GspSwBreakpoints[Index].Address);
- }
- }
- }
-}
-
-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.
- */
-KD_CONTINUE_TYPE
-NTAPI
-KdpGdbEnterDebuggerException(PEXCEPTION_RECORD ExceptionRecord,
- PCONTEXT Context,
- PKTRAP_FRAME TrapFrame)
-{
- 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());
-
- GspUnloadBreakpoints();
-
- /* 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;
- }
-
- if (GdbAttached)
- {
- GspStopReply(ExceptionCode, TrapFrame);
- GspPutPacket(GspOutBuffer);
- // DbgPrint(">>> (%s) >>>\n", GspOutBuffer);
- }
- else
- {
- GdbAttached = TRUE;
- }
-
- while (TRUE)
- {
- /* Zero the buffer now so we don't have to worry about the terminating zero
character */
- memset(GspOutBuffer, 0, sizeof(GspOutBuffer));
- ptr = GspGetPacket();
- // DbgPrint("<<< (%s) <<<\n", ptr);
-
- switch (*ptr++)
- {
- case '?':
- /* a little hack to send more complete status information */
- GspStopReply(ExceptionCode, TrapFrame);
- break;
-
- case 'd':
- GspRemoteDebug = !GspRemoteDebug; /* toggle debug flag */
- break;
-
- case 'g': /* return the value of the CPU Registers */
- GspGetRegisters(GspOutBuffer, TrapFrame);
- break;
-
- case 'G': /* set the value of the CPU Registers - return OK */
- if (NULL != GspDbgThread)
- GspSetRegistersInTrapFrame(ptr, Context,
GspDbgThread->Tcb.TrapFrame);
- else
- GspSetRegistersInTrapFrame(ptr, Context, TrapFrame);
-
- strcpy(GspOutBuffer, "OK");
- break;
-
- case 'P': /* set the value of a single CPU register - return OK */
- {
- LONG Register;
-
- if ((GspHex2Long(&ptr, &Register)) && (*ptr++ ==
'='))
- {
- if ((Register >= 0) && (Register < NUMREGS))
- {
- if (GspDbgThread)
- {
- GspSetSingleRegisterInTrapFrame(ptr, Register, Context,
-
GspDbgThread->Tcb.TrapFrame);
- }
- else
- {
- GspSetSingleRegisterInTrapFrame(ptr, Register, Context,
TrapFrame);
- }
- strcpy(GspOutBuffer, "OK");
- break;
- }
- }
-
- strcpy(GspOutBuffer, "E01");
- break;
- }
-
- /* mAA..AA,LLLL Read LLLL bytes at address AA..AA */
- case 'm':
- {
- /* TRY TO READ %x,%x. IF SUCCEED, SET PTR = 0 */
- if (GspHex2Long(&ptr, &Address) && *(ptr++) ==
',' && GspHex2Long(&ptr, &Length))
- {
- PEPROCESS DbgProcess = NULL;
-
- ptr = NULL;
- if (NULL != GspDbgThread &&
- PsGetCurrentProcess() != GspDbgThread->ThreadsProcess)
- {
- DbgProcess = GspDbgThread->ThreadsProcess;
- KeAttachProcess(&DbgProcess->Pcb);
- }
-
- GspMemoryError = FALSE;
- GspMem2Hex((PCHAR)Address, GspOutBuffer, Length, 1);
-
- if (NULL != DbgProcess)
- KeDetachProcess();
-
- if (GspMemoryError)
- {
- strcpy(GspOutBuffer, "E03");
- DPRINT1("Fault during memory read\n");
- }
- ptr = NULL;
- }
-
- 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++) == ',' && GspHex2Long(&ptr,
&Length) && *(ptr++) == ':')
- {
- PEPROCESS DbgProcess = NULL;
-
- 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");
- DPRINT1("Fault during memory write\n");
- }
- else
- {
- strcpy(GspOutBuffer, "OK");
- }
- ptr = NULL;
- }
- }
-
- if (NULL != ptr)
- strcpy(GspOutBuffer, "E02");
-
- break;
- }
-
- /* cAA..AA Continue at address AA..AA */
- /* sAA..AA Step one instruction from AA..AA */
- case 's':
- Stepping = TRUE;
- case 'c':
- {
- ULONG BreakpointNumber;
- ULONG Dr6;
-
- /* try to read optional parameter, pc changed if param */
- if (GspHex2Long(&ptr, &Address))
- {
- Context->Eip = Address;
- }
- else if (ExceptionCode == STATUS_BREAKPOINT)
- {
- if (GspReadMemSafe((PCHAR)Context->Eip) ==
(CHAR)I386_OPCODE_INT3)
- Context->Eip++;
- }
-
- /* clear the trace bit */
- Context->EFlags &= ~EFLAGS_TF;
-
- /* set the trace bit if we're Stepping */
- if (Stepping)
- Context->EFlags |= EFLAGS_TF;
-
- Dr6 = __readdr(6);
- if (!(Dr6 & DR6_BS))
- {
- for (BreakpointNumber = 0;
- BreakpointNumber < MAX_HW_BREAKPOINTS;
- BreakpointNumber++)
- {
- if (Dr6 & (1 << BreakpointNumber))
- {
- if (GspHwBreakpoints[BreakpointNumber].Type ==
I386_BP_TYPE_EXECUTE)
- {
- /* Set restore flag */
- Context->EFlags |= EFLAGS_RF;
- break;
- }
- }
- }
- }
-
- GspLoadBreakpoints(TrapFrame);
- __writedr(6, 0);
-
- if (NULL != GspDbgThread)
- {
- ObDereferenceObject(GspDbgThread);
- GspDbgThread = NULL;
- }
-
- DPRINT("Thread %p releasing mutex\n", PsGetCurrentThread());
- ExReleaseFastMutex(&GspLock);
- DPRINT("Thread %p leaving stub\n", PsGetCurrentThread());
-
- if (ExceptionCode == STATUS_BREAKPOINT ||
- ExceptionCode == STATUS_SINGLE_STEP)
- return kdContinue;
-
- return kdHandleException;
- }
-
- case 'k': /* kill the program */
- strcpy(GspOutBuffer, "OK");
- break;
-
- case 'H': /* Set thread */
- GspSetThread(ptr);
- break;
-
- case 'q': /* Query */
- GspQuery(ptr);
- break;
-
- case 'T': /* Query thread status */
- GspQueryThreadStatus(ptr);
- break;
-
- case 'Z':
- {
- LONG Type;
- LONG Address;
- LONG Length;
-
- GspHex2Long(&ptr, &Type);
- ptr++;
- GspHex2Long(&ptr, &Address);
- ptr++;
- GspHex2Long(&ptr, &Length);
-
- if (0 == Type)
- GspSetSwBreakpoint((ULONG_PTR)Address);
- else
- GspSetHwBreakpoint(Type, (ULONG_PTR)Address, Length);
-
- break;
- }
-
- case 'z':
- {
- LONG Type;
- LONG Address;
- LONG Length;
-
- GspHex2Long(&ptr, &Type);
- ptr++;
- GspHex2Long(&ptr, &Address);
- ptr++;
- GspHex2Long(&ptr, &Length);
-
- if (0 == Type)
- GspRemoveSwBreakpoint((ULONG_PTR)Address);
- else
- GspRemoveHwBreakpoint(Type, (ULONG_PTR)Address, Length);
-
- break;
- }
-
- default:
- break;
- }
-
- /* reply to the request */
- GspPutPacket(GspOutBuffer);
- // DbgPrint(">>> (%s) >>>\n", GspOutBuffer);
- }
-}
-
-BOOLEAN
-NTAPI
-GspBreakIn(PKINTERRUPT Interrupt, PVOID ServiceContext)
-{
- PKTRAP_FRAME TrapFrame;
- BOOLEAN DoBreakIn;
- CONTEXT Context;
- KIRQL OldIrql;
- UCHAR Value;
-
- DPRINT("Break In\n");
-
- DoBreakIn = FALSE;
- while (KdPortGetByteEx(&GdbPortInfo, &Value))
- {
- if (Value == 0x03)
- DoBreakIn = TRUE;
- }
-
- if (!DoBreakIn)
- return TRUE;
-
- KeRaiseIrql(HIGH_LEVEL, &OldIrql);
-
- TrapFrame = PsGetCurrentThread()->Tcb.TrapFrame;
-
- KeTrapFrameToContext(TrapFrame, NULL, &Context);
-
- KdpGdbEnterDebuggerException(NULL, &Context, TrapFrame);
-
- KeContextToTrapFrame(&Context, NULL, TrapFrame, Context.ContextFlags,
KernelMode);
-
- KeLowerIrql(OldIrql);
-
- return TRUE;
-}
-
-VOID
-NTAPI
-KdpGdbDebugPrint(PCH Message, ULONG Length)
-{
-}
-
-/* Initialize the GDB stub */
-VOID
-NTAPI
-KdpGdbStubInit(PKD_DISPATCH_TABLE WrapperTable, ULONG BootPhase)
-{
- if (!KdDebuggerEnabled || !KdpDebugMode.Gdb)
- return;
-
- if (BootPhase == 0)
- {
- ExInitializeFastMutex(&GspLock);
-
- /* Write out the functions that we support for now */
- WrapperTable->KdpInitRoutine = KdpGdbStubInit;
- WrapperTable->KdpPrintRoutine = KdpGdbDebugPrint;
- WrapperTable->KdpExceptionRoutine = KdpGdbEnterDebuggerException;
-
- /* Initialize the Port */
- KdPortInitializeEx(&GdbPortInfo, GdbPortNumber);
- }
- else if (BootPhase == 1)
- {
- GspInitialized = TRUE;
-
- GspRunThread = NULL;
- GspDbgThread = NULL;
- GspEnumThread = NULL;
-
- HalDisplayString("Waiting for GDB to attach\r\n");
- DbgBreakPointWithStatus(DBG_STATUS_CONTROL_C);
- }
- else if (BootPhase == 2)
- {
- HalDisplayString("\r\n GDB debugging enabled\r\n\r\n");
- }
-}
-
-/* EOF */
diff --git a/ntoskrnl/kd/wrappers/gdbstub_powerpc.c
b/ntoskrnl/kd/wrappers/gdbstub_powerpc.c
deleted file mode 100644
index 8a223543b63..00000000000
--- a/ntoskrnl/kd/wrappers/gdbstub_powerpc.c
+++ /dev/null
@@ -1,1698 +0,0 @@
-/****************************************************************************
-
- 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
- user accepts the software "AS IS" with all faults.
-
- HP DISCLAIMS ANY WARRANTIES, EXPRESS OR IMPLIED, WITH REGARD
- TO THIS SOFTWARE INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- 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(a)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>
-#define NDEBUG
-#include <debug.h>
-
-/************************************************************************/
-
-static BOOLEAN GspInitialized;
-static BOOLEAN GspRemoteDebug;
-
-static CONST CHAR HexChars[]="0123456789abcdef";
-
-static PETHREAD GspRunThread; /* NULL means run all threads */
-static PETHREAD GspDbgThread;
-static PETHREAD GspEnumThread;
-
-static FAST_MUTEX GspLock;
-
-extern LIST_ENTRY PsActiveProcessHead;
-
-/* FIXME hardcoded for COM2, 115200 baud */
-ULONG GdbPortNumber = DEFAULT_DEBUG_PORT;
-CPPORT GdbPortInfo = {0, DEFAULT_DEBUG_BAUD_RATE, 0};
-
-/* BUFMAX defines the maximum number of characters in inbound/outbound buffers*/
-/* at least NUMREGBYTES*2 are needed for register packets */
-#define BUFMAX 1000
-static CHAR GspInBuffer[BUFMAX];
-static CHAR GspOutBuffer[BUFMAX];
-
-/* Number of Registers. */
-#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
-};
-
-typedef struct _CPU_REGISTER
-{
- ULONG Size;
- ULONG OffsetInTF;
- ULONG OffsetInContext;
- BOOLEAN SetInContext;
-} CPU_REGISTER, *PCPU_REGISTER;
-
-static CPU_REGISTER GspRegisters[NUMREGS] =
-{
-};
-
-static PCHAR GspThreadStates[DeferredReady+1] =
-{
- "Initialized",
- "Ready",
- "Running",
- "Standby",
- "Terminated",
- "Waiting",
- "Transition",
- "DeferredReady"
-};
-
-
-LONG
-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;
-}
-
-VOID
-GdbPutChar(UCHAR Value)
-{
- KdPortPutByteEx(&GdbPortInfo, Value);
-}
-
-UCHAR
-GdbGetChar(VOID)
-{
- UCHAR Value;
-
- while (!KdPortGetByteEx(&GdbPortInfo, &Value)) ;
- return Value;
-}
-
-/* scan for the sequence $<data>#<Checksum> */
-
-PCHAR
-GspGetPacket(VOID)
-{
- PCHAR Buffer = &GspInBuffer[0];
- CHAR Checksum;
- CHAR XmitChecksum;
- ULONG Count;
- CHAR ch;
-
- while (TRUE)
- {
- /* wait around for the start character, ignore all other characters */
- while ((ch = GdbGetChar ()) != '$') ;
-
-retry:
- Checksum = 0;
- XmitChecksum = -1;
- Count = 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;
- }
- 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 */
- return &Buffer[0];
- }
- }
- }
-}
-
-/* send the packet in Buffer. */
-
-VOID
-GspPutPacket(PCHAR Buffer)
-{
- CHAR Checksum;
- LONG Count;
- CHAR ch;
-
- /* $<packet info>#<Checksum>. */
- do
- {
- 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]);
- }
- while (GdbGetChar() != '+');
-}
-
-
-VOID
-GspPutPacketNoWait(PCHAR Buffer)
-{
- CHAR Checksum;
- LONG Count;
- CHAR ch;
-
- /* $<packet info>#<Checksum>. */
- 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]);
-}
-
-/* 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;
-
- if (NULL == Address)
- {
- GspMemoryError = TRUE;
- return '\0';
- }
-
- GspAccessLocation = Address;
- ch = *Address;
- GspAccessLocation = NULL;
-
- return ch;
-}
-
-static CHAR
-GspWriteMemSafeGetContent(PVOID Context, ULONG Offset)
-{
- ASSERT(0 == Offset);
- return *((PCHAR) Context);
-}
-
-static void
-GspWriteMemSafe(PCHAR Address,
- CHAR Ch)
-{
- GspWriteMem(Address, 1, TRUE, GspWriteMemSafeGetContent, &Ch);
-}
-
-/* Convert the memory pointed to by Address into hex, placing result in Buffer */
-/* Return a pointer to the last char put in Buffer (null) */
-/* 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. */
-static PCHAR
-GspMem2Hex(PCHAR Address,
- PCHAR Buffer,
- LONG Count,
- BOOLEAN MayFault)
-{
- ULONG i;
- CHAR ch;
-
- for (i = 0; i < (ULONG) Count; i++)
- {
- if (MayFault)
- {
- ch = GspReadMemSafe(Address);
- if (GspMemoryError)
- return Buffer;
- }
- else
- {
- ch = *Address;
- }
- *Buffer++ = HexChars[(ch >> 4) & 0xf];
- *Buffer++ = HexChars[ch & 0xf];
- Address++;
- }
-
- *Buffer = 0;
- return Buffer;
-}
-
-static ULONG
-GspWriteMem(PCHAR Address,
- ULONG Count,
- BOOLEAN MayFault,
- CHAR (*GetContent)(PVOID Context, ULONG Offset),
- PVOID Context)
-{
- PCHAR Current;
- PCHAR Page;
- ULONG CountInPage;
- ULONG i;
- CHAR ch;
- ULONG OldProt = 0;
-
- Current = Address;
- while (Current < Address + Count)
- {
- Page = (PCHAR)PAGE_ROUND_DOWN(Current);
- if (Address + Count <= Page + PAGE_SIZE)
- {
- /* Fits in this page */
- CountInPage = Count;
- }
- else
- {
- /* Flows into next page, handle only current page in this iteration */
- CountInPage = PAGE_SIZE - (Address - Page);
- }
- if (MayFault)
- {
- OldProt = MmGetPageProtect(NULL, Address);
- MmSetPageProtect(NULL, Address, PAGE_EXECUTE_READWRITE);
- }
-
- for (i = 0; i < CountInPage && ! GspMemoryError; i++)
- {
- ch = (*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;
- }
- }
-
- return Current - Address;
-}
-
-static CHAR
-GspHex2MemGetContent(PVOID Context, ULONG Offset)
-{
- return (CHAR)((HexValue(*((PCHAR) Context + 2 * Offset)) << 4) +
- 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 */
-static PCHAR
-GspHex2Mem(PCHAR Buffer,
- PCHAR Address,
- ULONG Count,
- BOOLEAN MayFault)
-{
- Count = GspWriteMem(Address, Count, MayFault, GspHex2MemGetContent, Buffer);
- return Buffer + 2 * Count;
-}
-
-
-/* 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 */
-/* RETURN NUMBER OF CHARS PROCESSED */
-/**********************************************/
-LONG
-GspHex2Long(PCHAR *Address,
- PLONG Value)
-{
- LONG NumChars = 0;
- LONG Hex;
-
- *Value = 0;
-
- while (**Address)
- {
- Hex = HexValue(**Address);
- if (Hex >= 0)
- {
- *Value = (*Value << 4) | Hex;
- NumChars++;
- }
- else
- {
- break;
- }
-
- (*Address)++;
- }
-
- return NumChars;
-}
-
-
-VOID
-GspLong2Hex(PCHAR *Address,
- LONG Value)
-{
- LONG Save;
-
- Save = (((Value >> 0) & 0xff) << 24) |
- (((Value >> 8) & 0xff) << 16) |
- (((Value >> 16) & 0xff) << 8) |
- (((Value >> 24) & 0xff) << 0);
- *Address = GspMem2Hex((PCHAR) &Save, *Address, 4, FALSE);
-}
-
-
-/*
- * 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
- * when the exception occured. When coming from user mode, Esp is just
- * stored in the TrapFrame Esp member.
- */
-static LONG
-GspGetEspFromTrapFrame(PKTRAP_FRAME TrapFrame)
-{
- return KeGetPreviousMode() == KernelMode
- ? (LONG) &TrapFrame->Gpr1 : (LONG)TrapFrame->Gpr1;
-}
-
-
-static VOID
-GspGetRegisters(PCHAR Address,
- PKTRAP_FRAME TrapFrame)
-{
- ULONG_PTR Value;
- PULONG p;
- ULONG i;
- PETHREAD Thread;
- ULONG_PTR *KernelStack;
-
- if (NULL == GspDbgThread)
- {
- Thread = PsGetCurrentThread();
- }
- else
- {
- TrapFrame = GspDbgThread->Tcb.TrapFrame;
- Thread = GspDbgThread;
- }
-
- if (Waiting == Thread->Tcb.State)
- {
- KernelStack = Thread->Tcb.KernelStack;
- for (i = 0; i < sizeof(GspRegisters) / sizeof(GspRegisters[0]); i++)
- {
- switch(i)
- {
- }
- 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);
- }
- }
-}
-
-
-VOID
-GspSetRegistersInTrapFrame(PCHAR Address,
- PCONTEXT Context,
- PKTRAP_FRAME TrapFrame)
-{
- ULONG Value;
- PCHAR Buffer;
- PULONG p;
- ULONG i;
-
- if (!TrapFrame)
- {
- 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;
- }
-}
-
-
-VOID
-GspSetSingleRegisterInTrapFrame(PCHAR Address,
- LONG Number,
- PCONTEXT Context,
- PKTRAP_FRAME TrapFrame)
-{
- ULONG Value;
- PULONG p;
-
- if (!TrapFrame)
- {
- return;
- }
-
- if (GspRegisters[Number].SetInContext)
- {
- p = (PULONG) ((ULONG_PTR) Context + GspRegisters[Number].OffsetInContext);
- }
- else
- {
- p = (PULONG) ((ULONG_PTR) TrapFrame + GspRegisters[Number].OffsetInTF);
- }
- Value = 0;
- GspHex2Mem(Address, (PCHAR) &Value, GspRegisters[Number].Size, FALSE);
- *p = Value;
-}
-
-
-BOOLEAN
-GspFindThread(PCHAR Data,
- PETHREAD *Thread)
-{
- PETHREAD ThreadInfo = NULL;
-
- if (strcmp (Data, "-1") == 0)
- {
- /* All threads */
- ThreadInfo = NULL;
- }
- else
- {
- ULONG uThreadId;
- HANDLE ThreadId;
- PCHAR ptr = &Data[0];
-
- GspHex2Long(&ptr, (PLONG) &uThreadId);
- ThreadId = (HANDLE)uThreadId;
-
- if (!NT_SUCCESS(PsLookupThreadByThreadId(ThreadId, &ThreadInfo)))
- {
- *Thread = NULL;
- return FALSE;
- }
- }
- *Thread = ThreadInfo;
- return TRUE;
-}
-
-
-VOID
-GspSetThread(PCHAR Request)
-{
- PETHREAD ThreadInfo;
- PCHAR ptr = &Request[1];
-
- switch (Request[0])
- {
- case 'c': /* Run thread */
- if (GspFindThread(ptr, &ThreadInfo))
- {
- GspOutBuffer[0] = 'O';
- GspOutBuffer[1] = 'K';
-
- if (NULL != GspRunThread)
- {
- ObDereferenceObject(GspRunThread);
- }
- GspRunThread = ThreadInfo;
- if (NULL != GspRunThread)
- {
- ObReferenceObject(GspRunThread);
- }
- }
- else
- {
- GspOutBuffer[0] = 'E';
- }
- break;
- case 'g': /* Debug thread */
- 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)
-{
- ULONG Value;
-
- if (strncmp(Request, "C", 1) == 0)
- {
- 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 if (strncmp(Request, "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);
- }
- else
- {
- /* 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(Request, "sThreadInfo", 11) == 0)
- {
- 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(Request, "ThreadExtraInfo", 15) == 0)
- {
- PETHREAD ThreadInfo;
-
- /* Get thread information */
- if (GspFindThread(Request + 16, &ThreadInfo))
- {
- char Buffer[64];
- PEPROCESS Proc;
-
- Proc = (PEPROCESS) ThreadInfo->ThreadsProcess;
-
- 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]);
-
- ObDereferenceObject(ThreadInfo);
-
- GspMem2Hex(Buffer, &GspOutBuffer[0], strlen(Buffer), FALSE);
- }
- }
-}
-
-VOID
-GspQueryThreadStatus(PCHAR Request)
-{
- PETHREAD ThreadInfo;
- PCHAR ptr = &Request[0];
-
- if (GspFindThread(ptr, &ThreadInfo))
- {
- ObDereferenceObject(ThreadInfo);
-
- GspOutBuffer[0] = 'O';
- GspOutBuffer[1] = 'K';
- GspOutBuffer[2] = '\0';
- }
- else
- {
- GspOutBuffer[0] = 'E';
- GspOutBuffer[1] = '\0';
- }
-}
-
-#define DR7_L0 0x00000001 /* Local breakpoint 0 enable */
-#define DR7_G0 0x00000002 /* Global breakpoint 0 enable */
-#define DR7_L1 0x00000004 /* Local breakpoint 1 enable */
-#define DR7_G1 0x00000008 /* Global breakpoint 1 enable */
-#define DR7_L2 0x00000010 /* Local breakpoint 2 enable */
-#define DR7_G2 0x00000020 /* Global breakpoint 2 enable */
-#define DR7_L3 0x00000040 /* Local breakpoint 3 enable */
-#define DR7_G3 0x00000080 /* Global breakpoint 3 enable */
-#define DR7_LE 0x00000100 /* Local exact breakpoint enable (old) */
-#define DR7_GE 0x00000200 /* Global exact breakpoint enable (old) */
-#define DR7_GD 0x00002000 /* General detect enable */
-#define DR7_TYPE0_MASK 0x00030000 /* Breakpoint 0 condition */
-#define DR7_LEN0_MASK 0x000c0000 /* Breakpoint 0 length */
-#define DR7_TYPE1_MASK 0x00300000 /* Breakpoint 1 condition */
-#define DR7_LEN1_MASK 0x00c00000 /* Breakpoint 1 length */
-#define DR7_TYPE2_MASK 0x03000000 /* Breakpoint 2 condition */
-#define DR7_LEN2_MASK 0x0c000000 /* Breakpoint 2 length */
-#define DR7_TYPE3_MASK 0x30000000 /* Breakpoint 3 condition */
-#define DR7_LEN3_MASK 0xc0000000 /* Breakpoint 3 length */
-#define DR7_GLOBAL_ENABLE(Bp) (2 << (2 * (Bp)))
-#define DR7_TYPE(Bp, Type) ((Type) << (16 + 4 * (Bp)))
-#define DR7_LEN(Bp, Len) ((Len) << (18 + 4 * (Bp)))
-
-#define I386_BP_TYPE_EXECUTE 0
-#define I386_BP_TYPE_DATA_WRITE 1
-#define I386_BP_TYPE_DATA_READWRITE 3
-
-#define I386_OPCODE_INT3 0xcc
-
-#define GDB_ZTYPE_MEMORY_BREAKPOINT 0
-#define GDB_ZTYPE_HARDWARE_BREAKPOINT 1
-#define GDB_ZTYPE_WRITE_WATCHPOINT 2
-#define GDB_ZTYPE_READ_WATCHPOINT 3
-#define GDB_ZTYPE_ACCESS_WATCHPOINT 4
-
-typedef struct _GSPHWBREAKPOINT
-{
- ULONG Type;
- ULONG_PTR Address;
- ULONG Length;
-} GSPHWBREAKPOINT;
-
-#define MAX_HW_BREAKPOINTS 4
-static unsigned GspHwBreakpointCount = 0;
-static GSPHWBREAKPOINT GspHwBreakpoints[MAX_HW_BREAKPOINTS];
-
-typedef struct _GSPSWBREAKPOINT
-{
- ULONG_PTR Address;
- CHAR PrevContent;
- BOOLEAN Active;
-} GSPSWBREAKPOINT;
-
-#define MAX_SW_BREAKPOINTS 64
-static unsigned GspSwBreakpointCount = 0;
-static GSPSWBREAKPOINT GspSwBreakpoints[MAX_SW_BREAKPOINTS];
-
-static void
-GspSetHwBreakpoint(ULONG Type, ULONG_PTR Address, ULONG Length)
-{
- DPRINT("GspSetHwBreakpoint(%lu, 0x%p, %lu)\n", Type, Address, Length);
-
- if (GDB_ZTYPE_READ_WATCHPOINT == Type)
- {
- DPRINT1("Read watchpoint not supported\n");
- strcpy(GspOutBuffer, "E22");
- }
- else if (GDB_ZTYPE_HARDWARE_BREAKPOINT == Type && 1 != Length)
- {
- DPRINT1("Invalid length %lu for hardware breakpoint\n", Length);
- strcpy(GspOutBuffer, "E22");
- }
- else if (1 != Length && 2 != Length && 4 != Length)
- {
- DPRINT1("Invalid length %lu for GDB Z type %lu\n", Length, Type);
- strcpy(GspOutBuffer, "E22");
- }
- else if (0 != (Address & (Length - 1)))
- {
- DPRINT1("Invalid alignment for address 0x%p and length %d\n",
- Address, Length);
- strcpy(GspOutBuffer, "E22");
- }
- else if (MAX_HW_BREAKPOINTS == GspHwBreakpointCount)
- {
- DPRINT1("Trying to set too many hardware breakpoints\n");
- strcpy(GspOutBuffer, "E22");
- }
- else
- {
- DPRINT("Stored at index %u\n", GspHwBreakpointCount);
- GspHwBreakpoints[GspHwBreakpointCount].Type = Type;
- GspHwBreakpoints[GspHwBreakpointCount].Address = Address;
- GspHwBreakpoints[GspHwBreakpointCount].Length = Length;
- GspHwBreakpointCount++;
- strcpy(GspOutBuffer, "OK");
- }
-}
-
-static void
-GspRemoveHwBreakpoint(ULONG Type, ULONG_PTR Address, ULONG Length)
-{
- unsigned Index;
-
- DPRINT("GspRemoveHwBreakpoint(%lu, 0x%p, %lu)\n", Type, Address, Length);
- for (Index = 0; Index < GspHwBreakpointCount; Index++)
- {
- if (GspHwBreakpoints[Index].Type == Type &&
- GspHwBreakpoints[Index].Address == Address &&
- GspHwBreakpoints[Index].Length == Length)
- {
- DPRINT("Found match at index %u\n", Index);
- if (Index + 1 < GspHwBreakpointCount)
- {
- memmove(GspHwBreakpoints + Index,
- GspHwBreakpoints + (Index + 1),
- (GspHwBreakpointCount - Index - 1) *
- sizeof(GSPHWBREAKPOINT));
- }
- GspHwBreakpointCount--;
- strcpy(GspOutBuffer, "OK");
- return;
- }
- }
-
- DPRINT1("Not found\n");
- strcpy(GspOutBuffer, "E22");
-}
-
-static void
-GspSetSwBreakpoint(ULONG_PTR Address)
-{
- DPRINT("GspSetSwBreakpoint(0x%p)\n", Address);
-
- if (MAX_SW_BREAKPOINTS == GspSwBreakpointCount)
- {
- DPRINT1("Trying to set too many software breakpoints\n");
- strcpy(GspOutBuffer, "E22");
- }
- else
- {
- 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;
-
- 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);
- if (Index + 1 < GspSwBreakpointCount)
- {
- memmove(GspSwBreakpoints + Index,
- GspSwBreakpoints + (Index + 1),
- (GspSwBreakpointCount - Index - 1) *
- sizeof(GSPSWBREAKPOINT));
- }
- GspSwBreakpointCount--;
- strcpy(GspOutBuffer, "OK");
- return;
- }
- }
-
- DPRINT1("Not found\n");
- strcpy(GspOutBuffer, "E22");
-}
-
-static void
-GspLoadHwBreakpoint(PKTRAP_FRAME TrapFrame,
- unsigned BpIndex,
- ULONG_PTR Address,
- ULONG Length,
- ULONG Type)
-{
- DPRINT("GspLoadHwBreakpoint(0x%p, %d, 0x%p, %d)\n", TrapFrame, BpIndex,
- Address, Type);
-
- /* Set the DR7_Gx bit to globally enable the breakpoint */
- TrapFrame->Dr7 |= DR7_GLOBAL_ENABLE(BpIndex) |
- DR7_LEN(BpIndex, Length) |
- DR7_TYPE(BpIndex, Type);
-
- switch (BpIndex)
- {
- case 0:
- DPRINT("Setting DR0 to 0x%p\n", Address);
- TrapFrame->Dr0 = Address;
- break;
-
- case 1:
- DPRINT("Setting DR1 to 0x%p\n", Address);
- TrapFrame->Dr1 = Address;
- break;
-
- case 2:
- DPRINT("Setting DR2 to 0x%p\n", Address);
- TrapFrame->Dr2 = Address;
- break;
-
- case 3:
- DPRINT("Setting DR3 to 0x%p\n", Address);
- TrapFrame->Dr3 = Address;
- break;
- }
-}
-
-static void
-GspLoadBreakpoints(PKTRAP_FRAME TrapFrame)
-{
- unsigned Index;
- ULONG i386Type;
-
- 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 |
- DR7_TYPE0_MASK | DR7_LEN0_MASK |
- DR7_TYPE1_MASK | DR7_LEN1_MASK |
- DR7_TYPE2_MASK | DR7_LEN2_MASK |
- DR7_TYPE3_MASK | DR7_LEN3_MASK);
-
- for (Index = 0; Index < GspHwBreakpointCount; Index++)
- {
- switch(GspHwBreakpoints[Index].Type)
- {
- case GDB_ZTYPE_HARDWARE_BREAKPOINT:
- i386Type = I386_BP_TYPE_EXECUTE;
- break;
- case GDB_ZTYPE_WRITE_WATCHPOINT:
- i386Type = I386_BP_TYPE_DATA_WRITE;
- break;
- case GDB_ZTYPE_ACCESS_WATCHPOINT:
- i386Type = I386_BP_TYPE_DATA_READWRITE;
- break;
- default:
- ASSERT(FALSE);
- i386Type = I386_BP_TYPE_EXECUTE;
- break;
- }
-
- GspLoadHwBreakpoint(TrapFrame, Index, GspHwBreakpoints[Index].Address,
- GspHwBreakpoints[Index].Length - 1, i386Type);
- }
-
- 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("Final DR7 value 0x%08x\n", TrapFrame->Dr7);
-}
-
-static void
-GspUnloadBreakpoints(PKTRAP_FRAME TrapFrame)
-{
- unsigned Index;
-
- DPRINT("GspUnloadHwBreakpoints\n");
-
- for (Index = 0; Index < GspSwBreakpointCount; Index++)
- {
- if (GspSwBreakpoints[Index].Active)
- {
- GspMemoryError = FALSE;
- GspWriteMemSafe((PCHAR) GspSwBreakpoints[Index].Address,
- GspSwBreakpoints[Index].PrevContent);
- GspSwBreakpoints[Index].Active = FALSE;
- if (GspMemoryError)
- {
- DPRINT1("Failed to remove software breakpoint from 0x%p\n",
- GspSwBreakpoints[Index].Address);
- }
- else
- {
- DPRINT("Successfully removed software breakpoint from 0x%p\n",
- GspSwBreakpoints[Index].Address);
- }
- }
- }
-}
-
-static BOOLEAN gdb_attached_yet = FALSE;
-/*
- * This function does all command processing for interfacing to gdb.
- */
-KD_CONTINUE_TYPE
-NTAPI
-KdpGdbEnterDebuggerException(PEXCEPTION_RECORD ExceptionRecord,
- 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());
- /* 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);
-
- /* 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;
- }
-
- /* 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();
-
- switch(*ptr++)
- {
- case '?':
-#if 1
- /* a little hack to send more complete status information */
- goto stop_reply;
-#else
- GspOutBuffer[0] = 'S';
- GspOutBuffer[1] = HexChars[SigVal >> 4];
- GspOutBuffer[2] = HexChars[SigVal % 16];
- GspOutBuffer[3] = 0;
- break;
-#endif
- case 'd':
- GspRemoteDebug = !GspRemoteDebug; /* toggle debug flag */
- break;
- case 'g': /* return the value of the CPU Registers */
- GspGetRegisters(GspOutBuffer, TrapFrame);
- break;
- case 'G': /* set the value of the CPU Registers - return OK */
- if (NULL != GspDbgThread)
- {
- GspSetRegistersInTrapFrame(ptr, Context,
GspDbgThread->Tcb.TrapFrame);
- }
- else
- {
- GspSetRegistersInTrapFrame(ptr, Context, TrapFrame);
- }
- strcpy(GspOutBuffer, "OK");
- break;
- case 'P': /* set the value of a single CPU register - return OK */
- {
- LONG Register;
-
- if ((GspHex2Long(&ptr, &Register)) && (*ptr++ ==
'='))
- {
- if ((Register >= 0) && (Register < NUMREGS))
- {
- if (GspDbgThread)
- {
- GspSetSingleRegisterInTrapFrame(ptr, Register,
- Context,
-
GspDbgThread->Tcb.TrapFrame);
- }
- else
- {
- GspSetSingleRegisterInTrapFrame(ptr, Register,
- Context, TrapFrame);
- }
- strcpy(GspOutBuffer, "OK");
- break;
- }
- }
-
- strcpy(GspOutBuffer, "E01");
- break;
- }
-
- /* mAA..AA,LLLL Read LLLL bytes at address AA..AA */
- case 'm':
- /* TRY TO READ %x,%x. IF SUCCEED, SET PTR = 0 */
- if (GspHex2Long(&ptr, &Address) &&
- *(ptr++) == ',' &&
- GspHex2Long(&ptr, &Length))
- {
- PEPROCESS DbgProcess = NULL;
-
- ptr = NULL;
- if (NULL != GspDbgThread &&
- PsGetCurrentProcess() != GspDbgThread->ThreadsProcess)
- {
- 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 (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++) == ',' &&
- GspHex2Long(&ptr, &Length) &&
- *(ptr++) == ':')
- {
- PEPROCESS DbgProcess = NULL;
-
- 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;
- }
- }
-
- if (NULL != ptr)
- {
- strcpy(GspOutBuffer, "E02");
- }
- break;
-
- /* cAA..AA Continue at address AA..AA(optional) */
- /* sAA..AA Step one instruction from AA..AA(optional) */
- case 's':
- Stepping = TRUE;
- case 'c':
- {
- ULONG BreakpointNumber;
- ULONG dr6_ = 0;
-
- /* try to read optional parameter, pc unchanged if no parm */
- if (GspHex2Long (&ptr, &Address))
- {
- //Context->Eip = Address;
- }
-
- //NewPC = Context->Eip;
-
- /* clear the trace bit */
- //Context->EFlags &= 0xfffffeff;
-
- /* set the trace bit if we're Stepping */
- if (Stepping)
- {
- //Context->EFlags |= 0x100;
- }
-
- // XXX arty load dr6
- if (!(dr6_ & 0x4000))
- {
- for (BreakpointNumber = 0; BreakpointNumber < 4;
++BreakpointNumber)
- {
- if (dr6_ & (1 << BreakpointNumber))
- {
- if (GspHwBreakpoints[BreakpointNumber].Type == 0)
- {
- /* Set restore flag */
- //Context->EFlags |= 0x10000;
- break;
- }
- }
- }
- }
- GspLoadBreakpoints(TrapFrame);
- // XXX load dr6
- if (NULL != GspDbgThread)
- {
- ObDereferenceObject(GspDbgThread);
- GspDbgThread = NULL;
- }
-
- DPRINT("Thread %p releasing mutex\n", PsGetCurrentThread());
- ExReleaseFastMutex(&GspLock);
- DPRINT("Thread %p leaving stub\n", PsGetCurrentThread());
- return kdContinue;
- }
-
- case 'k': /* kill the program */
- strcpy(GspOutBuffer, "OK");
- break;
-
- case 'H': /* Set thread */
- GspSetThread(ptr);
- break;
-
- case 'q': /* Query */
- GspQuery(ptr);
- break;
-
- case 'T': /* Query thread status */
- GspQueryThreadStatus(ptr);
- break;
-
- case 'Z':
- {
- LONG Type;
- LONG Address;
- LONG Length;
-
- GspHex2Long(&ptr, &Type);
- ptr++;
- GspHex2Long(&ptr, &Address);
- ptr++;
- GspHex2Long(&ptr, &Length);
- if (0 == Type)
- {
- GspSetSwBreakpoint((ULONG_PTR) Address);
- }
- else
- {
- GspSetHwBreakpoint(Type, (ULONG_PTR) Address, Length);
- }
- break;
- }
-
- case 'z':
- {
- LONG Type;
- LONG Address;
- LONG Length;
-
- GspHex2Long(&ptr, &Type);
- ptr++;
- GspHex2Long(&ptr, &Address);
- ptr++;
- GspHex2Long(&ptr, &Length);
- if (0 == Type)
- {
- GspRemoveSwBreakpoint((ULONG_PTR) Address);
- }
- else
- {
- GspRemoveHwBreakpoint(Type, (ULONG_PTR) Address, Length);
- }
- break;
- }
-
- default:
- break;
- }
-
- /* reply to the request */
- GspPutPacket(GspOutBuffer);
- }
-
- /* not reached */
- ASSERT(0);
- }
-
- if (NULL != GspDbgThread)
- {
- ObDereferenceObject(GspDbgThread);
- GspDbgThread = NULL;
- }
-
- return kdContinue;
-}
-
-
-BOOLEAN
-NTAPI
-GspBreakIn(PKINTERRUPT Interrupt,
- PVOID ServiceContext)
-{
- PKTRAP_FRAME TrapFrame;
- BOOLEAN DoBreakIn;
- CONTEXT Context;
- KIRQL OldIrql;
- UCHAR Value;
-
- DPRINT("Break In\n");
-
- DoBreakIn = FALSE;
- while (KdPortGetByteEx(&GdbPortInfo, &Value))
- {
- if (Value == 0x03)
- DoBreakIn = TRUE;
- }
-
- if (!DoBreakIn)
- return TRUE;
-
- KeRaiseIrql(HIGH_LEVEL, &OldIrql);
-
- TrapFrame = PsGetCurrentThread()->Tcb.TrapFrame;
-
- KeTrapFrameToContext(TrapFrame, NULL, &Context);
-
- KdpGdbEnterDebuggerException(NULL, &Context, TrapFrame);
-
- KeContextToTrapFrame(&Context, NULL, TrapFrame, Context.ContextFlags,
KernelMode);
-
- KeLowerIrql(OldIrql);
-
- return TRUE;
-}
-
-VOID
-NTAPI
-KdpGdbDebugPrint(PCH Message, ULONG Length)
-{
-}
-
-/* Initialize the GDB stub */
-VOID
-NTAPI
-KdpGdbStubInit(PKD_DISPATCH_TABLE WrapperTable,
- ULONG BootPhase)
-{
- if (!KdDebuggerEnabled || !KdpDebugMode.Gdb)
- return;
-
- if (BootPhase == 0)
- {
- ExInitializeFastMutex(&GspLock);
-
- /* Write out the functions that we support for now */
- WrapperTable->KdpInitRoutine = KdpGdbStubInit;
- WrapperTable->KdpPrintRoutine = KdpGdbDebugPrint;
- WrapperTable->KdpExceptionRoutine = KdpGdbEnterDebuggerException;
-
- /* Initialize the Port */
- KdPortInitializeEx(&GdbPortInfo, GdbPortNumber);
- // KdpPort = GdbPortInfo.ComPort;
- }
- else if (BootPhase == 1)
- {
- GspInitialized = TRUE;
-
- GspRunThread = NULL;
- GspDbgThread = NULL;
- GspEnumThread = NULL;
-
- HalDisplayString("Waiting for GDB to attach\r\n");
- DbgBreakPointWithStatus(DBG_STATUS_CONTROL_C);
- }
- else if (BootPhase == 2)
- {
- HalDisplayString("\r\n GDB debugging enabled\r\n\r\n");
- }
-}
-
-/* EOF */
diff --git a/ntoskrnl/ntos.cmake b/ntoskrnl/ntos.cmake
index 6b2a127c2fd..c9928ef9706 100644
--- a/ntoskrnl/ntos.cmake
+++ b/ntoskrnl/ntos.cmake
@@ -374,8 +374,7 @@ endif()
if(NOT _WINKD_)
if(ARCH STREQUAL "i386")
list(APPEND SOURCE
- ${REACTOS_SOURCE_DIR}/ntoskrnl/kd/i386/kdbg.c
- ${REACTOS_SOURCE_DIR}/ntoskrnl/kd/wrappers/gdbstub.c)
+ ${REACTOS_SOURCE_DIR}/ntoskrnl/kd/i386/kdbg.c)
if(KDBG)
list(APPEND ASM_SOURCE ${REACTOS_SOURCE_DIR}/ntoskrnl/kdbg/i386/kdb_help.S)
list(APPEND SOURCE ${REACTOS_SOURCE_DIR}/ntoskrnl/kdbg/i386/i386-dis.c)
@@ -392,8 +391,6 @@ if(NOT _WINKD_)
endif()
elseif(ARCH STREQUAL "arm")
list(APPEND SOURCE ${REACTOS_SOURCE_DIR}/ntoskrnl/kd/arm/kdbg.c)
- elseif(ARCH STREQUAL "powerpc")
- list(APPEND SOURCE ${REACTOS_SOURCE_DIR}/ntoskrnl/kd/wrappers/gdbstub_powerpc.c)
endif()
if(KDBG)