//
struct _KD_DISPATCH_TABLE;
extern CPPORT GdbPortInfo;
-extern BOOLEAN KdBreakAfterSymbolLoad;
-extern BOOLEAN KdPitchDebugger;
-extern BOOLEAN KdIgnoreUmExceptions;
BOOLEAN
NTAPI
kdContinue = 0,
kdDoNotHandleException,
kdHandleException
-}
-KD_CONTINUE_TYPE;
+} KD_CONTINUE_TYPE;
typedef
VOID
PKTRAP_FRAME TrapFrame
);
-BOOLEAN
-NTAPI
-KdIsThisAKdTrap(
- IN PEXCEPTION_RECORD ExceptionRecord,
- IN PCONTEXT Context,
- IN KPROCESSOR_MODE PreviousMode
-);
-
/* INIT ROUTINES *************************************************************/
BOOLEAN
/* KD ROUTINES ***************************************************************/
-ULONG
-NTAPI
-KdpPrintString(
- _In_reads_bytes_(Length) PCHAR UnsafeString,
- _In_ ULONG Length,
- _In_ KPROCESSOR_MODE PreviousMode);
-
BOOLEAN
NTAPI
KdpDetectConflicts(PCM_RESOURCE_LIST DriverList);
IN ULONGLONG Value
);
-VOID
-NTAPI
-KdpEnableSafeMem(VOID);
-
/* KD GLOBALS ***************************************************************/
-typedef
-BOOLEAN
-(NTAPI *PKDEBUG_ROUTINE)(
- IN PKTRAP_FRAME TrapFrame,
- IN PKEXCEPTION_FRAME ExceptionFrame,
- IN PEXCEPTION_RECORD ExceptionRecord,
- IN PCONTEXT Context,
- IN KPROCESSOR_MODE PreviousMode,
- IN BOOLEAN SecondChance
-);
-
-/* serial debug connection */
+/* Serial debug connection */
#define DEFAULT_DEBUG_PORT 2 /* COM2 */
#define DEFAULT_DEBUG_COM1_IRQ 4 /* COM1 IRQ */
#define DEFAULT_DEBUG_COM2_IRQ 3 /* COM2 IRQ */
#define DEFAULT_DEBUG_BAUD_RATE 115200 /* 115200 Baud */
/* KD Native Modes */
-#define KdScreen 0
-#define KdSerial 1
-#define KdFile 2
-#define KdBochs 3
-#define KdKdbg 4
-#define KdMax 5
+#define KdScreen 0
+#define KdSerial 1
+#define KdFile 2
+#define KdBochs 3
+#define KdKdbg 4
+#define KdMax 5
/* KD Private Debug Modes */
typedef struct _KDP_DEBUG_MODE
/* Generic Value */
ULONG Value;
};
-}
-KDP_DEBUG_MODE;
+} KDP_DEBUG_MODE;
/* KD Internal Debug Services */
typedef enum _KDP_DEBUG_SERVICE
KdSpare3 = 0x24, /* j */
EnterDebugger = 0x25, /* k */
ThatsWhatSheSaid = 69 /* FIGURE IT OUT */
-}
-KDP_DEBUG_SERVICE;
+} KDP_DEBUG_SERVICE;
/* Dispatch Table for Wrapper Functions */
typedef struct _KD_DISPATCH_TABLE
PKDP_PRINT_ROUTINE KdpPrintRoutine;
PKDP_PROMPT_ROUTINE KdpPromptRoutine;
PKDP_EXCEPTION_ROUTINE KdpExceptionRoutine;
-}
-KD_DISPATCH_TABLE, *PKD_DISPATCH_TABLE;
+} KD_DISPATCH_TABLE, *PKD_DISPATCH_TABLE;
/* The current Debugging Mode */
extern KDP_DEBUG_MODE KdpDebugMode;
/* The KD Native Provider List */
extern LIST_ENTRY KdProviders;
-extern PKDEBUG_ROUTINE KiDebugRoutine;
-extern KD_CONTEXT KdpContext;
-extern ULONG Kd_WIN2000_Mask;
-
#endif
#if DBG && defined(_M_IX86) && !defined(_WINKD_) // See ke/i386/traphdlr.c
/* GENERAL FUNCTIONS *********************************************************/
-ULONG
+BOOLEAN
NTAPI
KdpPrintString(
- _In_reads_bytes_(Length) PCHAR UnsafeString,
- _In_ ULONG Length,
- _In_ KPROCESSOR_MODE PreviousMode)
+ _In_ PSTRING Output)
{
PLIST_ENTRY CurrentEntry;
PKD_DISPATCH_TABLE CurrentTable;
- PCHAR String;
- CHAR StringBuffer[512];
- if (!KdpDebugMode.Value) return 0;
-
- Length = min(Length, sizeof(StringBuffer));
-
- if (PreviousMode != KernelMode)
- {
- _SEH2_TRY
- {
- ProbeForRead(UnsafeString, Length, 1);
- String = StringBuffer;
- RtlCopyMemory(String, UnsafeString, Length);
- }
- _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
- {
- return 0;
- }
- _SEH2_END;
- }
- else
- {
- String = UnsafeString;
- }
+ if (!KdpDebugMode.Value) return FALSE;
/* Call the registered handlers */
CurrentEntry = KdProviders.Flink;
KdProvidersList);
/* Call it */
- CurrentTable->KdpPrintRoutine(String, Length);
+ CurrentTable->KdpPrintRoutine(Output->Buffer, Output->Length);
/* Next Table */
CurrentEntry = CurrentEntry->Flink;
/* Call the Wrapper Routine */
if (WrapperTable.KdpPrintRoutine)
- WrapperTable.KdpPrintRoutine(String, Length);
+ WrapperTable.KdpPrintRoutine(Output->Buffer, Output->Length);
+
+ return FALSE;
+}
+
+extern STRING KdbPromptString;
+
+BOOLEAN
+NTAPI
+KdpPromptString(
+ _In_ PSTRING PromptString,
+ _In_ PSTRING ResponseString)
+{
+ KIRQL OldIrql;
+ STRING StringChar;
+ CHAR Response;
+ USHORT i;
+ ULONG DummyScanCode;
+
+ StringChar.Buffer = &Response;
+ StringChar.Length = StringChar.MaximumLength = sizeof(Response);
+
+ /* Display the string and print a new line for log neatness */
+ KdpPrintString(PromptString);
+ *StringChar.Buffer = '\n';
+ KdpPrintString(&StringChar);
+
+ /* Print the kdb prompt */
+ KdpPrintString(&KdbPromptString);
+
+ // TODO: Use an improved KdbpReadCommand() function for our purposes.
+
+ /* Acquire the printing spinlock without waiting at raised IRQL */
+ OldIrql = KdpAcquireLock(&KdpSerialSpinLock);
+
+ if (!(KdbDebugState & KD_DEBUG_KDSERIAL))
+ KbdDisableMouse();
+
+ /* Loop the whole string */
+ for (i = 0; i < ResponseString->MaximumLength; i++)
+ {
+ /* Check if this is serial debugging mode */
+ if (KdbDebugState & KD_DEBUG_KDSERIAL)
+ {
+ /* Get the character from serial */
+ do
+ {
+ Response = KdbpTryGetCharSerial(MAXULONG);
+ } while (Response == -1);
+ }
+ else
+ {
+ /* Get the response from the keyboard */
+ do
+ {
+ Response = KdbpTryGetCharKeyboard(&DummyScanCode, MAXULONG);
+ } while (Response == -1);
+ }
+
+ /* Check for return */
+ if (Response == '\r')
+ {
+ /*
+ * We might need to discard the next '\n'.
+ * Wait a bit to make sure we receive it.
+ */
+ KeStallExecutionProcessor(100000);
+
+ /* Check the mode */
+ if (KdbDebugState & KD_DEBUG_KDSERIAL)
+ {
+ /* Read and discard the next character, if any */
+ KdbpTryGetCharSerial(5);
+ }
+ else
+ {
+ /* Read and discard the next character, if any */
+ KdbpTryGetCharKeyboard(&DummyScanCode, 5);
+ }
+
+ /*
+ * Null terminate the output string -- documentation states that
+ * DbgPrompt does not null terminate, but it does
+ */
+ *(PCHAR)(ResponseString->Buffer + i) = 0;
+ break;
+ }
+
+ /* Write it back and print it to the log */
+ *(PCHAR)(ResponseString->Buffer + i) = Response;
+ KdpReleaseLock(&KdpSerialSpinLock, OldIrql);
+ KdpPrintString(&StringChar);
+ OldIrql = KdpAcquireLock(&KdpSerialSpinLock);
+ }
+
+ /* Return the length */
+ ResponseString->Length = i;
+
+ if (!(KdbDebugState & KD_DEBUG_KDSERIAL))
+ KbdEnableMouse();
+
+ /* Release the spinlock */
+ KdpReleaseLock(&KdpSerialSpinLock, OldIrql);
+
+ /* Print a new line */
+ *StringChar.Buffer = '\n';
+ KdpPrintString(&StringChar);
- /* Return the Length */
- return Length;
+ /* Success; we don't need to resend */
+ return FALSE;
}
/* EOF */
#define NDEBUG
#include <debug.h>
+//
+// Retrieves the ComponentId and Level for BREAKPOINT_PRINT
+// and OutputString and OutputStringLength for BREAKPOINT_PROMPT.
+//
+#if defined(_X86_)
+
+//
+// EBX/EDI on x86
+//
+#define KdpGetParameterThree(Context) ((Context)->Ebx)
+#define KdpGetParameterFour(Context) ((Context)->Edi)
+
+#elif defined(_AMD64_)
+
+//
+// R8/R9 on AMD64
+//
+#define KdpGetParameterThree(Context) ((Context)->R8)
+#define KdpGetParameterFour(Context) ((Context)->R9)
+
+#elif defined(_ARM_)
+
+//
+// R3/R4 on ARM
+//
+#define KdpGetParameterThree(Context) ((Context)->R3)
+#define KdpGetParameterFour(Context) ((Context)->R4)
+
+#else
+#error Unsupported Architecture
+#endif
+
/* VARIABLES ***************************************************************/
BOOLEAN KdDebuggerEnabled = FALSE;
BOOLEAN KdBreakAfterSymbolLoad = FALSE;
BOOLEAN KdPitchDebugger = TRUE;
BOOLEAN KdIgnoreUmExceptions = FALSE;
-KD_CONTEXT KdpContext;
-ULONG Kd_WIN2000_Mask;
-LONG KdpTimeSlipPending;
-KDDEBUGGER_DATA64 KdDebuggerDataBlock;
-VOID NTAPI PspDumpThreads(BOOLEAN SystemThreads);
-typedef struct
-{
- ULONG ComponentId;
- ULONG Level;
-} KD_COMPONENT_DATA;
-#define MAX_KD_COMPONENT_TABLE_ENTRIES 128
-KD_COMPONENT_DATA KdpComponentTable[MAX_KD_COMPONENT_TABLE_ENTRIES];
-ULONG KdComponentTableEntries = 0;
+VOID NTAPI PspDumpThreads(BOOLEAN SystemThreads);
+#if 0
ULONG Kd_DEFAULT_MASK = 1 << DPFLTR_ERROR_LEVEL;
+#endif
/* PRIVATE FUNCTIONS *********************************************************/
switch (Service)
{
case BREAKPOINT_PRINT: /* DbgPrint */
- Result = KdpPrintString(Buffer1, Buffer1Length, PreviousMode);
+ {
+ /* Call KDBG */
+ BOOLEAN Handled;
+ Result = KdpPrint(MAXULONG,
+ DPFLTR_INFO_LEVEL,
+ (PCHAR)Buffer1,
+ (USHORT)Buffer1Length,
+ PreviousMode,
+ NULL, // TrapFrame,
+ NULL, // ExceptionFrame,
+ &Handled);
break;
+ }
#if DBG
case ' soR': /* ROS-INTERNAL */
/* Check if this is a debug print */
if (ExceptionCommand == BREAKPOINT_PRINT)
{
- /* Print the string */
- KdpServiceDispatcher(BREAKPOINT_PRINT,
- (PVOID)ExceptionRecord->ExceptionInformation[1],
- ExceptionRecord->ExceptionInformation[2],
- PreviousMode);
-
- /* Return success */
- KeSetContextReturnRegister(Context, STATUS_SUCCESS);
+ /* Call KDBG */
+ NTSTATUS ReturnStatus;
+ BOOLEAN Handled;
+ ReturnStatus = KdpPrint((ULONG)KdpGetParameterThree(Context),
+ (ULONG)KdpGetParameterFour(Context),
+ (PCHAR)ExceptionRecord->ExceptionInformation[1],
+ (USHORT)ExceptionRecord->ExceptionInformation[2],
+ PreviousMode,
+ TrapFrame,
+ ExceptionFrame,
+ &Handled);
+
+ /* Update the return value for the caller */
+ KeSetContextReturnRegister(Context, ReturnStatus);
}
#ifdef KDBG
else if (ExceptionCommand == BREAKPOINT_LOAD_SYMBOLS)
ProbeForRead(SymbolsInfo,
sizeof(*SymbolsInfo),
1);
- RtlCopyMemory(&CapturedSymbolsInfo,
+ KdpMoveMemory(&CapturedSymbolsInfo,
SymbolsInfo,
sizeof(*SymbolsInfo));
SymbolsInfo = &CapturedSymbolsInfo;
}
else if (ExceptionCommand == BREAKPOINT_PROMPT)
{
- ULONG ReturnValue;
- LPSTR OutString;
- USHORT OutStringLength;
-
- /* Get the response string and length */
- OutString = (LPSTR)Context->Ebx;
- OutStringLength = (USHORT)Context->Edi;
-
/* Call KDBG */
- ReturnValue = KdpPrompt((LPSTR)ExceptionRecord->
- ExceptionInformation[1],
- (USHORT)ExceptionRecord->
- ExceptionInformation[2],
- OutString,
- OutStringLength,
- PreviousMode,
- TrapFrame,
- ExceptionFrame);
-
- /* Return the number of characters that we received */
- Context->Eax = ReturnValue;
+ ULONG ReturnLength;
+ ReturnLength = KdpPrompt((PCHAR)ExceptionRecord->ExceptionInformation[1],
+ (USHORT)ExceptionRecord->ExceptionInformation[2],
+ (PCHAR)KdpGetParameterThree(Context),
+ (USHORT)KdpGetParameterFour(Context),
+ PreviousMode,
+ TrapFrame,
+ ExceptionFrame);
+
+ /* Update the return value for the caller */
+ KeSetContextReturnRegister(Context, ReturnLength);
}
#endif
{
}
+BOOLEAN
+NTAPI
+KdEnterDebugger(IN PKTRAP_FRAME TrapFrame,
+ IN PKEXCEPTION_FRAME ExceptionFrame)
+{
+ return FALSE;
+}
+
+VOID
+NTAPI
+KdExitDebugger(IN BOOLEAN Enable)
+{
+}
+
/*
* @implemented
*/
return STATUS_NOT_IMPLEMENTED;
}
-
-NTSTATUS
-NTAPI
-NtQueryDebugFilterState(IN ULONG ComponentId,
- IN ULONG Level)
-{
- ULONG i;
-
- /* Convert Level to mask if it isn't already one */
- if (Level < 32)
- Level = 1 << Level;
-
- /* Check if it is not the default component */
- if (ComponentId != MAXULONG)
- {
- /* No, search for an existing entry in the table */
- for (i = 0; i < KdComponentTableEntries; i++)
- {
- /* Check if it is the right component */
- if (ComponentId == KdpComponentTable[i].ComponentId)
- {
- /* Check if mask are matching */
- return (Level & KdpComponentTable[i].Level) ? TRUE : FALSE;
- }
- }
- }
-
- /* Entry not found in the table, use default mask */
- return (Level & Kd_DEFAULT_MASK) ? TRUE : FALSE;
-}
-
-NTSTATUS
-NTAPI
-NtSetDebugFilterState(IN ULONG ComponentId,
- IN ULONG Level,
- IN BOOLEAN State)
-{
- ULONG i;
-
- /* Convert Level to mask if it isn't already one */
- if (Level < 32)
- Level = 1 << Level;
- Level &= ~DPFLTR_MASK;
-
- /* Check if it is the default component */
- if (ComponentId == MAXULONG)
- {
- /* Yes, modify the default mask */
- if (State)
- Kd_DEFAULT_MASK |= Level;
- else
- Kd_DEFAULT_MASK &= ~Level;
-
- return STATUS_SUCCESS;
- }
-
- /* Search for an existing entry */
- for (i = 0; i < KdComponentTableEntries; i++ )
- {
- if (ComponentId == KdpComponentTable[i].ComponentId)
- break;
- }
-
- /* Check if we have found an existing entry */
- if (i == KdComponentTableEntries)
- {
- /* Check if we have enough space in the table */
- if (i == MAX_KD_COMPONENT_TABLE_ENTRIES)
- return STATUS_INVALID_PARAMETER_1;
-
- /* Add a new entry */
- ++KdComponentTableEntries;
- KdpComponentTable[i].ComponentId = ComponentId;
- KdpComponentTable[i].Level = Kd_DEFAULT_MASK;
- }
-
- /* Update entry table */
- if (State)
- KdpComponentTable[i].Level |= Level;
- else
- KdpComponentTable[i].Level &= ~Level;
-
- return STATUS_SUCCESS;
-}
-
/*
* @unimplemented
*/
#define NDEBUG
#include <debug.h>
+VOID NTAPI PspDumpThreads(BOOLEAN SystemThreads);
+
/* PRIVATE FUNCTIONS *********************************************************/
VOID
return RemainingLength == 0 ? STATUS_SUCCESS : STATUS_UNSUCCESSFUL;
}
+#ifdef _WINKD_
+
VOID
NTAPI
KdpQueryMemory(IN PDBGKD_MANIPULATE_STATE64 State,
return STATUS_SUCCESS;
}
+#endif // _WINKD_
+
/* PUBLIC FUNCTIONS **********************************************************/
+#ifdef _WINKD_
+
/*
* @implemented
*/
_In_ KPROCESSOR_MODE PreviousMode)
{
/* Handle some internal commands */
- if (Command == ' soR')
+ switch (Command)
{
- switch ((ULONG_PTR)InputBuffer)
+#if DBG
+ case ' soR': /* ROS-INTERNAL */
{
- case 0x24:
- MmDumpArmPfnDatabase(FALSE);
- break;
+ switch ((ULONG_PTR)InputBuffer)
+ {
+ case 0x21: // DumpAllThreads:
+ PspDumpThreads(TRUE);
+ break;
+
+ case 0x22: // DumpUserThreads:
+ PspDumpThreads(FALSE);
+ break;
+
+ case 0x24: // KdSpare3:
+ MmDumpArmPfnDatabase(FALSE);
+ break;
+
+ default:
+ break;
+ }
+ return STATUS_SUCCESS;
}
- return STATUS_SUCCESS;
+
+ /* Special case for stack frame dumps */
+ case 'DsoR':
+ {
+ KeRosDumpStackFrames((PULONG)InputBuffer, InputBufferLength);
+ break;
+ }
+#endif
+ default:
+ break;
}
/* Local kernel debugging is not yet supported */
return DebuggerNotPresent;
}
+#endif // _WINKD_
+
/*
* @implemented
*/
//
// Debug Trap Handlers
//
+#ifdef _WINKD_
PKDEBUG_ROUTINE KiDebugRoutine = KdpStub;
PKDEBUG_SWITCH_ROUTINE KiDebugSwitchRoutine;
+#endif
//
// Debugger Configuration Settings
//
+#ifdef _WINKD_
BOOLEAN KdBreakAfterSymbolLoad;
BOOLEAN KdPitchDebugger;
BOOLEAN KdDebuggerNotPresent;
BOOLEAN KdEnteredDebugger;
ULONG KdDisableCount;
LARGE_INTEGER KdPerformanceCounterRate;
+#endif
//
// Breakpoint Data
/* FUNCTIONS *****************************************************************/
+#ifdef _WINKD_
+
BOOLEAN
NTAPI
KdpPrintString(
KdExitDebugger(Enable);
}
+#else
+
+extern
+BOOLEAN
+NTAPI
+KdpPrintString(
+ _In_ PSTRING Output);
+
+extern
+BOOLEAN
+NTAPI
+KdpPromptString(
+ _In_ PSTRING PromptString,
+ _In_ PSTRING ResponseString);
+
+#endif // _WINKD_
+
USHORT
NTAPI
KdpPrompt(
/* Setup the prompt and response buffers */
PromptBuffer.Buffer = PromptString;
- PromptBuffer.Length = PromptLength;
+ PromptBuffer.Length = PromptBuffer.MaximumLength = PromptLength;
ResponseBuffer.Buffer = SafeResponseString;
ResponseBuffer.Length = 0;
ResponseBuffer.MaximumLength = MaximumResponseLength;
NTSTATUS Status;
BOOLEAN Enable;
STRING OutputString;
- PVOID CapturedString;
+ CHAR CapturedString[512];
/* Assume failure */
*Handled = FALSE;
}
/* Normalize the length */
- Length = min(Length, 512);
+ Length = min(Length, sizeof(CapturedString));
/* Check if we need to verify the string */
if (PreviousMode != KernelMode)
{
/* Probe and capture the string */
ProbeForRead(String, Length, 1);
- CapturedString = alloca(Length);
KdpMoveMemory(CapturedString, String, Length);
String = CapturedString;
}
/* Setup the output string */
OutputString.Buffer = String;
- OutputString.Length = Length;
+ OutputString.Length = OutputString.MaximumLength = Length;
/* Log the print */
//KdLogDbgPrint(&OutputString);
sizeof(Buffer),
Format,
ap);
+ va_end(ap);
/* Set it up */
String.Buffer = Buffer;
- String.Length = Length + 1;
+ String.Length = String.MaximumLength = Length;
/* Send it to the debugger directly */
KdpPrintString(&String);
- va_end(ap);
}
}
}
-/*
- * Copied from ntoskrnl/kd64/kdapi.c
- */
-NTSTATUS
-NTAPI
-KdpCopyMemoryChunks(IN ULONG64 Address,
- IN PVOID Buffer,
- IN ULONG TotalSize,
- IN ULONG ChunkSize,
- IN ULONG Flags,
- OUT PULONG ActualSize OPTIONAL)
-{
- NTSTATUS Status;
- ULONG RemainingLength, CopyChunk;
-
- /* Check if we didn't get a chunk size or if it is too big */
- if (ChunkSize == 0)
- {
- /* Default to 4 byte chunks */
- ChunkSize = 4;
- }
- else if (ChunkSize > MMDBG_COPY_MAX_SIZE)
- {
- /* Normalize to maximum size */
- ChunkSize = MMDBG_COPY_MAX_SIZE;
- }
-
- /* 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 aligned, isn't larger than the
- * the remaining length and respects the chunk limit.
- */
- while (((CopyChunk * 2) <= RemainingLength) &&
- (CopyChunk < ChunkSize) &&
- ((Address & ((CopyChunk * 2) - 1)) == 0))
- {
- /* Increase it */
- CopyChunk *= 2;
- }
-
- /*
- * The chunk size can be larger than the remaining size if this
- * isn't the first round, so check if we need to shrink it back.
- */
- while (CopyChunk > RemainingLength)
- {
- /* Shrink it */
- CopyChunk /= 2;
- }
-
- /* Do the copy */
- Status = MmDbgCopyMemory(Address,
- Buffer,
- CopyChunk,
- Flags);
- if (!NT_SUCCESS(Status))
- {
- /* Copy failed, break out */
- break;
- }
-
- /* Update pointers and length for the next run */
- Address = Address + CopyChunk;
- Buffer = (PVOID)((ULONG_PTR)Buffer + CopyChunk);
- RemainingLength = RemainingLength - CopyChunk;
- }
-
- /* We may have modified executable code, flush the instruction cache */
- KeSweepICache((PVOID)(ULONG_PTR)Address, TotalSize);
-
- /*
- * Return the size we managed to copy and return
- * success if we could copy the whole range.
- */
- if (ActualSize) *ActualSize = TotalSize - RemainingLength;
- return RemainingLength == 0 ? STATUS_SUCCESS : STATUS_UNSUCCESSFUL;
-}
-
NTSTATUS
KdbpSafeReadMemory(
OUT PVOID Dest,
extern volatile ULONG KdpDmesgFreeBytes;
extern volatile ULONG KdbDmesgTotalWritten;
+STRING KdbPromptString = RTL_CONSTANT_STRING("kdb:> ");
+
static const struct
{
PCHAR Name;
}
/* Evaluate the expression */
- Ok = KdbpEvaluateExpression(Argv[1], sizeof("kdb:> ")-1 + (Argv[1]-Argv[0]), &Result);
+ Ok = KdbpEvaluateExpression(Argv[1], KdbPromptString.Length + (Argv[1]-Argv[0]), &Result);
if (Ok)
{
if (Result > 0x00000000ffffffffLL)
/* Evaluate the expression */
if (Argc > 1)
{
- if (!KdbpEvaluateExpression(Argv[1], sizeof("kdb:> ")-1 + (Argv[1]-Argv[0]), &Result))
+ if (!KdbpEvaluateExpression(Argv[1], KdbPromptString.Length + (Argv[1]-Argv[0]), &Result))
return TRUE;
if (Result > (ULONGLONG)(~((ULONG_PTR)0)))
Argv[1]++;
/* Evaluate the expression */
- if (!KdbpEvaluateExpression(Argv[1], sizeof("kdb:> ")-1 + (Argv[1]-Argv[0]), &Result))
+ if (!KdbpEvaluateExpression(Argv[1], KdbPromptString.Length + (Argv[1]-Argv[0]), &Result))
return TRUE;
if (Result > (ULONGLONG)(~((ULONG_PTR)0)))
/* Evaluate the address expression */
if (!KdbpEvaluateExpression(Argv[AddressArgIndex],
- sizeof("kdb:> ")-1 + (Argv[AddressArgIndex]-Argv[0]),
+ KdbPromptString.Length + (Argv[AddressArgIndex]-Argv[0]),
&Result))
{
return TRUE;
Argv[Argc][strlen(Argv[Argc])] = ' ';
/* Evaluate the expression */
- if (!KdbpEvaluateExpression(Argv[1], sizeof("kdb:> ")-1 + (Argv[1]-Argv[0]), &Result))
+ if (!KdbpEvaluateExpression(Argv[1], KdbPromptString.Length + (Argv[1]-Argv[0]), &Result))
{
return TRUE;
}
KdbNumberOfRowsPrinted = KdbNumberOfColsPrinted = 0;
/* Print the prompt */
- KdbpPrint("kdb:> ");
+ KdbpPrint(KdbPromptString.Buffer);
/* Read a command and remember it */
KdbpReadCommand(Command, sizeof (Command));
ExFreePool(FileBuffer);
}
-
-VOID
-NTAPI
-KdpSerialDebugPrint(
- LPSTR Message,
- ULONG Length
-);
-
-STRING KdpPromptString = RTL_CONSTANT_STRING("kdb:> ");
-extern KSPIN_LOCK KdpSerialSpinLock;
-
-USHORT
-NTAPI
-KdpPrompt(
- _In_reads_bytes_(InStringLength) PCHAR UnsafeInString,
- _In_ USHORT InStringLength,
- _Out_writes_bytes_(OutStringLength) PCHAR UnsafeOutString,
- _In_ USHORT OutStringLength,
- _In_ KPROCESSOR_MODE PreviousMode,
- _In_ PKTRAP_FRAME TrapFrame,
- _In_ PKEXCEPTION_FRAME ExceptionFrame)
-{
- USHORT i;
- CHAR Response;
- ULONG DummyScanCode;
- KIRQL OldIrql;
- PCHAR InString;
- PCHAR OutString;
- CHAR InStringBuffer[512];
- CHAR OutStringBuffer[512];
-
- /* Normalize the lengths */
- InStringLength = min(InStringLength,
- sizeof(InStringBuffer));
- OutStringLength = min(OutStringLength,
- sizeof(OutStringBuffer));
-
- /* Check if we need to verify the string */
- if (PreviousMode != KernelMode)
- {
- /* Handle user-mode buffers safely */
- _SEH2_TRY
- {
- /* Probe the prompt */
- ProbeForRead(UnsafeInString,
- InStringLength,
- 1);
-
- /* Capture prompt */
- InString = InStringBuffer;
- RtlCopyMemory(InString,
- UnsafeInString,
- InStringLength);
-
- /* Probe and make room for response */
- ProbeForWrite(UnsafeOutString,
- OutStringLength,
- 1);
- OutString = OutStringBuffer;
- }
- _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
- {
- /* Bad string pointer, bail out */
- _SEH2_YIELD(return 0);
- }
- _SEH2_END;
- }
- else
- {
- InString = UnsafeInString;
- OutString = UnsafeOutString;
- }
-
- /* Acquire the printing spinlock without waiting at raised IRQL */
- while (TRUE)
- {
- /* Wait when the spinlock becomes available */
- while (!KeTestSpinLock(&KdpSerialSpinLock));
-
- /* Spinlock was free, raise IRQL */
- KeRaiseIrql(HIGH_LEVEL, &OldIrql);
-
- /* Try to get the spinlock */
- if (KeTryToAcquireSpinLockAtDpcLevel(&KdpSerialSpinLock))
- break;
-
- /* Someone else got the spinlock, lower IRQL back */
- KeLowerIrql(OldIrql);
- }
-
- /* Loop the string to send */
- for (i = 0; i < InStringLength; i++)
- {
- /* Print it to serial */
- KdPortPutByteEx(&SerialPortInfo, *(PCHAR)(InString + i));
- }
-
- /* Print a new line for log neatness */
- KdPortPutByteEx(&SerialPortInfo, '\r');
- KdPortPutByteEx(&SerialPortInfo, '\n');
-
- /* Print the kdb prompt */
- for (i = 0; i < KdpPromptString.Length; i++)
- {
- /* Print it to serial */
- KdPortPutByteEx(&SerialPortInfo,
- *(KdpPromptString.Buffer + i));
- }
-
- if (!(KdbDebugState & KD_DEBUG_KDSERIAL))
- KbdDisableMouse();
-
- /* Loop the whole string */
- for (i = 0; i < OutStringLength; i++)
- {
- /* Check if this is serial debugging mode */
- if (KdbDebugState & KD_DEBUG_KDSERIAL)
- {
- /* Get the character from serial */
- do
- {
- Response = KdbpTryGetCharSerial(MAXULONG);
- } while (Response == -1);
- }
- else
- {
- /* Get the response from the keyboard */
- do
- {
- Response = KdbpTryGetCharKeyboard(&DummyScanCode, MAXULONG);
- } while (Response == -1);
- }
-
- /* Check for return */
- if (Response == '\r')
- {
- /*
- * We might need to discard the next '\n'.
- * Wait a bit to make sure we receive it.
- */
- KeStallExecutionProcessor(100000);
-
- /* Check the mode */
- if (KdbDebugState & KD_DEBUG_KDSERIAL)
- {
- /* Read and discard the next character, if any */
- KdbpTryGetCharSerial(5);
- }
- else
- {
- /* Read and discard the next character, if any */
- KdbpTryGetCharKeyboard(&DummyScanCode, 5);
- }
-
- /*
- * Null terminate the output string -- documentation states that
- * DbgPrompt does not null terminate, but it does
- */
- *(PCHAR)(OutString + i) = 0;
- break;
- }
-
- /* Write it back and print it to the log */
- *(PCHAR)(OutString + i) = Response;
- KdPortPutByteEx(&SerialPortInfo, Response);
- }
-
- if (!(KdbDebugState & KD_DEBUG_KDSERIAL))
- KbdEnableMouse();
-
- /* Print a new line */
- KdPortPutByteEx(&SerialPortInfo, '\r');
- KdPortPutByteEx(&SerialPortInfo, '\n');
-
- /* Release spinlock */
- KiReleaseSpinLock(&KdpSerialSpinLock);
-
- /* Lower IRQL back */
- KeLowerIrql(OldIrql);
-
- /* Copy back response if required */
- if (PreviousMode != KernelMode)
- {
- _SEH2_TRY
- {
- /* Safely copy back response to user mode */
- RtlCopyMemory(UnsafeOutString,
- OutString,
- i);
- }
- _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
- {
- /* String became invalid after we exited, fail */
- _SEH2_YIELD(return 0);
- }
- _SEH2_END;
- }
-
- /* Return the length */
- return i;
-}
ULONG
NTAPI
-KdpServiceDispatcher(ULONG Service, PCHAR Buffer, ULONG Length);
+KdpServiceDispatcher(ULONG Service,
+ PVOID Buffer1,
+ ULONG Buffer1Length,
+ KPROCESSOR_MODE PreviousMode);
typedef ULONG (*PSYSCALL_FUN)
(ULONG,ULONG,ULONG,ULONG,ULONG,ULONG,ULONG,ULONG,ULONG,ULONG);
trap_frame->gpr[3] = KdpServiceDispatcher
(trap_frame->gpr[3],
(PCHAR)trap_frame->gpr[4],
- trap_frame->gpr[5]);
+ trap_frame->gpr[5],
+ UserMode /*KernelMode*/);
break;
case 0xf0000: /* Thread startup */
/* XXX how to use UserThread (gpr[6]) */
${REACTOS_SOURCE_DIR}/ntoskrnl/kd/wrappers/kdbg.c
${REACTOS_SOURCE_DIR}/ntoskrnl/kd/kdinit.c
${REACTOS_SOURCE_DIR}/ntoskrnl/kd/kdio.c
- ${REACTOS_SOURCE_DIR}/ntoskrnl/kd/kdmain.c)
+ ${REACTOS_SOURCE_DIR}/ntoskrnl/kd/kdmain.c
+ ${REACTOS_SOURCE_DIR}/ntoskrnl/kd64/kdapi.c
+ ${REACTOS_SOURCE_DIR}/ntoskrnl/kd64/kddata.c
+ ${REACTOS_SOURCE_DIR}/ntoskrnl/kd64/kdprint.c)
else() # _WINKD_