From: Alex Ionescu Date: Sat, 3 Mar 2007 04:39:25 +0000 (+0000) Subject: - Remove KD APIs from stub HAL, they've been in kdcom for a while (merge from kd... X-Git-Tag: backups/ddk2003@36850~1140 X-Git-Url: https://git.reactos.org/?p=reactos.git;a=commitdiff_plain;h=af68f5e42d7a3a8cef35a4aacf64dc000b390d3f - Remove KD APIs from stub HAL, they've been in kdcom for a while (merge from kd-branch). - DebugPrint/DebugPrompt should have an int3 after the int2d, and the int2d handler should ++ the trap frame's EIP to compensate (merge from kd-branch). - Remove KDB symbol hooks (merge from kd-branch). - Make PSEH compialble in MSVC again after Greatlord's break. - Fix KiSaveProcessorControlState/KiRestoreProcessorControlState (merge from kd-branch). - Disable GDB hook/hacks (merge from kd-branch). - Add KD64 directory from kd-branch with SharedUserData access enabled (no other code changed). It's not currently compiled though, just putting it here. svn path=/trunk/; revision=25965 --- diff --git a/reactos/hal/hal/hal.c b/reactos/hal/hal/hal.c index c3a966101d8..fbcb9301b92 100644 --- a/reactos/hal/hal/hal.c +++ b/reactos/hal/hal/hal.c @@ -17,7 +17,6 @@ #include #include #include -#include #define NDEBUG #include @@ -727,132 +726,6 @@ IoMapTransfer( } -BOOLEAN -NTAPI -KdPortGetByte( - PUCHAR ByteRecieved) -{ - UNIMPLEMENTED; - - return TRUE; -} - - -BOOLEAN -NTAPI -KdPortGetByteEx( - PKD_PORT_INFORMATION PortInformation, - PUCHAR ByteRecieved) -{ - UNIMPLEMENTED; - - return TRUE; -} - - -BOOLEAN -NTAPI -KdPortInitialize( - PKD_PORT_INFORMATION PortInformation, - ULONG Unknown1, - ULONG Unknown2) -{ - UNIMPLEMENTED; - - return TRUE; -} - - -BOOLEAN -NTAPI -KdPortInitializeEx( - PKD_PORT_INFORMATION PortInformation, - ULONG Unknown1, - ULONG Unknown2) -{ - UNIMPLEMENTED; - - return TRUE; -} - - -BOOLEAN -NTAPI -KdPortPollByte( - PUCHAR ByteRecieved) -{ - UNIMPLEMENTED; - - return TRUE; -} - - -BOOLEAN -NTAPI -KdPortPollByteEx( - PKD_PORT_INFORMATION PortInformation, - PUCHAR ByteRecieved) -{ - UNIMPLEMENTED; - - return TRUE; -} - - -VOID -NTAPI -KdPortPutByte( - UCHAR ByteToSend) -{ - UNIMPLEMENTED; -} - - -VOID -NTAPI -KdPortPutByteEx( - PKD_PORT_INFORMATION PortInformation, - UCHAR ByteToSend) -{ - UNIMPLEMENTED; -} - - -VOID -NTAPI -KdPortRestore(VOID) -{ - UNIMPLEMENTED; -} - - -VOID -NTAPI -KdPortSave(VOID) -{ - UNIMPLEMENTED; -} - - -BOOLEAN -NTAPI -KdPortDisableInterrupts() -{ - UNIMPLEMENTED; - - return FALSE; -} - - -BOOLEAN -NTAPI -KdPortEnableInterrupts() -{ - UNIMPLEMENTED; - - return FALSE; -} - #undef KeAcquireSpinLock VOID NTAPI diff --git a/reactos/hal/halx86/generic/misc.c b/reactos/hal/halx86/generic/misc.c index 3322643ec01..7eb1d9170f9 100644 --- a/reactos/hal/halx86/generic/misc.c +++ b/reactos/hal/halx86/generic/misc.c @@ -77,7 +77,7 @@ HalHandleNMI(IN PVOID NmiInfo) /* Halt the system */ HalDisplayString("\n*** The system has halted ***\n"); - KeEnterKernelDebugger(); + //KeEnterKernelDebugger(); } /* diff --git a/reactos/include/reactos/libs/pseh/framebased.h b/reactos/include/reactos/libs/pseh/framebased.h index bc2b3c3a96e..4fbb1742227 100644 --- a/reactos/include/reactos/libs/pseh/framebased.h +++ b/reactos/include/reactos/libs/pseh/framebased.h @@ -73,14 +73,8 @@ static __declspec(noreturn) __inline void __stdcall _SEHCompilerSpecificHandler _SEHPortableTryLevel_t * trylevel ) { - /* - * help detetct if pseh going into endless loop - * if we see this debug msg repet never break - * we known something cause pseh going into - * endless loop, but it should never happen - */ - DbgPrint("_SEHCompilerSpecificHandler(%p)\n", trylevel); _SEHTryLevel_t * mytrylevel; + DbgPrint("_SEHCompilerSpecificHandler(%p)\n", trylevel); mytrylevel = _SEH_CONTAINING_RECORD(trylevel, _SEHTryLevel_t, ST_Header); _SEHLongJmp(mytrylevel->ST_JmpBuf, 1); } diff --git a/reactos/lib/rtl/debug.c b/reactos/lib/rtl/debug.c index defd7fe3ad8..c0f0173c354 100644 --- a/reactos/lib/rtl/debug.c +++ b/reactos/lib/rtl/debug.c @@ -23,6 +23,7 @@ DebugPrint(IN PANSI_STRING DebugString, IN ULONG Level) { /* Call the INT2D Service */ + //return STATUS_SUCCESS; return DebugService(BREAKPOINT_PRINT, DebugString->Buffer, DebugString->Length, diff --git a/reactos/lib/rtl/i386/debug_asm.S b/reactos/lib/rtl/i386/debug_asm.S index 79b7badc030..8ec4d862c97 100644 --- a/reactos/lib/rtl/i386/debug_asm.S +++ b/reactos/lib/rtl/i386/debug_asm.S @@ -54,7 +54,7 @@ _DebugService2@12: mov ecx, [ebp+8] mov edx, [ebp+12] int 0x2D - //int 3 + int 3 /* Restore stack */ pop ebp @@ -82,7 +82,7 @@ _DebugService@20: mov ebx, [ebp+20] mov edi, [ebp+24] int 0x2D - //int 3 + int 3 /* Restore registers */ pop ebx diff --git a/reactos/ntoskrnl/include/internal/ke.h b/reactos/ntoskrnl/include/internal/ke.h index 3623139042f..6c9b8fff723 100644 --- a/reactos/ntoskrnl/include/internal/ke.h +++ b/reactos/ntoskrnl/include/internal/ke.h @@ -151,6 +151,7 @@ extern UCHAR KiDebugRegisterTrapOffsets[9]; extern UCHAR KiDebugRegisterContextOffsets[9]; extern ULONG KeTimeIncrement; extern ULONG_PTR KiBugCheckData[5]; +extern ULONG KiFreezeFlag; /* MACROS *************************************************************************/ diff --git a/reactos/ntoskrnl/io/iomgr/driver.c b/reactos/ntoskrnl/io/iomgr/driver.c index 838e292b246..b17134ae1d6 100644 --- a/reactos/ntoskrnl/io/iomgr/driver.c +++ b/reactos/ntoskrnl/io/iomgr/driver.c @@ -874,9 +874,6 @@ IopInitializeBuiltinDriver(IN PLDR_DATA_TABLE_ENTRY LdrEntry) } #endif - /* Load symbols */ - KDB_SYMBOLFILE_HOOK(ModuleName); - /* * Strip the file extension from ServiceName */ @@ -926,9 +923,6 @@ IopInitializeBootDrivers(VOID) { PLIST_ENTRY ListHead, NextEntry; PLDR_DATA_TABLE_ENTRY LdrEntry; -#ifdef DBG - UNICODE_STRING NtosSymName = RTL_CONSTANT_STRING(L"ntoskrnl.sym"); -#endif PDEVICE_NODE DeviceNode; PDRIVER_OBJECT DriverObject; LDR_DATA_TABLE_ENTRY ModuleObject; @@ -974,9 +968,6 @@ IopInitializeBootDrivers(VOID) return; } - /* Hack for NTOSKRNL.SYM */ - KDB_SYMBOLFILE_HOOK(&NtosSymName); - /* Loop the boot modules */ ListHead = &KeLoaderBlock->LoadOrderListHead; NextEntry = ListHead->Flink; diff --git a/reactos/ntoskrnl/kd64/kdapi.c b/reactos/ntoskrnl/kd64/kdapi.c new file mode 100644 index 00000000000..0bbce23a38c --- /dev/null +++ b/reactos/ntoskrnl/kd64/kdapi.c @@ -0,0 +1,1158 @@ +/* + * 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 (alex.ionescu@reactos.org) + */ + +/* INCLUDES ******************************************************************/ + +#include +#define NDEBUG +#include + +/* PRIVATE FUNCTIONS *********************************************************/ + +VOID +NTAPI +KdpGetStateChange(IN PDBGKD_MANIPULATE_STATE64 State, + IN PCONTEXT Context) +{ + PKPRCB Prcb; + ULONG i; + + /* Check for success */ + if (NT_SUCCESS(State->u.Continue2.ContinueStatus)) + { + /* Check if we're tracing */ + if (State->u.Continue2.ControlSet.TraceFlag) + { + /* Enable TF */ + Context->EFlags |= EFLAGS_TF; + } + else + { + /* Remove it */ + Context->EFlags &= ~EFLAGS_TF; + } + + /* Loop all processors */ + for (i = 0; i < KeNumberProcessors; i++) + { + /* Get the PRCB and update DR7 and DR6 */ + Prcb = KiProcessorBlock[i]; + Prcb->ProcessorState.SpecialRegisters.KernelDr7 = + State->u.Continue2.ControlSet.Dr7; + Prcb->ProcessorState.SpecialRegisters.KernelDr6 = 0; + } + + /* Check if we have new symbol information */ + if (State->u.Continue2.ControlSet.CurrentSymbolStart != 1) + { + /* Update it */ + KdpCurrentSymbolStart = + State->u.Continue2.ControlSet.CurrentSymbolStart; + KdpCurrentSymbolEnd= State->u.Continue2.ControlSet.CurrentSymbolEnd; + } + } +} + +VOID +NTAPI +KdpSetCommonState(IN ULONG NewState, + IN PCONTEXT Context, + IN PDBGKD_WAIT_STATE_CHANGE64 WaitStateChange) +{ + USHORT InstructionCount; + BOOLEAN HadBreakpoints; + + /* Setup common stuff available for all CPU architectures */ + WaitStateChange->NewState = NewState; + WaitStateChange->ProcessorLevel = KeProcessorLevel; + WaitStateChange->Processor = (USHORT)KeGetCurrentPrcb()->Number; + WaitStateChange->NumberProcessors = (ULONG)KeNumberProcessors; + WaitStateChange->Thread = (ULONG)(LONG_PTR)KeGetCurrentThread(); + WaitStateChange->ProgramCounter = (ULONG)(LONG_PTR)Context->Eip; + + /* Zero out the Control Report */ + RtlZeroMemory(&WaitStateChange->ControlReport, + sizeof(DBGKD_CONTROL_REPORT)); + + /* Now copy the instruction stream and set the count */ + RtlCopyMemory(&WaitStateChange->ControlReport.InstructionStream[0], + (PVOID)(ULONG_PTR)WaitStateChange->ProgramCounter, + DBGKD_MAXSTREAM); + InstructionCount = DBGKD_MAXSTREAM; + WaitStateChange->ControlReport.InstructionCount = InstructionCount; + + /* Clear all the breakpoints in this region */ + HadBreakpoints = FALSE; +#if 0 + KdpDeleteBreakpointRange((PVOID)WaitStateChange->ProgramCounter, + (PVOID)(WaitStateChange->ProgramCounter + + WaitStateChange->ControlReport. + InstructionCount - 1)); +#endif + if (HadBreakpoints) + { + /* Copy the instruction stream again, this time without breakpoints */ + RtlCopyMemory(&WaitStateChange->ControlReport.InstructionStream[0], + (PVOID)(ULONG_PTR)WaitStateChange->ProgramCounter, + WaitStateChange->ControlReport.InstructionCount); + } +} + +VOID +NTAPI +KdpSetContextState(IN PDBGKD_WAIT_STATE_CHANGE64 WaitStateChange, + IN PCONTEXT Context) +{ + PKPRCB Prcb = KeGetCurrentPrcb(); + + /* Copy i386 specific debug registers */ + WaitStateChange->ControlReport.Dr6 = Prcb->ProcessorState.SpecialRegisters. + KernelDr6; + WaitStateChange->ControlReport.Dr7 = Prcb->ProcessorState.SpecialRegisters. + KernelDr7; + + /* Copy i386 specific segments */ + WaitStateChange->ControlReport.SegCs = (USHORT)Context->SegCs; + WaitStateChange->ControlReport.SegDs = (USHORT)Context->SegDs; + WaitStateChange->ControlReport.SegEs = (USHORT)Context->SegEs; + WaitStateChange->ControlReport.SegFs = (USHORT)Context->SegFs; + + /* Copy EFlags */ + WaitStateChange->ControlReport.EFlags = Context->EFlags; + + /* Set Report Flags */ + WaitStateChange->ControlReport.ReportFlags = REPORT_INCLUDES_SEGS; + if (WaitStateChange->ControlReport.SegCs == KGDT_R0_CODE) + { + WaitStateChange->ControlReport.ReportFlags = REPORT_INCLUDES_CS; + } +} + +VOID +NTAPI +KdpSysGetVersion(IN PDBGKD_GET_VERSION64 Version) +{ + /* Copy the version block */ + RtlCopyMemory(Version, &KdVersionBlock, sizeof(DBGKD_GET_VERSION64)); +} + +VOID +NTAPI +KdpGetVersion(IN PDBGKD_MANIPULATE_STATE64 State) +{ + STRING Header; + + /* Fill out the header */ + Header.Length = sizeof(DBGKD_MANIPULATE_STATE64); + Header.Buffer = (PCHAR)State; + + /* Get the version block */ + KdpSysGetVersion(&State->u.GetVersion64); + + /* Fill out the state */ + State->ApiNumber = DbgKdGetVersionApi; + State->ReturnStatus = STATUS_SUCCESS; + + /* Send the packet */ + KdSendPacket(PACKET_TYPE_KD_STATE_MANIPULATE, + &Header, + NULL, + &KdpContext); +} + +VOID +NTAPI +KdpReadVirtualMemory(IN PDBGKD_MANIPULATE_STATE64 State, + IN PSTRING Data, + IN PCONTEXT Context) +{ + STRING Header; + ULONG Length = State->u.ReadMemory.TransferCount; + NTSTATUS Status = STATUS_SUCCESS; + + /* Validate length */ + if (Length > (PACKET_MAX_SIZE - sizeof(DBGKD_MANIPULATE_STATE64))) + { + /* Overflow, set it to maximum possible */ + Length = PACKET_MAX_SIZE - sizeof(DBGKD_MANIPULATE_STATE64); + } + +#if 0 + if (!MmIsAddressValid((PVOID)(ULONG_PTR)State->u.ReadMemory.TargetBaseAddress)) + { + Ke386SetCr2(State->u.ReadMemory.TargetBaseAddress); + while (TRUE); + } +#endif + + if ((ULONG_PTR)State->u.ReadMemory.TargetBaseAddress < KSEG0_BASE) + { + Length = 0; + Status = STATUS_UNSUCCESSFUL; + } + else if ((ULONG_PTR)State->u.ReadMemory.TargetBaseAddress >= (ULONG_PTR)SharedUserData) + { + Length = 0; + Status = STATUS_UNSUCCESSFUL; + } + else + { + RtlCopyMemory(Data->Buffer, + (PVOID)(ULONG_PTR)State->u.ReadMemory.TargetBaseAddress, + Length); + } + + /* Fill out the header */ + Data->Length = Length; + Header.Length = sizeof(DBGKD_MANIPULATE_STATE64); + Header.Buffer = (PCHAR)State; + + /* Fill out the state */ + State->ReturnStatus = Status; + State->u.ReadMemory.ActualBytesRead = Length; + + /* Send the packet */ + KdSendPacket(PACKET_TYPE_KD_STATE_MANIPULATE, + &Header, + Data, + &KdpContext); +} + +VOID +NTAPI +KdpReadControlSpace(IN PDBGKD_MANIPULATE_STATE64 State, + IN PSTRING Data, + IN PCONTEXT Context) +{ + PDBGKD_READ_MEMORY64 ReadMemory = &State->u.ReadMemory; + STRING Header; + ULONG Length, RealLength; + PVOID ControlStart; + + /* Setup the header */ + Header.Length = sizeof(DBGKD_MANIPULATE_STATE64); + Header.Buffer = (PCHAR)State; + ASSERT(Data->Length == 0); + + /* Check the length requested */ + Length = ReadMemory->TransferCount; + if (Length > (PACKET_MAX_SIZE - sizeof(DBGKD_MANIPULATE_STATE64))) + { + /* Use maximum allowed */ + Length = PACKET_MAX_SIZE - sizeof(DBGKD_MANIPULATE_STATE64); + } + + /* Make sure that this is a valid request */ + if (((ULONG)ReadMemory->TargetBaseAddress < sizeof(KPROCESSOR_STATE)) && + (State->Processor < KeNumberProcessors)) + { + /* Get the actual length */ + RealLength = sizeof(KPROCESSOR_STATE) - + (ULONG_PTR)ReadMemory->TargetBaseAddress; + if (RealLength < Length) Length = RealLength; + + /* Set the proper address */ + ControlStart = (PVOID)((ULONG_PTR)ReadMemory->TargetBaseAddress + + (ULONG_PTR)&KiProcessorBlock[State->Processor]-> + ProcessorState); + + /* Copy the memory */ + RtlCopyMemory(Data->Buffer, ControlStart, Length); + Data->Length = Length; + + /* Finish up */ + State->ReturnStatus = STATUS_SUCCESS; + ReadMemory->ActualBytesRead = Data->Length; + } + else + { + /* Invalid request */ + Data->Length = 0; + State->ReturnStatus = STATUS_UNSUCCESSFUL; + ReadMemory->ActualBytesRead = 0; + } + + /* Send the reply */ + KdSendPacket(PACKET_TYPE_KD_STATE_MANIPULATE, + &Header, + Data, + &KdpContext); +} + +VOID +NTAPI +KdpWriteControlSpace(IN PDBGKD_MANIPULATE_STATE64 State, + IN PSTRING Data, + IN PCONTEXT Context) +{ + PDBGKD_WRITE_MEMORY64 WriteMemory = &State->u.WriteMemory; + STRING Header; + ULONG Length; + PVOID ControlStart; + + /* Setup the header */ + Header.Length = sizeof(DBGKD_MANIPULATE_STATE64); + Header.Buffer = (PCHAR)State; + + /* Make sure that this is a valid request */ + Length = WriteMemory->TransferCount; + if ((((ULONG)WriteMemory->TargetBaseAddress + Length) <= + sizeof(KPROCESSOR_STATE)) && + (State->Processor < KeNumberProcessors)) + { + /* Set the proper address */ + ControlStart = (PVOID)((ULONG_PTR)WriteMemory->TargetBaseAddress + + (ULONG_PTR)&KiProcessorBlock[State->Processor]-> + ProcessorState); + + /* Copy the memory */ + RtlCopyMemory(ControlStart, Data->Buffer, Data->Length); + Length = Data->Length; + + /* Finish up */ + State->ReturnStatus = STATUS_SUCCESS; + WriteMemory->ActualBytesWritten = Length; + } + else + { + /* Invalid request */ + Data->Length = 0; + State->ReturnStatus = STATUS_UNSUCCESSFUL; + WriteMemory->ActualBytesWritten = 0; + } + + /* Send the reply */ + KdSendPacket(PACKET_TYPE_KD_STATE_MANIPULATE, + &Header, + Data, + &KdpContext); +} + +VOID +NTAPI +KdpRestoreBreakpoint(IN PDBGKD_MANIPULATE_STATE64 State, + IN PSTRING Data, + IN PCONTEXT Context) +{ + PDBGKD_RESTORE_BREAKPOINT RestoreBp = &State->u.RestoreBreakPoint; + STRING Header; + + /* Fill out the header */ + Header.Length = sizeof(DBGKD_MANIPULATE_STATE64); + Header.Buffer = (PCHAR)State; + ASSERT(Data->Length == 0); + + /* Get the version block */ + if (KdpDeleteBreakpoint(RestoreBp->BreakPointHandle)) + { + /* We're all good */ + State->ReturnStatus = STATUS_SUCCESS; + } + else + { + /* We failed */ + State->ReturnStatus = STATUS_UNSUCCESSFUL; + } + + /* Send the packet */ + KdSendPacket(PACKET_TYPE_KD_STATE_MANIPULATE, + &Header, + NULL, + &KdpContext); +} + +VOID +NTAPI +KdpGetContext(IN PDBGKD_MANIPULATE_STATE64 State, + IN PSTRING Data, + IN PCONTEXT Context) +{ + STRING Header; + PVOID ControlStart; + + /* Setup the header */ + Header.Length = sizeof(DBGKD_MANIPULATE_STATE64); + Header.Buffer = (PCHAR)State; + ASSERT(Data->Length == 0); + + /* Make sure that this is a valid request */ + if (State->Processor < KeNumberProcessors) + { + /* Check if the request is for this CPU */ + if (State->Processor == KeGetCurrentPrcb()->Number) + { + /* We're just copying our own context */ + ControlStart = Context; + } + else + { + /* SMP not yet handled */ + ControlStart = NULL; + while (TRUE); + } + + /* Copy the memory */ + RtlCopyMemory(Data->Buffer, ControlStart, sizeof(CONTEXT)); + Data->Length = sizeof(CONTEXT); + + /* Finish up */ + State->ReturnStatus = STATUS_SUCCESS; + } + else + { + /* Invalid request */ + State->ReturnStatus = STATUS_UNSUCCESSFUL; + } + + /* Send the reply */ + KdSendPacket(PACKET_TYPE_KD_STATE_MANIPULATE, + &Header, + Data, + &KdpContext); +} + +VOID +NTAPI +KdpSetContext(IN PDBGKD_MANIPULATE_STATE64 State, + IN PSTRING Data, + IN PCONTEXT Context) +{ + STRING Header; + PVOID ControlStart; + + /* Setup the header */ + Header.Length = sizeof(DBGKD_MANIPULATE_STATE64); + Header.Buffer = (PCHAR)State; + ASSERT(Data->Length == sizeof(CONTEXT)); + + /* Make sure that this is a valid request */ + if (State->Processor < KeNumberProcessors) + { + /* Check if the request is for this CPU */ + if (State->Processor == KeGetCurrentPrcb()->Number) + { + /* We're just copying our own context */ + ControlStart = Context; + } + else + { + /* SMP not yet handled */ + ControlStart = NULL; + while (TRUE); + } + + /* Copy the memory */ + RtlCopyMemory(ControlStart, Data->Buffer, sizeof(CONTEXT)); + + /* Finish up */ + State->ReturnStatus = STATUS_SUCCESS; + } + else + { + /* Invalid request */ + State->ReturnStatus = STATUS_UNSUCCESSFUL; + } + + /* Send the reply */ + KdSendPacket(PACKET_TYPE_KD_STATE_MANIPULATE, + &Header, + Data, + &KdpContext); +} + +KCONTINUE_STATUS +NTAPI +KdpSendWaitContinue(IN ULONG PacketType, + IN PSTRING SendHeader, + IN PSTRING SendData OPTIONAL, + IN OUT PCONTEXT Context) +{ + STRING Data, Header; + DBGKD_MANIPULATE_STATE64 ManipulateState; + ULONG Length; + KDSTATUS RecvCode; + + /* Setup the Manipulate State structure */ + Header.MaximumLength = sizeof(DBGKD_MANIPULATE_STATE64); + Header.Buffer = (PCHAR)&ManipulateState; + Data.MaximumLength = sizeof(KdpMessageBuffer); + Data.Buffer = KdpMessageBuffer; + //KdpContextSent = FALSE; + +SendPacket: + /* Send the Packet */ + KdSendPacket(PacketType, SendHeader, SendData, &KdpContext); + + /* If the debugger isn't present anymore, just return success */ + if (KdDebuggerNotPresent) return ContinueSuccess; + + /* Main processing Loop */ + for (;;) + { + /* Receive Loop */ + do + { + /* Wait to get a reply to our packet */ + RecvCode = KdReceivePacket(PACKET_TYPE_KD_STATE_MANIPULATE, + &Header, + &Data, + &Length, + &KdpContext); + + /* If we got a resend request, do it */ + if (RecvCode == KdPacketNeedsResend) goto SendPacket; + } while (RecvCode == KdPacketTimedOut); + + /* Now check what API we got */ + switch (ManipulateState.ApiNumber) + { + case DbgKdReadVirtualMemoryApi: + + /* Read virtual memory */ + KdpReadVirtualMemory(&ManipulateState, &Data, Context); + break; + + case DbgKdWriteVirtualMemoryApi: + + /* FIXME: TODO */ + Ke386SetCr2(DbgKdWriteVirtualMemoryApi); + while (TRUE); + break; + + case DbgKdGetContextApi: + + /* Get the current context */ + KdpGetContext(&ManipulateState, &Data, Context); + break; + + case DbgKdSetContextApi: + + /* Set a new context */ + KdpSetContext(&ManipulateState, &Data, Context); + break; + + case DbgKdWriteBreakPointApi: + + /* FIXME: TODO */ + Ke386SetCr2(DbgKdWriteBreakPointApi); + while (TRUE); + break; + + case DbgKdRestoreBreakPointApi: + + /* FIXME: TODO */ + KdpRestoreBreakpoint(&ManipulateState, &Data, Context); + break; + + case DbgKdContinueApi: + + /* Simply continue */ + return NT_SUCCESS(ManipulateState.u.Continue.ContinueStatus); + + case DbgKdReadControlSpaceApi: + + /* Read control space */ + KdpReadControlSpace(&ManipulateState, &Data, Context); + break; + + case DbgKdWriteControlSpaceApi: + + /* FIXME: TODO */ + KdpWriteControlSpace(&ManipulateState, &Data, Context); + break; + + case DbgKdReadIoSpaceApi: + + /* FIXME: TODO */ + Ke386SetCr2(DbgKdReadIoSpaceApi); + while (TRUE); + break; + + case DbgKdWriteIoSpaceApi: + + /* FIXME: TODO */ + Ke386SetCr2(DbgKdWriteIoSpaceApi); + while (TRUE); + break; + + case DbgKdRebootApi: + + /* FIXME: TODO */ + Ke386SetCr2(DbgKdRebootApi); + while (TRUE); + break; + + case DbgKdContinueApi2: + + /* Check if caller reports success */ + if (NT_SUCCESS(ManipulateState.u.Continue2.ContinueStatus)) + { + /* Update the state */ + KdpGetStateChange(&ManipulateState, Context); + return ContinueSuccess; + } + else + { + /* Return an error */ + return ContinueError; + } + break; + + case DbgKdReadPhysicalMemoryApi: + + /* FIXME: TODO */ + goto fail; + Ke386SetCr2(DbgKdReadPhysicalMemoryApi); + while (TRUE); + break; + + case DbgKdWritePhysicalMemoryApi: + + /* FIXME: TODO */ + Ke386SetCr2(DbgKdWritePhysicalMemoryApi); + while (TRUE); + break; + + case DbgKdQuerySpecialCallsApi: + + /* FIXME: TODO */ + Ke386SetCr2(DbgKdQuerySpecialCallsApi); + while (TRUE); + break; + + case DbgKdSetSpecialCallApi: + + /* FIXME: TODO */ + Ke386SetCr2(DbgKdSetSpecialCallApi); + while (TRUE); + break; + + case DbgKdClearSpecialCallsApi: + + /* FIXME: TODO */ + Ke386SetCr2(DbgKdClearSpecialCallsApi); + while (TRUE); + break; + + case DbgKdSetInternalBreakPointApi: + + /* FIXME: TODO */ + Ke386SetCr2(DbgKdSetInternalBreakPointApi); + while (TRUE); + break; + + case DbgKdGetInternalBreakPointApi: + + /* FIXME: TODO */ + Ke386SetCr2(DbgKdGetInternalBreakPointApi); + while (TRUE); + break; + + case DbgKdReadIoSpaceExtendedApi: + + /* FIXME: TODO */ + Ke386SetCr2(DbgKdReadIoSpaceExtendedApi); + while (TRUE); + break; + + case DbgKdWriteIoSpaceExtendedApi: + + /* FIXME: TODO */ + Ke386SetCr2(DbgKdWriteIoSpaceExtendedApi); + while (TRUE); + break; + + case DbgKdGetVersionApi: + + /* Get version data */ + KdpGetVersion(&ManipulateState); + break; + + case DbgKdWriteBreakPointExApi: + + /* FIXME: TODO */ + Ke386SetCr2(DbgKdWriteBreakPointExApi); + while (TRUE); + break; + + case DbgKdRestoreBreakPointExApi: + + /* FIXME: TODO */ + Ke386SetCr2(DbgKdRestoreBreakPointExApi); + while (TRUE); + break; + + case DbgKdCauseBugCheckApi: + + /* FIXME: TODO */ + Ke386SetCr2(DbgKdCauseBugCheckApi); + while (TRUE); + break; + + case DbgKdSwitchProcessor: + + /* FIXME: TODO */ + Ke386SetCr2(DbgKdSwitchProcessor); + while (TRUE); + break; + + case DbgKdPageInApi: + + /* FIXME: TODO */ + Ke386SetCr2(DbgKdPageInApi); + while (TRUE); + break; + + case DbgKdReadMachineSpecificRegister: + + /* FIXME: TODO */ + Ke386SetCr2(DbgKdReadMachineSpecificRegister); + while (TRUE); + break; + + case DbgKdWriteMachineSpecificRegister: + + /* FIXME: TODO */ + Ke386SetCr2(DbgKdWriteMachineSpecificRegister); + while (TRUE); + break; + + case OldVlm1: + + /* FIXME: TODO */ + Ke386SetCr2(OldVlm1); + while (TRUE); + break; + + case OldVlm2: + + /* FIXME: TODO */ + Ke386SetCr2(OldVlm2); + while (TRUE); + break; + + case DbgKdSearchMemoryApi: + + /* FIXME: TODO */ + Ke386SetCr2(DbgKdSearchMemoryApi); + while (TRUE); + break; + + case DbgKdGetBusDataApi: + + /* FIXME: TODO */ + Ke386SetCr2(DbgKdGetBusDataApi); + while (TRUE); + break; + + case DbgKdSetBusDataApi: + + /* FIXME: TODO */ + Ke386SetCr2(DbgKdSetBusDataApi); + while (TRUE); + break; + + case DbgKdCheckLowMemoryApi: + + /* FIXME: TODO */ + Ke386SetCr2(DbgKdCheckLowMemoryApi); + while (TRUE); + break; + + case DbgKdClearAllInternalBreakpointsApi: + + /* Just clear the counter */ + KdpNumInternalBreakpoints = 0; + break; + + case DbgKdFillMemoryApi: + + /* FIXME: TODO */ + Ke386SetCr2(DbgKdFillMemoryApi); + while (TRUE); + break; + + case DbgKdQueryMemoryApi: + + /* FIXME: TODO */ + Ke386SetCr2(DbgKdQueryMemoryApi); + while (TRUE); + break; + + case DbgKdSwitchPartition: + + /* FIXME: TODO */ + Ke386SetCr2(DbgKdSwitchPartition); + while (TRUE); + break; + + /* Unsupported Message */ + default: + + /* Setup an empty message, with failure */ + while (TRUE); +fail: + Data.Length = 0; + ManipulateState.ReturnStatus = STATUS_UNSUCCESSFUL; + + /* Send it */ + KdSendPacket(PACKET_TYPE_KD_STATE_MANIPULATE, + &Header, + &Data, + &KdpContext); + break; + } + } +} + +BOOLEAN +NTAPI +KdpReportLoadSymbolsStateChange(IN PSTRING PathName, + IN PKD_SYMBOLS_INFO SymbolInfo, + IN BOOLEAN Unload, + IN OUT PCONTEXT Context) +{ + PSTRING ExtraData; + STRING Data, Header; + DBGKD_WAIT_STATE_CHANGE64 WaitStateChange; + KCONTINUE_STATUS Status; + + /* Start wait loop */ + do + { + /* Build the architecture common parts of the message */ + KdpSetCommonState(DbgKdLoadSymbolsStateChange, + Context, + &WaitStateChange); + + /* Now finish creating the structure */ + KdpSetContextState(&WaitStateChange, Context); + + /* Fill out load data */ + WaitStateChange.u.LoadSymbols.UnloadSymbols = Unload; + WaitStateChange.u.LoadSymbols.BaseOfDll = (ULONGLONG)(LONG_PTR)SymbolInfo->BaseOfDll; + WaitStateChange.u.LoadSymbols.ProcessId = SymbolInfo->ProcessId; + WaitStateChange.u.LoadSymbols.CheckSum = SymbolInfo->CheckSum; + WaitStateChange.u.LoadSymbols.SizeOfImage = SymbolInfo->SizeOfImage; + + /* Check if we have a symbol name */ + if (PathName) + { + /* Setup the information */ + WaitStateChange.u.LoadSymbols.PathNameLength = PathName->Length; + RtlCopyMemory(KdpPathBuffer, PathName->Buffer, PathName->Length); + Data.Buffer = KdpPathBuffer; + Data.Length = WaitStateChange.u.LoadSymbols.PathNameLength; + ExtraData = &Data; + } + else + { + /* No name */ + WaitStateChange.u.LoadSymbols.PathNameLength = 0; + ExtraData = NULL; + } + + /* Setup the header */ + Header.Length = sizeof(DBGKD_WAIT_STATE_CHANGE64); + Header.Buffer = (PCHAR)&WaitStateChange; + + /* Send the packet */ + Status = KdpSendWaitContinue(PACKET_TYPE_KD_STATE_CHANGE64, + &Header, + ExtraData, + Context); + } while(Status == ContinueProcessorReselected); + + /* Return status */ + return Status; +} + +BOOLEAN +NTAPI +KdpReportExceptionStateChange(IN PEXCEPTION_RECORD ExceptionRecord, + IN OUT PCONTEXT Context, + IN BOOLEAN SecondChanceException) +{ + STRING Header, Data; + DBGKD_WAIT_STATE_CHANGE64 WaitStateChange; + BOOLEAN Status; + + /* Start report loop */ + do + { + /* Build the architecture common parts of the message */ + KdpSetCommonState(DbgKdExceptionStateChange, Context, &WaitStateChange); + + /* Convert the exception record to 64-bits and set First Chance flag */ + ExceptionRecord32To64((PEXCEPTION_RECORD32)ExceptionRecord, + &WaitStateChange.u.Exception.ExceptionRecord); + WaitStateChange.u.Exception.FirstChance = !SecondChanceException; + + /* Now finish creating the structure */ + KdpSetContextState(&WaitStateChange, Context); + + /* Setup the actual header to send to KD */ + Header.Length = sizeof(DBGKD_WAIT_STATE_CHANGE64); + Header.Buffer = (PCHAR)&WaitStateChange; + + /* Send State Change packet and wait for a reply */ + Status = KdpSendWaitContinue(PACKET_TYPE_KD_STATE_CHANGE64, + &Header, + &Data, + Context); + } while (Status == KdPacketNeedsResend); + + /* Return */ + return Status; +} + +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 = PASSIVE_LEVEL; + + /* 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); +} + diff --git a/reactos/ntoskrnl/kd64/kdbreak.c b/reactos/ntoskrnl/kd64/kdbreak.c new file mode 100644 index 00000000000..4b9b9af12f7 --- /dev/null +++ b/reactos/ntoskrnl/kd64/kdbreak.c @@ -0,0 +1,149 @@ +/* + * PROJECT: ReactOS Kernel + * LICENSE: GPL - See COPYING in the top level directory + * FILE: ntoskrnl/kd64/kdbreak.c + * PURPOSE: KD64 Breakpoint Support + * PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org) + */ + +/* INCLUDES ******************************************************************/ + +#include +#define NDEBUG +#include + +/* FUNCTIONS *****************************************************************/ + +BOOLEAN +NTAPI +KdpLowWriteContent(IN ULONG BpIndex) +{ + /* Make sure that the breakpoint is actually active */ + if (KdpBreakpointTable[BpIndex].Flags & KdpBreakpointPending) + { + /* So we have a valid breakpoint, but it hasn't been used yet... */ + KdpBreakpointTable[BpIndex].Flags &= ~KdpBreakpointPending; + return TRUE; + } + + /* Is the original instruction an INT3 anyway? */ + if (KdpBreakpointTable[BpIndex].Content == KdpBreakpointInstruction) + { + /* Then leave it that way... */ + return TRUE; + } + + /* We have an active breakpoint with an instruction to bring back. Do it. */ + RtlCopyMemory(KdpBreakpointTable[BpIndex].Address, + &KdpBreakpointTable[BpIndex].Content, + sizeof(UCHAR)); + + /* Everything went fine, return */ + return TRUE; +} + +BOOLEAN +NTAPI +KdpLowRestoreBreakpoint(IN ULONG BpIndex) +{ + /* Were we not able to remove it earlier? */ + if (KdpBreakpointTable[BpIndex].Flags & KdpBreakpointExpired) + { + /* Well then, we'll just re-use it and return success! */ + KdpBreakpointTable[BpIndex].Flags &= ~KdpBreakpointExpired; + return TRUE; + } + + /* Are we merely writing an INT3 on top of another INT3? */ + if (KdpBreakpointTable[BpIndex].Content == KdpBreakpointInstruction) + { + /* Nothing to do then... */ + return TRUE; + } + + /* Ok, we actually have to overwrite the instruction now */ + RtlCopyMemory(KdpBreakpointTable[BpIndex].Address, + &KdpBreakpointInstruction, + sizeof(UCHAR)); + + /* Clear any possible previous pending flag and return success */ + KdpBreakpointTable[BpIndex].Flags &= ~KdpBreakpointPending; + return TRUE; +} + +BOOLEAN +NTAPI +KdpDeleteBreakpoint(IN ULONG BpEntry) +{ + ULONG BpIndex = BpEntry - 1; + + /* Check for invalid breakpoint entry */ + if (!(BpEntry) || (BpEntry > 20)) return FALSE; + + /* If the specified breakpoint table entry is not valid, then return FALSE. */ + if (!KdpBreakpointTable[BpIndex].Flags) return FALSE; + + /* Check if the breakpoint is suspended */ + if (KdpBreakpointTable[BpIndex].Flags & KdpBreakpointSuspended) + { + /* Check if breakpoint is not ...? */ + if (!(KdpBreakpointTable[BpIndex].Flags & KdpBreakpointExpired)) + { + /* Invalidate it and return success */ + KdpBreakpointTable[BpIndex].Flags = 0; + return TRUE; + } + } + + /* Restore original data, then invalidate it and return success */ + if (KdpLowWriteContent(BpIndex)) KdpBreakpointTable[BpIndex].Flags = 0; + return TRUE; +} + +BOOLEAN +NTAPI +KdpDeleteBreakpointRange(IN PVOID Base, + IN PVOID Limit) +{ + ULONG BpIndex; + BOOLEAN Return = FALSE; + + /* Loop the breakpoint table */ + for (BpIndex = 0; BpIndex < 20; BpIndex++) + { + /* Make sure that the breakpoint is active and matches the range. */ + if ((KdpBreakpointTable[BpIndex].Flags & KdpBreakpointActive) && + ((KdpBreakpointTable[BpIndex].Address >= Base) && + (KdpBreakpointTable[BpIndex].Address <= Limit))) + { + /* Delete it */ + Return = Return || KdpDeleteBreakpoint(BpIndex + 1); + } + } + + /* Return to caller */ + return Return; +} + +VOID +NTAPI +KdpRestoreAllBreakpoints(VOID) +{ + ULONG BpIndex; + + /* No more suspended Breakpoints */ + BreakpointsSuspended = FALSE; + + /* Loop the breakpoints */ + for (BpIndex = 0; BpIndex < 20; BpIndex++ ) + { + /* Check if they are valid, suspended breakpoints */ + if ((KdpBreakpointTable[BpIndex].Flags & KdpBreakpointActive) && + (KdpBreakpointTable[BpIndex].Flags & KdpBreakpointSuspended)) + { + /* Unsuspend them */ + KdpBreakpointTable[BpIndex].Flags &= ~KdpBreakpointSuspended; + KdpLowRestoreBreakpoint(BpIndex); + } + } +} diff --git a/reactos/ntoskrnl/kd64/kddata.c b/reactos/ntoskrnl/kd64/kddata.c new file mode 100644 index 00000000000..d1389f445ab --- /dev/null +++ b/reactos/ntoskrnl/kd64/kddata.c @@ -0,0 +1,467 @@ +/* + * 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 (alex.ionescu@reactos.org) + */ + +/* INCLUDES ******************************************************************/ + +#include +#define NDEBUG +#include + +VOID NTAPI RtlpBreakWithStatusInstruction(VOID); + +/* GLOBALS *******************************************************************/ + +// +// 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; +BOOLEAN _KdDebuggerEnabled; +BOOLEAN KdAutoEnableOnEvent; +BOOLEAN KdPreviouslyEnabled; +BOOLEAN KdpDebuggerStructuresInitialized; +BOOLEAN KdEnteredDebugger; +ULONG KdDisableCount; +LARGE_INTEGER KdPerformanceCounterRate; + +// +// Breakpoint Data +// +BREAKPOINT_ENTRY KdpBreakpointTable[20]; +ULONG KdpBreakpointInstruction = 0xCC; +BOOLEAN KdpOweBreakpoint; +BOOLEAN BreakpointsSuspended; +ULONG KdpNumInternalBreakpoints; + +ULONG KdpCurrentSymbolStart, KdpCurrentSymbolEnd; + +// +// Time Slip Support +// +KDPC KdpTimeSlipDpc; +KTIMER KdpTimeSlipTimer; +WORK_QUEUE_ITEM KdpTimeSlipWorkItem; +LONG KdpTimeSlipPending = 1; +PKEVENT KdpTimeSlipEvent; +KSPIN_LOCK KdpTimeSlipEventLock; +LARGE_INTEGER KdTimerStop, KdTimerStart, KdTimerDifference; + +// +// Buffers +// +CHAR KdpMessageBuffer[4096]; +CHAR KdpPathBuffer[4096]; + +// +// KdPrint Buffers +// +CHAR KdPrintDefaultCircularBuffer[0x8000]; +PCHAR KdPrintWritePointer = KdPrintDefaultCircularBuffer; +ULONG KdPrintRolloverCount; +PCHAR KdPrintCircularBuffer = KdPrintDefaultCircularBuffer; +ULONG KdPrintBufferSize = sizeof(KdPrintDefaultCircularBuffer); +ULONG KdPrintBufferChanges = 0; + +// +// 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); + +// +// Debugger Data +// +LIST_ENTRY KdpDebuggerDataListHead; +KSPIN_LOCK KdpDataSpinLock; + +// +// Debugger Version and Data 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 +}; +KDDEBUGGER_DATA64 KdDebuggerDataBlock = +{ + {{0}}, + 0, + {PtrToUlong(RtlpBreakWithStatusInstruction)}, + 0, + FIELD_OFFSET(KTHREAD, CallbackStack), + CBSTACK_CALLBACK_STACK, + CBSTACK_EBP, + 0, + {PtrToUlong(KiCallUserMode)}, + {0}, + {PtrToUlong(&PsLoadedModuleList)}, + {PtrToUlong(&PsActiveProcessHead)}, + {PtrToUlong(&PspCidTable)}, + {PtrToUlong(&ExpSystemResourcesList)}, + {0}, // ExpPagedPoolDescriptor + {0}, // ExpNumberOfPagedPools + {PtrToUlong(&KeTimeIncrement)}, + {PtrToUlong(&KeBugcheckCallbackListHead)}, + {PtrToUlong(KiBugCheckData)}, + {PtrToUlong(&IopErrorLogListHead)}, + {PtrToUlong(&ObpRootDirectoryObject)}, + {PtrToUlong(&ObpTypeObjectType)}, + {0}, // MmSystemCacheStart + {0}, // MmSystemCacheEnd + {0}, // MmSystemCacheWs + {0}, // MmPfnDatabase + {0}, // MmSystemPtesStart + {0}, // MmSystemPtesEnd + {0}, // MmSubsectionBase + {0}, // MmNumberOfPagingFiles + {0}, // MmLowestPhysicalPage + {0}, // MmHighestPhysicalPage + {0}, // MmNumberOfPhysicalPages + {0}, // MmMaximumNonPagedPoolInBytes + {0}, // MmNonPagedSystemStart + {0}, // MmNonPagedPoolStart + {0}, // MmNonPagedPoolEnd + {0}, // MmPagedPoolStart + {0}, // MmPagedPoolEnd + {0}, // MmPagedPoolInfo + PAGE_SIZE, + {0}, // MmSizeOfPagedPoolInBytes + {0}, // MmTotalCommitLimit + {0}, // MmTotalCommittedPages + {0}, // MmSharedCommit + {0}, // MmDriverCommit + {0}, // MmProcessCommit + {0}, // MmPagedPoolCommit + {0}, + {0}, // MmZeroedPageListHead + {0}, // MmFreePageListHead + {0}, // MmStandbyPageListHead + {0}, // MmModifiedPageListHead + {0}, // MmModifiedNoWritePageListHead + {0}, // MmAvailablePages + {0}, // MmResidentAvailablePages + {0}, // PoolTrackTable + {0}, // NonPagedPoolDescriptor + {PtrToUlong(&MmHighestUserAddress)}, + {PtrToUlong(&MmSystemRangeStart)}, + {PtrToUlong(&MmUserProbeAddress)}, + {PtrToUlong(KdPrintDefaultCircularBuffer)}, + {PtrToUlong(KdPrintDefaultCircularBuffer + 1)}, + {PtrToUlong(&KdPrintWritePointer)}, + {PtrToUlong(&KdPrintRolloverCount)}, + {0}, // MmLoadedUserImageList + {PtrToUlong(&NtBuildLab)}, + {0}, + {PtrToUlong(KiProcessorBlock)}, + {0}, // MmUnloadedDrivers + {0}, // MmLastUnloadedDrivers + {0}, // MmTriageActionTaken + {0}, // MmSpecialPoolTag + {0}, // KernelVerifier + {0}, // MmVerifierData + {0}, // MmAllocatedNonPagedPool + {0}, // MmPeakCommitment + {0}, // MmtotalCommitLimitMaximum + {PtrToUlong(&CmNtCSDVersion)}, + {0}, // MmPhysicalMemoryBlock + {0}, // MmSessionBase + {0}, // MmSessionSize + {0}, + {0}, + FIELD_OFFSET(KTHREAD, NextProcessor), + FIELD_OFFSET(KTHREAD, Teb), + FIELD_OFFSET(KTHREAD, KernelStack), + FIELD_OFFSET(KTHREAD, InitialStack), + FIELD_OFFSET(KTHREAD, ApcState.Process), + FIELD_OFFSET(KTHREAD, State), + 0, + 0, + sizeof(EPROCESS), + FIELD_OFFSET(EPROCESS, Peb), + FIELD_OFFSET(EPROCESS, InheritedFromUniqueProcessId), + FIELD_OFFSET(EPROCESS, Pcb.DirectoryTableBase), + sizeof(KPRCB), + FIELD_OFFSET(KPRCB, DpcRoutineActive), + FIELD_OFFSET(KPRCB, CurrentThread), + FIELD_OFFSET(KPRCB, MHz), + FIELD_OFFSET(KPRCB, CpuType), + FIELD_OFFSET(KPRCB, VendorString), + FIELD_OFFSET(KPRCB, ProcessorState.ContextFrame), + FIELD_OFFSET(KPRCB, Number), + sizeof(ETHREAD), + {PtrToUlong(KdPrintDefaultCircularBuffer)}, + {PtrToUlong(&KdPrintBufferSize)}, + {PtrToUlong(&KeLoaderBlock)}, + sizeof(KIPCR) + sizeof(KPRCB), + FIELD_OFFSET(KIPCR, Self), + FIELD_OFFSET(KPCR, Prcb), + FIELD_OFFSET(KIPCR, PrcbData), + 0, + 0, + 0, + 0, + 0, + FIELD_OFFSET(KIPCR, PrcbData) + + FIELD_OFFSET(KPRCB, ProcessorState.SpecialRegisters), + KGDT_R0_CODE, + KGDT_R0_DATA, + KGDT_R0_PCR, + KGDT_R3_CODE, + KGDT_R3_DATA, + KGDT_R3_TEB, + KGDT_LDT, + KGDT_TSS, + 0, + 0, + {0}, // IopNumTriagDumpDataBlocks + {0}, // IopTriageDumpDataBlocks +}; diff --git a/reactos/ntoskrnl/kd64/kdinit.c b/reactos/ntoskrnl/kd64/kdinit.c new file mode 100644 index 00000000000..8a88e3aab5f --- /dev/null +++ b/reactos/ntoskrnl/kd64/kdinit.c @@ -0,0 +1,267 @@ +/* + * PROJECT: ReactOS Kernel + * LICENSE: GPL - See COPYING in the top level directory + * FILE: ntoskrnl/kd64/kdinit.c + * PURPOSE: KD64 Initialization Code + * PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org) + */ + +/* INCLUDES ******************************************************************/ + +#include +#define NDEBUG +#include + +/* 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, j, Length; + CHAR NameBuffer[256]; + PWCHAR Name; + + /* 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 = (ULONGLONG)(LONG_PTR)&PsLoadedModuleList; + KdVersionBlock.DebuggerDataList = (ULONGLONG)(LONG_PTR)&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) + { + /* Get the image entry */ + LdrEntry = CONTAINING_RECORD(LoaderBlock->LoadOrderListHead.Flink, + LDR_DATA_TABLE_ENTRY, + InLoadOrderLinks); + + /* Save the Kernel Base */ + PsNtosImageBase = (ULONG)LdrEntry->DllBase; + KdVersionBlock.KernBase = (ULONGLONG)(LONG_PTR)LdrEntry->DllBase; + + /* 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 = (ULONGLONG)(LONG_PTR)PsNtosImageBase; + + /* Unconditionally enable KD */ + EnableKd = TRUE; + } + + /* Set the Kernel Base in the Data Block */ + KdDebuggerDataBlock.KernBase = (ULONGLONG)(LONG_PTR)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 */ + Name = LdrEntry->FullDllName.Buffer; + Length = LdrEntry->FullDllName.Length / sizeof(WCHAR); + j = 0; + do + { + /* Do cheap Unicode to ANSI conversion */ + NameBuffer[j++] = (CHAR)*Name++; + } while (j < Length); + + /* Null-terminate */ + NameBuffer[j] = ANSI_NULL; + + /* 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; +} diff --git a/reactos/ntoskrnl/kd64/kdlock.c b/reactos/ntoskrnl/kd64/kdlock.c new file mode 100644 index 00000000000..141df038d8c --- /dev/null +++ b/reactos/ntoskrnl/kd64/kdlock.c @@ -0,0 +1,125 @@ +/* + * 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 (alex.ionescu@reactos.org) + */ + +/* INCLUDES ******************************************************************/ + +#include +#define NDEBUG +#include + +/* PRIVATE FUNCTIONS *********************************************************/ + +VOID +NTAPI +KdpPortLock(VOID) +{ + /* Acquire the lock */ + KiAcquireSpinLock(&KdpDebuggerLock); +} + +VOID +NTAPI +KdpPortUnlock(VOID) +{ + /* Release the lock */ + KiReleaseSpinLock(&KdpDebuggerLock); +} + +BOOLEAN +NTAPI +KdpPollBreakInWithPortLock(VOID) +{ + BOOLEAN DoBreak = FALSE; + + /* First make sure that KD is enabled */ + if (KdDebuggerEnabled) + { + /* Check if a CTRL-C is in the queue */ + if (KdpContext.KdpControlCPending) + { + /* Set it and prepare for break */ + DoBreak = TRUE; + KdpContext.KdpControlCPending = FALSE; + } + else + { + /* Now get a packet */ + if (!KdReceivePacket(PACKET_TYPE_KD_POLL_BREAKIN, + NULL, + NULL, + NULL, + NULL)) + { + /* Successful breakin */ + DoBreak = TRUE; + } + } + } + + /* Tell the caller to do a break */ + return DoBreak; +} + +/* PUBLIC FUNCTIONS **********************************************************/ + +/* + * @implemented + */ +BOOLEAN +NTAPI +KdPollBreakIn(VOID) +{ + BOOLEAN DoBreak = FALSE; + ULONG Flags = 0; + + /* 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; +} + diff --git a/reactos/ntoskrnl/kd64/kdprint.c b/reactos/ntoskrnl/kd64/kdprint.c new file mode 100644 index 00000000000..2f3559248ef --- /dev/null +++ b/reactos/ntoskrnl/kd64/kdprint.c @@ -0,0 +1,198 @@ +/* + * PROJECT: ReactOS Kernel + * LICENSE: GPL - See COPYING in the top level directory + * FILE: ntoskrnl/kd64/kdprint.c + * PURPOSE: KD64 Trap Handler Routines + * PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org) + */ + +/* INCLUDES ******************************************************************/ + +#include +#define NDEBUG +#include + +/* FUNCTIONS *****************************************************************/ + +BOOLEAN +NTAPI +KdpPrintString(IN PSTRING Output) +{ + STRING Data, Header; + DBGKD_DEBUG_IO DebugIo; + ULONG Length = Output->Length; + + /* Copy the string */ + RtlMoveMemory(KdpMessageBuffer, Output->Buffer, Length); + + /* Make sure we don't exceed the KD Packet size */ + if ((sizeof(DBGKD_DEBUG_IO) + Length) > PACKET_MAX_SIZE) + { + /* Normalize length */ + Length = PACKET_MAX_SIZE - sizeof(DBGKD_DEBUG_IO); + } + + /* Build the packet header */ + DebugIo.ApiNumber = DbgKdPrintStringApi; + DebugIo.ProcessorLevel = KeProcessorLevel; + DebugIo.Processor = KeGetCurrentPrcb()->Number; + DebugIo.u.PrintString.LengthOfString = Length; + Header.Length = sizeof(DBGKD_DEBUG_IO); + Header.Buffer = (PCHAR)&DebugIo; + + /* Build the data */ + Data.Length = Length; + Data.Buffer = KdpMessageBuffer; + + /* Send the packet */ + KdSendPacket(PACKET_TYPE_KD_DEBUG_IO, &Header, &Data, &KdpContext); + + /* Check if the user pressed CTRL+C */ + return KdpPollBreakInWithPortLock(); +} + +ULONG +NTAPI +KdpCommandString(IN ULONG Length, + IN LPSTR String, + IN KPROCESSOR_MODE PreviousMode, + IN PCONTEXT ContextRecord, + IN PKTRAP_FRAME TrapFrame, + IN PKEXCEPTION_FRAME ExceptionFrame) +{ + /* FIXME */ + return FALSE; +} + +ULONG +NTAPI +KdpSymbol(IN PSTRING DllPath, + IN PKD_SYMBOLS_INFO DllBase, + IN BOOLEAN Unload, + IN KPROCESSOR_MODE PreviousMode, + IN PCONTEXT ContextRecord, + IN PKTRAP_FRAME TrapFrame, + IN PKEXCEPTION_FRAME ExceptionFrame) +{ + BOOLEAN Entered; + PKPRCB Prcb = KeGetCurrentPrcb(); + ULONG Status; + + /* Check if we need to do anything */ + if ((PreviousMode != KernelMode) || (KdDebuggerNotPresent)) return 0; + + /* Enter the debugger */ + Entered = KdEnterDebugger(TrapFrame, ExceptionFrame); + + /* Save the CPU Control State and save the context */ + KiSaveProcessorControlState(&Prcb->ProcessorState); + RtlCopyMemory(&Prcb->ProcessorState.ContextFrame, + ContextRecord, + sizeof(CONTEXT)); + + /* Report the new state */ + Status = KdpReportLoadSymbolsStateChange(DllPath, + DllBase, + Unload, + &Prcb->ProcessorState. + ContextFrame); + + /* 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); + return 0; +} + +ULONG +NTAPI +KdpPrompt(IN LPSTR InString, + IN ULONG InStringLength, + OUT LPSTR OutString, + IN ULONG OutStringLength, + IN KPROCESSOR_MODE PreviousMode, + IN PKTRAP_FRAME TrapFrame, + IN PKEXCEPTION_FRAME ExceptionFrame) +{ + /* FIXME */ + return FALSE; +} + +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) +{ + NTSTATUS ReturnValue; + BOOLEAN Entered; + ANSI_STRING AnsiString; + + /* Assume failure */ + *Status = FALSE; + + /* Validate the mask */ + if (ComponentMask <= 0x1F) ComponentMask = 1 << ComponentMask; + if (!(Kd_WIN2000_Mask & ComponentMask) || + ((ComponentId < KdComponentTableSize) && + !(*KdComponentTable[ComponentId] & ComponentMask))) + { + /* Mask validation failed */ + *Status = TRUE; + return FALSE; + } + + /* Normalize the length */ + Length = min(Length, 512); + + /* Check if we need to verify the buffer */ + if (PreviousMode != KernelMode) + { + /* FIXME: Support user-mode */ + } + + /* Setup the ANSI string */ + AnsiString.Buffer = String; + AnsiString.Length = (USHORT)Length; + + /* Log the print */ + //KdLogDbgPrint(&AnsiString); + + /* Check for a debugger */ + if (KdDebuggerNotPresent) + { + /* Fail */ + *Status = TRUE; + return (ULONG)STATUS_DEVICE_NOT_CONNECTED; + } + + /* Enter the debugger */ + Entered = KdEnterDebugger(TrapFrame, ExceptionFrame); + + /* Print the string */ + if (KdpPrintString(&AnsiString)) + { + /* User pressed CTRL-C, breakpoint on return */ + ReturnValue = STATUS_BREAKPOINT; + } + else + { + /* String was printed */ + ReturnValue = STATUS_SUCCESS; + } + + /* Exit the debugger and return */ + KdExitDebugger(Entered); + *Status = TRUE; + return ReturnValue; +} + diff --git a/reactos/ntoskrnl/kd64/kdtrap.c b/reactos/ntoskrnl/kd64/kdtrap.c new file mode 100644 index 00000000000..264b2830422 --- /dev/null +++ b/reactos/ntoskrnl/kd64/kdtrap.c @@ -0,0 +1,239 @@ +/* + * PROJECT: ReactOS Kernel + * LICENSE: GPL - See COPYING in the top level directory + * FILE: ntoskrnl/kd64/kdtrap.c + * PURPOSE: KD64 Trap Handlers + * PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org) + */ + +/* INCLUDES ******************************************************************/ + +#include +#define NDEBUG +#include + +/* 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; + NTSTATUS ExceptionCode = ExceptionRecord->ExceptionCode; + + /* Check if this is INT1 or 3, or if we're forced to handle it */ + if ((ExceptionCode == STATUS_BREAKPOINT) || + (ExceptionCode == STATUS_SINGLE_STEP) || + //(ExceptionCode == STATUS_ASSERTION_FAILURE) || + (NtGlobalFlag & FLG_STOP_ON_EXCEPTION)) + { + /* Check if we can't really handle this */ + if ((SecondChanceException) || + (ExceptionCode == STATUS_PORT_DISCONNECTED) || + (NT_SUCCESS(ExceptionCode))) + { + /* Return false to have someone else take care of the exception */ + return FALSE; + } + } + else if (SecondChanceException) + { + /* We won't bother unless this is second chance */ + 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 */ + Status = KdpReportExceptionStateChange(ExceptionRecord, + &Prcb->ProcessorState. + ContextFrame, + SecondChanceException); + + /* 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; +} + +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; + + /* + * 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 = KdpPrint(ContextRecord->Ebx, + ContextRecord->Edi, + (LPSTR)ExceptionRecord->ExceptionInformation[1], + (ULONG)ExceptionRecord->ExceptionInformation[2], + PreviousMode, + TrapFrame, + ExceptionFrame, + &Status); + + /* Update the return value for the caller */ + ContextRecord->Eax = Eax; + break; + + /* DbgPrompt */ + case BREAKPOINT_PROMPT: + + /* Call the worker routine */ + while (TRUE); + 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 */ + KdpSymbol((PVOID)ExceptionRecord->ExceptionInformation[1], + (PVOID)ExceptionRecord->ExceptionInformation[2], + Unload, + PreviousMode, + ContextRecord, + TrapFrame, + ExceptionFrame); + Status = TRUE; + break; + + /* DbgCommandString*/ + case BREAKPOINT_COMMAND_STRING: + + /* Call the worker routine */ + while (TRUE); + 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; + } +} diff --git a/reactos/ntoskrnl/ke/i386/cpu.c b/reactos/ntoskrnl/ke/i386/cpu.c index 332560e9435..979b02b8631 100644 --- a/reactos/ntoskrnl/ke/i386/cpu.c +++ b/reactos/ntoskrnl/ke/i386/cpu.c @@ -697,8 +697,8 @@ KiRestoreProcessorControlState(PKPROCESSOR_STATE ProcessorState) // // Restore GDT, IDT, LDT and TSS // - Ke386SetGlobalDescriptorTable(ProcessorState->SpecialRegisters.Gdtr); - Ke386SetInterruptDescriptorTable(ProcessorState->SpecialRegisters.Idtr); + Ke386SetGlobalDescriptorTable(ProcessorState->SpecialRegisters.Gdtr.Base); + Ke386SetInterruptDescriptorTable(ProcessorState->SpecialRegisters.Idtr.Base); Ke386SetTr(ProcessorState->SpecialRegisters.Tr); Ke386SetLocalDescriptorTable(ProcessorState->SpecialRegisters.Ldtr); } @@ -724,8 +724,8 @@ KiSaveProcessorControlState(OUT PKPROCESSOR_STATE ProcessorState) Ke386SetDr7(0); /* Save GDT, IDT, LDT and TSS */ - Ke386GetGlobalDescriptorTable(ProcessorState->SpecialRegisters.Gdtr); - Ke386GetInterruptDescriptorTable(ProcessorState->SpecialRegisters.Idtr); + Ke386GetGlobalDescriptorTable(ProcessorState->SpecialRegisters.Gdtr.Base); + Ke386GetInterruptDescriptorTable(ProcessorState->SpecialRegisters.Idtr.Base); Ke386GetTr(ProcessorState->SpecialRegisters.Tr); Ke386GetLocalDescriptorTable(ProcessorState->SpecialRegisters.Ldtr); } diff --git a/reactos/ntoskrnl/ke/i386/exp.c b/reactos/ntoskrnl/ke/i386/exp.c index 500a1db28dd..90a365fd8a4 100644 --- a/reactos/ntoskrnl/ke/i386/exp.c +++ b/reactos/ntoskrnl/ke/i386/exp.c @@ -800,7 +800,7 @@ KiDispatchException(IN PEXCEPTION_RECORD ExceptionRecord, /* Set the context flags */ Context.ContextFlags = CONTEXT_FULL | CONTEXT_DEBUG_REGISTERS; - /* Check if User Mode or if the debugger isenabled */ + /* Check if User Mode or if the debugger is enabled */ if ((PreviousMode == UserMode) || (KdDebuggerEnabled)) { /* Add the FPU Flag */ @@ -846,9 +846,6 @@ KiDispatchException(IN PEXCEPTION_RECORD ExceptionRecord, goto Handled; } - /* HACK: GDB Entry */ - if (KdpCallGdb(TrapFrame, ExceptionRecord, &Context)) goto Handled; - /* If the Debugger couldn't handle it, dispatch the exception */ if (RtlDispatchException(ExceptionRecord, &Context)) goto Handled; } @@ -894,9 +891,6 @@ KiDispatchException(IN PEXCEPTION_RECORD ExceptionRecord, goto Handled; } - /* HACK: GDB Entry */ - if (KdpCallGdb(TrapFrame, ExceptionRecord, &Context)) goto Handled; - /* Forward exception to user mode debugger */ if (DbgkForwardException(ExceptionRecord, TRUE, FALSE)) goto Exit; @@ -1045,4 +1039,3 @@ KeRaiseUserException(IN NTSTATUS ExceptionCode) /* Return the old EIP */ return (NTSTATUS)OldEip; } - diff --git a/reactos/ntoskrnl/ke/i386/trap.s b/reactos/ntoskrnl/ke/i386/trap.s index abb36b77552..7392de685d6 100644 --- a/reactos/ntoskrnl/ke/i386/trap.s +++ b/reactos/ntoskrnl/ke/i386/trap.s @@ -228,22 +228,6 @@ CopyParams: /* Copy the parameters */ rep movsd -#ifdef DBG - /* - * The following lines are for the benefit of GDB. It will see the return - * address of the "call ebx" below, find the last label before it and - * thinks that that's the start of the function. It will then check to see - * if it starts with a standard function prolog (push ebp, mov ebp,esp1). - * When that standard function prolog is not found, it will stop the - * stack backtrace. Since we do want to backtrace into usermode, let's - * make GDB happy and create a standard prolog. - */ -KiSystemService: - push ebp - mov ebp,esp - pop ebp -#endif - /* Do the System Call */ call ebx @@ -482,7 +466,7 @@ _KiDebugService: TRAP_PROLOG kids /* Increase EIP so we skip the INT3 */ - //inc dword ptr [ebp+KTRAP_FRAME_EIP] + inc dword ptr [ebp+KTRAP_FRAME_EIP] /* Call debug service dispatcher */ mov eax, [ebp+KTRAP_FRAME_EAX] @@ -821,7 +805,11 @@ _KiTrap3: /* Enter trap */ TRAP_PROLOG kit3 + /* Set status code */ + mov eax, 0 //STATUS_SUCCESS + /* Check for V86 */ +PrepareInt3: test dword ptr [ebp+KTRAP_FRAME_EFLAGS], EFLAGS_V86_MASK jnz V86Int3 diff --git a/reactos/ntoskrnl/mm/rmap.c b/reactos/ntoskrnl/mm/rmap.c index 1228a02118a..7b1d51b01af 100644 --- a/reactos/ntoskrnl/mm/rmap.c +++ b/reactos/ntoskrnl/mm/rmap.c @@ -432,9 +432,9 @@ MmInsertRmap(PFN_TYPE Page, PEPROCESS Process, { DbgPrint("MmInsertRmap tries to add a second rmap entry for address %p\n current caller ", current_entry->Address); - KeRosPrintAddress(new_entry->Caller); + DbgPrint("%p", new_entry->Caller); DbgPrint("\n previous caller "); - KeRosPrintAddress(current_entry->Caller); + DbgPrint("%p", current_entry->Caller); DbgPrint("\n"); KeBugCheck(0); } diff --git a/reactos/ntoskrnl/mm/sysldr.c b/reactos/ntoskrnl/mm/sysldr.c index d67d4a4bfc4..d8d599b2a2d 100644 --- a/reactos/ntoskrnl/mm/sysldr.c +++ b/reactos/ntoskrnl/mm/sysldr.c @@ -1752,9 +1752,6 @@ LoaderScan: if (ModuleObject) *ModuleObject = LdrEntry; if (ImageBaseAddress) *ImageBaseAddress = LdrEntry->DllBase; - /* Hook for KDB on loading a driver. */ - KDB_LOADDRIVER_HOOK(FileName, LdrEntry); - Quickie: /* If we have a file handle, close it */ if (FileHandle) ZwClose(FileHandle); diff --git a/reactos/ntoskrnl/ps/kill.c b/reactos/ntoskrnl/ps/kill.c index d5e05d0892e..c8e99579c30 100644 --- a/reactos/ntoskrnl/ps/kill.c +++ b/reactos/ntoskrnl/ps/kill.c @@ -287,9 +287,6 @@ PspDeleteProcess(IN PVOID ObjectBody) KeUnstackDetachProcess(&ApcState); } - /* KDB hook */ - KDB_DELETEPROCESS_HOOK(Process); - /* Check if we have an address space, and clean it */ if (Process->HasAddressSpace) {