- KdDebuggerNotPresent should be FALSE by default.
authorAlex Ionescu <aionescu@gmail.com>
Sun, 18 Feb 2007 22:32:32 +0000 (22:32 +0000)
committerAlex Ionescu <aionescu@gmail.com>
Sun, 18 Feb 2007 22:32:32 +0000 (22:32 +0000)
- KdpTimeSlipPending should be 1 by defalt.
- Enable KdInitSystem; don't touch SharedUserData yet because our loader doesn't map it properly until we hit MmInit1, so disable this code for now.
- Implement KdpPollBreakInWithPortLock.
- Add calls to KdpPrint, KdpSymbol since KdpTrap now gets activated. Implement KdpPrint and KdpPrintString, but not KdLogDbgPrint (so debug messages before WinDBG connects are currently lost).
- Implement KdpSymbol but not essential call to KdpReportLoadSymbolsStateChange.
- Only save/restore CR4 if KeFeatureBits indicates CR4 support exists.
- Export KdDebuggerNotPresent since KDCOM needs it.

svn path=/branches/alex-kd-branch/; revision=25839

reactos/ntoskrnl/include/internal/kd.h
reactos/ntoskrnl/kd64/kddata.c
reactos/ntoskrnl/kd64/kdinit.c
reactos/ntoskrnl/kd64/kdlock.c
reactos/ntoskrnl/kd64/kdprint.c [new file with mode: 0644]
reactos/ntoskrnl/kd64/kdtrap.c
reactos/ntoskrnl/ke/i386/cpu.c
reactos/ntoskrnl/ke/i386/kiinit.c
reactos/ntoskrnl/ntoskrnl.def
reactos/ntoskrnl/ntoskrnl.rbuild

index 699e0f0..a065b35 100644 (file)
@@ -104,6 +104,37 @@ KdEnableDebuggerWithLock(
     IN BOOLEAN NeedLock
 );
 
+ULONG
+NTAPI
+KdpPrint(
+    IN ULONG ComponentId,
+    IN ULONG ComponentMask,
+    IN LPSTR String,
+    IN ULONG Length,
+    IN KPROCESSOR_MODE PreviousMode,
+    IN PKTRAP_FRAME TrapFrame,
+    IN PKEXCEPTION_FRAME ExceptionFrame,
+    OUT PBOOLEAN Status
+);
+
+ULONG
+NTAPI
+KdpSymbol(
+    IN LPSTR DllPath,
+    IN ULONG DllBase,
+    IN BOOLEAN Unload,
+    IN KPROCESSOR_MODE PreviousMode,
+    IN PCONTEXT ContextRecord,
+    IN PKTRAP_FRAME TrapFrame,
+    IN PKEXCEPTION_FRAME ExceptionFrame
+);
+
+BOOLEAN
+NTAPI
+KdpPollBreakInWithPortLock(
+    VOID
+);
+
 extern DBGKD_GET_VERSION64 KdVersionBlock;
 extern KDDEBUGGER_DATA64 KdDebuggerDataBlock;
 extern LIST_ENTRY KdpDebuggerDataListHead;
@@ -133,4 +164,6 @@ extern BOOLEAN KdpControlCWaiting;
 extern BOOLEAN KdpPortLocked;
 extern KSPIN_LOCK KdpDebuggerLock;
 extern LARGE_INTEGER KdTimerStop, KdTimerStart, KdTimerDifference;
-
+extern ULONG KdComponentTableSize;
+extern ULONG Kd_WIN2000_Mask;
+extern PULONG KdComponentTable[104];
index da85b0b..50daca0 100644 (file)
@@ -62,7 +62,7 @@ PKDEBUG_SWITCH_ROUTINE KiDebugSwitchRoutine;
 //\r
 BOOLEAN KdBreakAfterSymbolLoad;\r
 BOOLEAN KdPitchDebugger;\r
-BOOLEAN _KdDebuggerNotPresent = TRUE;\r
+BOOLEAN _KdDebuggerNotPresent;\r
 BOOLEAN _KdDebuggerEnabled;\r
 BOOLEAN KdAutoEnableOnEvent;\r
 BOOLEAN KdPreviouslyEnabled;\r
