https://git.reactos.org/?p=reactos.git;a=commitdiff;h=2046a17ef475ac8d80bfdcffc09d35712e14ec4a

commit 2046a17ef475ac8d80bfdcffc09d35712e14ec4a
Author:     Hermès Bélusca-Maïto <hermes.belusca-ma...@reactos.org>
AuthorDate: Tue Mar 21 18:42:29 2023 +0100
Commit:     Hermès Bélusca-Maïto <hermes.belusca-ma...@reactos.org>
CommitDate: Thu Aug 31 16:07:51 2023 +0200

    [NTOS:KD:KDBG] Integration into KD framework (Part 1/3)
    
    Split KdSendPacket and KdReceivePacket into those that manipulate the
    KDBG state proper (reside in kdbg/kdbg.c), and those that deal only with
    debug input/output that will reside in a KDTERM "KD Terminal Driver" DLL.
    
    Based on some previous preparatory work by Hervé Poussineau in PR #4600.
    (Equivalents of commits 5162bf106 and partly e9bcf7275.)
---
 ntoskrnl/include/internal/kd.h |   7 --
 ntoskrnl/include/ntoskrnl.h    |  12 +--
 ntoskrnl/kd/kdio.c             | 151 +++++++-----------------------------
 ntoskrnl/kdbg/kdb.h            |  28 ++++---
 ntoskrnl/kdbg/kdb_print.c      |  22 ++++--
 ntoskrnl/kdbg/kdbg.c           | 170 +++++++++++++++++++++++++++++++++++++++++
 ntoskrnl/ntos.cmake            |   1 +
 7 files changed, 242 insertions(+), 149 deletions(-)

