[NTOS:KD] Make implementation of KdInitSystem more similar with the kd64 one

Move some kd initializations into KdDebuggerInitialize0() function.
This commit is contained in:
Hervé Poussineau 2020-03-07 17:18:33 +01:00
parent f417a53743
commit 6025df33a5
4 changed files with 316 additions and 180 deletions

View file

@ -39,76 +39,11 @@ extern ANSI_STRING KdpLogFileName;
/* PRIVATE FUNCTIONS *********************************************************/
CODE_SEG("INIT")
PCHAR
BOOLEAN
NTAPI
KdpGetDebugMode(PCHAR Currentp2)
{
PCHAR p1, p2 = Currentp2;
ULONG Value;
/* Check for Screen Debugging */
if (!_strnicmp(p2, "SCREEN", 6))
{
/* Enable It */
p2 += 6;
KdpDebugMode.Screen = TRUE;
}
/* Check for Serial Debugging */
else if (!_strnicmp(p2, "COM", 3))
{
/* Gheck for a valid Serial Port */
p2 += 3;
if (*p2 != ':')
{
Value = (ULONG)atol(p2);
if (Value > 0 && Value < 5)
{
/* Valid port found, enable Serial Debugging */
KdpDebugMode.Serial = TRUE;
/* Set the port to use */
SerialPortNumber = Value;
KdpPort = Value;
}
}
else
{
Value = strtoul(p2 + 1, NULL, 0);
if (Value)
{
KdpDebugMode.Serial = TRUE;
SerialPortInfo.Address = UlongToPtr(Value);
SerialPortNumber = 0;
KdpPort = 0;
}
}
}
/* Check for Debug Log Debugging */
else if (!_strnicmp(p2, "FILE", 4))
{
/* Enable It */
p2 += 4;
KdpDebugMode.File = TRUE;
if (*p2 == ':')
{
p2++;
p1 = p2;
while (*p2 != '\0' && *p2 != ' ') p2++;
KdpLogFileName.MaximumLength = KdpLogFileName.Length = p2 - p1;
KdpLogFileName.Buffer = p1;
}
}
/* Check for BOCHS Debugging */
else if (!_strnicmp(p2, "BOCHS", 5))
{
/* Enable It */
p2 += 5;
KdpDebugMode.Bochs = TRUE;
}
return p2;
}
KdRegisterDebuggerDataBlock(IN ULONG Tag,
IN PDBGKD_DEBUG_DATA_HEADER64 DataHeader,
IN ULONG Size);
CODE_SEG("INIT")
VOID
@ -141,133 +76,172 @@ KdpCallInitRoutine(ULONG BootPhase)
BOOLEAN
NTAPI
KdInitSystem(ULONG BootPhase,
PLOADER_PARAMETER_BLOCK LoaderBlock)
KdInitSystem(IN ULONG BootPhase,
IN PLOADER_PARAMETER_BLOCK LoaderBlock)
{
ULONG Value;
BOOLEAN EnableKd;
LPSTR DebugLine;
PLDR_DATA_TABLE_ENTRY LdrEntry;
ULONG i;
PCHAR CommandLine, Port = NULL, BaudRate = NULL, Irq = NULL;
PCHAR CommandLine;
/* Set Default Port Options */
if (BootPhase == 0)
/* Check if this is Phase 1 */
if (BootPhase)
{
/* Check if we have a loader block */
if (LoaderBlock)
{
/* Check if we have a command line */
CommandLine = LoaderBlock->LoadOptions;
if (CommandLine)
{
/* Upcase it */
_strupr(CommandLine);
/* Call the Initialization Routines of the Registered Providers */
KdpCallInitRoutine(BootPhase);
return TRUE;
}
/* XXX Check for settings that we support */
if (strstr(CommandLine, "NODEBUG")) KdDebuggerEnabled = FALSE;
else if (strstr(CommandLine, "CRASHDEBUG")) KdDebuggerEnabled = FALSE;
else if (strstr(CommandLine, "DEBUG"))
{
/* Enable the kernel debugger */
KdDebuggerNotPresent = FALSE;
KdDebuggerEnabled = TRUE;
#ifdef KDBG
/* Get the KDBG Settings */
KdbpGetCommandLineSettings(LoaderBlock->LoadOptions);
/* Check if we already initialized once */
if (KdDebuggerEnabled) return TRUE;
/* Disable break after symbol load for now */
KdBreakAfterSymbolLoad = FALSE;
/* Check if the Debugger Data Block was already initialized */
if (!KdpDebuggerDataListHead.Flink)
{
/* It wasn't...Initialize the KD Data Listhead */
InitializeListHead(&KdpDebuggerDataListHead);
/* Register the Debugger Data Block */
KdRegisterDebuggerDataBlock(KDBG_TAG,
&KdDebuggerDataBlock.Header,
sizeof(KdDebuggerDataBlock));
/* Fill out the KD Version Block */
KdVersionBlock.MajorVersion = (USHORT)((DBGKD_MAJOR_NT << 8) | (NtBuildNumber >> 28));
KdVersionBlock.MinorVersion = (USHORT)(NtBuildNumber & 0xFFFF);
#ifdef CONFIG_SMP
/* This is an MP Build */
KdVersionBlock.Flags |= DBGKD_VERS_FLAG_MP;
#endif
}
/* Get the port and baud rate */
Port = strstr(CommandLine, "DEBUGPORT");
BaudRate = strstr(CommandLine, "BAUDRATE");
Irq = strstr(CommandLine, "IRQ");
}
else
/* Save Pointers to Loaded Module List and Debugger Data */
KdVersionBlock.PsLoadedModuleList = (ULONG64)(LONG_PTR)&PsLoadedModuleList;
KdVersionBlock.DebuggerDataList = (ULONG64)(LONG_PTR)&KdpDebuggerDataListHead;
/* Set protocol limits */
KdVersionBlock.MaxStateChange = DbgKdMaximumStateChange -
DbgKdMinimumStateChange;
KdVersionBlock.MaxManipulate = DbgKdMaximumManipulate -
DbgKdMinimumManipulate;
KdVersionBlock.Unused[0] = 0;
/* Link us in the KPCR */
KeGetPcr()->KdVersionBlock = &KdVersionBlock;
}
/* Check if we have a loader block */
if (LoaderBlock)
{
/* Get the image entry */
LdrEntry = CONTAINING_RECORD(LoaderBlock->LoadOrderListHead.Flink,
LDR_DATA_TABLE_ENTRY,
InLoadOrderLinks);
/* Save the Kernel Base */
PsNtosImageBase = (ULONG_PTR)LdrEntry->DllBase;
KdVersionBlock.KernBase = (ULONG64)(LONG_PTR)LdrEntry->DllBase;
/* Check if we have a command line */
CommandLine = LoaderBlock->LoadOptions;
if (CommandLine)
{
/* Upcase it */
_strupr(CommandLine);
/* Assume we'll disable KD */
EnableKd = FALSE;
/* Check for CRASHDEBUG, NODEBUG and just DEBUG */
if (strstr(CommandLine, "CRASHDEBUG"))
{
/* No command line options? Disable debugger by default */
KdDebuggerEnabled = FALSE;
/* 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;
KdDebuggerNotPresent = FALSE;
#ifdef KDBG
/* Get the KDBG Settings */
KdbpGetCommandLineSettings(LoaderBlock->LoadOptions);
#endif
}
}
else
{
/* Called from a bugcheck or a re-enable. Unconditionally enable KD. */
KdDebuggerEnabled = TRUE;
/* No command line options? Disable debugger by default */
KdPitchDebugger = TRUE;
EnableKd = FALSE;
}
/* Let user-mode know our state */
SharedUserData->KdDebuggerEnabled = KdDebuggerEnabled;
/* Check if we got the /DEBUGPORT parameter(s) */
while (Port)
{
/* Move past the actual string, to reach the port*/
Port += sizeof("DEBUGPORT") - 1;
/* Now get past any spaces and skip the equal sign */
while (*Port == ' ') Port++;
Port++;
/* Get the debug mode and wrapper */
Port = KdpGetDebugMode(Port);
Port = strstr(Port, "DEBUGPORT");
}
/* Use serial port then */
if (KdDebuggerEnabled && KdpDebugMode.Value == 0)
KdpDebugMode.Serial = TRUE;
/* Check if we got a baud rate */
if (BaudRate)
{
/* Move past the actual string, to reach the rate */
BaudRate += sizeof("BAUDRATE") - 1;
/* Now get past any spaces */
while (*BaudRate == ' ') BaudRate++;
/* And make sure we have a rate */
if (*BaudRate)
{
/* Read and set it */
Value = atol(BaudRate + 1);
if (Value) PortInfo.BaudRate = SerialPortInfo.BaudRate = Value;
}
}
/* Check Serial Port Settings [IRQ] */
if (Irq)
{
/* Move past the actual string, to reach the rate */
Irq += sizeof("IRQ") - 1;
/* Now get past any spaces */
while (*Irq == ' ') Irq++;
/* And make sure we have an IRQ */
if (*Irq)
{
/* Read and set it */
Value = atol(Irq + 1);
if (Value) KdpPortIrq = Value;
}
}
/* Call Providers at Phase 0 */
for (i = 0; i < KdMax; i++)
{
InitRoutines[i](&DispatchTable[i], 0);
}
/* Call Wrapper at Phase 0 */
if (WrapperInitRoutine) WrapperInitRoutine(&WrapperTable, 0);
return TRUE;
}
else /* BootPhase > 0 */
else
{
/* Called from a bugcheck or a re-enable. Save the Kernel Base. */
KdVersionBlock.KernBase = (ULONG64)(LONG_PTR)PsNtosImageBase;
/* Unconditionally enable KD */
EnableKd = TRUE;
}
/* Call the Initialization Routines of the Registered Providers */
KdpCallInitRoutine(BootPhase);
/* Set the Kernel Base in the Data Block */
KdDebuggerDataBlock.KernBase = (ULONG_PTR)KdVersionBlock.KernBase;
/* Return success */
/* Initialize the debugger if requested */
if (EnableKd && (NT_SUCCESS(KdDebuggerInitialize0(LoaderBlock))))
{
/* Check if we've already initialized our structures */
if (!KdpDebuggerStructuresInitialized)
{
/* Set the Debug Switch Routine and Retries */
KdpContext.KdpDefaultRetries = 20;
KiDebugSwitchRoutine = KdpSwitchProcessor;
/* Initialize breakpoints owed flag and table */
KdpOweBreakpoint = FALSE;
for (i = 0; i < KD_BREAKPOINT_MAX; i++)
{
KdpBreakpointTable[i].Flags = 0;
KdpBreakpointTable[i].DirectoryTableBase = 0;
KdpBreakpointTable[i].Address = NULL;
}
/* Initialize the Time Slip DPC */
KeInitializeDpc(&KdpTimeSlipDpc, KdpTimeSlipDpcRoutine, NULL);
KeInitializeTimer(&KdpTimeSlipTimer);
ExInitializeWorkItem(&KdpTimeSlipWorkItem, KdpTimeSlipWork, NULL);
/* First-time initialization done! */
KdpDebuggerStructuresInitialized = TRUE;
}
/* Initialize the timer */
KdTimerStart.QuadPart = 0;
/* Officially enable KD */
KdPitchDebugger = FALSE;
KdDebuggerEnabled = TRUE;
/* Let user-mode know that it's enabled as well */
SharedUserData->KdDebuggerEnabled = TRUE;
}
else
{
/* Disable debugger */
KdDebuggerNotPresent = TRUE;
}
/* Return initialized */
return TRUE;
}

View file

@ -58,6 +58,9 @@ VOID NTAPI PspDumpThreads(BOOLEAN SystemThreads);
ULONG Kd_DEFAULT_MASK = 1 << DPFLTR_ERROR_LEVEL;
#endif
extern CPPORT PortInfo;
extern ANSI_STRING KdpLogFileName;
/* PRIVATE FUNCTIONS *********************************************************/
ULONG
@ -413,12 +416,164 @@ KdSystemDebugControl(IN SYSDBG_COMMAND Command,
PKDEBUG_ROUTINE KiDebugRoutine = KdpEnterDebuggerException;
CODE_SEG("INIT")
PCHAR
NTAPI
KdpGetDebugMode(PCHAR Currentp2)
{
PCHAR p1, p2 = Currentp2;
ULONG Value;
/* Check for Screen Debugging */
if (!_strnicmp(p2, "SCREEN", 6))
{
/* Enable It */
p2 += 6;
KdpDebugMode.Screen = TRUE;
}
/* Check for Serial Debugging */
else if (!_strnicmp(p2, "COM", 3))
{
/* Gheck for a valid Serial Port */
p2 += 3;
if (*p2 != ':')
{
Value = (ULONG)atol(p2);
if (Value > 0 && Value < 5)
{
/* Valid port found, enable Serial Debugging */
KdpDebugMode.Serial = TRUE;
/* Set the port to use */
SerialPortNumber = Value;
KdpPort = Value;
}
}
else
{
Value = strtoul(p2 + 1, NULL, 0);
if (Value)
{
KdpDebugMode.Serial = TRUE;
SerialPortInfo.Address = UlongToPtr(Value);
SerialPortNumber = 0;
KdpPort = 0;
}
}
}
/* Check for Debug Log Debugging */
else if (!_strnicmp(p2, "FILE", 4))
{
/* Enable It */
p2 += 4;
KdpDebugMode.File = TRUE;
if (*p2 == ':')
{
p2++;
p1 = p2;
while (*p2 != '\0' && *p2 != ' ') p2++;
KdpLogFileName.MaximumLength = KdpLogFileName.Length = p2 - p1;
KdpLogFileName.Buffer = p1;
}
}
/* Check for BOCHS Debugging */
else if (!_strnicmp(p2, "BOCHS", 5))
{
/* Enable It */
p2 += 5;
KdpDebugMode.Bochs = TRUE;
}
return p2;
}
NTSTATUS
NTAPI
KdDebuggerInitialize0(
IN PLOADER_PARAMETER_BLOCK LoaderBlock OPTIONAL)
{
return STATUS_NOT_IMPLEMENTED;
ULONG Value;
ULONG i;
PCHAR CommandLine, Port = NULL, BaudRate = NULL, Irq = NULL;
if (LoaderBlock)
{
/* Check if we have a command line */
CommandLine = LoaderBlock->LoadOptions;
if (CommandLine)
{
/* Upcase it */
_strupr(CommandLine);
/* Get the port and baud rate */
Port = strstr(CommandLine, "DEBUGPORT");
BaudRate = strstr(CommandLine, "BAUDRATE");
Irq = strstr(CommandLine, "IRQ");
}
}
/* Check if we got the /DEBUGPORT parameter(s) */
while (Port)
{
/* Move past the actual string, to reach the port*/
Port += sizeof("DEBUGPORT") - 1;
/* Now get past any spaces and skip the equal sign */
while (*Port == ' ') Port++;
Port++;
/* Get the debug mode and wrapper */
Port = KdpGetDebugMode(Port);
Port = strstr(Port, "DEBUGPORT");
}
/* Use serial port then */
if (KdpDebugMode.Value == 0)
KdpDebugMode.Serial = TRUE;
/* Check if we got a baud rate */
if (BaudRate)
{
/* Move past the actual string, to reach the rate */
BaudRate += sizeof("BAUDRATE") - 1;
/* Now get past any spaces */
while (*BaudRate == ' ') BaudRate++;
/* And make sure we have a rate */
if (*BaudRate)
{
/* Read and set it */
Value = atol(BaudRate + 1);
if (Value) PortInfo.BaudRate = SerialPortInfo.BaudRate = Value;
}
}
/* Check Serial Port Settings [IRQ] */
if (Irq)
{
/* Move past the actual string, to reach the rate */
Irq += sizeof("IRQ") - 1;
/* Now get past any spaces */
while (*Irq == ' ') Irq++;
/* And make sure we have an IRQ */
if (*Irq)
{
/* Read and set it */
Value = atol(Irq + 1);
if (Value) KdpPortIrq = Value;
}
}
/* Call Providers at Phase 0 */
for (i = 0; i < KdMax; i++)
{
InitRoutines[i](&DispatchTable[i], 0);
}
return STATUS_SUCCESS;
}
NTSTATUS

View file

@ -1726,6 +1726,7 @@ KdpReportCommandStringStateChange(IN PSTRING NameString,
Context);
} while (Status == ContinueProcessorReselected);
}
#endif
BOOLEAN
NTAPI
@ -1733,6 +1734,7 @@ KdpReportExceptionStateChange(IN PEXCEPTION_RECORD ExceptionRecord,
IN OUT PCONTEXT Context,
IN BOOLEAN SecondChanceException)
{
#ifdef _WINKD_
STRING Header, Data;
DBGKD_ANY_WAIT_STATE_CHANGE WaitStateChange;
KCONTINUE_STATUS Status;
@ -1780,6 +1782,10 @@ KdpReportExceptionStateChange(IN PEXCEPTION_RECORD ExceptionRecord,
/* Return */
return Status;
#else
UNIMPLEMENTED;
return FALSE;
#endif
}
VOID
@ -1851,6 +1857,7 @@ KdpSwitchProcessor(IN PEXCEPTION_RECORD ExceptionRecord,
return Status;
}
#ifdef _WINKD_
LARGE_INTEGER
NTAPI
KdpQueryPerformanceCounter(IN PKTRAP_FRAME TrapFrame)

View file

@ -73,8 +73,8 @@ BOOLEAN KdpContextSent;
//
#ifdef _WINKD_
PKDEBUG_ROUTINE KiDebugRoutine = KdpStub;
PKDEBUG_SWITCH_ROUTINE KiDebugSwitchRoutine;
#endif
PKDEBUG_SWITCH_ROUTINE KiDebugSwitchRoutine;
//
// Debugger Configuration Settings