@@ -77,7 +77,7 @@ LARGE_INTEGER KdPerformanceCounterRate;
 KDPC KdpTimeSlipDpc;\r
 KTIMER KdpTimeSlipTimer;\r
 WORK_QUEUE_ITEM KdpTimeSlipWorkItem;\r
-LONG KdpTimeSlipPending;\r
+LONG KdpTimeSlipPending = 1;\r
 PKEVENT KdpTimeSlipEvent;\r
 KSPIN_LOCK KdpTimeSlipEventLock;\r
 LARGE_INTEGER KdTimerStop, KdTimerStart, KdTimerDifference;\r
index 40b449f..0022756 100644 (file)
@@ -70,7 +70,6 @@ KdInitSystem(IN ULONG BootPhase,
     PLIST_ENTRY NextEntry;\r
     ULONG i;\r
     CHAR NameBuffer[256];\r
-    return TRUE;\r
 \r
     /* Check if this is Phase 1 */\r
     if (BootPhase)\r
@@ -207,9 +206,9 @@ KdInitSystem(IN ULONG BootPhase,
         KdDebuggerEnabled = TRUE;\r
 \r
         /* Let user-mode know that it's enabled as well */\r
-#undef KdDebuggerEnabled\r
-        SharedUserData->KdDebuggerEnabled = TRUE;\r
-#define KdDebuggerEnabled _KdDebuggerEnabled\r
+//#undef KdDebuggerEnabled\r
+        //SharedUserData->KdDebuggerEnabled = TRUE;\r
+//#define KdDebuggerEnabled _KdDebuggerEnabled\r
 \r
         /* Check if we have a loader block */\r
         if (LoaderBlock)\r
index 179115b..9f5eafd 100644 (file)
@@ -30,6 +30,41 @@ KdpPortUnlock(VOID)
     KiReleaseSpinLock(&KdpDebuggerLock);\r
 }\r
 \r
+BOOLEAN\r
+NTAPI\r
+KdpPollBreakInWithPortLock(VOID)\r
+{\r
+    BOOLEAN DoBreak = FALSE;\r
+\r
+    /* First make sure that KD is enabled */\r
+    if (KdDebuggerEnabled)\r
+    {\r
+        /* Check if a CTRL-C is in the queue */\r
+        if (KdpContext.KdpControlCPending)\r
+        {\r
+            /* Set it and prepare for break */\r
+            DoBreak = TRUE;\r
+            KdpContext.KdpControlCPending = FALSE;\r
+        }\r
+        else\r
+        {\r
+            /* Now get a packet */\r
+            if (!KdReceivePacket(PACKET_TYPE_KD_POLL_BREAKIN,\r
+                                 NULL,\r
+                                 NULL,\r
+                                 NULL,\r
+                                 NULL))\r
+            {\r
+                /* Successful breakin */\r
+                DoBreak = TRUE;\r
+            }\r
+        }\r
+    }\r
+\r
+    /* Tell the caller to do a break */\r
+    return DoBreak;\r
+}\r
+\r
 /* PUBLIC FUNCTIONS **********************************************************/\r
 \r
 /*\r
diff --git a/reactos/ntoskrnl/kd64/kdprint.c b/reactos/ntoskrnl/kd64/kdprint.c
new file mode 100644 (file)
index 0000000..a46b54b
--- /dev/null
@@ -0,0 +1,204 @@
+/*\r
+ * PROJECT:         ReactOS Kernel\r
+ * LICENSE:         GPL - See COPYING in the top level directory\r
+ * FILE:            ntoskrnl/kd64/kdprint.c\r
+ * PURPOSE:         KD64 Trap Handler Routines\r
+ * PROGRAMMERS:     Alex Ionescu (alex.ionescu@reactos.org)\r
+ */\r
+\r
+/* INCLUDES ******************************************************************/\r
+\r
+#include <ntoskrnl.h>\r
+#define NDEBUG\r
+#include <debug.h>\r
+\r
+CHAR KdpMessageBuffer[4096];\r
+\r
+/* FUNCTIONS *****************************************************************/\r
+\r
+BOOLEAN\r
+NTAPI\r
+KdpPrintString(IN PSTRING Output)\r
+{\r
+    STRING Data, Header;\r
+    DBGKD_DEBUG_IO DebugIo;\r
+    ULONG Length = Output->Length;\r
+\r
+    /* Copy the string */\r
+    RtlMoveMemory(KdpMessageBuffer, Output->Buffer, Length);\r
+\r
+    /* Make sure we don't exceed the KD Packet size */\r
+    if ((sizeof(DBGKD_DEBUG_IO) + Length) > PACKET_MAX_SIZE)\r
+    {\r
+        /* Normalize length */\r
+        Length = PACKET_MAX_SIZE - sizeof(DBGKD_DEBUG_IO);\r
+    }\r
+\r
+    /* Build the packet header */\r
+    DebugIo.ApiNumber = DbgKdPrintStringApi;\r
+    DebugIo.ProcessorLevel = KeProcessorLevel;\r
+    DebugIo.Processor = KeGetCurrentPrcb()->Number;\r
+    DebugIo.u.PrintString.LengthOfString = Length;\r
+    Header.Length = sizeof(DBGKD_DEBUG_IO);\r
+    Header.Buffer = (PCHAR)&DebugIo;\r
+\r
+    /* Build the data */\r
+    Data.Length = Length;\r
+    Data.Buffer = KdpMessageBuffer;\r
+\r
+    /* Send the packet */\r
+    KdSendPacket(PACKET_TYPE_KD_DEBUG_IO, &Header, &Data, &KdpContext);\r
+\r
+    /* Check if the user pressed CTRL+C */\r
+    return KdpPollBreakInWithPortLock();\r
+}\r
+\r
+ULONG\r
+NTAPI\r
+KdpCommandString(IN ULONG Length,\r
+                 IN LPSTR String,\r
+                 IN KPROCESSOR_MODE PreviousMode,\r
+                 IN PCONTEXT ContextRecord,\r
+                 IN PKTRAP_FRAME TrapFrame,\r
+                 IN PKEXCEPTION_FRAME ExceptionFrame)\r
+{\r
+    /* FIXME */\r
+    return FALSE;\r
+}\r
+\r
+ULONG\r
+NTAPI\r
+KdpSymbol(IN LPSTR DllPath,\r
+          IN ULONG DllBase,\r
+          IN BOOLEAN Unload,\r
+          IN KPROCESSOR_MODE PreviousMode,\r
+          IN PCONTEXT ContextRecord,\r
+          IN PKTRAP_FRAME TrapFrame,\r
+          IN PKEXCEPTION_FRAME ExceptionFrame)\r
+{\r
+    BOOLEAN Entered;\r
+    PKPRCB Prcb = KeGetCurrentPrcb();\r
+    ULONG Status;\r
+\r
+    /* Check if we need to do anything */\r
+    if ((PreviousMode != KernelMode) || (KdDebuggerNotPresent)) return 0;\r
+\r
+    /* Enter the debugger */\r
+    Entered = KdEnterDebugger(TrapFrame, ExceptionFrame);\r
+\r
+    /* Save the CPU Control State and save the context */\r
+    KiSaveProcessorControlState(&Prcb->ProcessorState);\r
+    RtlCopyMemory(&Prcb->ProcessorState.ContextFrame,\r
+                  ContextRecord,\r
+                  sizeof(CONTEXT));\r
+\r
+    /* Report the new state */\r
+#if 0\r
+    Status = KdpReportLoadSymbolsStateChange(DllPath,\r
+                                             DllBase,\r
+                                             Unload,\r
+                                             &Prcb->\r
+                                             ProcessorState.ContextFrame);\r
+#else\r
+    Status = FALSE;\r
+#endif\r
+\r
+    /* Now restore the processor state, manually again. */\r
+    RtlCopyMemory(ContextRecord,\r
+                  &Prcb->ProcessorState.ContextFrame,\r
+                  sizeof(CONTEXT));\r
+    KiRestoreProcessorControlState(&Prcb->ProcessorState);\r
+\r
+    /* Exit the debugger and clear the CTRL-C state */\r
+    KdExitDebugger(Entered);\r
+    return 0;\r
+}\r
+\r
+ULONG\r
+NTAPI\r
+KdpPrompt(IN LPSTR InString,\r
+          IN ULONG InStringLength,\r
+          OUT LPSTR OutString,\r
+          IN ULONG OutStringLength,\r
+          IN KPROCESSOR_MODE PreviousMode,\r
+          IN PKTRAP_FRAME TrapFrame,\r
+          IN PKEXCEPTION_FRAME ExceptionFrame)\r
+{\r
+    /* FIXME */\r
+    return FALSE;\r
+}\r
+\r
+ULONG\r
+NTAPI\r
+KdpPrint(IN ULONG ComponentId,\r
+         IN ULONG ComponentMask,\r
+         IN LPSTR String,\r
+         IN ULONG Length,\r
+         IN KPROCESSOR_MODE PreviousMode,\r
+         IN PKTRAP_FRAME TrapFrame,\r
+         IN PKEXCEPTION_FRAME ExceptionFrame,\r
+         OUT PBOOLEAN Status)\r
+{\r
+    NTSTATUS ReturnValue;\r
+    BOOLEAN Entered;\r
+    ANSI_STRING AnsiString;\r
+\r
+    /* Assume failure */\r
+    *Status = FALSE;\r
+\r
+    /* Validate the mask */\r
+    if (ComponentMask <= 0x1F) ComponentMask = 1 << ComponentMask;\r
+    if (!(Kd_WIN2000_Mask & ComponentMask) ||\r
+        ((ComponentId < KdComponentTableSize) &&\r
+        !(*KdComponentTable[ComponentId] & ComponentMask)))\r
+    {\r
+        /* Mask validation failed */\r
+        *Status = TRUE;\r
+        return FALSE;\r
+    }\r
+\r
+    /* Normalize the length */\r
+    Length = min(Length, 512);\r
+\r
+    /* Check if we need to verify the buffer */\r
+    if (PreviousMode != KernelMode)\r
+    {\r
+        /* FIXME: Support user-mode */\r
+    }\r
+\r
+    /* Setup the ANSI string */\r
+    AnsiString.Buffer = String;\r
+    AnsiString.Length = (USHORT)Length;\r
+\r
+    /* Log the print */\r
+    //KdLogDbgPrint(&AnsiString);\r
+\r
+    /* Check for a debugger */\r
+    if (KdDebuggerNotPresent)\r
+    {\r
+        /* Fail */\r
+        *Status = TRUE;\r
+        return (ULONG)STATUS_DEVICE_NOT_CONNECTED;\r
+    }\r
+\r
+    /* Enter the debugger */\r
+    Entered = KdEnterDebugger(TrapFrame, ExceptionFrame);\r
+\r
+    /* Print the string */\r
+    if (KdpPrintString(&AnsiString))\r
+    {\r
+        /* User pressed CTRL-C, breakpoint on return */\r
+        ReturnValue = STATUS_BREAKPOINT;\r
+    }\r
+    else\r
+    {\r
+        /* String was printed */\r
+        ReturnValue = STATUS_SUCCESS;\r
+    }\r
+\r
+    /* Exit the debugger and return */\r
+    KdExitDebugger(Entered);\r
+    *Status = TRUE;\r
+    return ReturnValue;\r
+}\r
+\r
index ecb56cb..a6f6c1b 100644 (file)
@@ -101,7 +101,6 @@ KdpTrap(IN PKTRAP_FRAME TrapFrame,
     BOOLEAN Unload = FALSE;\r
     ULONG Eip, Eax;\r
     BOOLEAN Status = FALSE;\r
-    while (TRUE);\r
 \r
     /*\r
      * Check if we got a STATUS_BREAKPOINT with a SubID for Print, Prompt or\r
@@ -120,7 +119,14 @@ KdpTrap(IN PKTRAP_FRAME TrapFrame,
             case BREAKPOINT_PRINT:\r
 \r
                 /* Call the worker routine */\r
-                Eax = 0;\r
+                Eax = KdpPrint(ContextRecord->Ebx,\r
+                               ContextRecord->Edi,\r
+                               (LPSTR)ExceptionRecord->ExceptionInformation[1],\r
+                               (ULONG)ExceptionRecord->ExceptionInformation[2],\r
+                               PreviousMode,\r
+                               TrapFrame,\r
+                               ExceptionFrame,\r
+                               &Status);\r
 \r
                 /* Update the return value for the caller */\r
                 ContextRecord->Eax = Eax;\r
@@ -130,6 +136,7 @@ KdpTrap(IN PKTRAP_FRAME TrapFrame,
             case BREAKPOINT_PROMPT:\r
 \r
                 /* Call the worker routine */\r
+                while (TRUE);\r
                 Eax = 0;\r
                 Status = TRUE;\r
 \r
@@ -147,6 +154,13 @@ KdpTrap(IN PKTRAP_FRAME TrapFrame,
             case BREAKPOINT_LOAD_SYMBOLS:\r
 \r
                 /* Call the worker routine */\r
+                KdpSymbol(UlongToPtr(ExceptionRecord->ExceptionInformation[1]),\r
+                          (ULONG)ExceptionRecord->ExceptionInformation[2],\r
+                          Unload,\r
+                          PreviousMode,\r
+                          ContextRecord,\r
+                          TrapFrame,\r
+                          ExceptionFrame);\r
                 Status = TRUE;\r
                 break;\r
 \r
@@ -154,6 +168,7 @@ KdpTrap(IN PKTRAP_FRAME TrapFrame,
             case BREAKPOINT_COMMAND_STRING:\r
 \r
                 /* Call the worker routine */\r
+                while (TRUE);\r
                 Status = TRUE;\r
 \r
             /* Anything else, do nothing */\r
index 612caf9..b07ed5f 100644 (file)
@@ -678,11 +678,12 @@ VOID
 NTAPI
 KiRestoreProcessorControlState(PKPROCESSOR_STATE ProcessorState)
 {
+    return;
     /* Restore the CR registers */
     __writecr0(ProcessorState->SpecialRegisters.Cr0);
     Ke386SetCr2(ProcessorState->SpecialRegisters.Cr2);
     __writecr3(ProcessorState->SpecialRegisters.Cr3);
-    __writecr4(ProcessorState->SpecialRegisters.Cr4);
+    if (KeFeatureBits & KF_CR4) __writecr4(ProcessorState->SpecialRegisters.Cr4);
 
     //
     // Restore the DR registers
@@ -711,7 +712,8 @@ KiSaveProcessorControlState(OUT PKPROCESSOR_STATE ProcessorState)
     ProcessorState->SpecialRegisters.Cr0 = __readcr0();
     ProcessorState->SpecialRegisters.Cr2 = __readcr2();
     ProcessorState->SpecialRegisters.Cr3 = __readcr3();
-    ProcessorState->SpecialRegisters.Cr4 = __readcr4();
+    ProcessorState->SpecialRegisters.Cr4 = (KeFeatureBits & KF_CR4) ?
+                                           __readcr4() : 0;
 
     /* Save the DR registers */
     ProcessorState->SpecialRegisters.KernelDr0 = Ke386GetDr0();
index 032a6b3..79061fd 100644 (file)
@@ -786,5 +786,3 @@ AppCpuInit:
     /* Jump into the idle loop */
     KiIdleLoop();
 }
-
-
index 70579c4..d423b61 100644 (file)
@@ -518,7 +518,8 @@ IoWriteTransferCount DATA
 @IofCallDriver@8
 @IofCompleteRequest@8
 IoIsWdmVersionAvailable@8
-KdComPortInUse DATA
+KdComPortInUse
+KdDebuggerNotPresent=_KdDebuggerNotPresent
 Ke386CallBios@8
 @KeAcquireGuardedMutex@4
 @KeAcquireGuardedMutexUnsafe@4
index 2f90887..7985971 100644 (file)
         <file>kddata.c</file>
         <file>kdinit.c</file>
         <file>kdlock.c</file>
+        <file>kdprint.c</file>
         <file>kdtrap.c</file>
     </directory>
     <directory name="ldr">