- Fix support for /CRASHDEBUG and /NODEBUG; we didn't respect those settings properly and would initialize KD at boot even if they were set.

- Re-enable the breakpoint in vDbgPrintExWithPrefixInternal() as this works properly now. Without this breakpoint some break-in requests got lost if the break-in occurred when handling a debug print (happened a lot at boot).
- Implement Command String support for DbgCommandString() -- we now handle every debug service call.
- Implement NtSetDebugFilterState() and NtQueryDebugFilterState() for KD, meaning we now support debug filters properly.
- Implement KdRefreshDebuggerNotPresent(), KdChangeOption() and KdPowerTransition(). Stub KdSystemDebugControl() to return error status instead of hanging the system.
- Stub the rest of the KD API to print a warning and return a failure packet instead of hanging.
- Set and respect KdpContextSent when getting and setting the thread context -- WinDbg doesn't seem to rely on this, but better safe than sorry.
- Support MP when getting and setting the thread context too -- if the context is operation is for another processor than the current, just get it through the KiProcessorBlock array.
- Initialize the MajorVersion in the KD version block more properly -- the high byte is the major identifier (0 for NT). Add the required DBGKD_MAJOR_TYPES enumeration to wdbgexts.h.
- Simplify setting and clearing the InDbgPrint flag in the TEB to minimize the impact on kernel execution; use 2 dedicated routines instead of a generic one.
- KdpSymbol doesn't return anything, so don't return an ignore status from KdpReportLoadSymbolsStateChange.
- Expose the KdpDefaultRetries and Kd_WIN2000_Mask variables to the registry and add them to KDBG too (unused there).
- No reason to implement KdpSysGetVersion per architecture; move it back to the generic code.
- Add some ARM offsets to the debugger data block that (N/A on other architectures).
- Fix the default size of the DbgPrint log buffer for free builds to save some space. It should be 4 KB for a free build and 32 KB for a checked build.
- Move KeDisableInterrupts to cpu.c as it fits here more than in the IRQ support code in irqobj.c.
- Use KeDisableInterrupts in KeFreezeExecution instead of checking the x86 EFLAG directly.

svn path=/trunk/; revision=43912
This commit is contained in:
Stefan Ginsberg 2009-11-02 17:45:51 +00:00
parent 1859ef4ec9
commit f84d5a02f4
22 changed files with 615 additions and 212 deletions

View file

@ -41,16 +41,9 @@ RtlpCheckForActiveDebugger(VOID)
BOOLEAN
NTAPI
RtlpSetInDbgPrint(IN BOOLEAN NewValue)
RtlpSetInDbgPrint(VOID)
{
/* If we're setting it to false, do it and return */
if (NewValue == FALSE)
{
NtCurrentTeb()->InDbgPrint = FALSE;
return FALSE;
}
/* Setting to true; check if it's not already */
/* Check if it's already set and return TRUE if so */
if (NtCurrentTeb()->InDbgPrint) return TRUE;
/* Set it and return */
@ -58,6 +51,14 @@ RtlpSetInDbgPrint(IN BOOLEAN NewValue)
return FALSE;
}
VOID
NTAPI
RtlpClearInDbgPrint(VOID)
{
/* Clear the flag */
NtCurrentTeb()->InDbgPrint = FALSE;
}
KPROCESSOR_MODE
NTAPI
RtlpGetMode()

View file

@ -2682,6 +2682,13 @@ DbgUnLoadImageSymbols(
IN ULONG_PTR ProcessId
);
VOID
NTAPI
DbgCommandString(
IN PCCH Name,
IN PCCH Command
);
//
// Generic Table Functions
//

View file

