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