- Add kd64 folder for KD64 6.0 implementation.
authorAlex Ionescu <aionescu@gmail.com>
Sun, 18 Feb 2007 20:51:30 +0000 (20:51 +0000)
committerAlex Ionescu <aionescu@gmail.com>
Sun, 18 Feb 2007 20:51:30 +0000 (20:51 +0000)
- Implement KdEnterDebugger, KdExitDebugger, KdEnableDebuggerWithLock, KdEnableDebugger.
- Add KD Version Block, KD Component Masks, and KD Configuration Options.
- Implement KdInitSystem and KdRegisterDebuggerDataBlock.
- Implement KdPollBreakIn, KdpLockPort, KdpUnlockPort.
- Implement KdpStub and KdpReport. Implement logic of KdpTrap but not helper calls (KdpTrap is only enabled after KD connects).
- Implement KD Time Slip support, KdpSwitchProcessor, KdpQueryPerformanceCounter.

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

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

index 6cc53e8..699e0f0 100644 (file)
@@ -1,12 +1,3 @@
-//
-// Kernel Debugger Port Definition
-//
-extern BOOLEAN _KdDebuggerEnabled;
-extern BOOLEAN _KdDebuggerNotPresent;
-extern BOOLEAN KdBreakAfterSymbolLoad;
-
-/* KD GLOBALS  ***************************************************************/
-
 typedef
 BOOLEAN
 (NTAPI *PKDEBUG_ROUTINE)(
@@ -18,4 +9,128 @@ BOOLEAN
     IN BOOLEAN SecondChance
 );
 
+typedef
+BOOLEAN
+(NTAPI *PKDEBUG_SWITCH_ROUTINE)(
+    IN PEXCEPTION_RECORD ExceptionRecord,
+    IN PCONTEXT Context,
+    IN BOOLEAN SecondChance
+);
+
+BOOLEAN
+NTAPI
+KdpEnterDebuggerException(
+    IN PKTRAP_FRAME TrapFrame,
+    IN PKEXCEPTION_FRAME ExceptionFrame,
+    IN PEXCEPTION_RECORD ExceptionRecord,
+    IN PCONTEXT Context,
+    IN KPROCESSOR_MODE PreviousMode,
+    IN BOOLEAN SecondChance
+);
+
+VOID
+NTAPI
+KdpTimeSlipWork(
+    IN PVOID Context
+);
+
+BOOLEAN
+NTAPI
+KdpSwitchProcessor(
+    IN PEXCEPTION_RECORD ExceptionRecord,
+    IN OUT PCONTEXT ContextRecord,
+    IN BOOLEAN SecondChanceException
+);
+
+VOID
+NTAPI
+KdpTimeSlipDpcRoutine(
+    IN PKDPC Dpc,
+    IN PVOID DeferredContext,
+    IN PVOID SystemArgument1,
+    IN PVOID SystemArgument2
+);
+
+BOOLEAN
+NTAPI
+KdpStub(
+    IN PKTRAP_FRAME TrapFrame,
+    IN PKEXCEPTION_FRAME ExceptionFrame,
+    IN PEXCEPTION_RECORD ExceptionRecord,
+    IN PCONTEXT ContextRecord,
+    IN KPROCESSOR_MODE PreviousMode,
+    IN BOOLEAN SecondChanceException
+);
+
+BOOLEAN
+NTAPI
+KdpTrap(
+    IN PKTRAP_FRAME TrapFrame,
+    IN PKEXCEPTION_FRAME ExceptionFrame,
+    IN PEXCEPTION_RECORD ExceptionRecord,
+    IN PCONTEXT ContextRecord,
+    IN KPROCESSOR_MODE PreviousMode,
+    IN BOOLEAN SecondChanceException
+);
+
+VOID
+NTAPI
+KdpPortLock(
+    VOID
+);
+
+VOID
+NTAPI
+KdpPortUnlock(
+    VOID
+);
+
+BOOLEAN
+NTAPI
+KdEnterDebugger(
+    IN PKTRAP_FRAME TrapFrame,
+    IN PKEXCEPTION_FRAME ExceptionFrame
+);
+
+VOID
+NTAPI
+KdExitDebugger(
+    IN BOOLEAN Entered
+);
+
+NTSTATUS
+NTAPI
+KdEnableDebuggerWithLock(
+    IN BOOLEAN NeedLock
+);
+
+extern DBGKD_GET_VERSION64 KdVersionBlock;
+extern KDDEBUGGER_DATA64 KdDebuggerDataBlock;
+extern LIST_ENTRY KdpDebuggerDataListHead;
+extern KSPIN_LOCK KdpDataSpinLock;
+extern LARGE_INTEGER KdPerformanceCounterRate;
+extern LARGE_INTEGER KdTimerStart;
+extern ULONG KdDisableCount;
+extern KD_CONTEXT KdpContext;
 extern PKDEBUG_ROUTINE KiDebugRoutine;