@ -27,6 +27,26 @@ enum
#define KDBG_TAG 'GBDK'
typedef enum _DBGKD_MAJOR_TYPES
{
DBGKD_MAJOR_NT,
DBGKD_MAJOR_XBOX,
DBGKD_MAJOR_BIG,
DBGKD_MAJOR_EXDI,
DBGKD_MAJOR_NTBD,
DBGKD_MAJOR_EFI,
DBGKD_MAJOR_TNT,
DBGKD_MAJOR_SINGULARITY,
DBGKD_MAJOR_HYPERVISOR,
DBGKD_MAJOR_COUNT
} DBGKD_MAJOR_TYPES;
//
// The major type is in the high byte
//
#define DBGKD_MAJOR_TYPE(MajorVersion) \
((DBGKD_MAJOR_TYPES)((MajorVersion) >> 8))
typedef struct _DBGKD_GET_VERSION32
{
USHORT MajorVersion;

View file

@ -69,7 +69,7 @@ vDbgPrintExWithPrefixInternal(IN PCCH Prefix,
}
/* For user mode, don't recursively DbgPrint */
if (RtlpSetInDbgPrint(TRUE)) return STATUS_SUCCESS;
if (RtlpSetInDbgPrint()) return STATUS_SUCCESS;
/* Guard against incorrect pointers */
_SEH2_TRY
@ -142,13 +142,13 @@ vDbgPrintExWithPrefixInternal(IN PCCH Prefix,
if (Status == STATUS_BREAKPOINT)
{
/* Breakpoint */
//DbgBreakPointWithStatus(DBG_STATUS_CONTROL_C);
DbgBreakPointWithStatus(DBG_STATUS_CONTROL_C);
Status = STATUS_SUCCESS;
}
}
/* In user-mode, remove the InDbgPrint Flag */
RtlpSetInDbgPrint(FALSE);
/* In user-mode, clear the InDbgPrint Flag */
RtlpClearInDbgPrint();
/* Return */
return Status;
@ -282,7 +282,7 @@ DbgPrompt(IN PCCH Prompt,
/* Setup the output string */
Output.Length = strlen(Prompt);
Output.Buffer = (PCH)Prompt;
Output.Buffer = (PCHAR)Prompt;
/* Call the system service */
return DebugPrompt(&Output, &Input);
@ -340,7 +340,8 @@ DbgLoadImageSymbols(IN PSTRING Name,
else
{
/* No data available */
SymbolInfo.CheckSum = SymbolInfo.SizeOfImage = 0;
SymbolInfo.CheckSum =
SymbolInfo.SizeOfImage = 0;
}
/* Load the symbols */
@ -366,3 +367,23 @@ DbgUnLoadImageSymbols(IN PSTRING Name,
/* Load the symbols */
DebugService2(Name, &SymbolInfo, BREAKPOINT_UNLOAD_SYMBOLS);
}
/*
* @implemented
*/
VOID
NTAPI
DbgCommandString(IN PCCH Name,
IN PCCH Command)
{
STRING NameString, CommandString;
/* Setup the strings */
NameString.Buffer = (PCHAR)Name;
NameString.Length = strlen(Name);
CommandString.Buffer = (PCHAR)Command;
CommandString.Length = strlen(Command);
/* Send them to the debugger */
DebugService2(&NameString, &CommandString, BREAKPOINT_COMMAND_STRING);
}

View file

@ -114,7 +114,15 @@ RtlpHandleDpcStackException(IN PEXCEPTION_REGISTRATION_RECORD RegistrationFrame,
BOOLEAN
NTAPI
RtlpSetInDbgPrint(IN BOOLEAN NewValue);
RtlpSetInDbgPrint(
VOID
);
VOID
NTAPI
RtlpClearInDbgPrint(
VOID
);
/* i386/except.S */

View file

@ -780,11 +780,21 @@ CM_SYSTEM_CONTROL_VECTOR CmControlVector[] =
{
L"Session Manager",
L"Debugger Retries",
&DummyData,
&KdpContext.KdpDefaultRetries,
NULL,
NULL
},
{
L"Session Manager\\Debug Print Filter",
L"WIN2000",
&Kd_WIN2000_Mask,
NULL,
NULL
},
/* TODO: Add the other masks */
{
L"WMI",
L"MaxEventSize",

View file

@ -360,6 +360,8 @@ extern LIST_ENTRY KdProviders;
extern BOOLEAN KdpEarlyBreak;
extern PKDEBUG_ROUTINE KiDebugRoutine;
extern KD_CONTEXT KdpContext;
extern ULONG Kd_WIN2000_Mask;
#endif
#endif /* __INCLUDE_INTERNAL_KERNEL_DEBUGGER_H */

View file

@ -11,6 +11,15 @@
//
#define KD_BREAKPOINT_MAX 32
//
// Default size of the DbgPrint log buffer
//
#if DBG
#define KD_DEFAULT_LOG_BUFFER_SIZE 0x8000
#else
#define KD_DEFAULT_LOG_BUFFER_SIZE 0x1000
#endif
//
// Breakpoint Status Flags
//
@ -192,7 +201,7 @@ NTSTATUS
NTAPI
KdpPrint(
IN ULONG ComponentId,
IN ULONG ComponentMask,
IN ULONG Level,
IN LPSTR String,
IN USHORT Length,
IN KPROCESSOR_MODE PreviousMode,
@ -228,8 +237,8 @@ KdpSymbol(
VOID
NTAPI
KdpCommandString(
IN ULONG Length,
IN LPSTR String,
IN PSTRING NameString,
IN PSTRING CommandString,
IN KPROCESSOR_MODE PreviousMode,
IN PCONTEXT ContextRecord,
IN PKTRAP_FRAME TrapFrame,
@ -239,7 +248,7 @@ KdpCommandString(
//
// State Change Notifications
//
BOOLEAN
VOID
NTAPI
KdpReportLoadSymbolsStateChange(
IN PSTRING PathName,
@ -248,6 +257,14 @@ KdpReportLoadSymbolsStateChange(
IN OUT PCONTEXT Context
);
VOID
NTAPI
KdpReportCommandStringStateChange(
IN PSTRING NameString,
IN PSTRING CommandString,
IN OUT PCONTEXT Context
);
BOOLEAN
NTAPI
KdpReportExceptionStateChange(
@ -311,7 +328,7 @@ KdpCopyMemoryChunks(
);
//
// Architecture dependent support routines
// Low Level Support Routines for the KD API
//
//
@ -484,12 +501,14 @@ extern PKEVENT KdpTimeSlipEvent;
extern KSPIN_LOCK KdpTimeSlipEventLock;
extern BOOLEAN KdpPortLocked;
extern BOOLEAN KdpControlCPressed;
extern BOOLEAN KdpContextSent;
extern KSPIN_LOCK KdpDebuggerLock;
extern LARGE_INTEGER KdTimerStop, KdTimerStart, KdTimerDifference;
extern ULONG KdComponentTableSize;
extern ULONG Kd_WIN2000_Mask;
extern PULONG KdComponentTable[104];
extern CHAR KdpMessageBuffer[4096], KdpPathBuffer[4096];
extern CHAR KdpMessageBuffer[0x1000], KdpPathBuffer[0x1000];
extern CHAR KdPrintDefaultCircularBuffer[KD_DEFAULT_LOG_BUFFER_SIZE];
extern BREAKPOINT_ENTRY KdpBreakpointTable[KD_BREAKPOINT_MAX];
extern KD_BREAKPOINT_TYPE KdpBreakpointInstruction;
extern BOOLEAN KdpOweBreakpoint;

View file

@ -20,6 +20,8 @@ BOOLEAN KdBreakAfterSymbolLoad = FALSE;
BOOLEAN KdpBreakPending = FALSE;
BOOLEAN KdPitchDebugger = TRUE;
BOOLEAN KdIgnoreUmExceptions = FALSE;
KD_CONTEXT KdpContext;
ULONG Kd_WIN2000_Mask;
VOID NTAPI PspDumpThreads(BOOLEAN SystemThreads);
typedef struct

View file

@ -35,14 +35,6 @@ KdpSetContextState(IN PDBGKD_ANY_WAIT_STATE_CHANGE WaitStateChange,
while (TRUE);
}
VOID
NTAPI
KdpSysGetVersion(IN PDBGKD_GET_VERSION64 Version)
{
UNIMPLEMENTED;
while (TRUE);
}
NTSTATUS
NTAPI
KdpSysReadMsr(IN ULONG Msr,

View file

@ -35,14 +35,6 @@ KdpSetContextState(IN PDBGKD_ANY_WAIT_STATE_CHANGE WaitStateChange,
while (TRUE);
}
VOID
NTAPI
KdpSysGetVersion(IN PDBGKD_GET_VERSION64 Version)
{
UNIMPLEMENTED;
while (TRUE);
}
NTSTATUS
NTAPI
KdpSysReadMsr(IN ULONG Msr,

View file

@ -15,14 +15,6 @@
/* FUNCTIONS *****************************************************************/
VOID
NTAPI
KdpSysGetVersion(IN PDBGKD_GET_VERSION64 Version)
{
/* Copy the version block */
RtlCopyMemory(Version, &KdVersionBlock, sizeof(DBGKD_GET_VERSION64));
}
VOID
NTAPI
KdpGetStateChange(IN PDBGKD_MANIPULATE_STATE64 State,

View file

@ -39,14 +39,14 @@ KdpCopyMemoryChunks(IN ULONG64 Address,
ChunkSize = MMDBG_COPY_MAX_SIZE;
}
/* Copy the whole range in page aligned chunks */
/* Copy the whole range in aligned chunks */
RemainingLength = TotalSize;
CopyChunk = 1;
while (RemainingLength > 0)
{
/*
* Determine the best chunk size for this round.
* The ideal size is page aligned, isn't larger than the
* The ideal size is aligned, isn't larger than the
* the remaining length and respects the chunk limit.
*/
while (((CopyChunk * 2) <= RemainingLength) &&
@ -54,7 +54,7 @@ KdpCopyMemoryChunks(IN ULONG64 Address,
((Address & ((CopyChunk * 2) - 1)) == 0))
{
/* Increase it */
CopyChunk = CopyChunk * 2;
CopyChunk *= 2;
}
/*
@ -148,9 +148,20 @@ KdpSearchMemory(IN PDBGKD_MANIPULATE_STATE64 State,
IN PSTRING Data,
IN PCONTEXT Context)
{
/* FIXME: STUB */
KdpDprintf("KdpSearchMemory called\n");
while (TRUE);
//PDBGKD_SEARCH_MEMORY SearchMemory = &State->u.SearchMemory;
STRING Header;
/* TODO */
KdpDprintf("Memory Search support is unimplemented!\n");
/* Send a failure packet */
State->ReturnStatus = STATUS_UNSUCCESSFUL;
Header.Length = sizeof(DBGKD_MANIPULATE_STATE64);
Header.Buffer = (PCHAR)State;
KdSendPacket(PACKET_TYPE_KD_STATE_MANIPULATE,
&Header,
NULL,
&KdpContext);
}
VOID
@ -159,9 +170,20 @@ KdpFillMemory(IN PDBGKD_MANIPULATE_STATE64 State,
IN PSTRING Data,
IN PCONTEXT Context)
{
/* FIXME: STUB */
KdpDprintf("KdpFillMemory called\n");
while (TRUE);
//PDBGKD_FILL_MEMORY FillMemory = &State->u.FillMemory;
STRING Header;
/* TODO */
KdpDprintf("Memory Fill support is unimplemented!\n");
/* Send a failure packet */
State->ReturnStatus = STATUS_UNSUCCESSFUL;
Header.Length = sizeof(DBGKD_MANIPULATE_STATE64);
Header.Buffer = (PCHAR)State;
KdSendPacket(PACKET_TYPE_KD_STATE_MANIPULATE,
&Header,
NULL,
&KdpContext);
}
VOID
@ -238,9 +260,20 @@ KdpWriteBreakPointEx(IN PDBGKD_MANIPULATE_STATE64 State,
IN PSTRING Data,
IN PCONTEXT Context)
{
/* FIXME: STUB */
KdpDprintf("KdpWriteBreakPointEx called\n");
while (TRUE);
//PDBGKD_BREAKPOINTEX = &State->u.BreakPointEx;
STRING Header;
/* TODO */
KdpDprintf("Extended Breakpoint Write support is unimplemented!\n");
/* Send a failure packet */
State->ReturnStatus = STATUS_UNSUCCESSFUL;
Header.Length = sizeof(DBGKD_MANIPULATE_STATE64);
Header.Buffer = (PCHAR)State;
KdSendPacket(PACKET_TYPE_KD_STATE_MANIPULATE,
&Header,
Data,
&KdpContext);
return STATUS_UNSUCCESSFUL;
}
@ -250,9 +283,20 @@ KdpRestoreBreakPointEx(IN PDBGKD_MANIPULATE_STATE64 State,
IN PSTRING Data,
IN PCONTEXT Context)
{
/* FIXME: STUB */
KdpDprintf("KdpRestoreBreakPointEx called\n");
while (TRUE);
//PDBGKD_BREAKPOINTEX = &State->u.BreakPointEx;
STRING Header;
/* TODO */
KdpDprintf("Extended Breakpoint Restore support is unimplemented!\n");
/* Send a failure packet */
State->ReturnStatus = STATUS_UNSUCCESSFUL;
Header.Length = sizeof(DBGKD_MANIPULATE_STATE64);
Header.Buffer = (PCHAR)State;
KdSendPacket(PACKET_TYPE_KD_STATE_MANIPULATE,
&Header,
Data,
&KdpContext);
}
VOID
@ -317,6 +361,14 @@ KdpSetCommonState(IN ULONG NewState,
}
}
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)
@ -596,7 +648,7 @@ KdpGetContext(IN PDBGKD_MANIPULATE_STATE64 State,
IN PCONTEXT Context)
{
STRING Header;
PVOID ControlStart;
PCONTEXT TargetContext;
/* Setup the header */
Header.Length = sizeof(DBGKD_MANIPULATE_STATE64);
@ -610,20 +662,22 @@ KdpGetContext(IN PDBGKD_MANIPULATE_STATE64 State,
if (State->Processor == KeGetCurrentPrcb()->Number)
{
/* We're just copying our own context */
ControlStart = Context;
TargetContext = Context;
}
else
{
/* SMP not yet handled */
KdpDprintf("KdpGetContext: SMP UNHANDLED\n");
ControlStart = NULL;
while (TRUE);
/* Get the context from the PRCB array */
TargetContext = &KiProcessorBlock[State->Processor]->
ProcessorState.ContextFrame;
}
/* Copy the memory */
RtlCopyMemory(Data->Buffer, ControlStart, sizeof(CONTEXT));
/* Copy it over */
RtlCopyMemory(Data->Buffer, TargetContext, sizeof(CONTEXT));
Data->Length = sizeof(CONTEXT);
/* Let the debugger set the context now */
KdpContextSent = TRUE;
/* Finish up */
State->ReturnStatus = STATUS_SUCCESS;
}
@ -647,7 +701,7 @@ KdpSetContext(IN PDBGKD_MANIPULATE_STATE64 State,
IN PCONTEXT Context)
{
STRING Header;
PVOID ControlStart;
PCONTEXT TargetContext;
/* Setup the header */
Header.Length = sizeof(DBGKD_MANIPULATE_STATE64);
@ -655,24 +709,23 @@ KdpSetContext(IN PDBGKD_MANIPULATE_STATE64 State,
ASSERT(Data->Length == sizeof(CONTEXT));
/* Make sure that this is a valid request */
if (State->Processor < KeNumberProcessors)
if ((State->Processor < KeNumberProcessors) && (KdpContextSent == TRUE))
{
/* Check if the request is for this CPU */
if (State->Processor == KeGetCurrentPrcb()->Number)
{
/* We're just copying our own context */
ControlStart = Context;
TargetContext = Context;
}
else
{
/* SMP not yet handled */
KdpDprintf("KdpSetContext: SMP UNHANDLED\n");
ControlStart = NULL;
while (TRUE);
/* Get the context from the PRCB array */
TargetContext = &KiProcessorBlock[State->Processor]->
ProcessorState.ContextFrame;
}
/* Copy the memory */
RtlCopyMemory(ControlStart, Data->Buffer, sizeof(CONTEXT));
/* Get the context from the PRCB array */
RtlCopyMemory(TargetContext, Data->Buffer, sizeof(CONTEXT));
/* Finish up */
State->ReturnStatus = STATUS_SUCCESS;
@ -985,6 +1038,26 @@ KdpCheckLowMemory(IN PDBGKD_MANIPULATE_STATE64 State)
&KdpContext);
}
VOID
NTAPI
KdpNotSupported(IN PDBGKD_MANIPULATE_STATE64 State)
{
STRING Header;
/* Set failure */
State->ReturnStatus = STATUS_UNSUCCESSFUL;
/* Setup the packet */
Header.Length = sizeof(DBGKD_MANIPULATE_STATE64);
Header.Buffer = (PCHAR)State;
/* Send it */
KdSendPacket(PACKET_TYPE_KD_STATE_MANIPULATE,
&Header,
NULL,
&KdpContext);
}
KCONTINUE_STATUS
NTAPI
KdpSendWaitContinue(IN ULONG PacketType,
@ -1002,7 +1075,12 @@ KdpSendWaitContinue(IN ULONG PacketType,
Header.Buffer = (PCHAR)&ManipulateState;
Data.MaximumLength = sizeof(KdpMessageBuffer);
Data.Buffer = KdpMessageBuffer;
//KdpContextSent = FALSE;
/*
* Reset the context state to ensure the debugger has received
* the current context before it sets it
*/
KdpContextSent = FALSE;
SendPacket:
/* Send the Packet */
@ -1130,38 +1208,20 @@ SendPacket:
break;
case DbgKdQuerySpecialCallsApi:
/* FIXME: TODO */
KdpDprintf("DbgKdQuerySpecialCallsApi called\n");
while (TRUE);
break;
case DbgKdSetSpecialCallApi:
/* FIXME: TODO */
KdpDprintf("DbgKdSetSpecialCallApi called\n");
while (TRUE);
break;
case DbgKdClearSpecialCallsApi:
/* FIXME: TODO */
KdpDprintf("DbgKdClearSpecialCallsApi called\n");
while (TRUE);
/* TODO */
KdpDprintf("Special Call support is unimplemented!\n");
KdpNotSupported(&ManipulateState);
break;
case DbgKdSetInternalBreakPointApi:
/* FIXME: TODO */
KdpDprintf("DbgKdSetInternalBreakPointApi called\n");
while (TRUE);
break;
case DbgKdGetInternalBreakPointApi:
/* FIXME: TODO */
KdpDprintf("DbgKdGetInternalBreakPointApi called\n");
while (TRUE);
/* TODO */
KdpDprintf("Internal Breakpoint support is unimplemented!\n");
KdpNotSupported(&ManipulateState);
break;
case DbgKdReadIoSpaceExtendedApi:
@ -1208,16 +1268,16 @@ SendPacket:
case DbgKdSwitchProcessor:
/* FIXME: TODO */
KdpDprintf("DbgKdSwitchProcessor called\n");
while (TRUE);
/* TODO */
KdpDprintf("Processor Switch support is unimplemented!\n");
KdpNotSupported(&ManipulateState);
break;
case DbgKdPageInApi:
/* FIXME: TODO */
KdpDprintf("DbgKdPageInApi called\n");
while (TRUE);
/* TODO */
KdpDprintf("Page-In support is unimplemented!\n");
KdpNotSupported(&ManipulateState);
break;
case DbgKdReadMachineSpecificRegister:
@ -1276,9 +1336,9 @@ SendPacket:
case DbgKdSwitchPartition:
/* FIXME: TODO */
KdpDprintf("DbgKdSwitchPartition called\n");
while (TRUE);
/* TODO */
KdpDprintf("Partition Switch support is unimplemented!\n");
KdpNotSupported(&ManipulateState);
break;
/* Unsupported Message */
@ -1299,7 +1359,7 @@ SendPacket:
}
}
BOOLEAN
VOID
NTAPI
KdpReportLoadSymbolsStateChange(IN PSTRING PathName,
IN PKD_SYMBOLS_INFO SymbolInfo,
@ -1342,8 +1402,7 @@ KdpReportLoadSymbolsStateChange(IN PSTRING PathName,
&PathNameLength);
/* Null terminate */
KdpPathBuffer[PathNameLength] = ANSI_NULL;
PathNameLength++;
KdpPathBuffer[PathNameLength++] = ANSI_NULL;
/* Set the path length */
WaitStateChange.u.LoadSymbols.PathNameLength = PathNameLength;
@ -1370,9 +1429,83 @@ KdpReportLoadSymbolsStateChange(IN PSTRING PathName,
ExtraData,
Context);
} while (Status == ContinueProcessorReselected);
}
/* Return status */
return Status;
VOID
NTAPI
KdpReportCommandStringStateChange(IN PSTRING NameString,
IN PSTRING CommandString,
IN OUT PCONTEXT Context)
{
STRING Header, Data;
DBGKD_ANY_WAIT_STATE_CHANGE WaitStateChange;
ULONG Length, ActualLength, TotalLength;
KCONTINUE_STATUS Status;
/* Start wait loop */
do
{
/* Build the architecture common parts of the message */
KdpSetCommonState(DbgKdCommandStringStateChange,
Context,
&WaitStateChange);
/* Set the context */
KdpSetContextState(&WaitStateChange, Context);
/* Clear the command string structure */
RtlZeroMemory(&WaitStateChange.u.CommandString,
sizeof(DBGKD_COMMAND_STRING));
/* Normalize name string to max */
Length = min(128 - 1, NameString->Length);
/* Copy it to the message buffer */
KdpCopyMemoryChunks((ULONG_PTR)NameString->Buffer,
KdpMessageBuffer,
Length,
0,
MMDBG_COPY_UNSAFE,
&ActualLength);
/* Null terminate and calculate the total length */
TotalLength = ActualLength;
KdpMessageBuffer[TotalLength++] = ANSI_NULL;
/* Check if the command string is too long */
Length = CommandString->Length;
if (Length > (PACKET_MAX_SIZE -
sizeof(DBGKD_ANY_WAIT_STATE_CHANGE) - TotalLength))
{
/* Use maximum possible size */
Length = (PACKET_MAX_SIZE -
sizeof(DBGKD_ANY_WAIT_STATE_CHANGE) - TotalLength);
}
/* Copy it to the message buffer */
KdpCopyMemoryChunks((ULONG_PTR)CommandString->Buffer,
KdpMessageBuffer + TotalLength,
Length,
0,
MMDBG_COPY_UNSAFE,
&ActualLength);
/* Null terminate and calculate the total length */
TotalLength += ActualLength;
KdpMessageBuffer[TotalLength++] = ANSI_NULL;
/* Now set up the header and the data */
Header.Length = sizeof(DBGKD_ANY_WAIT_STATE_CHANGE);
Header.Buffer = (PCHAR)&WaitStateChange;
Data.Length = TotalLength;
Data.Buffer = KdpMessageBuffer;
/* Send State Change packet and wait for a reply */
Status = KdpSendWaitContinue(PACKET_TYPE_KD_STATE_CHANGE64,
&Header,
&Data,
Context);
} while (Status == ContinueProcessorReselected);
}
BOOLEAN
@ -1818,12 +1951,13 @@ KdSystemDebugControl(IN SYSDBG_COMMAND Command,
IN OUT PULONG ReturnLength,
IN KPROCESSOR_MODE PreviousMode)
{
/* HACK */
return STATUS_SUCCESS;
/* Local kernel debugging is not yet supported */
DbgPrint("KdSystemDebugControl is unimplemented!\n");
return STATUS_NOT_IMPLEMENTED;
}
/*
* @unimplemented
* @implemented
*/
NTSTATUS
NTAPI
@ -1834,46 +1968,161 @@ KdChangeOption(IN KD_OPTION Option,
OUT PVOID OutBuffer,
OUT PULONG OutBufferNeeded OPTIONAL)
{
/* HACK */
/* Fail if there is no debugger */
if (KdPitchDebugger)
{
/* No debugger, no options */
return STATUS_DEBUGGER_INACTIVE;
}
/* Do we recognize this option? */
if (Option != KD_OPTION_SET_BLOCK_ENABLE)
{
/* We don't, clear the output length and fail */
if (OutBufferNeeded) *OutBufferNeeded = 0;
return STATUS_INVALID_INFO_CLASS;
}
/* Verify parameters */
if ((InBufferBytes != sizeof(BOOLEAN)) ||
(OutBufferBytes != 0) ||
(OutBuffer != NULL))
{
/* Invalid parameters for this option, fail */
return STATUS_INVALID_PARAMETER;
}
/*
* Check if the high bit is set, meaning we don't
* allow the debugger to be enabled
*/
if (KdBlockEnable & 0x80)
{
/* Fail regardless of what state the caller tried to set */
return STATUS_ACCESS_VIOLATION;
}
/* Set the new block enable state */
KdBlockEnable = *(PBOOLEAN)InBuffer;
/* No output buffer required for this option */
if (OutBufferNeeded) *OutBufferNeeded = 0;
/* We are done */
return STATUS_SUCCESS;
}
/*
* @unimplemented
* @implemented
*/
NTSTATUS
NTAPI
KdPowerTransition(IN DEVICE_POWER_STATE NewState)
{
/* HACK */
return STATUS_SUCCESS;
/* Check what power state this is */
if (NewState == PowerDeviceD0)
{
/* Wake up the debug port */
KdD0Transition();
return STATUS_SUCCESS;
}
else if ((NewState == PowerDeviceD1) ||
(NewState == PowerDeviceD2) ||
(NewState == PowerDeviceD3))
{
/* Power down the debug port */
KdD3Transition();
return STATUS_SUCCESS;
}
else
{
/* Invalid state! */
return STATUS_INVALID_PARAMETER_1;
}
}
/*
* @unimplemented
* @implemented
*/
BOOLEAN
NTAPI
KdRefreshDebuggerNotPresent(VOID)
{
/* HACK */
return KdDebuggerNotPresent;
BOOLEAN Entered, DebuggerNotPresent;
/* Check if the debugger is completely disabled */
if (KdPitchDebugger)
{
/* Don't try to refresh then -- fail early */
return TRUE;
}
/* Enter the debugger */
Entered = KdEnterDebugger(NULL, NULL);
/*
* Attempt to send a string to the debugger to refresh the
* connection state
*/
KdpDprintf("KDTARGET: Refreshing KD connection\n");
/* Save the state while we are holding the lock */
DebuggerNotPresent = KdDebuggerNotPresent;
/* Exit the debugger and return the state */
KdExitDebugger(Entered);
return DebuggerNotPresent;
}
/*
* @unimplemented
* @implemented
*/
NTSTATUS
NTAPI
NtQueryDebugFilterState(IN ULONG ComponentId,
IN ULONG Level)
{
/* HACK */
return STATUS_SUCCESS;
PULONG Mask;
/* Check if the ID fits in the component table */
if (ComponentId < KdComponentTableSize)
{
/* It does, so get the mask from there */
Mask = KdComponentTable[ComponentId];
}
else if (ComponentId == MAXULONG)
{
/*
* This is the internal ID used for DbgPrint messages without ID and
* Level. Use the system-wide mask for those.
*/
Mask = &Kd_WIN2000_Mask;
}
else
{
/* Invalid ID, fail */
return STATUS_INVALID_PARAMETER_1;
}
/* Convert Level to bit field if necessary */
if (Level < 32) Level = 1 << Level;
/* Determine if this Level is filtered out */
if ((Kd_WIN2000_Mask & Level) ||
(*Mask & Level))
{
/* This mask will get through to the debugger */
return (NTSTATUS)TRUE;
}
else
{
/* This mask is filtered out */
return (NTSTATUS)FALSE;
}
}
/*
* @unimplemented
* @implemented
*/
NTSTATUS
NTAPI
@ -1881,6 +2130,51 @@ NtSetDebugFilterState(IN ULONG ComponentId,
IN ULONG Level,
IN BOOLEAN State)
{
/* HACK */
PULONG Mask;
/* Modifying debug filters requires the debug privilege */
if (!SeSinglePrivilegeCheck(SeDebugPrivilege,
ExGetPreviousMode()))
{
/* Fail */
return STATUS_ACCESS_DENIED;
}
/* Check if the ID fits in the component table */
if (ComponentId < KdComponentTableSize)
{
/* It does, so get the mask from there */
Mask = KdComponentTable[ComponentId];
}
else if (ComponentId == MAXULONG)
{
/*
* This is the internal ID used for DbgPrint messages without ID and
* Level. Use the system-wide mask for those.
*/
Mask = &Kd_WIN2000_Mask;
}
else
{
/* Invalid ID, fail */
return STATUS_INVALID_PARAMETER_1;
}
/* Convert Level to bit field if required */
if (Level < 32) Level = 1 << Level;
/* Check what kind of operation this is */
if (State)
{
/* Set the Level */
*Mask |= Level;
}
else
{
/* Remove the Level */
*Mask &= ~Level;
}
/* Success */
return STATUS_SUCCESS;
}

View file

@ -9,7 +9,7 @@
/* INCLUDES ******************************************************************/
#include <ntoskrnl.h>
#include "../mm/arm3/miarm.h"
#include "../mm/ARM3/miarm.h"
#define NDEBUG
#include <debug.h>
@ -18,27 +18,36 @@ VOID NTAPI RtlpBreakWithStatusInstruction(VOID);
//
// Apply the KIPCR WDK workaround for x86 and AMD64
//
#if defined(_M_IX86) || defined(_M_AMD64)
#if defined(_X86_) || defined(_AMD64_)
#define KPCR KIPCR
#endif
#if defined(_M_IX86)
#if defined(_X86_)
#define KPCR_SELF_OFFSET FIELD_OFFSET(KPCR, Self)
#define KPCR_SELF_PCR_OFFSET FIELD_OFFSET(KPCR, Self)
#define KPCR_CURRENT_PRCB_OFFSET FIELD_OFFSET(KPCR, Prcb)
#define KPCR_CONTAINED_PRCB_OFFSET FIELD_OFFSET(KPCR, PrcbData)
#define KPCR_INITIAL_STACK_OFFSET 0
#define KPCR_STACK_LIMIT_OFFSET 0
#define KPRCB_PCR_PAGE_OFFSET 0
#elif defined(_M_AMD64)
#elif defined(_AMD64_)
#define KPCR_SELF_OFFSET FIELD_OFFSET(KPCR, Self)
#define KPCR_SELF_PCR_OFFSET FIELD_OFFSET(KPCR, Self)
#define KPCR_CURRENT_PRCB_OFFSET FIELD_OFFSET(KPCR, CurrentPrcb)
#define KPCR_CONTAINED_PRCB_OFFSET FIELD_OFFSET(KPCR, Prcb)
#define KPCR_INITIAL_STACK_OFFSET 0
#define KPCR_STACK_LIMIT_OFFSET 0
#define KPRCB_PCR_PAGE_OFFSET 0
#elif defined(_M_ARM)
#elif defined(_ARM_)
#define KPCR_SELF_OFFSET 0
#define KPCR_SELF_PCR_OFFSET 0
#define KPCR_CURRENT_PRCB_OFFSET FIELD_OFFSET(KPCR, Prcb)
#define KPCR_CONTAINED_PRCB_OFFSET 0
#define KPCR_INITIAL_STACK_OFFSET FIELD_OFFSET(KPCR, InitialStack)
#define KPCR_STACK_LIMIT_OFFSET FIELD_OFFSET(KPCR, StackLimit)
#define KPRCB_PCR_PAGE_OFFSET FIELD_OFFSET(KPRCB, PcrPage)
#else
#error Unsupported Architecture
@ -53,6 +62,7 @@ KD_CONTEXT KdpContext;
BOOLEAN KdpPortLocked;
KSPIN_LOCK KdpDebuggerLock;
BOOLEAN KdpControlCPressed;
BOOLEAN KdpContextSent;
//
// Debug Trap Handlers
@ -110,13 +120,13 @@ LARGE_INTEGER KdTimerStop, KdTimerStart, KdTimerDifference;
//
// Buffers
//
CHAR KdpMessageBuffer[4096];
CHAR KdpPathBuffer[4096];
CHAR KdpMessageBuffer[0x1000];
CHAR KdpPathBuffer[0x1000];
//
// KdPrint Buffers
//
CHAR KdPrintDefaultCircularBuffer[0x8000];
CHAR KdPrintDefaultCircularBuffer[KD_DEFAULT_LOG_BUFFER_SIZE];
PCHAR KdPrintWritePointer = KdPrintDefaultCircularBuffer;
ULONG KdPrintRolloverCount;
PCHAR KdPrintCircularBuffer = KdPrintDefaultCircularBuffer;
@ -486,14 +496,14 @@ KDDEBUGGER_DATA64 KdDebuggerDataBlock =
{(ULONG_PTR)&KdPrintBufferSize},
{(ULONG_PTR)&KeLoaderBlock},
sizeof(KPCR),
KPCR_SELF_OFFSET,
KPCR_SELF_PCR_OFFSET,
KPCR_CURRENT_PRCB_OFFSET,
KPCR_CONTAINED_PRCB_OFFSET,
0,
0,
0,
0,
0,
KPCR_INITIAL_STACK_OFFSET,
KPCR_STACK_LIMIT_OFFSET,
KPRCB_PCR_PAGE_OFFSET,
FIELD_OFFSET(KPRCB, ProcessorState.SpecialRegisters),
#if defined(_M_IX86)
//

View file

@ -116,7 +116,7 @@ KdInitSystem(IN ULONG BootPhase,
sizeof(KdDebuggerDataBlock));
/* Fill out the KD Version Block */
KdVersionBlock.MajorVersion = (USHORT)(NtBuildNumber >> 28);
KdVersionBlock.MajorVersion = (USHORT)((DBGKD_MAJOR_NT << 8) | (NtBuildNumber >> 28));
KdVersionBlock.MinorVersion = (USHORT)(NtBuildNumber & 0xFFFF);
#ifdef CONFIG_SMP
@ -161,13 +161,18 @@ KdInitSystem(IN ULONG BootPhase,
/* 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)
/* Check for CRASHDEBUG, NODEBUG and just DEBUG */
if (strstr(CommandLine, "CRASHDEBUG"))
{
/* Don't enable KD now, but allow it to be enabled later */
KdPitchDebugger = FALSE;
}
else if (strstr(CommandLine, "NODEBUG"))
{
/* Don't enable KD and don't let it be enabled later */
KdPitchDebugger = TRUE;
}
else if ((DebugLine = strstr(CommandLine, "DEBUG")) != NULL)
{
/* Enable KD */
EnableKd = TRUE;

View file

@ -50,10 +50,10 @@ KdpPollBreakInWithPortLock(VOID)
{
/* Now get a packet */
if (KdReceivePacket(PACKET_TYPE_KD_POLL_BREAKIN,
NULL,
NULL,
NULL,
NULL) == KdPacketReceived)
NULL,
NULL,
NULL,
NULL) == KdPacketReceived)
{
/* Successful breakin */
DoBreak = TRUE;
@ -97,10 +97,10 @@ KdPollBreakIn(VOID)
{
/* Now get a packet */
if (KdReceivePacket(PACKET_TYPE_KD_POLL_BREAKIN,
NULL,
NULL,
NULL,
NULL) == KdPacketReceived)
NULL,
NULL,
NULL,
NULL) == KdPacketReceived)
{
/* Successful breakin */
DoBreak = TRUE;

View file

@ -123,16 +123,41 @@ KdpPromptString(IN PSTRING PromptString,
VOID
NTAPI
KdpCommandString(IN ULONG Length,
IN LPSTR String,
KdpCommandString(IN PSTRING NameString,
IN PSTRING CommandString,
IN KPROCESSOR_MODE PreviousMode,
IN PCONTEXT ContextRecord,
IN PKTRAP_FRAME TrapFrame,
IN PKEXCEPTION_FRAME ExceptionFrame)
{
/* FIXME */
KdpDprintf("KdpCommandString called\n");
while (TRUE);
BOOLEAN Entered;
PKPRCB Prcb = KeGetCurrentPrcb();
/* Check if we need to do anything */
if ((PreviousMode != KernelMode) || (KdDebuggerNotPresent)) return;
/* 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));
/* Send the command string to the debugger */
KdpReportCommandStringStateChange(NameString,
CommandString,
&Prcb->ProcessorState.ContextFrame);
/* Restore the processor state */
RtlCopyMemory(ContextRecord,
&Prcb->ProcessorState.ContextFrame,
sizeof(CONTEXT));
KiRestoreProcessorControlState(&Prcb->ProcessorState);
/* Exit the debugger and return */
KdExitDebugger(Entered);
}
VOID
@ -147,7 +172,6 @@ KdpSymbol(IN PSTRING DllPath,
{
BOOLEAN Entered;
PKPRCB Prcb = KeGetCurrentPrcb();
ULONG Status;
/* Check if we need to do anything */
if ((PreviousMode != KernelMode) || (KdDebuggerNotPresent)) return;
@ -162,19 +186,18 @@ KdpSymbol(IN PSTRING DllPath,
sizeof(CONTEXT));
/* Report the new state */
Status = KdpReportLoadSymbolsStateChange(DllPath,
SymbolInfo,
Unload,
&Prcb->ProcessorState.
ContextFrame);
KdpReportLoadSymbolsStateChange(DllPath,
SymbolInfo,
Unload,
&Prcb->ProcessorState.ContextFrame);
/* Now restore the processor state, manually again. */
/* Restore the processor state */
RtlCopyMemory(ContextRecord,
&Prcb->ProcessorState.ContextFrame,
sizeof(CONTEXT));
KiRestoreProcessorControlState(&Prcb->ProcessorState);
/* Exit the debugger and clear the CTRL-C state */
/* Exit the debugger and return */
KdExitDebugger(Entered);
}
@ -233,7 +256,7 @@ KdpPrompt(IN LPSTR PromptString,
NTSTATUS
NTAPI
KdpPrint(IN ULONG ComponentId,
IN ULONG ComponentMask,
IN ULONG Level,
IN LPSTR String,
IN USHORT Length,
IN KPROCESSOR_MODE PreviousMode,
@ -249,14 +272,14 @@ KdpPrint(IN ULONG ComponentId,
*Status = FALSE;
/* Validate the mask */
if (ComponentMask < 0x20) ComponentMask = 1 << ComponentMask;
if (!(Kd_WIN2000_Mask & ComponentMask) ||
if (Level < 32) Level = 1 << Level;
if (!(Kd_WIN2000_Mask & Level) ||
((ComponentId < KdComponentTableSize) &&
!(*KdComponentTable[ComponentId] & ComponentMask)))
!(*KdComponentTable[ComponentId] & Level)))
{
/* Mask validation failed */
*Status = TRUE;
return FALSE;
return STATUS_SUCCESS;
}
/* Normalize the length */

View file

@ -17,7 +17,7 @@
// Retrieves the ComponentId and Level for BREAKPOINT_PRINT
// and OutputString and OutputStringLength for BREAKPOINT_PROMPT.
//
#if defined(_M_IX86)
#if defined(_X86_)
//
// EBX/EDI on x86
@ -25,7 +25,7 @@
#define KdpGetFirstParameter(Context) ((Context)->Ebx)
#define KdpGetSecondParameter(Context) ((Context)->Edi)
#elif defined(_M_AMD64)
#elif defined(_AMD64_)
//
// R8/R9 on AMD64
@ -33,7 +33,7 @@
#define KdpGetFirstParameter(Context) ((Context)->R8)
#define KdpGetSecondParameter(Context) ((Context)->R9)
#elif defined(_M_ARM)
#elif defined(_ARM_)
#error Yo Ninjas!
@ -218,9 +218,9 @@ KdpTrap(IN PKTRAP_FRAME TrapFrame,
case BREAKPOINT_COMMAND_STRING:
/* Call the worker routine */
KdpCommandString((ULONG)ExceptionRecord->
KdpCommandString((PSTRING)ExceptionRecord->
ExceptionInformation[1],
(LPSTR)ExceptionRecord->
(PSTRING)ExceptionRecord->
ExceptionInformation[2],
PreviousMode,
ContextRecord,

View file

@ -913,17 +913,31 @@ KiI386PentiumLockErrataFixup(VOID)
MmSetPageProtect(NULL, NewIdt, PAGE_READONLY);
}
BOOLEAN
NTAPI
KeDisableInterrupts(VOID)
{
ULONG Flags;
BOOLEAN Return;
/* Get EFLAGS and check if the interrupt bit is set */
Flags = __readeflags();
Return = (Flags & EFLAGS_INTERRUPT_MASK) ? TRUE: FALSE;
/* Disable interrupts */
_disable();
return Return;
}
BOOLEAN
NTAPI
KeFreezeExecution(IN PKTRAP_FRAME TrapFrame,
IN PKEXCEPTION_FRAME ExceptionFrame)
{
ULONG Flags;
BOOLEAN Enable;
/* Disable interrupts and get previous state */
Flags = __readeflags();
//Flags = __getcallerseflags();
_disable();
Enable = KeDisableInterrupts();
/* Save freeze flag */
KiFreezeFlag = 4;
@ -932,7 +946,7 @@ KeFreezeExecution(IN PKTRAP_FRAME TrapFrame,
KiOldIrql = KeGetCurrentIrql();
/* Return whether interrupts were enabled */
return (Flags & EFLAGS_INTERRUPT_MASK) ? TRUE: FALSE;
return Enable;
}
VOID

View file

@ -3,7 +3,7 @@
* LICENSE: GPL - See COPYING in the top level directory
* FILE: ntoskrnl/ke/i386/irq.c
* PURPOSE: Manages the Kernel's IRQ support for external drivers,
* for the purpopses of connecting, disconnecting and setting
* for the purpouses of connecting, disconnecting and setting
* up ISRs for drivers. The backend behind the Io* Interrupt
* routines.
* PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org)
@ -23,22 +23,6 @@ extern ULONG NTAPI KiChainedDispatch2ndLvl(VOID);
/* PRIVATE FUNCTIONS *********************************************************/
BOOLEAN
NTAPI
KeDisableInterrupts(VOID)
{
ULONG Flags;
BOOLEAN Return;
/* Get EFLAGS and check if the interrupt bit is set */
Flags = __readeflags();
Return = (Flags & EFLAGS_INTERRUPT_MASK) ? TRUE: FALSE;
/* Disable interrupts */
_disable();
return Return;
}
VOID
NTAPI
KiGetVectorDispatch(IN ULONG Vector,

View file

@ -47,7 +47,7 @@
@ stdcall CmUnRegisterCallback(long long)
@ stdcall DbgBreakPoint()
@ stdcall DbgBreakPointWithStatus(long)
;DbgCommandString
@ stdcall DbgCommandString(ptr ptr)
@ stdcall DbgLoadImageSymbols(ptr ptr long)
@ cdecl DbgPrint(str)
@ cdecl DbgPrintEx(long long str)

View file

@ -52,12 +52,19 @@ RtlpCheckForActiveDebugger(VOID)
BOOLEAN
NTAPI
RtlpSetInDbgPrint(IN BOOLEAN NewValue)
RtlpSetInDbgPrint(VOID)
{
/* This check is meaningless in kernel-mode */
/* Nothing to set in kernel mode */
return FALSE;
}
VOID
NTAPI
RtlpClearInDbgPrint(VOID)
{
/* Nothing to clear in kernel mode */
}
KPROCESSOR_MODE
NTAPI
RtlpGetMode()