mirror of
https://github.com/reactos/reactos.git
synced 2024-12-28 18:15:11 +00:00
- KdDebuggerNotPresent should be FALSE by default.
- KdpTimeSlipPending should be 1 by defalt. - Enable KdInitSystem; don't touch SharedUserData yet because our loader doesn't map it properly until we hit MmInit1, so disable this code for now. - Implement KdpPollBreakInWithPortLock. - Add calls to KdpPrint, KdpSymbol since KdpTrap now gets activated. Implement KdpPrint and KdpPrintString, but not KdLogDbgPrint (so debug messages before WinDBG connects are currently lost). - Implement KdpSymbol but not essential call to KdpReportLoadSymbolsStateChange. - Only save/restore CR4 if KeFeatureBits indicates CR4 support exists. - Export KdDebuggerNotPresent since KDCOM needs it. svn path=/branches/alex-kd-branch/; revision=25839
This commit is contained in:
parent
929844ef2a
commit
75497d0898
10 changed files with 302 additions and 14 deletions
|
@ -104,6 +104,37 @@ KdEnableDebuggerWithLock(
|
|||
IN BOOLEAN NeedLock
|
||||
);
|
||||
|
||||
ULONG
|
||||
NTAPI
|
||||
KdpPrint(
|
||||
IN ULONG ComponentId,
|
||||
IN ULONG ComponentMask,
|
||||
IN LPSTR String,
|
||||
IN ULONG Length,
|
||||
IN KPROCESSOR_MODE PreviousMode,
|
||||
IN PKTRAP_FRAME TrapFrame,
|
||||
IN PKEXCEPTION_FRAME ExceptionFrame,
|
||||
OUT PBOOLEAN Status
|
||||
);
|
||||
|
||||
ULONG
|
||||
NTAPI
|
||||
KdpSymbol(
|
||||
IN LPSTR DllPath,
|
||||
IN ULONG DllBase,
|
||||
IN BOOLEAN Unload,
|
||||
IN KPROCESSOR_MODE PreviousMode,
|
||||
IN PCONTEXT ContextRecord,
|
||||
IN PKTRAP_FRAME TrapFrame,
|
||||
IN PKEXCEPTION_FRAME ExceptionFrame
|
||||
);
|
||||
|
||||
BOOLEAN
|
||||
NTAPI
|
||||
KdpPollBreakInWithPortLock(
|
||||
VOID
|
||||
);
|
||||
|
||||
extern DBGKD_GET_VERSION64 KdVersionBlock;
|
||||
extern KDDEBUGGER_DATA64 KdDebuggerDataBlock;
|
||||
extern LIST_ENTRY KdpDebuggerDataListHead;
|
||||
|
@ -133,4 +164,6 @@ extern BOOLEAN KdpControlCWaiting;
|
|||
extern BOOLEAN KdpPortLocked;
|
||||
extern KSPIN_LOCK KdpDebuggerLock;
|
||||
extern LARGE_INTEGER KdTimerStop, KdTimerStart, KdTimerDifference;
|
||||
|
||||
extern ULONG KdComponentTableSize;
|
||||
extern ULONG Kd_WIN2000_Mask;
|
||||
extern PULONG KdComponentTable[104];
|
||||
|
|
|
@ -62,7 +62,7 @@ PKDEBUG_SWITCH_ROUTINE KiDebugSwitchRoutine;
|
|||
//
|
||||
BOOLEAN KdBreakAfterSymbolLoad;
|
||||
BOOLEAN KdPitchDebugger;
|
||||
BOOLEAN _KdDebuggerNotPresent = TRUE;
|
||||
BOOLEAN _KdDebuggerNotPresent;
|
||||
BOOLEAN _KdDebuggerEnabled;
|
||||
BOOLEAN KdAutoEnableOnEvent;
|
||||
BOOLEAN KdPreviouslyEnabled;
|
||||
|
@ -77,7 +77,7 @@ LARGE_INTEGER KdPerformanceCounterRate;
|
|||
KDPC KdpTimeSlipDpc;
|
||||
KTIMER KdpTimeSlipTimer;
|
||||
WORK_QUEUE_ITEM KdpTimeSlipWorkItem;
|
||||
LONG KdpTimeSlipPending;
|
||||
LONG KdpTimeSlipPending = 1;
|
||||
PKEVENT KdpTimeSlipEvent;
|
||||
KSPIN_LOCK KdpTimeSlipEventLock;
|
||||
LARGE_INTEGER KdTimerStop, KdTimerStart, KdTimerDifference;
|
||||
|
|
|
@ -70,7 +70,6 @@ KdInitSystem(IN ULONG BootPhase,
|
|||
PLIST_ENTRY NextEntry;
|
||||
ULONG i;
|
||||
CHAR NameBuffer[256];
|
||||
return TRUE;
|
||||
|
||||
/* Check if this is Phase 1 */
|
||||
if (BootPhase)
|
||||
|
@ -207,9 +206,9 @@ KdInitSystem(IN ULONG BootPhase,
|
|||
KdDebuggerEnabled = TRUE;
|
||||
|
||||
/* Let user-mode know that it's enabled as well */
|
||||
#undef KdDebuggerEnabled
|
||||
SharedUserData->KdDebuggerEnabled = TRUE;
|
||||
#define KdDebuggerEnabled _KdDebuggerEnabled
|
||||
//#undef KdDebuggerEnabled
|
||||
//SharedUserData->KdDebuggerEnabled = TRUE;
|
||||
//#define KdDebuggerEnabled _KdDebuggerEnabled
|
||||
|
||||
/* Check if we have a loader block */
|
||||
if (LoaderBlock)
|
||||
|
|
|
@ -30,6 +30,41 @@ KdpPortUnlock(VOID)
|
|||
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 **********************************************************/
|
||||
|
||||
/*
|
||||
|
|
204
reactos/ntoskrnl/kd64/kdprint.c
Normal file
204
reactos/ntoskrnl/kd64/kdprint.c
Normal file
|
@ -0,0 +1,204 @@
|
|||
/*
|
||||
* 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 <ntoskrnl.h>
|
||||
#define NDEBUG
|
||||
#include <debug.h>
|
||||
|
||||
CHAR KdpMessageBuffer[4096];
|
||||
|
||||
/* 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 LPSTR DllPath,
|
||||
IN ULONG 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 */
|
||||
#if 0
|
||||
Status = KdpReportLoadSymbolsStateChange(DllPath,
|
||||
DllBase,
|
||||
Unload,
|
||||
&Prcb->
|
||||
ProcessorState.ContextFrame);
|
||||
#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);
|
||||
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;
|
||||
}
|
||||
|
|
@ -101,7 +101,6 @@ KdpTrap(IN PKTRAP_FRAME TrapFrame,
|
|||
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
|
||||
|
@ -120,7 +119,14 @@ KdpTrap(IN PKTRAP_FRAME TrapFrame,
|
|||
case BREAKPOINT_PRINT:
|
||||
|
||||
/* Call the worker routine */
|
||||
Eax = 0;
|
||||
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;
|
||||
|
@ -130,6 +136,7 @@ KdpTrap(IN PKTRAP_FRAME TrapFrame,
|
|||
case BREAKPOINT_PROMPT:
|
||||
|
||||
/* Call the worker routine */
|
||||
while (TRUE);
|
||||
Eax = 0;
|
||||
Status = TRUE;
|
||||
|
||||
|
@ -147,6 +154,13 @@ KdpTrap(IN PKTRAP_FRAME TrapFrame,
|
|||
case BREAKPOINT_LOAD_SYMBOLS:
|
||||
|
||||
/* Call the worker routine */
|
||||
KdpSymbol(UlongToPtr(ExceptionRecord->ExceptionInformation[1]),
|
||||
(ULONG)ExceptionRecord->ExceptionInformation[2],
|
||||
Unload,
|
||||
PreviousMode,
|
||||
ContextRecord,
|
||||
TrapFrame,
|
||||
ExceptionFrame);
|
||||
Status = TRUE;
|
||||
break;
|
||||
|
||||
|
@ -154,6 +168,7 @@ KdpTrap(IN PKTRAP_FRAME TrapFrame,
|
|||
case BREAKPOINT_COMMAND_STRING:
|
||||
|
||||
/* Call the worker routine */
|
||||
while (TRUE);
|
||||
Status = TRUE;
|
||||
|
||||
/* Anything else, do nothing */
|
||||
|
|
|
@ -678,11 +678,12 @@ VOID
|
|||
NTAPI
|
||||
KiRestoreProcessorControlState(PKPROCESSOR_STATE ProcessorState)
|
||||
{
|
||||
return;
|
||||
/* Restore the CR registers */
|
||||
__writecr0(ProcessorState->SpecialRegisters.Cr0);
|
||||
Ke386SetCr2(ProcessorState->SpecialRegisters.Cr2);
|
||||
__writecr3(ProcessorState->SpecialRegisters.Cr3);
|
||||
__writecr4(ProcessorState->SpecialRegisters.Cr4);
|
||||
if (KeFeatureBits & KF_CR4) __writecr4(ProcessorState->SpecialRegisters.Cr4);
|
||||
|
||||
//
|
||||
// Restore the DR registers
|
||||
|
@ -711,7 +712,8 @@ KiSaveProcessorControlState(OUT PKPROCESSOR_STATE ProcessorState)
|
|||
ProcessorState->SpecialRegisters.Cr0 = __readcr0();
|
||||
ProcessorState->SpecialRegisters.Cr2 = __readcr2();
|
||||
ProcessorState->SpecialRegisters.Cr3 = __readcr3();
|
||||
ProcessorState->SpecialRegisters.Cr4 = __readcr4();
|
||||
ProcessorState->SpecialRegisters.Cr4 = (KeFeatureBits & KF_CR4) ?
|
||||
__readcr4() : 0;
|
||||
|
||||
/* Save the DR registers */
|
||||
ProcessorState->SpecialRegisters.KernelDr0 = Ke386GetDr0();
|
||||
|
|
|
@ -786,5 +786,3 @@ AppCpuInit:
|
|||
/* Jump into the idle loop */
|
||||
KiIdleLoop();
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -518,7 +518,8 @@ IoWriteTransferCount DATA
|
|||
@IofCallDriver@8
|
||||
@IofCompleteRequest@8
|
||||
IoIsWdmVersionAvailable@8
|
||||
KdComPortInUse DATA
|
||||
KdComPortInUse
|
||||
KdDebuggerNotPresent=_KdDebuggerNotPresent
|
||||
Ke386CallBios@8
|
||||
@KeAcquireGuardedMutex@4
|
||||
@KeAcquireGuardedMutexUnsafe@4
|
||||
|
|
|
@ -198,6 +198,7 @@
|
|||
<file>kddata.c</file>
|
||||
<file>kdinit.c</file>
|
||||
<file>kdlock.c</file>
|
||||
<file>kdprint.c</file>
|
||||
<file>kdtrap.c</file>
|
||||
</directory>
|
||||
<directory name="ldr">
|
||||
|
|
Loading…
Reference in a new issue