diff --git a/ntoskrnl/include/internal/kd.h b/ntoskrnl/include/internal/kd.h
index a180acf5478..caeb605cb12 100644
--- a/ntoskrnl/include/internal/kd.h
+++ b/ntoskrnl/include/internal/kd.h
@@ -30,13 +30,6 @@ KdPortPutByteEx(
 
 /* KD GLOBALS ****************************************************************/
 
-typedef enum _KD_CONTINUE_TYPE
-{
-    kdContinue = 0,
-    kdDoNotHandleException,
-    kdHandleException
-} KD_CONTINUE_TYPE;
-
 /* KD Internal Debug Services */
 typedef enum _KDP_DEBUG_SERVICE
 {
diff --git a/ntoskrnl/include/ntoskrnl.h b/ntoskrnl/include/ntoskrnl.h
index 6f2f5379bec..4d70fd91627 100644
--- a/ntoskrnl/include/ntoskrnl.h
+++ b/ntoskrnl/include/ntoskrnl.h
@@ -88,13 +88,15 @@
 #define NOEXTAPI
 #include <windbgkd.h>
 #include <wdbgexts.h>
+#include <kddll.h>
 #ifdef KDBG
-#define KdDebuggerInitialize0 KdpDebuggerInitialize0
-#define KdDebuggerInitialize1 KdpDebuggerInitialize1
-#define KdSendPacket KdpSendPacket
-#define KdReceivePacket KdpReceivePacket
+    /* Define new names for these exports also present in KDBG */
+    #define KdSendPacket            KdbgSendPacket
+    #define KdReceivePacket         KdbgReceivePacket
+    /* And reload the definitions with these new names */
+    #undef _KDDLL_
+    #include <kddll.h>
 #endif
-#include <kddll.h>
 #ifdef __ROS_ROSSYM__
 #include <reactos/rossym.h>
 #endif
diff --git a/ntoskrnl/kd/kdio.c b/ntoskrnl/kd/kdio.c
index 82a1ade1ed7..1a9c4c5fbb4 100644
--- a/ntoskrnl/kd/kdio.c
+++ b/ntoskrnl/kd/kdio.c
@@ -20,6 +20,9 @@
 #define NDEBUG
 #include <debug.h>
 
+#undef KdSendPacket
+#undef KdReceivePacket
+
 /* GLOBALS *******************************************************************/
 
 #define KdpBufferSize  (1024 * 512)
@@ -54,12 +57,6 @@ PKDP_INIT_ROUTINE InitRoutines[KdMax] =
 #endif
 };
 
-static ULONG KdbgNextApiNumber = DbgKdContinueApi;
-static CONTEXT KdbgContext;
-static EXCEPTION_RECORD64 KdbgExceptionRecord;
-static BOOLEAN KdbgFirstChanceException;
-static NTSTATUS KdbgContinueStatus = STATUS_SUCCESS;
-
 /* LOCKING FUNCTIONS *********************************************************/
 
 KIRQL
@@ -607,93 +604,36 @@ KdSendPacket(
     _In_opt_ PSTRING MessageData,
     _Inout_ PKD_CONTEXT Context)
 {
-    if (PacketType == PACKET_TYPE_KD_DEBUG_IO)
-    {
-        ULONG ApiNumber = ((PDBGKD_DEBUG_IO)MessageHeader->Buffer)->ApiNumber;
-
-        /* Validate API call */
-        if (MessageHeader->Length != sizeof(DBGKD_DEBUG_IO))
-            return;
-        if ((ApiNumber != DbgKdPrintStringApi) &&
-            (ApiNumber != DbgKdGetStringApi))
-        {
-            return;
-        }
-        if (!MessageData)
-            return;
+    PDBGKD_DEBUG_IO DebugIo;
 
-        /* NOTE: MessageData->Length should be equal to
-         * DebugIo.u.PrintString.LengthOfString, or to
-         * DebugIo.u.GetString.LengthOfPromptString */
+    if (PacketType != PACKET_TYPE_KD_DEBUG_IO)
+    {
+        KdIoPrintf("%s: PacketType %d is UNIMPLEMENTED\n", __FUNCTION__, 
PacketType);
+        return;
+    }
 
-        if (!KdpDebugMode.Value)
-            return;
+    DebugIo = (PDBGKD_DEBUG_IO)MessageHeader->Buffer;
 
-        /* Print the string proper */
-        KdIoPrintString(MessageData->Buffer, MessageData->Length);
+    /* Validate API call */
+    if (MessageHeader->Length != sizeof(DBGKD_DEBUG_IO))
         return;
-    }
-    else if (PacketType == PACKET_TYPE_KD_STATE_CHANGE64)
+    if ((DebugIo->ApiNumber != DbgKdPrintStringApi) &&
+        (DebugIo->ApiNumber != DbgKdGetStringApi))
     {
-        PDBGKD_ANY_WAIT_STATE_CHANGE WaitStateChange = 
(PDBGKD_ANY_WAIT_STATE_CHANGE)MessageHeader->Buffer;
-        if (WaitStateChange->NewState == DbgKdLoadSymbolsStateChange)
-        {
-#ifdef KDBG
-            PLDR_DATA_TABLE_ENTRY LdrEntry;
-            /* Load symbols. Currently implemented only for KDBG! */
-            if 
(KdbpSymFindModule((PVOID)(ULONG_PTR)WaitStateChange->u.LoadSymbols.BaseOfDll, 
-1, &LdrEntry))
-            {
-                KdbSymProcessSymbols(LdrEntry, 
!WaitStateChange->u.LoadSymbols.UnloadSymbols);
-            }
-#endif
-            return;
-        }
-        else if (WaitStateChange->NewState == DbgKdExceptionStateChange)
-        {
-            KdbgNextApiNumber = DbgKdGetContextApi;
-            KdbgExceptionRecord = WaitStateChange->u.Exception.ExceptionRecord;
-            KdbgFirstChanceException = 
WaitStateChange->u.Exception.FirstChance;
-            return;
-        }
+        return;
     }
-    else if (PacketType == PACKET_TYPE_KD_STATE_MANIPULATE)
-    {
-        PDBGKD_MANIPULATE_STATE64 ManipulateState = 
(PDBGKD_MANIPULATE_STATE64)MessageHeader->Buffer;
-        if (ManipulateState->ApiNumber == DbgKdGetContextApi)
-        {
-            KD_CONTINUE_TYPE Result;
+    if (!MessageData)
+        return;
 
-#ifdef KDBG
-            /* Check if this is an assertion failure */
-            if (KdbgExceptionRecord.ExceptionCode == STATUS_ASSERTION_FAILURE)
-            {
-                /* Bump EIP to the instruction following the int 2C */
-                KeSetContextPc(&KdbgContext, KeGetContextPc(&KdbgContext) + 2);
-            }
+    /* NOTE: MessageData->Length should be equal to
+     * DebugIo.u.PrintString.LengthOfString, or to
+     * DebugIo.u.GetString.LengthOfPromptString */
 
-            Result = KdbEnterDebuggerException(&KdbgExceptionRecord,
-                                               KdbgContext.SegCs & 1,
-                                               &KdbgContext,
-                                               KdbgFirstChanceException);
-#else
-            /* We'll manually dump the stack for the user... */
-            KeRosDumpStackFrames(NULL, 0);
-            Result = kdHandleException;
-#endif
-            if (Result != kdHandleException)
-                KdbgContinueStatus = STATUS_SUCCESS;
-            else
-                KdbgContinueStatus = STATUS_UNSUCCESSFUL;
-            KdbgNextApiNumber = DbgKdSetContextApi;
-            return;
-        }
-        else if (ManipulateState->ApiNumber == DbgKdSetContextApi)
-        {
-            KdbgNextApiNumber = DbgKdContinueApi;
-            return;
-        }
-    }
-    UNIMPLEMENTED;
+    if (!KdpDebugMode.Value)
+        return;
+
+    /* Print the string proper */
+    KdIoPrintString(MessageData->Buffer, MessageData->Length);
 }
 
 KDSTATUS
@@ -705,48 +645,16 @@ KdReceivePacket(
     _Out_ PULONG DataLength,
     _Inout_ PKD_CONTEXT Context)
 {
-#ifdef KDBG
-    STRING ResponseString;
     PDBGKD_DEBUG_IO DebugIo;
+    STRING ResponseString;
     CHAR MessageBuffer[512];
-#endif
-
-    if (PacketType == PACKET_TYPE_KD_STATE_MANIPULATE)
-    {
-        PDBGKD_MANIPULATE_STATE64 ManipulateState = 
(PDBGKD_MANIPULATE_STATE64)MessageHeader->Buffer;
-        RtlZeroMemory(MessageHeader->Buffer, MessageHeader->MaximumLength);
-        if (KdbgNextApiNumber == DbgKdGetContextApi)
-        {
-            ManipulateState->ApiNumber = DbgKdGetContextApi;
-            MessageData->Length = 0;
-            MessageData->Buffer = (PCHAR)&KdbgContext;
-            return KdPacketReceived;
-        }
-        else if (KdbgNextApiNumber == DbgKdSetContextApi)
-        {
-            ManipulateState->ApiNumber = DbgKdSetContextApi;
-            MessageData->Length = sizeof(KdbgContext);
-            MessageData->Buffer = (PCHAR)&KdbgContext;
-            return KdPacketReceived;
-        }
-        else if (KdbgNextApiNumber != DbgKdContinueApi)
-        {
-            UNIMPLEMENTED;
-        }
-        ManipulateState->ApiNumber = DbgKdContinueApi;
-        ManipulateState->u.Continue.ContinueStatus = KdbgContinueStatus;
-
-        /* Prepare for next time */
-        KdbgNextApiNumber = DbgKdContinueApi;
-        KdbgContinueStatus = STATUS_SUCCESS;
-
-        return KdPacketReceived;
-    }
 
     if (PacketType != PACKET_TYPE_KD_DEBUG_IO)
+    {
+        KdIoPrintf("%s: PacketType %d is UNIMPLEMENTED\n", __FUNCTION__, 
PacketType);
         return KdPacketTimedOut;
+    }
 
-#ifdef KDBG
     DebugIo = (PDBGKD_DEBUG_IO)MessageHeader->Buffer;
 
     /* Validate API call */
@@ -795,7 +703,6 @@ KdReceivePacket(
 
     /* Only now we can copy back the data into MessageData->Buffer */
     RtlCopyMemory(MessageData->Buffer, ResponseString.Buffer, *DataLength);
-#endif
 
     return KdPacketReceived;
 }
diff --git a/ntoskrnl/kdbg/kdb.h b/ntoskrnl/kdbg/kdb.h
index 2170be54f9f..df2945a7d9c 100644
--- a/ntoskrnl/kdbg/kdb.h
+++ b/ntoskrnl/kdbg/kdb.h
@@ -51,6 +51,25 @@ typedef enum _KDB_ENTER_CONDITION
    KdbEnterFromUmode
 } KDB_ENTER_CONDITION;
 
+typedef enum _KD_CONTINUE_TYPE
+{
+    kdContinue = 0,
+    kdDoNotHandleException,
+    kdHandleException
+} KD_CONTINUE_TYPE;
+
+
+/* GLOBALS *******************************************************************/
+
+extern PCHAR KdbInitFileBuffer;
+
+extern PEPROCESS KdbCurrentProcess;
+extern PETHREAD KdbCurrentThread;
+extern LONG KdbLastBreakPointNr;
+extern ULONG KdbNumSingleSteps;
+extern BOOLEAN KdbSingleStepOver;
+extern PKDB_KTRAP_FRAME KdbCurrentTrapFrame;
+
 
 /* FUNCTIONS *****************************************************************/
 
@@ -74,8 +93,6 @@ KdbpStackSwitchAndCall(
 
 /* from kdb_cli.c */
 
-extern PCHAR KdbInitFileBuffer;
-
 NTSTATUS
 NTAPI
 KdbInitialize(
@@ -175,13 +192,6 @@ KdbSymInit(
 
 /* from kdb.c */
 
-extern PEPROCESS KdbCurrentProcess;
-extern PETHREAD KdbCurrentThread;
-extern LONG KdbLastBreakPointNr;
-extern ULONG KdbNumSingleSteps;
-extern BOOLEAN KdbSingleStepOver;
-extern PKDB_KTRAP_FRAME KdbCurrentTrapFrame;
-
 LONG
 KdbpGetNextBreakPointNr(
    IN ULONG Start  OPTIONAL);
diff --git a/ntoskrnl/kdbg/kdb_print.c b/ntoskrnl/kdbg/kdb_print.c
index 257b37e1225..85b3ac20a6c 100644
--- a/ntoskrnl/kdbg/kdb_print.c
+++ b/ntoskrnl/kdbg/kdb_print.c
@@ -13,6 +13,14 @@
 
 /* FUNCTIONS *****************************************************************/
 
+static KD_CONTEXT KdbgKdContext;
+
+#undef KdSendPacket
+#define pKdSendPacket KdSendPacket
+
+#undef KdReceivePacket
+#define pKdReceivePacket KdReceivePacket
+
 static VOID
 KdbPrintStringWorker(
     _In_ const CSTRING* Output,
@@ -48,7 +56,8 @@ KdbPrintStringWorker(
     Data->Buffer = (PCHAR)Output->Buffer;
 
     /* Send the packet */
-    KdSendPacket(PACKET_TYPE_KD_DEBUG_IO, Header, Data, &KdpContext);
+    /* IO packet: call KdTerm */
+    pKdSendPacket(PACKET_TYPE_KD_DEBUG_IO, Header, Data, &KdbgKdContext);
 }
 
 VOID
@@ -88,11 +97,12 @@ KdbPromptStringWorker(
     do
     {
         /* Get our reply */
-        Status = KdReceivePacket(PACKET_TYPE_KD_DEBUG_IO,
-                                 &Header,
-                                 &Data,
-                                 &Length,
-                                 &KdpContext);
+        /* IO packet: call KdTerm */
+        Status = pKdReceivePacket(PACKET_TYPE_KD_DEBUG_IO,
+                                  &Header,
+                                  &Data,
+                                  &Length,
+                                  &KdbgKdContext);
 
         /* Return TRUE if we need to resend */
         if (Status == KdPacketNeedsResend)
diff --git a/ntoskrnl/kdbg/kdbg.c b/ntoskrnl/kdbg/kdbg.c
new file mode 100644
index 00000000000..ac78f72b7e3
--- /dev/null
+++ b/ntoskrnl/kdbg/kdbg.c
@@ -0,0 +1,170 @@
+/*
+ * PROJECT:     ReactOS KDBG Kernel Debugger
+ * LICENSE:     GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later)
+ * PURPOSE:     Kernel Debugger Initialization
+ * COPYRIGHT:   Copyright 2020-2021 Hervé Poussineau <hpous...@reactos.org>
+ *              Copyright 2021 Jérôme Gardou <jerome.gar...@reactos.org>
+ *              Copyright 2023 Hermès Bélusca-Maïto 
<hermes.belusca-ma...@reactos.org>
+ */
+
+/* INCLUDES ******************************************************************/
+
+#include <ntoskrnl.h>
+#include "kdb.h"
+
+/* GLOBALS *******************************************************************/
+
+static ULONG KdbgNextApiNumber = DbgKdContinueApi;
+static CONTEXT KdbgContext;
+static EXCEPTION_RECORD64 KdbgExceptionRecord;
+static BOOLEAN KdbgFirstChanceException;
+static NTSTATUS KdbgContinueStatus = STATUS_SUCCESS;
+
+/* FUNCTIONS *****************************************************************/
+
+VOID
+NTAPI
+KdSendPacket(
+    _In_ ULONG PacketType,
+    _In_ PSTRING MessageHeader,
+    _In_opt_ PSTRING MessageData,
+    _Inout_ PKD_CONTEXT Context)
+#undef KdSendPacket
+#define pKdSendPacket KdSendPacket
+{
+    if (PacketType == PACKET_TYPE_KD_DEBUG_IO)
+    {
+        /* Call KdTerm */
+        pKdSendPacket(PacketType, MessageHeader, MessageData, Context);
+        return;
+    }
+
+    /* Debugger-only packets */
+    if (PacketType == PACKET_TYPE_KD_STATE_CHANGE64)
+    {
+        PDBGKD_ANY_WAIT_STATE_CHANGE WaitStateChange = 
(PDBGKD_ANY_WAIT_STATE_CHANGE)MessageHeader->Buffer;
+        if (WaitStateChange->NewState == DbgKdLoadSymbolsStateChange)
+        {
+            /* Load or unload symbols */
+            PLDR_DATA_TABLE_ENTRY LdrEntry;
+            if 
(KdbpSymFindModule((PVOID)(ULONG_PTR)WaitStateChange->u.LoadSymbols.BaseOfDll, 
-1, &LdrEntry))
+            {
+                KdbSymProcessSymbols(LdrEntry, 
!WaitStateChange->u.LoadSymbols.UnloadSymbols);
+            }
+            return;
+        }
+        else if (WaitStateChange->NewState == DbgKdExceptionStateChange)
+        {
+            KdbgNextApiNumber = DbgKdGetContextApi;
+            KdbgExceptionRecord = WaitStateChange->u.Exception.ExceptionRecord;
+            KdbgFirstChanceException = 
WaitStateChange->u.Exception.FirstChance;
+            return;
+        }
+    }
+    else if (PacketType == PACKET_TYPE_KD_STATE_MANIPULATE)
+    {
+        PDBGKD_MANIPULATE_STATE64 ManipulateState = 
(PDBGKD_MANIPULATE_STATE64)MessageHeader->Buffer;
+        if (ManipulateState->ApiNumber == DbgKdGetContextApi)
+        {
+            KD_CONTINUE_TYPE Result;
+
+            /* Check if this is an assertion failure */
+            if (KdbgExceptionRecord.ExceptionCode == STATUS_ASSERTION_FAILURE)
+            {
+                /* Bump EIP to the instruction following the int 2C */
+                KeSetContextPc(&KdbgContext, KeGetContextPc(&KdbgContext) + 2);
+            }
+
+            Result = KdbEnterDebuggerException(&KdbgExceptionRecord,
+                                               KdbgContext.SegCs & 1,
+                                               &KdbgContext,
+                                               KdbgFirstChanceException);
+#if 0
+            /* Manually dump the stack for the user */
+            KeRosDumpStackFrames(NULL, 0);
+            Result = kdHandleException;
+#endif
+            if (Result != kdHandleException)
+                KdbgContinueStatus = STATUS_SUCCESS;
+            else
+                KdbgContinueStatus = STATUS_UNSUCCESSFUL;
+            KdbgNextApiNumber = DbgKdSetContextApi;
+            return;
+        }
+        else if (ManipulateState->ApiNumber == DbgKdSetContextApi)
+        {
+            KdbgNextApiNumber = DbgKdContinueApi;
+            return;
+        }
+    }
+
+    KdbPrintf("%s: PacketType %d is UNIMPLEMENTED\n", __FUNCTION__, 
PacketType);
+    return;
+}
+
+KDSTATUS
+NTAPI
+KdReceivePacket(
+    _In_ ULONG PacketType,
+    _Out_ PSTRING MessageHeader,
+    _Out_ PSTRING MessageData,
+    _Out_ PULONG DataLength,
+    _Inout_ PKD_CONTEXT Context)
+#undef KdReceivePacket
+#define pKdReceivePacket KdReceivePacket
+{
+    if (PacketType == PACKET_TYPE_KD_POLL_BREAKIN)
+    {
+        // FIXME TODO: Implement break-in for the debugger
+        // and return KdPacketReceived when handled properly.
+        return KdPacketTimedOut;
+    }
+
+    if (PacketType == PACKET_TYPE_KD_DEBUG_IO)
+    {
+        /* Call KdTerm */
+        return pKdReceivePacket(PacketType,
+                                MessageHeader,
+                                MessageData,
+                                DataLength,
+                                Context);
+    }
+
+    /* Debugger-only packets */
+    if (PacketType == PACKET_TYPE_KD_STATE_MANIPULATE)
+    {
+        PDBGKD_MANIPULATE_STATE64 ManipulateState = 
(PDBGKD_MANIPULATE_STATE64)MessageHeader->Buffer;
+        RtlZeroMemory(MessageHeader->Buffer, MessageHeader->MaximumLength);
+        if (KdbgNextApiNumber == DbgKdGetContextApi)
+        {
+            ManipulateState->ApiNumber = DbgKdGetContextApi;
+            MessageData->Length = 0;
+            MessageData->Buffer = (PCHAR)&KdbgContext;
+            return KdPacketReceived;
+        }
+        else if (KdbgNextApiNumber == DbgKdSetContextApi)
+        {
+            ManipulateState->ApiNumber = DbgKdSetContextApi;
+            MessageData->Length = sizeof(KdbgContext);
+            MessageData->Buffer = (PCHAR)&KdbgContext;
+            return KdPacketReceived;
+        }
+        else if (KdbgNextApiNumber != DbgKdContinueApi)
+        {
+            KdbPrintf("%s:%d is UNIMPLEMENTED\n", __FUNCTION__, __LINE__);
+        }
+        ManipulateState->ApiNumber = DbgKdContinueApi;
+        ManipulateState->u.Continue.ContinueStatus = KdbgContinueStatus;
+
+        /* Prepare for next time */
+        KdbgNextApiNumber = DbgKdContinueApi;
+        KdbgContinueStatus = STATUS_SUCCESS;
+
+        return KdPacketReceived;
+    }
+
+    KdbPrintf("%s: PacketType %d is UNIMPLEMENTED\n", __FUNCTION__, 
PacketType);
+    return KdPacketTimedOut;
+}
+
+/* EOF */
diff --git a/ntoskrnl/ntos.cmake b/ntoskrnl/ntos.cmake
index dddb6cae4ab..a85cb19e39a 100644
--- a/ntoskrnl/ntos.cmake
+++ b/ntoskrnl/ntos.cmake
@@ -404,6 +404,7 @@ if(NOT _WINKD_)
 
     if(KDBG)
         list(APPEND SOURCE
+            ${REACTOS_SOURCE_DIR}/ntoskrnl/kdbg/kdbg.c
             ${REACTOS_SOURCE_DIR}/ntoskrnl/kdbg/kdb.c
             ${REACTOS_SOURCE_DIR}/ntoskrnl/kdbg/kdb_cli.c
             ${REACTOS_SOURCE_DIR}/ntoskrnl/kdbg/kdb_cmdhist.c

Reply via email to