+extern PKDEBUG_SWITCH_ROUTINE KiDebugSwitchRoutine;
+extern BOOLEAN KdBreakAfterSymbolLoad;
+extern BOOLEAN KdPitchDebugger;
+extern BOOLEAN _KdDebuggerNotPresent;
+extern BOOLEAN _KdDebuggerEnabled;
+extern BOOLEAN KdAutoEnableOnEvent;
+extern BOOLEAN KdPreviouslyEnabled;
+extern BOOLEAN KdpDebuggerStructuresInitialized;
+extern BOOLEAN KdEnteredDebugger;
+extern KDPC KdpTimeSlipDpc;
+extern KTIMER KdpTimeSlipTimer;
+extern WORK_QUEUE_ITEM KdpTimeSlipWorkItem;
+extern LONG KdpTimeSlipPending;
+extern PKEVENT KdpTimeSlipEvent;
+extern KSPIN_LOCK KdpTimeSlipEventLock;
+extern BOOLEAN KdpControlCPressed;
+extern BOOLEAN KdpControlCWaiting;
+extern BOOLEAN KdpPortLocked;
+extern KSPIN_LOCK KdpDebuggerLock;
+extern LARGE_INTEGER KdTimerStop, KdTimerStart, KdTimerDifference;
+
diff --git a/reactos/ntoskrnl/kd64/kdapi.c b/reactos/ntoskrnl/kd64/kdapi.c
new file mode 100644 (file)
index 0000000..cb7fbd9
--- /dev/null
@@ -0,0 +1,261 @@
+/*\r
+ * PROJECT:         ReactOS Kernel\r
+ * LICENSE:         GPL - See COPYING in the top level directory\r
+ * FILE:            ntoskrnl/kd64/kdapi.c\r
+ * PURPOSE:         KD64 Public Routines and Internal Support\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
+/* PRIVATE FUNCTIONS *********************************************************/\r
+\r
+VOID\r
+NTAPI\r
+KdpTimeSlipDpcRoutine(IN PKDPC Dpc,\r
+                      IN PVOID DeferredContext,\r
+                      IN PVOID SystemArgument1,\r
+                      IN PVOID SystemArgument2)\r
+{\r
+    LONG OldSlip, NewSlip, PendingSlip;\r
+\r
+    /* Get the current pending slip */\r
+    PendingSlip = KdpTimeSlipPending;\r
+    do\r
+    {\r
+        /* Save the old value and either disable or enable it now. */\r
+        OldSlip = PendingSlip;\r
+        NewSlip = OldSlip > 1 ? 1 : 0;\r
+\r
+        /* Try to change the value */\r
+    } while (InterlockedCompareExchange(&KdpTimeSlipPending,\r
+                                        NewSlip,\r
+                                        OldSlip) != OldSlip);\r
+\r
+    /* If the New Slip value is 1, then do the Time Slipping */\r
+    if (NewSlip) ExQueueWorkItem(&KdpTimeSlipWorkItem, DelayedWorkQueue);\r
+}\r
+\r
+VOID\r
+NTAPI\r
+KdpTimeSlipWork(IN PVOID Context)\r
+{\r
+    KIRQL OldIrql;\r
+    LARGE_INTEGER DueTime;\r
+\r
+    /* Update the System time from the CMOS */\r
+    ExAcquireTimeRefreshLock(FALSE);\r
+    ExUpdateSystemTimeFromCmos(FALSE, 0);\r
+    ExReleaseTimeRefreshLock();\r
+\r
+    /* Check if we have a registered Time Slip Event and signal it */\r
+    KeAcquireSpinLock(&KdpTimeSlipEventLock, &OldIrql);\r
+    if (KdpTimeSlipEvent) KeSetEvent(KdpTimeSlipEvent, 0, FALSE);\r
+    KeReleaseSpinLock(&KdpTimeSlipEventLock, OldIrql);\r
+\r
+    /* Delay the DPC until it runs next time */\r
+    DueTime.QuadPart = -1800000000;\r
+    KeSetTimer(&KdpTimeSlipTimer, DueTime, &KdpTimeSlipDpc);\r
+}\r
+\r
+BOOLEAN\r
+NTAPI\r
+KdpSwitchProcessor(IN PEXCEPTION_RECORD ExceptionRecord,\r
+                   IN OUT PCONTEXT ContextRecord,\r
+                   IN BOOLEAN SecondChanceException)\r
+{\r
+    BOOLEAN Status;\r
+\r
+    /* Save the port data */\r
+    KdSave(FALSE);\r
+\r
+    /* Report a state change */\r
+#if 0\r
+    Status = KdpReportExceptionStateChange(ExceptionRecord,\r
+                                           ContextRecord,\r
+                                           SecondChanceException);\r
+#else\r
+    Status = FALSE;\r
+#endif\r
+\r
+    /* Restore the port data and return */\r
+    KdRestore(FALSE);\r
+    return Status;\r
+}\r
+\r
+LARGE_INTEGER\r
+NTAPI\r
+KdpQueryPerformanceCounter(IN PKTRAP_FRAME TrapFrame)\r
+{\r
+    LARGE_INTEGER Null = {{0}};\r
+\r
+    /* Check if interrupts were disabled */\r
+    if (!(TrapFrame->EFlags & EFLAGS_INTERRUPT_MASK))\r
+    {\r
+        /* Nothing to return */\r
+        return Null;\r
+    }\r
+\r
+    /* Otherwise, do the call */\r
+    return KeQueryPerformanceCounter(NULL);\r
+}\r
+\r
+BOOLEAN\r
+NTAPI\r
+KdEnterDebugger(IN PKTRAP_FRAME TrapFrame,\r
+                IN PKEXCEPTION_FRAME ExceptionFrame)\r
+{\r
+    BOOLEAN Entered;\r
+\r
+    /* Check if we have a trap frame */\r
+    if (TrapFrame)\r
+    {\r
+        /* Calculate the time difference for the enter */\r
+        KdTimerStop = KdpQueryPerformanceCounter(TrapFrame);\r
+        KdTimerDifference.QuadPart = KdTimerStop.QuadPart -\r
+                                     KdTimerStart.QuadPart;\r
+    }\r
+    else\r
+    {\r
+        /* No trap frame, so can't calculate */\r
+        KdTimerStop.QuadPart = 0;\r
+    }\r
+\r
+    /* Save the current IRQL */\r
+    KeGetCurrentPrcb()->DebuggerSavedIRQL = KeGetCurrentIrql();\r
+\r
+    /* Freeze all CPUs */\r
+    Entered = KeFreezeExecution(TrapFrame, ExceptionFrame);\r
+\r
+    /* Lock the port, save the state and set debugger entered */\r
+    KdpPortLocked = KeTryToAcquireSpinLockAtDpcLevel(&KdpDebuggerLock);\r
+    KdSave(FALSE);\r
+    KdEnteredDebugger = TRUE;\r
+\r
+    /* Check freeze flag */\r
+    if (KiFreezeFlag & 1)\r
+    {\r
+        /* Print out errror */\r
+        DbgPrint("FreezeLock was jammed!  Backup SpinLock was used!\n");\r
+    }\r
+\r
+    /* Check processor state */\r
+    if (KiFreezeFlag & 2)\r
+    {\r
+        /* Print out errror */\r
+        DbgPrint("Some processors not frozen in debugger!\n");\r
+    }\r
+\r
+    /* Make sure we acquired the port */\r
+    if (!KdpPortLocked) DbgPrint("Port lock was not acquired!\n");\r
+\r
+    /* Return enter state */\r
+    return Entered;\r
+}\r
+\r
+VOID\r
+NTAPI\r
+KdExitDebugger(IN BOOLEAN Entered)\r
+{\r
+    ULONG TimeSlip;\r
+\r
+    /* Restore the state and unlock the port */\r
+    KdRestore(FALSE);\r
+    if (KdpPortLocked) KdpPortUnlock();\r
+\r
+    /* Unfreeze the CPUs */\r
+    KeThawExecution(Entered);\r
+\r
+    /* Compare time with the one from KdEnterDebugger */\r
+    if (!KdTimerStop.QuadPart)\r
+    {\r
+        /* We didn't get a trap frame earlier in so never got the time */\r
+        KdTimerStart = KdTimerStop;\r
+    }\r
+    else\r
+    {\r
+        /* Query the timer */\r
+        KdTimerStart = KeQueryPerformanceCounter(NULL);\r
+    }\r
+\r
+    /* Check if a Time Slip was on queue */\r
+    TimeSlip = InterlockedIncrement(&KdpTimeSlipPending);\r
+    if (TimeSlip == 1)\r
+    {\r
+        /* Queue a DPC for the time slip */\r
+        InterlockedIncrement(&KdpTimeSlipPending);\r
+        KeInsertQueueDpc(&KdpTimeSlipDpc, NULL, NULL);\r
+    }\r
+}\r
+\r
+NTSTATUS\r
+NTAPI\r
+KdEnableDebuggerWithLock(BOOLEAN NeedLock)\r
+{\r
+    KIRQL OldIrql;\r
+\r
+    /* Check if we need to acquire the lock */\r
+    if (NeedLock)\r
+    {\r
+        /* Lock the port */\r
+        KeRaiseIrql(DISPATCH_LEVEL, &OldIrql);\r
+        KdpPortLock();\r
+    }\r
+\r
+    /* Check if we're not disabled */\r
+    if (!KdDisableCount)\r
+    {\r
+        /* Check if we had locked the port before */\r
+        if (NeedLock)\r
+        {\r
+            /* Do the unlock */\r
+            KeLowerIrql(OldIrql);\r
+            KdpPortUnlock();\r
+        }\r
+\r
+        /* Fail: We're already enabled */\r
+        return STATUS_INVALID_PARAMETER;\r
+    }\r
+\r
+    /* Decrease the disable count */\r
+    if (!(--KdDisableCount))\r
+    {\r
+        /* We're now enabled again! Were we enabled before, too? */\r
+        if (KdPreviouslyEnabled)\r
+        {\r
+            /* Reinitialize the Debugger */\r
+            KdInitSystem(0, NULL) ;\r
+            //KdpRestoreAllBreakpoints();\r
+        }\r
+    }\r
+\r
+    /* Check if we had locked the port before */\r
+    if (NeedLock)\r
+    {\r
+        /* Yes, now unlock it */\r
+        KeLowerIrql(OldIrql);\r
+        KdpPortUnlock();\r
+    }\r
+\r
+    /* We're done */\r
+    return STATUS_SUCCESS;\r
+}\r
+\r
+/* PUBLIC FUNCTIONS **********************************************************/\r
+\r
+/*\r
+ * @implemented\r
+ */\r
+NTSTATUS\r
+NTAPI\r
+KdEnableDebugger(VOID)\r
+{\r
+    /* Use the internal routine */\r
+    while (TRUE);\r
+    return KdEnableDebuggerWithLock(TRUE);\r
+}\r
+\r
diff --git a/reactos/ntoskrnl/kd64/kddata.c b/reactos/ntoskrnl/kd64/kddata.c
new file mode 100644 (file)
index 0000000..da85b0b
--- /dev/null
@@ -0,0 +1,305 @@
+/*\r
+ * PROJECT:         ReactOS Kernel\r
+ * LICENSE:         GPL - See COPYING in the top level directory\r
+ * FILE:            ntoskrnl/kd64/kddata.c\r
+ * PURPOSE:         Contains all global variables and settings for KD64\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
+/* GLOBALS *******************************************************************/\r
+\r
+//\r
+// Debugger Version Block\r
+//\r
+DBGKD_GET_VERSION64 KdVersionBlock =\r
+{\r
+    0,\r
+    0,\r
+    DBGKD_64BIT_PROTOCOL_VERSION2,\r
+    KD_SECONDARY_VERSION_DEFAULT,\r
+    DBGKD_VERS_FLAG_DATA,\r
+    IMAGE_FILE_MACHINE_I386,\r
+    PACKET_TYPE_MAX,\r
+    0,\r
+    0,\r
+    DBGKD_SIMULATION_NONE,\r
+    {0},\r
+    0,\r
+    0,\r
+    0\r
+};\r
+\r
+//\r
+// Debugger Data\r
+//\r
+KDDEBUGGER_DATA64 KdDebuggerDataBlock;\r
+LIST_ENTRY KdpDebuggerDataListHead;\r
+KSPIN_LOCK KdpDataSpinLock;\r
+\r
+//\r
+// Debugger State\r
+//\r
+KD_CONTEXT KdpContext;\r
+BOOLEAN KdpControlCPressed;\r
+BOOLEAN KdpControlCWaiting;\r
+BOOLEAN KdpPortLocked;\r
+KSPIN_LOCK KdpDebuggerLock;\r
+\r
+//\r
+// Debug Trap Handlers\r
+//\r
+PKDEBUG_ROUTINE KiDebugRoutine = KdpStub;\r
+PKDEBUG_SWITCH_ROUTINE KiDebugSwitchRoutine;\r
+\r
+//\r
+// Debugger Configuration Settings\r
+//\r
+BOOLEAN KdBreakAfterSymbolLoad;\r
+BOOLEAN KdPitchDebugger;\r
+BOOLEAN _KdDebuggerNotPresent = TRUE;\r
+BOOLEAN _KdDebuggerEnabled;\r
+BOOLEAN KdAutoEnableOnEvent;\r
+BOOLEAN KdPreviouslyEnabled;\r
+BOOLEAN KdpDebuggerStructuresInitialized;\r
+BOOLEAN KdEnteredDebugger;\r
+ULONG KdDisableCount;\r
+LARGE_INTEGER KdPerformanceCounterRate;\r
+\r
+//\r
+// Time Slip Support\r
+//\r
+KDPC KdpTimeSlipDpc;\r
+KTIMER KdpTimeSlipTimer;\r
+WORK_QUEUE_ITEM KdpTimeSlipWorkItem;\r
+LONG KdpTimeSlipPending;\r
+PKEVENT KdpTimeSlipEvent;\r
+KSPIN_LOCK KdpTimeSlipEventLock;\r
+LARGE_INTEGER KdTimerStop, KdTimerStart, KdTimerDifference;\r
+\r
+//\r
+// Debug Filter Masks\r
+//\r
+ULONG Kd_WIN2000_Mask = 1;\r
+ULONG Kd_SYSTEM_Mask;\r
+ULONG Kd_SMSS_Mask;\r
+ULONG Kd_SETUP_Mask;\r
+ULONG Kd_NTFS_Mask;\r
+ULONG Kd_FSTUB_Mask;\r
+ULONG Kd_CRASHDUMP_Mask;\r
+ULONG Kd_CDAUDIO_Mask;\r
+ULONG Kd_CDROM_Mask;\r
+ULONG Kd_CLASSPNP_Mask;\r
+ULONG Kd_DISK_Mask;\r
+ULONG Kd_REDBOOK_Mask;\r
+ULONG Kd_STORPROP_Mask;\r
+ULONG Kd_SCSIPORT_Mask;\r
+ULONG Kd_SCSIMINIPORT_Mask;\r
+ULONG Kd_CONFIG_Mask;\r
+ULONG Kd_I8042PRT_Mask;\r
+ULONG Kd_SERMOUSE_Mask;\r
+ULONG Kd_LSERMOUS_Mask;\r
+ULONG Kd_KBDHID_Mask;\r
+ULONG Kd_MOUHID_Mask;\r
+ULONG Kd_KBDCLASS_Mask;\r
+ULONG Kd_MOUCLASS_Mask;\r
+ULONG Kd_TWOTRACK_Mask;\r
+ULONG Kd_WMILIB_Mask;\r
+ULONG Kd_ACPI_Mask;\r
+ULONG Kd_AMLI_Mask;\r
+ULONG Kd_HALIA64_Mask;\r
+ULONG Kd_VIDEO_Mask;\r
+ULONG Kd_SVCHOST_Mask;\r
+ULONG Kd_VIDEOPRT_Mask;\r
+ULONG Kd_TCPIP_Mask;\r
+ULONG Kd_DMSYNTH_Mask;\r
+ULONG Kd_NTOSPNP_Mask;\r
+ULONG Kd_FASTFAT_Mask;\r
+ULONG Kd_SAMSS_Mask;\r
+ULONG Kd_PNPMGR_Mask;\r
+ULONG Kd_NETAPI_Mask;\r
+ULONG Kd_SCSERVER_Mask;\r
+ULONG Kd_SCCLIENT_Mask;\r
+ULONG Kd_SERIAL_Mask;\r
+ULONG Kd_SERENUM_Mask;\r
+ULONG Kd_UHCD_Mask;\r
+ULONG Kd_RPCPROXY_Mask;\r
+ULONG Kd_AUTOCHK_Mask;\r
+ULONG Kd_DCOMSS_Mask;\r
+ULONG Kd_UNIMODEM_Mask;\r
+ULONG Kd_SIS_Mask;\r
+ULONG Kd_FLTMGR_Mask;\r
+ULONG Kd_WMICORE_Mask;\r
+ULONG Kd_BURNENG_Mask;\r
+ULONG Kd_IMAPI_Mask;\r
+ULONG Kd_SXS_Mask;\r
+ULONG Kd_FUSION_Mask;\r
+ULONG Kd_IDLETASK_Mask;\r
+ULONG Kd_SOFTPCI_Mask;\r
+ULONG Kd_TAPE_Mask;\r
+ULONG Kd_MCHGR_Mask;\r
+ULONG Kd_IDEP_Mask;\r
+ULONG Kd_PCIIDE_Mask;\r
+ULONG Kd_FLOPPY_Mask;\r
+ULONG Kd_FDC_Mask;\r
+ULONG Kd_TERMSRV_Mask;\r
+ULONG Kd_W32TIME_Mask;\r
+ULONG Kd_PREFETCHER_Mask;\r
+ULONG Kd_RSFILTER_Mask;\r
+ULONG Kd_FCPORT_Mask;\r
+ULONG Kd_PCI_Mask;\r
+ULONG Kd_DMIO_Mask;\r
+ULONG Kd_DMCONFIG_Mask;\r
+ULONG Kd_DMADMIN_Mask;\r
+ULONG Kd_WSOCKTRANSPORT_Mask;\r
+ULONG Kd_VSS_Mask;\r
+ULONG Kd_PNPMEM_Mask;\r
+ULONG Kd_PROCESSOR_Mask;\r
+ULONG Kd_DMSERVER_Mask;\r
+ULONG Kd_SR_Mask;\r
+ULONG Kd_INFINIBAND_Mask;\r
+ULONG Kd_IHVDRIVER_Mask;\r
+ULONG Kd_IHVVIDEO_Mask;\r
+ULONG Kd_IHVAUDIO_Mask;\r
+ULONG Kd_IHVNETWORK_Mask;\r
+ULONG Kd_IHVSTREAMING_Mask;\r
+ULONG Kd_IHVBUS_Mask;\r
+ULONG Kd_HPS_Mask;\r
+ULONG Kd_RTLTHREADPOOL_Mask;\r
+ULONG Kd_LDR_Mask;\r
+ULONG Kd_TCPIP6_Mask;\r
+ULONG Kd_ISAPNP_Mask;\r
+ULONG Kd_SHPC_Mask;\r
+ULONG Kd_STORPORT_Mask;\r
+ULONG Kd_STORMINIPORT_Mask;\r
+ULONG Kd_PRINTSPOOLER_Mask;\r
+ULONG Kd_VSSDYNDISK_Mask;\r
+ULONG Kd_VERIFIER_Mask;\r
+ULONG Kd_VDS_Mask;\r
+ULONG Kd_VDSBAS_Mask;\r
+ULONG Kd_VDSDYNDR_Mask;\r
+ULONG Kd_VDSUTIL_Mask;\r
+ULONG Kd_DFRGIFC_Mask;\r
+ULONG Kd_DEFAULT_Mask;\r
+ULONG Kd_MM_Mask;\r
+ULONG Kd_DFSC_Mask;\r
+ULONG Kd_WOW64_Mask;\r
+ULONG Kd_ENDOFTABLE_Mask;\r
+\r
+//\r
+// Debug Filter Component Table\r
+//\r
+PULONG KdComponentTable[104] =\r
+{\r
+    &Kd_SYSTEM_Mask,\r
+    &Kd_SMSS_Mask,\r
+    &Kd_SETUP_Mask,\r
+    &Kd_NTFS_Mask,\r
+    &Kd_FSTUB_Mask,\r
+    &Kd_CRASHDUMP_Mask,\r
+    &Kd_CDAUDIO_Mask,\r
+    &Kd_CDROM_Mask,\r
+    &Kd_CLASSPNP_Mask,\r
+    &Kd_DISK_Mask,\r
+    &Kd_REDBOOK_Mask,\r
+    &Kd_STORPROP_Mask,\r
+    &Kd_SCSIPORT_Mask,\r
+    &Kd_SCSIMINIPORT_Mask,\r
+    &Kd_CONFIG_Mask,\r
+    &Kd_I8042PRT_Mask,\r
+    &Kd_SERMOUSE_Mask,\r
+    &Kd_LSERMOUS_Mask,\r
+    &Kd_KBDHID_Mask,\r
+    &Kd_MOUHID_Mask,\r
+    &Kd_KBDCLASS_Mask,\r
+    &Kd_MOUCLASS_Mask,\r
+    &Kd_TWOTRACK_Mask,\r
+    &Kd_WMILIB_Mask,\r
+    &Kd_ACPI_Mask,\r
+    &Kd_AMLI_Mask,\r
+    &Kd_HALIA64_Mask,\r
+    &Kd_VIDEO_Mask,\r
+    &Kd_SVCHOST_Mask,\r
+    &Kd_VIDEOPRT_Mask,\r
+    &Kd_TCPIP_Mask,\r
+    &Kd_DMSYNTH_Mask,\r
+    &Kd_NTOSPNP_Mask,\r
+    &Kd_FASTFAT_Mask,\r
+    &Kd_SAMSS_Mask,\r
+    &Kd_PNPMGR_Mask,\r
+    &Kd_NETAPI_Mask,\r
+    &Kd_SCSERVER_Mask,\r
+    &Kd_SCCLIENT_Mask,\r
+    &Kd_SERIAL_Mask,\r
+    &Kd_SERENUM_Mask,\r
+    &Kd_UHCD_Mask,\r
+    &Kd_RPCPROXY_Mask,\r
+    &Kd_AUTOCHK_Mask,\r
+    &Kd_DCOMSS_Mask,\r
+    &Kd_UNIMODEM_Mask,\r
+    &Kd_SIS_Mask,\r
+    &Kd_FLTMGR_Mask,\r
+    &Kd_WMICORE_Mask,\r
+    &Kd_BURNENG_Mask,\r
+    &Kd_IMAPI_Mask,\r
+    &Kd_SXS_Mask,\r
+    &Kd_FUSION_Mask,\r
+    &Kd_IDLETASK_Mask,\r
+    &Kd_SOFTPCI_Mask,\r
+    &Kd_TAPE_Mask,\r
+    &Kd_MCHGR_Mask,\r
+    &Kd_IDEP_Mask,\r
+    &Kd_PCIIDE_Mask,\r
+    &Kd_FLOPPY_Mask,\r
+    &Kd_FDC_Mask,\r
+    &Kd_TERMSRV_Mask,\r
+    &Kd_W32TIME_Mask,\r
+    &Kd_PREFETCHER_Mask,\r
+    &Kd_RSFILTER_Mask,\r
+    &Kd_FCPORT_Mask,\r
+    &Kd_PCI_Mask,\r
+    &Kd_DMIO_Mask,\r
+    &Kd_DMCONFIG_Mask,\r
+    &Kd_DMADMIN_Mask,\r
+    &Kd_WSOCKTRANSPORT_Mask,\r
+    &Kd_VSS_Mask,\r
+    &Kd_PNPMEM_Mask,\r
+    &Kd_PROCESSOR_Mask,\r
+    &Kd_DMSERVER_Mask,\r
+    &Kd_SR_Mask,\r
+    &Kd_INFINIBAND_Mask,\r
+    &Kd_IHVDRIVER_Mask,\r
+    &Kd_IHVVIDEO_Mask,\r
+    &Kd_IHVAUDIO_Mask,\r
+    &Kd_IHVNETWORK_Mask,\r
+    &Kd_IHVSTREAMING_Mask,\r
+    &Kd_IHVBUS_Mask,\r
+    &Kd_HPS_Mask,\r
+    &Kd_RTLTHREADPOOL_Mask,\r
+    &Kd_LDR_Mask,\r
+    &Kd_TCPIP6_Mask,\r
+    &Kd_ISAPNP_Mask,\r
+    &Kd_SHPC_Mask,\r
+    &Kd_STORPORT_Mask,\r
+    &Kd_STORMINIPORT_Mask,\r
+    &Kd_PRINTSPOOLER_Mask,\r
+    &Kd_VSSDYNDISK_Mask,\r
+    &Kd_VERIFIER_Mask,\r
+    &Kd_VDS_Mask,\r
+    &Kd_VDSBAS_Mask,\r
+    &Kd_VDSDYNDR_Mask,\r
+    &Kd_VDSUTIL_Mask,\r
+    &Kd_DFRGIFC_Mask,\r
+    &Kd_DEFAULT_Mask,\r
+    &Kd_MM_Mask,\r
+    &Kd_DFSC_Mask,\r
+    &Kd_WOW64_Mask,\r
+    &Kd_ENDOFTABLE_Mask,\r
+};\r
+\r
+ULONG KdComponentTableSize = sizeof(KdComponentTable);\r
diff --git a/reactos/ntoskrnl/kd64/kdinit.c b/reactos/ntoskrnl/kd64/kdinit.c
new file mode 100644 (file)
index 0000000..40b449f
--- /dev/null
@@ -0,0 +1,250 @@
+/*\r
+ * PROJECT:         ReactOS Kernel\r
+ * LICENSE:         GPL - See COPYING in the top level directory\r
+ * FILE:            ntoskrnl/kd64/kdinit.c\r
+ * PURPOSE:         KD64 Initialization Code\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
+/* FUNCTIONS *****************************************************************/\r
+\r
+BOOLEAN\r
+NTAPI\r
+KdRegisterDebuggerDataBlock(IN ULONG Tag,\r
+                            IN PDBGKD_DEBUG_DATA_HEADER64 DataHeader,\r
+                            IN ULONG Size)\r
+{\r
+    KIRQL OldIrql;\r
+    PLIST_ENTRY NextEntry;\r
+    PDBGKD_DEBUG_DATA_HEADER64 CurrentHeader;\r
+\r
+    /* Acquire the Data Lock */\r
+    KeAcquireSpinLock(&KdpDataSpinLock, &OldIrql);\r
+\r
+    /* Loop the debugger data list */\r
+    NextEntry = KdpDebuggerDataListHead.Flink;\r
+    while (NextEntry != &KdpDebuggerDataListHead)\r
+    {\r
+        /* Get the header for this entry */\r
+        CurrentHeader = CONTAINING_RECORD(NextEntry,\r
+                                          DBGKD_DEBUG_DATA_HEADER64,\r
+                                          List);\r
+\r
+        /*  Move to the next one */\r
+        NextEntry = NextEntry->Flink;\r
+\r
+        /* Check if we already have this data block */\r
+        if ((CurrentHeader == DataHeader) || (CurrentHeader->OwnerTag == Tag))\r
+        {\r
+            /* Release the lock and fail */\r
+            KeReleaseSpinLock(&KdpDataSpinLock, OldIrql);\r
+            return FALSE;\r
+        }\r
+    }\r
+\r
+    /* Setup the header */\r
+    DataHeader->OwnerTag = Tag;\r
+    DataHeader->Size = Size;\r
+\r
+    /* Insert it into the list and release the lock */\r
+    InsertTailList(&KdpDebuggerDataListHead, (PLIST_ENTRY)&DataHeader->List);\r
+    KeReleaseSpinLock(&KdpDataSpinLock, OldIrql);\r
+    return TRUE;\r
+}\r
+\r
+BOOLEAN\r
+NTAPI\r
+KdInitSystem(IN ULONG BootPhase,\r
+             IN PLOADER_PARAMETER_BLOCK LoaderBlock)\r
+{\r
+    BOOLEAN EnableKd;\r
+    LPSTR CommandLine, DebugLine;\r
+    ANSI_STRING ImageName;\r
+    PLDR_DATA_TABLE_ENTRY LdrEntry;\r
+    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
+    {\r
+        /* Just query the performance counter */\r
+        KeQueryPerformanceCounter(&KdPerformanceCounterRate);\r
+        return TRUE;\r
+    }\r
+\r
+    /* Check if we already initialized once */\r
+    if (KdDebuggerEnabled) return TRUE;\r
+\r
+    /* Set the Debug Routine as the Stub for now */\r
+    KiDebugRoutine = KdpStub;\r
+\r
+    /* Disable break after symbol load for now */\r
+    KdBreakAfterSymbolLoad = FALSE;\r
+\r
+    /* Check if the Debugger Data Block was already initialized */\r
+    if (!KdpDebuggerDataListHead.Flink)\r
+    {\r
+        /* It wasn't...Initialize the KD Data Listhead */\r
+        InitializeListHead(&KdpDebuggerDataListHead);\r
+\r
+        /* Register the Debugger Data Block */\r
+        KdRegisterDebuggerDataBlock(KDBG_TAG,\r
+                                    &KdDebuggerDataBlock.Header,\r
+                                    sizeof(KdDebuggerDataBlock));\r
+\r
+        /* Fill out the KD Version Block */\r
+        KdVersionBlock.MajorVersion = (USHORT)(NtBuildNumber >> 28);\r
+        KdVersionBlock.MinorVersion = (USHORT)(NtBuildNumber & 0xFFFF);\r
+\r
+#ifdef CONFIG_SMP\r
+        /* This is an MP Build */\r
+        KdVersionBlock.Flags |= DBGKD_VERS_FLAG_MP;\r
+#endif\r
+\r
+        /* Save Pointers to Loaded Module List and Debugger Data */\r
+        KdVersionBlock.PsLoadedModuleList = (ULONG64)&PsLoadedModuleList;\r
+        KdVersionBlock.DebuggerDataList = (ULONG64)&KdpDebuggerDataListHead;\r
+\r
+        /* Set protocol limits */\r
+        KdVersionBlock.MaxStateChange = DbgKdMaximumStateChange -\r
+                                        DbgKdMinimumStateChange;\r
+        KdVersionBlock.MaxManipulate = DbgKdMaximumManipulate -\r
+                                       DbgKdMinimumManipulate;\r
+        KdVersionBlock.Unused[0] = 0;\r
+\r
+        /* Link us in the KPCR */\r
+        KeGetPcr()->KdVersionBlock =  &KdVersionBlock;\r
+    }\r
+\r
+    /* Check if we have a loader block */\r
+    if (LoaderBlock)\r
+    {\r
+        /* Save the Kernel Base */\r
+        KdVersionBlock.KernBase = (ULONG64)LoaderBlock->KernelStack;\r
+\r
+        /* Check if we have a command line */\r
+        CommandLine = LoaderBlock->LoadOptions;\r
+        if (CommandLine)\r
+        {\r
+            /* Upcase it */\r
+            _strupr(CommandLine);\r
+\r
+            /* Assume we'll disable KD */\r
+            EnableKd = FALSE;\r
+\r
+            /* Check for CRASHDEBUG and NODEBUG */\r
+            if (strstr(CommandLine, "CRASHDEBUG")) KdPitchDebugger = FALSE;\r
+            if (strstr(CommandLine, "NODEBUG")) KdPitchDebugger = TRUE;\r
+\r
+            /* Check if DEBUG was on */\r
+            DebugLine = strstr(CommandLine, "DEBUG");\r
+            if (DebugLine)\r
+            {\r
+                /* Enable KD */\r
+                EnableKd = TRUE;\r
+\r
+                /* Check if there was additional data */\r
+                if (DebugLine[5] == '=')\r
+                {\r
+                    /* FIXME: Check for NOUMEX, DISABLE, AUTOENABLE */\r
+                }\r
+            }\r
+        }\r
+        else\r
+        {\r
+            /* No command line options? Disable debugger by default */\r
+            KdPitchDebugger = TRUE;\r
+            EnableKd = FALSE;\r
+        }\r
+    }\r
+    else\r
+    {\r
+        /* Called from a bugcheck...Save the Kernel Base */\r
+        KdVersionBlock.KernBase = PsNtosImageBase;\r
+\r
+        /* Unconditionally enable KD */\r
+        EnableKd = TRUE;\r
+    }\r
+\r
+    /* Set the Kernel Base in the Data Block */\r
+    KdDebuggerDataBlock.KernBase = KdVersionBlock.KernBase;\r
+\r
+    /* Initialize the debugger if requested */\r
+    if ((EnableKd) && (NT_SUCCESS(KdDebuggerInitialize0(LoaderBlock))))\r
+    {\r
+        /* Now set our real KD routine */\r
+        KiDebugRoutine = KdpTrap;\r
+\r
+        /* Check if we've already initialized our structures */\r
+        if (!KdpDebuggerStructuresInitialized)\r
+        {\r
+            /* Set the Debug Switch Routine and Retries*/\r
+            KdpContext.KdpDefaultRetries = 20;\r
+            KiDebugSwitchRoutine = KdpSwitchProcessor;\r
+\r
+            /* Initialize the Time Slip DPC */\r
+            KeInitializeDpc(&KdpTimeSlipDpc, KdpTimeSlipDpcRoutine, NULL);\r
+            KeInitializeTimer(&KdpTimeSlipTimer);\r
+            ExInitializeWorkItem(&KdpTimeSlipWorkItem, KdpTimeSlipWork, NULL);\r
+\r
+            /* First-time initialization done! */\r
+            KdpDebuggerStructuresInitialized = TRUE;\r
+        }\r
+\r
+        /* Initialize the timer */\r
+        KdTimerStart.QuadPart = 0;\r
+\r
+        /* Officially enable KD */\r
+        KdPitchDebugger = FALSE;\r
+        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
+\r
+        /* Check if we have a loader block */\r
+        if (LoaderBlock)\r
+        {\r
+            /* Loop boot images */\r
+            NextEntry = LoaderBlock->LoadOrderListHead.Flink;\r
+            i = 0;\r
+            while ((NextEntry != &LoaderBlock->LoadOrderListHead) && (i < 2))\r
+            {\r
+                /* Get the image entry */\r
+                LdrEntry = CONTAINING_RECORD(NextEntry,\r
+                                             LDR_DATA_TABLE_ENTRY,\r
+                                             InLoadOrderLinks);\r
+\r
+                /* Generate the image name */\r
+\r
+                /* Load symbols for image */\r
+                RtlInitAnsiString(&ImageName, NameBuffer);\r
+                DbgLoadImageSymbols(&ImageName, LdrEntry->DllBase, -1);\r
+\r
+                /* Go to the next entry */\r
+                NextEntry = NextEntry->Flink;\r
+                i++;\r
+            }\r
+        }\r
+\r
+        /* Check for incoming breakin and break on symbol load if we have it*/\r
+        KdBreakAfterSymbolLoad = KdPollBreakIn();\r
+    }\r
+    else\r
+    {\r
+        /* Disable debugger */\r
+        KdDebuggerNotPresent = TRUE;\r
+    }\r
+\r
+    /* Return initialized */\r
+    return TRUE;\r
+}\r
diff --git a/reactos/ntoskrnl/kd64/kdlock.c b/reactos/ntoskrnl/kd64/kdlock.c
new file mode 100644 (file)
index 0000000..179115b
--- /dev/null
@@ -0,0 +1,90 @@
+/*\r
+ * PROJECT:         ReactOS Kernel\r
+ * LICENSE:         GPL - See COPYING in the top level directory\r
+ * FILE:            ntoskrnl/kd64/kdlock.c\r
+ * PURPOSE:         KD64 Port Lock and Breakin Support\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
+/* PRIVATE FUNCTIONS *********************************************************/\r
+\r
+VOID\r
+NTAPI\r
+KdpPortLock(VOID)\r
+{\r
+    /* Acquire the lock */\r
+    KiAcquireSpinLock(&KdpDebuggerLock);\r
+}\r
+\r
+VOID\r
+NTAPI\r
+KdpPortUnlock(VOID)\r
+{\r
+    /* Release the lock */\r
+    KiReleaseSpinLock(&KdpDebuggerLock);\r
+}\r
+\r
+/* PUBLIC FUNCTIONS **********************************************************/\r
+\r
+/*\r
+ * @implemented\r
+ */\r
+BOOLEAN\r
+NTAPI\r
+KdPollBreakIn(VOID)\r
+{\r
+    BOOLEAN DoBreak = FALSE;\r
+    ULONG Flags;\r
+\r
+    /* First make sure that KD is enabled */\r
+    if (KdDebuggerEnabled)\r
+    {\r
+        /* Disable interrupts */\r
+        Ke386SaveFlags(Flags);\r
+        //Flags = __getcallerseflags();\r
+        _disable();\r
+\r
+        /* Check if a CTRL-C is in the queue */\r
+        if (KdpControlCWaiting)\r
+        {\r
+            /* Set it and prepare for break */\r
+            KdpControlCPressed = TRUE;\r
+            DoBreak = TRUE;\r
+            KdpControlCWaiting = FALSE;\r
+        }\r
+        else\r
+        {\r
+            /* Try to acquire the lock */\r
+            if (KeTryToAcquireSpinLockAtDpcLevel(&KdpDebuggerLock))\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
+                    KdpControlCPressed = TRUE;\r
+                }\r
+\r
+                /* Let go of the port */\r
+                KdpPortUnlock();\r
+            }\r
+        }\r
+\r
+        /* Re-enable interrupts if they were disabled */\r
+        if (Flags & EFLAGS_INTERRUPT_MASK) _enable();\r
+    }\r
+\r
+    /* Tell the caller to do a break */\r
+    return DoBreak;\r
+}\r
+\r
diff --git a/reactos/ntoskrnl/kd64/kdtrap.c b/reactos/ntoskrnl/kd64/kdtrap.c
new file mode 100644 (file)
index 0000000..ecb56cb
--- /dev/null
@@ -0,0 +1,234 @@
+/*\r
+ * PROJECT:         ReactOS Kernel\r
+ * LICENSE:         GPL - See COPYING in the top level directory\r
+ * FILE:            ntoskrnl/kd64/kdtrap.c\r
+ * PURPOSE:         KD64 Trap Handlers\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
+/* FUNCTIONS *****************************************************************/\r
+\r
+BOOLEAN\r
+NTAPI\r
+KdpReport(IN PKTRAP_FRAME TrapFrame,\r
+          IN PKEXCEPTION_FRAME ExceptionFrame,\r
+          IN PEXCEPTION_RECORD ExceptionRecord,\r
+          IN PCONTEXT ContextRecord,\r
+          IN KPROCESSOR_MODE PreviousMode,\r
+          IN BOOLEAN SecondChanceException)\r
+{\r
+    BOOLEAN Entered, Status;\r
+    PKPRCB Prcb;\r
+    while (TRUE);\r
+\r
+    /*\r
+     * Only go ahead with this if this is an INT3 or an INT1, or if the global\r
+     * flag forces us to call up the debugger on exception, or if this is a\r
+     * second chance exception which means it hasn't been handled by now.\r
+     */\r
+    if ((ExceptionRecord->ExceptionCode == STATUS_BREAKPOINT) ||\r
+        (ExceptionRecord->ExceptionCode == STATUS_SINGLE_STEP)  ||\r
+        (NtGlobalFlag & FLG_STOP_ON_EXCEPTION) ||\r
+        (SecondChanceException))\r
+    {\r
+        /*\r
+         * Also, unless this is a second chance exception, then do not call up\r
+         * the debugger if the debug port is disconnected or the exception code\r
+         * indicates success.\r
+         */\r
+        if (!(SecondChanceException) &&\r
+            ((ExceptionRecord->ExceptionCode == STATUS_PORT_DISCONNECTED) ||\r
+             (NT_SUCCESS(ExceptionRecord->ExceptionCode))))\r
+        {\r
+            /* Return false to hide the exception */\r
+            return FALSE;\r
+        }\r
+\r
+        /* Enter the debugger */\r
+        Entered = KdEnterDebugger(TrapFrame, ExceptionFrame);\r
+\r
+        /*\r
+         * Get the KPRCB and save the CPU Control State manually instead of\r
+         * using KiSaveProcessorState, since we already have a valid CONTEXT.\r
+         */\r
+        Prcb = KeGetCurrentPrcb();\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 = KdpReportExceptionStateChange(ExceptionRecord,\r
+                                               &Prcb->ProcessorState.\r
+                                               ContextFrame,\r
+                                               SecondChanceException);\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
+        KdpControlCPressed = FALSE;\r
+        return Status;\r
+    }\r
+\r
+    /* Fail if we got here */\r
+    return FALSE;\r
+}\r
+\r
+BOOLEAN\r
+NTAPI\r
+KdpTrap(IN PKTRAP_FRAME TrapFrame,\r
+        IN PKEXCEPTION_FRAME ExceptionFrame,\r
+        IN PEXCEPTION_RECORD ExceptionRecord,\r
+        IN PCONTEXT ContextRecord,\r
+        IN KPROCESSOR_MODE PreviousMode,\r
+        IN BOOLEAN SecondChanceException)\r
+{\r
+    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
+     * Load/Unload symbols.\r
+     */\r
+    if ((ExceptionRecord->ExceptionCode == STATUS_BREAKPOINT) &&\r
+        (ExceptionRecord->ExceptionInformation[0] != BREAKPOINT_BREAK))\r
+    {\r
+        /* Save EIP */\r
+        Eip = ContextRecord->Eip;\r
+\r
+        /* Check what kind of operation was requested from us */\r
+        switch (ExceptionRecord->ExceptionInformation[0])\r
+        {\r
+            /* DbgPrint */\r
+            case BREAKPOINT_PRINT:\r
+\r
+                /* Call the worker routine */\r
+                Eax = 0;\r
+\r
+                /* Update the return value for the caller */\r
+                ContextRecord->Eax = Eax;\r
+                break;\r
+\r
+            /* DbgPrompt */\r
+            case BREAKPOINT_PROMPT:\r
+\r
+                /* Call the worker routine */\r
+                Eax = 0;\r
+                Status = TRUE;\r
+\r
+                /* Update the return value for the caller */\r
+                ContextRecord->Eax = Eax;\r
+                break;\r
+\r
+            /* DbgUnloadSymbols */\r
+            case BREAKPOINT_UNLOAD_SYMBOLS:\r
+\r
+                /* Drop into the load case below, with the unload parameter */\r
+                Unload = TRUE;\r
+\r
+            /* DbgLoadSymbols */\r
+            case BREAKPOINT_LOAD_SYMBOLS:\r
+\r
+                /* Call the worker routine */\r
+                Status = TRUE;\r
+                break;\r
+\r
+            /* DbgCommandString*/\r
+            case BREAKPOINT_COMMAND_STRING:\r
+\r
+                /* Call the worker routine */\r
+                Status = TRUE;\r
+\r
+            /* Anything else, do nothing */\r
+            default:\r
+\r
+                /* Get out */\r
+                break;\r
+        }\r
+\r
+        /*\r
+         * If EIP was not updated, we'll increment it ourselves so execution\r
+         * continues past the breakpoint.\r
+         */\r
+        if (ContextRecord->Eip == Eip) ContextRecord->Eip++;\r
+    }\r
+    else\r
+    {\r
+        /* Call the worker routine */\r
+        Status = KdpReport(TrapFrame,\r
+                           ExceptionFrame,\r
+                           ExceptionRecord,\r
+                           ContextRecord,\r
+                           PreviousMode,\r
+                           SecondChanceException);\r
+    }\r
+\r
+    /* Return TRUE or FALSE to caller */\r
+    return Status;\r
+}\r
+\r
+BOOLEAN\r
+NTAPI\r
+KdpStub(IN PKTRAP_FRAME TrapFrame,\r
+        IN PKEXCEPTION_FRAME ExceptionFrame,\r
+        IN PEXCEPTION_RECORD ExceptionRecord,\r
+        IN PCONTEXT ContextRecord,\r
+        IN KPROCESSOR_MODE PreviousMode,\r
+        IN BOOLEAN SecondChanceException)\r
+{\r
+    ULONG ExceptionCommand = ExceptionRecord->ExceptionInformation[0];\r
+\r
+    /* Check if this was a breakpoint due to DbgPrint or Load/UnloadSymbols */\r
+    if ((ExceptionRecord->ExceptionCode == STATUS_BREAKPOINT) &&\r
+        (ExceptionRecord->NumberParameters > 0) &&\r
+        ((ExceptionCommand == BREAKPOINT_LOAD_SYMBOLS) ||\r
+         (ExceptionCommand == BREAKPOINT_UNLOAD_SYMBOLS) ||\r
+         (ExceptionCommand == BREAKPOINT_COMMAND_STRING) ||\r
+         (ExceptionCommand == BREAKPOINT_PRINT)))\r
+    {\r
+        /* This we can handle: simply bump EIP */\r
+        ContextRecord->Eip++;\r
+        return TRUE;\r
+    }\r
+    else if (KdPitchDebugger)\r
+    {\r
+        /* There's no debugger, fail. */\r
+        return FALSE;\r
+    }\r
+    else if ((KdAutoEnableOnEvent) &&\r
+             (KdPreviouslyEnabled) &&\r
+             !(KdDebuggerEnabled) &&\r
+             (KdEnableDebugger()) &&\r
+             (KdDebuggerEnabled))\r
+    {\r
+        /* Debugging was Auto-Enabled. We can now send this to KD. */\r
+        return KdpTrap(TrapFrame,\r
+                       ExceptionFrame,\r
+                       ExceptionRecord,\r
+                       ContextRecord,\r
+                       PreviousMode,\r
+                       SecondChanceException);\r
+    }\r
+    else\r
+    {\r
+        /* FIXME: All we can do in this case is trace this exception */\r
+        return FALSE;\r
+    }\r
+}\r
index f8e2f17..bf10539 100644 (file)
 
 /* GLOBALS *******************************************************************/
 
