diff --git a/ntoskrnl/include/internal/kd.h b/ntoskrnl/include/internal/kd.h index ef66e2abea2..ede52d82c57 100644 --- a/ntoskrnl/include/internal/kd.h +++ b/ntoskrnl/include/internal/kd.h @@ -7,9 +7,6 @@ // struct _KD_DISPATCH_TABLE; extern CPPORT GdbPortInfo; -extern BOOLEAN KdBreakAfterSymbolLoad; -extern BOOLEAN KdPitchDebugger; -extern BOOLEAN KdIgnoreUmExceptions; BOOLEAN NTAPI @@ -93,8 +90,7 @@ typedef enum _KD_CONTINUE_TYPE kdContinue = 0, kdDoNotHandleException, kdHandleException -} -KD_CONTINUE_TYPE; +} KD_CONTINUE_TYPE; typedef VOID @@ -122,14 +118,6 @@ KD_CONTINUE_TYPE PKTRAP_FRAME TrapFrame ); -BOOLEAN -NTAPI -KdIsThisAKdTrap( - IN PEXCEPTION_RECORD ExceptionRecord, - IN PCONTEXT Context, - IN KPROCESSOR_MODE PreviousMode -); - /* INIT ROUTINES *************************************************************/ BOOLEAN @@ -188,13 +176,6 @@ KdpKdbgInit( /* 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); @@ -215,37 +196,22 @@ KdpSafeWriteMemory( 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 @@ -268,8 +234,7 @@ typedef struct _KDP_DEBUG_MODE /* Generic Value */ ULONG Value; }; -} -KDP_DEBUG_MODE; +} KDP_DEBUG_MODE; /* KD Internal Debug Services */ typedef enum _KDP_DEBUG_SERVICE @@ -286,8 +251,7 @@ 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 @@ -297,8 +261,7 @@ 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; @@ -328,10 +291,6 @@ extern KD_DISPATCH_TABLE WrapperTable; /* 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 diff --git a/ntoskrnl/kd/kdio.c b/ntoskrnl/kd/kdio.c index 23b163b4ebf..4921d6af7c2 100644 --- a/ntoskrnl/kd/kdio.c +++ b/ntoskrnl/kd/kdio.c @@ -585,40 +585,15 @@ KdpScreenInit(PKD_DISPATCH_TABLE DispatchTable, /* 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; @@ -630,7 +605,7 @@ KdpPrintString( KdProvidersList); /* Call it */ - CurrentTable->KdpPrintRoutine(String, Length); + CurrentTable->KdpPrintRoutine(Output->Buffer, Output->Length); /* Next Table */ CurrentEntry = CurrentEntry->Flink; @@ -638,10 +613,116 @@ KdpPrintString( /* Call the Wrapper Routine */ if (WrapperTable.KdpPrintRoutine) - WrapperTable.KdpPrintRoutine(String, Length); + WrapperTable.KdpPrintRoutine(Output->Buffer, Output->Length); - /* Return the Length */ - return 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); + + /* Success; we don't need to resend */ + return FALSE; } /* EOF */ diff --git a/ntoskrnl/kd/kdmain.c b/ntoskrnl/kd/kdmain.c index fdbeeea4deb..ce8a738f26d 100644 --- a/ntoskrnl/kd/kdmain.c +++ b/ntoskrnl/kd/kdmain.c @@ -11,6 +11,38 @@ #define NDEBUG #include +// +// 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; @@ -19,22 +51,12 @@ BOOLEAN KdDebuggerNotPresent = TRUE; 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; - +#if 0 ULONG Kd_DEFAULT_MASK = 1 << DPFLTR_ERROR_LEVEL; +#endif /* PRIVATE FUNCTIONS *********************************************************/ @@ -50,8 +72,19 @@ KdpServiceDispatcher(ULONG Service, 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 */ @@ -144,14 +177,20 @@ KdpEnterDebuggerException(IN PKTRAP_FRAME TrapFrame, /* 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); + /* 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); - /* Return success */ - KeSetContextReturnRegister(Context, STATUS_SUCCESS); + /* Update the return value for the caller */ + KeSetContextReturnRegister(Context, ReturnStatus); } #ifdef KDBG else if (ExceptionCommand == BREAKPOINT_LOAD_SYMBOLS) @@ -168,7 +207,7 @@ KdpEnterDebuggerException(IN PKTRAP_FRAME TrapFrame, ProbeForRead(SymbolsInfo, sizeof(*SymbolsInfo), 1); - RtlCopyMemory(&CapturedSymbolsInfo, + KdpMoveMemory(&CapturedSymbolsInfo, SymbolsInfo, sizeof(*SymbolsInfo)); SymbolsInfo = &CapturedSymbolsInfo; @@ -191,27 +230,18 @@ KdpEnterDebuggerException(IN PKTRAP_FRAME TrapFrame, } 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); + ULONG ReturnLength; + ReturnLength = KdpPrompt((PCHAR)ExceptionRecord->ExceptionInformation[1], + (USHORT)ExceptionRecord->ExceptionInformation[2], + (PCHAR)KdpGetParameterThree(Context), + (USHORT)KdpGetParameterFour(Context), + PreviousMode, + TrapFrame, + ExceptionFrame); - /* Return the number of characters that we received */ - Context->Eax = ReturnValue; + /* Update the return value for the caller */ + KeSetContextReturnRegister(Context, ReturnLength); } #endif @@ -274,6 +304,20 @@ KdUpdateDataBlock(VOID) { } +BOOLEAN +NTAPI +KdEnterDebugger(IN PKTRAP_FRAME TrapFrame, + IN PKEXCEPTION_FRAME ExceptionFrame) +{ + return FALSE; +} + +VOID +NTAPI +KdExitDebugger(IN BOOLEAN Enable) +{ +} + /* * @implemented */ @@ -381,91 +425,6 @@ KdChangeOption(IN KD_OPTION Option, 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 */ diff --git a/ntoskrnl/kd64/kdapi.c b/ntoskrnl/kd64/kdapi.c index 5c48a1e767e..e12ac7e5353 100644 --- a/ntoskrnl/kd64/kdapi.c +++ b/ntoskrnl/kd64/kdapi.c @@ -13,6 +13,8 @@ #define NDEBUG #include +VOID NTAPI PspDumpThreads(BOOLEAN SystemThreads); + /* PRIVATE FUNCTIONS *********************************************************/ VOID @@ -121,6 +123,8 @@ KdpCopyMemoryChunks( return RemainingLength == 0 ? STATUS_SUCCESS : STATUS_UNSUCCESSFUL; } +#ifdef _WINKD_ + VOID NTAPI KdpQueryMemory(IN PDBGKD_MANIPULATE_STATE64 State, @@ -2118,8 +2122,12 @@ KdDisableDebuggerWithLock(IN BOOLEAN NeedLock) return STATUS_SUCCESS; } +#endif // _WINKD_ + /* PUBLIC FUNCTIONS **********************************************************/ +#ifdef _WINKD_ + /* * @implemented */ @@ -2157,15 +2165,40 @@ KdSystemDebugControl( _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 */ @@ -2291,6 +2324,8 @@ KdRefreshDebuggerNotPresent(VOID) return DebuggerNotPresent; } +#endif // _WINKD_ + /* * @implemented */ diff --git a/ntoskrnl/kd64/kddata.c b/ntoskrnl/kd64/kddata.c index 5576c405842..23887d165cf 100644 --- a/ntoskrnl/kd64/kddata.c +++ b/ntoskrnl/kd64/kddata.c @@ -71,12 +71,15 @@ BOOLEAN KdpContextSent; // // 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; @@ -89,6 +92,7 @@ BOOLEAN KdpDebuggerStructuresInitialized; BOOLEAN KdEnteredDebugger; ULONG KdDisableCount; LARGE_INTEGER KdPerformanceCounterRate; +#endif // // Breakpoint Data diff --git a/ntoskrnl/kd64/kdprint.c b/ntoskrnl/kd64/kdprint.c index 0389f32e39b..4d35bf6df76 100644 --- a/ntoskrnl/kd64/kdprint.c +++ b/ntoskrnl/kd64/kdprint.c @@ -15,6 +15,8 @@ /* FUNCTIONS *****************************************************************/ +#ifdef _WINKD_ + BOOLEAN NTAPI KdpPrintString( @@ -210,6 +212,23 @@ KdpSymbol(IN PSTRING DllPath, 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( @@ -262,7 +281,7 @@ 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; @@ -322,7 +341,7 @@ KdpPrint( NTSTATUS Status; BOOLEAN Enable; STRING OutputString; - PVOID CapturedString; + CHAR CapturedString[512]; /* Assume failure */ *Handled = FALSE; @@ -350,7 +369,7 @@ KdpPrint( } /* Normalize the length */ - Length = min(Length, 512); + Length = min(Length, sizeof(CapturedString)); /* Check if we need to verify the string */ if (PreviousMode != KernelMode) @@ -360,7 +379,6 @@ KdpPrint( { /* Probe and capture the string */ ProbeForRead(String, Length, 1); - CapturedString = alloca(Length); KdpMoveMemory(CapturedString, String, Length); String = CapturedString; } @@ -374,7 +392,7 @@ KdpPrint( /* Setup the output string */ OutputString.Buffer = String; - OutputString.Length = Length; + OutputString.Length = OutputString.MaximumLength = Length; /* Log the print */ //KdLogDbgPrint(&OutputString); @@ -425,12 +443,12 @@ KdpDprintf( 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); } diff --git a/ntoskrnl/kdbg/kdb.c b/ntoskrnl/kdbg/kdb.c index 5e7f5e249fc..d2a890276fe 100644 --- a/ntoskrnl/kdbg/kdb.c +++ b/ntoskrnl/kdbg/kdb.c @@ -1723,89 +1723,6 @@ KdbpGetCommandLineSettings( } } -/* - * 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, diff --git a/ntoskrnl/kdbg/kdb_cli.c b/ntoskrnl/kdbg/kdb_cli.c index 5e7d40d230f..8debef5dca9 100644 --- a/ntoskrnl/kdbg/kdb_cli.c +++ b/ntoskrnl/kdbg/kdb_cli.c @@ -133,6 +133,8 @@ extern volatile ULONG KdpDmesgCurrentPosition; extern volatile ULONG KdpDmesgFreeBytes; extern volatile ULONG KdbDmesgTotalWritten; +STRING KdbPromptString = RTL_CONSTANT_STRING("kdb:> "); + static const struct { PCHAR Name; @@ -476,7 +478,7 @@ KdbpCmdEvalExpression( } /* 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) @@ -785,7 +787,7 @@ KdbpCmdDisassembleX( /* 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))) @@ -1164,7 +1166,7 @@ KdbpCmdBackTrace( 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))) @@ -1557,7 +1559,7 @@ KdbpCmdBreakPoint(ULONG Argc, PCHAR Argv[]) /* Evaluate the address expression */ if (!KdbpEvaluateExpression(Argv[AddressArgIndex], - sizeof("kdb:> ")-1 + (Argv[AddressArgIndex]-Argv[0]), + KdbPromptString.Length + (Argv[AddressArgIndex]-Argv[0]), &Result)) { return TRUE; @@ -1922,7 +1924,7 @@ KdbpCmdMod( 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; } @@ -3651,7 +3653,7 @@ KdbpCliMainLoop( KdbNumberOfRowsPrinted = KdbNumberOfColsPrinted = 0; /* Print the prompt */ - KdbpPrint("kdb:> "); + KdbpPrint(KdbPromptString.Buffer); /* Read a command and remember it */ KdbpReadCommand(Command, sizeof (Command)); @@ -3814,204 +3816,3 @@ KdbpCliInit(VOID) 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; -} diff --git a/ntoskrnl/ke/powerpc/ppc_irq.c b/ntoskrnl/ke/powerpc/ppc_irq.c index 772f06b7c79..d516861bd53 100644 --- a/ntoskrnl/ke/powerpc/ppc_irq.c +++ b/ntoskrnl/ke/powerpc/ppc_irq.c @@ -745,7 +745,10 @@ KeDisableInterrupts(VOID) 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); @@ -769,7 +772,8 @@ KiSystemService(ppc_trap_frame_t *trap_frame) 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]) */ diff --git a/ntoskrnl/ntos.cmake b/ntoskrnl/ntos.cmake index 9d4d6685408..ffe14d67078 100644 --- a/ntoskrnl/ntos.cmake +++ b/ntoskrnl/ntos.cmake @@ -405,7 +405,10 @@ if(NOT _WINKD_) ${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_