-BOOLEAN
-NTAPI
-KdpEnterDebuggerException(IN PKTRAP_FRAME TrapFrame,
-                          IN PKEXCEPTION_FRAME ExceptionFrame,
-                          IN PEXCEPTION_RECORD ExceptionRecord,
-                          IN PCONTEXT Context,
-                          IN KPROCESSOR_MODE PreviousMode,
-                          IN BOOLEAN SecondChance)
-{
-    /* HACK (just like all this routine */
-    if (ExceptionRecord->ExceptionCode == STATUS_BREAKPOINT)
-    {
-        Context->Eip++;
-        return TRUE;
-    }
-
-    return FALSE;
-}
-
-BOOLEAN
-NTAPI
-KdInitSystem(IN ULONG BootPhase,
-             IN PLOADER_PARAMETER_BLOCK LoaderBlock)
-{
-    /* STUB */
-    return TRUE;
-}
-
-BOOLEAN
-NTAPI
-KdPollBreakIn(VOID)
-{
-    /* STUB */
-    return FALSE;
-}
-
-BOOLEAN _KdDebuggerEnabled = FALSE;
-BOOLEAN _KdDebuggerNotPresent = TRUE;
-BOOLEAN KdBreakAfterSymbolLoad = FALSE;
-PKDEBUG_ROUTINE KiDebugRoutine = KdpEnterDebuggerException;
-
 /* DR Registers in the CONTEXT structure */
 UCHAR KiDebugRegisterContextOffsets[9] =
 {
index 2c7d7dc..2f90887 100644 (file)
             <file>pnproot.c</file>
         </directory>
     </directory>
+    <directory name="kd64">
+        <file>kdapi.c</file>
+        <file>kddata.c</file>
+        <file>kdinit.c</file>
+        <file>kdlock.c</file>
+        <file>kdtrap.c</file>
+    </directory>
     <directory name="ldr">
             <file>loader.c</file>
             <file>rtl.c</file>