2009-10-12 03:35:35 +00:00
|
|
|
/*
|
|
|
|
* PROJECT: ReactOS Kernel
|
|
|
|
* LICENSE: GPL - See COPYING in the top level directory
|
|
|
|
* FILE: ntoskrnl/kd64/kdinit.c
|
|
|
|
* PURPOSE: KD64 Initialization Code
|
|
|
|
* PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org)
|
2009-10-23 22:51:39 +00:00
|
|
|
* Stefan Ginsberg (stefan.ginsberg@reactos.org)
|
2009-10-12 03:35:35 +00:00
|
|
|
*/
|
|
|
|
|
|
|
|
/* INCLUDES ******************************************************************/
|
|
|
|
|
|
|
|
#include <ntoskrnl.h>
|
2016-10-06 19:01:33 +00:00
|
|
|
#include <reactos/buildno.h>
|
2024-11-28 21:53:10 +00:00
|
|
|
|
2009-10-12 03:35:35 +00:00
|
|
|
#define NDEBUG
|
|
|
|
#include <debug.h>
|
|
|
|
|
2024-11-28 21:53:10 +00:00
|
|
|
/*
|
|
|
|
* Override DbgPrint(), used by the debugger banner DPRINTs below,
|
|
|
|
* because KdInitSystem() can be called under the debugger lock by
|
|
|
|
* KdEnableDebugger(WithLock)().
|
|
|
|
*/
|
|
|
|
#define DbgPrint(fmt, ...) (KdpDprintf(fmt, ##__VA_ARGS__), 0)
|
|
|
|
#define DbgPrintEx(cmpid, lvl, fmt, ...) (KdpDprintf(fmt, ##__VA_ARGS__), 0)
|
|
|
|
|
2016-10-06 19:01:33 +00:00
|
|
|
/* UTILITY FUNCTIONS *********************************************************/
|
|
|
|
|
2024-11-28 20:52:22 +00:00
|
|
|
#include <mm/ARM3/miarm.h> // For MiIsMemoryTypeInvisible()
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief
|
|
|
|
* Retrieves the total size of the memory before Mm is initialized,
|
|
|
|
* by counting the number of physical pages. Useful for debug logging.
|
2016-10-06 19:01:33 +00:00
|
|
|
*
|
2024-11-28 20:52:22 +00:00
|
|
|
* Adapted from mm/ARM3/mminit.c!MiScanMemoryDescriptors().
|
|
|
|
**/
|
[NTOS:KD64] Fix usage of the debugging banner code, based on when KdInitSystem() is called (#7540)
- The debugging banner helpers *CANNOT* be in the INIT section, because
it is possible for KdInitSystem() to enable the debugger **MUCH LATER**
after boot time. (Reverts part of commit f239ca0f0 (r72922).)
This can happen in two situations:
* When the debugger is in CRASHDEBUG mode, i.e. initialized at boot
time but not immediately enabled, and a BSOD happens later that
enables the debugger with a `KdInitSystem(0, NULL)` call.
* When the debugger was possibly manually disabled with a
KdDisableDebugger() call, then later re-enabled with a
KdEnableDebugger() call.
- In the same cases as described above, the KeLoaderBlock is freed after
boot time. Thus, KdpGetMemorySizeInMBs() cannot use it and enumerate
the MemoryDescriptors to evaluate the number of physical memory pages
available on the system. Instead, we can use what the memory manager
has already computed, since the latter is already initialized by now.
These two fixes avoid (invisible) crashes when (re-)enabling
the debugger at non-boot run time.
2024-11-28 20:26:03 +00:00
|
|
|
static
|
2019-11-17 15:44:22 +00:00
|
|
|
SIZE_T
|
[NTOS:KD64] Fix usage of the debugging banner code, based on when KdInitSystem() is called (#7540)
- The debugging banner helpers *CANNOT* be in the INIT section, because
it is possible for KdInitSystem() to enable the debugger **MUCH LATER**
after boot time. (Reverts part of commit f239ca0f0 (r72922).)
This can happen in two situations:
* When the debugger is in CRASHDEBUG mode, i.e. initialized at boot
time but not immediately enabled, and a BSOD happens later that
enables the debugger with a `KdInitSystem(0, NULL)` call.
* When the debugger was possibly manually disabled with a
KdDisableDebugger() call, then later re-enabled with a
KdEnableDebugger() call.
- In the same cases as described above, the KeLoaderBlock is freed after
boot time. Thus, KdpGetMemorySizeInMBs() cannot use it and enumerate
the MemoryDescriptors to evaluate the number of physical memory pages
available on the system. Instead, we can use what the memory manager
has already computed, since the latter is already initialized by now.
These two fixes avoid (invisible) crashes when (re-)enabling
the debugger at non-boot run time.
2024-11-28 20:26:03 +00:00
|
|
|
KdpGetMemorySizeInMBs(
|
|
|
|
_In_opt_ PLOADER_PARAMETER_BLOCK LoaderBlock)
|
2016-10-06 19:01:33 +00:00
|
|
|
{
|
|
|
|
PLIST_ENTRY ListEntry;
|
|
|
|
PMEMORY_ALLOCATION_DESCRIPTOR Descriptor;
|
|
|
|
SIZE_T NumberOfPhysicalPages = 0;
|
|
|
|
|
[NTOS:KD64] Fix usage of the debugging banner code, based on when KdInitSystem() is called (#7540)
- The debugging banner helpers *CANNOT* be in the INIT section, because
it is possible for KdInitSystem() to enable the debugger **MUCH LATER**
after boot time. (Reverts part of commit f239ca0f0 (r72922).)
This can happen in two situations:
* When the debugger is in CRASHDEBUG mode, i.e. initialized at boot
time but not immediately enabled, and a BSOD happens later that
enables the debugger with a `KdInitSystem(0, NULL)` call.
* When the debugger was possibly manually disabled with a
KdDisableDebugger() call, then later re-enabled with a
KdEnableDebugger() call.
- In the same cases as described above, the KeLoaderBlock is freed after
boot time. Thus, KdpGetMemorySizeInMBs() cannot use it and enumerate
the MemoryDescriptors to evaluate the number of physical memory pages
available on the system. Instead, we can use what the memory manager
has already computed, since the latter is already initialized by now.
These two fixes avoid (invisible) crashes when (re-)enabling
the debugger at non-boot run time.
2024-11-28 20:26:03 +00:00
|
|
|
/*
|
|
|
|
* If no loader block is present (e.g. the debugger is initialized only
|
|
|
|
* much later after boot), just use the already-initialized Mm-computed
|
|
|
|
* number of physical pages. Otherwise do the evaluation ourselves.
|
|
|
|
*/
|
|
|
|
if (!LoaderBlock)
|
|
|
|
{
|
|
|
|
NumberOfPhysicalPages = MmNumberOfPhysicalPages;
|
|
|
|
goto ReturnSize;
|
|
|
|
}
|
|
|
|
|
2016-10-06 19:01:33 +00:00
|
|
|
/* Loop the memory descriptors */
|
|
|
|
for (ListEntry = LoaderBlock->MemoryDescriptorListHead.Flink;
|
|
|
|
ListEntry != &LoaderBlock->MemoryDescriptorListHead;
|
|
|
|
ListEntry = ListEntry->Flink)
|
|
|
|
{
|
|
|
|
/* Get the descriptor */
|
|
|
|
Descriptor = CONTAINING_RECORD(ListEntry,
|
|
|
|
MEMORY_ALLOCATION_DESCRIPTOR,
|
|
|
|
ListEntry);
|
|
|
|
|
2024-11-28 20:52:22 +00:00
|
|
|
/* If this is invisible memory, skip this descriptor */
|
|
|
|
if (MiIsMemoryTypeInvisible(Descriptor->MemoryType))
|
2016-10-06 19:01:33 +00:00
|
|
|
continue;
|
|
|
|
|
2024-11-28 20:52:22 +00:00
|
|
|
/* Check if this isn't bad memory */
|
2016-10-06 19:01:33 +00:00
|
|
|
if (Descriptor->MemoryType != LoaderBad)
|
|
|
|
{
|
2024-11-28 20:52:22 +00:00
|
|
|
/* Count it in the physical pages */
|
2016-10-06 19:01:33 +00:00
|
|
|
NumberOfPhysicalPages += Descriptor->PageCount;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
[NTOS:KD64] Fix usage of the debugging banner code, based on when KdInitSystem() is called (#7540)
- The debugging banner helpers *CANNOT* be in the INIT section, because
it is possible for KdInitSystem() to enable the debugger **MUCH LATER**
after boot time. (Reverts part of commit f239ca0f0 (r72922).)
This can happen in two situations:
* When the debugger is in CRASHDEBUG mode, i.e. initialized at boot
time but not immediately enabled, and a BSOD happens later that
enables the debugger with a `KdInitSystem(0, NULL)` call.
* When the debugger was possibly manually disabled with a
KdDisableDebugger() call, then later re-enabled with a
KdEnableDebugger() call.
- In the same cases as described above, the KeLoaderBlock is freed after
boot time. Thus, KdpGetMemorySizeInMBs() cannot use it and enumerate
the MemoryDescriptors to evaluate the number of physical memory pages
available on the system. Instead, we can use what the memory manager
has already computed, since the latter is already initialized by now.
These two fixes avoid (invisible) crashes when (re-)enabling
the debugger at non-boot run time.
2024-11-28 20:26:03 +00:00
|
|
|
ReturnSize:
|
2018-02-02 23:19:18 +00:00
|
|
|
/* Round size up. Assumed to better match actual physical RAM size */
|
|
|
|
return ALIGN_UP_BY(NumberOfPhysicalPages * PAGE_SIZE, 1024 * 1024) / (1024 * 1024);
|
2016-10-06 19:01:33 +00:00
|
|
|
}
|
|
|
|
|
2024-11-28 20:52:22 +00:00
|
|
|
/**
|
|
|
|
* @brief
|
|
|
|
* Displays the kernel debugger initialization banner.
|
|
|
|
**/
|
[NTOS:KD64] Fix usage of the debugging banner code, based on when KdInitSystem() is called (#7540)
- The debugging banner helpers *CANNOT* be in the INIT section, because
it is possible for KdInitSystem() to enable the debugger **MUCH LATER**
after boot time. (Reverts part of commit f239ca0f0 (r72922).)
This can happen in two situations:
* When the debugger is in CRASHDEBUG mode, i.e. initialized at boot
time but not immediately enabled, and a BSOD happens later that
enables the debugger with a `KdInitSystem(0, NULL)` call.
* When the debugger was possibly manually disabled with a
KdDisableDebugger() call, then later re-enabled with a
KdEnableDebugger() call.
- In the same cases as described above, the KeLoaderBlock is freed after
boot time. Thus, KdpGetMemorySizeInMBs() cannot use it and enumerate
the MemoryDescriptors to evaluate the number of physical memory pages
available on the system. Instead, we can use what the memory manager
has already computed, since the latter is already initialized by now.
These two fixes avoid (invisible) crashes when (re-)enabling
the debugger at non-boot run time.
2024-11-28 20:26:03 +00:00
|
|
|
static
|
2019-11-17 15:44:22 +00:00
|
|
|
VOID
|
2024-11-28 20:52:22 +00:00
|
|
|
KdpPrintBanner(VOID)
|
2017-10-16 09:47:14 +00:00
|
|
|
{
|
2024-11-28 20:52:22 +00:00
|
|
|
SIZE_T MemSizeMBs = KdpGetMemorySizeInMBs(KeLoaderBlock);
|
|
|
|
|
2017-10-16 09:47:14 +00:00
|
|
|
DPRINT1("-----------------------------------------------------\n");
|
|
|
|
DPRINT1("ReactOS " KERNEL_VERSION_STR " (Build " KERNEL_VERSION_BUILD_STR ") (Commit " KERNEL_VERSION_COMMIT_HASH ")\n");
|
|
|
|
DPRINT1("%u System Processor [%u MB Memory]\n", KeNumberProcessors, MemSizeMBs);
|
|
|
|
|
|
|
|
if (KeLoaderBlock)
|
|
|
|
{
|
|
|
|
DPRINT1("Command Line: %s\n", KeLoaderBlock->LoadOptions);
|
2024-11-28 20:52:22 +00:00
|
|
|
DPRINT1("ARC Paths: %s %s %s %s\n",
|
|
|
|
KeLoaderBlock->ArcBootDeviceName, KeLoaderBlock->NtHalPathName,
|
|
|
|
KeLoaderBlock->ArcHalDeviceName, KeLoaderBlock->NtBootPathName);
|
2017-10-16 09:47:14 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-10-12 03:35:35 +00:00
|
|
|
/* FUNCTIONS *****************************************************************/
|
|
|
|
|
|
|
|
VOID
|
|
|
|
NTAPI
|
|
|
|
KdUpdateDataBlock(VOID)
|
|
|
|
{
|
|
|
|
/* Update the KeUserCallbackDispatcher pointer */
|
|
|
|
KdDebuggerDataBlock.KeUserCallbackDispatcher =
|
|
|
|
(ULONG_PTR)KeUserCallbackDispatcher;
|
2020-03-07 18:14:09 +00:00
|
|
|
}
|
2009-10-12 03:35:35 +00:00
|
|
|
|
|
|
|
BOOLEAN
|
|
|
|
NTAPI
|
|
|
|
KdRegisterDebuggerDataBlock(IN ULONG Tag,
|
|
|
|
IN PDBGKD_DEBUG_DATA_HEADER64 DataHeader,
|
|
|
|
IN ULONG Size)
|
|
|
|
{
|
|
|
|
KIRQL OldIrql;
|
|
|
|
PLIST_ENTRY NextEntry;
|
|
|
|
PDBGKD_DEBUG_DATA_HEADER64 CurrentHeader;
|
|
|
|
|
|
|
|
/* Acquire the Data Lock */
|
|
|
|
KeAcquireSpinLock(&KdpDataSpinLock, &OldIrql);
|
|
|
|
|
|
|
|
/* Loop the debugger data list */
|
|
|
|
NextEntry = KdpDebuggerDataListHead.Flink;
|
|
|
|
while (NextEntry != &KdpDebuggerDataListHead)
|
|
|
|
{
|
|
|
|
/* Get the header for this entry */
|
|
|
|
CurrentHeader = CONTAINING_RECORD(NextEntry,
|
|
|
|
DBGKD_DEBUG_DATA_HEADER64,
|
|
|
|
List);
|
|
|
|
|
|
|
|
/* Move to the next one */
|
|
|
|
NextEntry = NextEntry->Flink;
|
|
|
|
|
|
|
|
/* Check if we already have this data block */
|
|
|
|
if ((CurrentHeader == DataHeader) || (CurrentHeader->OwnerTag == Tag))
|
|
|
|
{
|
|
|
|
/* Release the lock and fail */
|
|
|
|
KeReleaseSpinLock(&KdpDataSpinLock, OldIrql);
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Setup the header */
|
|
|
|
DataHeader->OwnerTag = Tag;
|
|
|
|
DataHeader->Size = Size;
|
|
|
|
|
|
|
|
/* Insert it into the list and release the lock */
|
|
|
|
InsertTailList(&KdpDebuggerDataListHead, (PLIST_ENTRY)&DataHeader->List);
|
|
|
|
KeReleaseSpinLock(&KdpDataSpinLock, OldIrql);
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
BOOLEAN
|
|
|
|
NTAPI
|
2022-11-18 15:23:06 +00:00
|
|
|
KdInitSystem(
|
|
|
|
_In_ ULONG BootPhase,
|
|
|
|
_In_opt_ PLOADER_PARAMETER_BLOCK LoaderBlock)
|
2009-10-12 03:35:35 +00:00
|
|
|
{
|
2024-11-28 19:07:25 +00:00
|
|
|
BOOLEAN EnableKd, DisableKdAfterInit = FALSE, BlockEnable = FALSE;
|
2009-10-12 03:35:35 +00:00
|
|
|
PLDR_DATA_TABLE_ENTRY LdrEntry;
|
2024-11-28 19:07:25 +00:00
|
|
|
ULONG i;
|
2009-10-17 14:31:38 +00:00
|
|
|
|
2009-10-12 03:35:35 +00:00
|
|
|
/* Check if this is Phase 1 */
|
|
|
|
if (BootPhase)
|
|
|
|
{
|
|
|
|
/* Just query the performance counter */
|
|
|
|
KeQueryPerformanceCounter(&KdPerformanceCounterRate);
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Check if we already initialized once */
|
2024-11-28 19:07:25 +00:00
|
|
|
if (KdDebuggerEnabled)
|
|
|
|
return TRUE;
|
2009-10-12 03:35:35 +00:00
|
|
|
|
|
|
|
/* Set the Debug Routine as the Stub for now */
|
|
|
|
KiDebugRoutine = KdpStub;
|
|
|
|
|
|
|
|
/* 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 */
|
2009-11-02 17:45:51 +00:00
|
|
|
KdVersionBlock.MajorVersion = (USHORT)((DBGKD_MAJOR_NT << 8) | (NtBuildNumber >> 28));
|
2009-10-12 03:35:35 +00:00
|
|
|
KdVersionBlock.MinorVersion = (USHORT)(NtBuildNumber & 0xFFFF);
|
|
|
|
|
|
|
|
#ifdef CONFIG_SMP
|
|
|
|
/* This is an MP Build */
|
|
|
|
KdVersionBlock.Flags |= DBGKD_VERS_FLAG_MP;
|
|
|
|
#endif
|
|
|
|
|
|
|
|
/* 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 */
|
2024-11-28 18:42:06 +00:00
|
|
|
KeGetPcr()->KdVersionBlock = &KdVersionBlock;
|
2009-10-12 03:35:35 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Check if we have a loader block */
|
|
|
|
if (LoaderBlock)
|
|
|
|
{
|
2024-11-28 19:07:25 +00:00
|
|
|
PSTR CommandLine, DebugLine;
|
|
|
|
|
2009-10-12 03:35:35 +00:00
|
|
|
/* 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;
|
|
|
|
|
2009-11-02 17:45:51 +00:00
|
|
|
/* 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;
|
|
|
|
}
|
2024-11-28 19:07:25 +00:00
|
|
|
else if ((DebugLine = strstr(CommandLine, "DEBUG")))
|
2009-10-12 03:35:35 +00:00
|
|
|
{
|
|
|
|
/* Enable KD */
|
|
|
|
EnableKd = TRUE;
|
|
|
|
|
2009-10-17 14:31:38 +00:00
|
|
|
/* Check if there are any options */
|
2009-10-12 03:35:35 +00:00
|
|
|
if (DebugLine[5] == '=')
|
|
|
|
{
|
2009-10-17 14:31:38 +00:00
|
|
|
/* Save pointers */
|
2024-11-28 19:07:25 +00:00
|
|
|
PSTR DebugOptionStart, DebugOptionEnd;
|
2009-10-17 14:31:38 +00:00
|
|
|
DebugOptionStart = DebugOptionEnd = &DebugLine[6];
|
|
|
|
|
|
|
|
/* Scan the string for debug options */
|
|
|
|
for (;;)
|
|
|
|
{
|
2024-11-28 19:07:25 +00:00
|
|
|
SIZE_T DebugOptionLength;
|
|
|
|
|
2009-10-17 14:31:38 +00:00
|
|
|
/* Loop until we reach the end of the string */
|
|
|
|
while (*DebugOptionEnd != ANSI_NULL)
|
|
|
|
{
|
|
|
|
/* Check if this is a comma, a space or a tab */
|
|
|
|
if ((*DebugOptionEnd == ',') ||
|
|
|
|
(*DebugOptionEnd == ' ') ||
|
2012-11-24 19:36:07 +00:00
|
|
|
(*DebugOptionEnd == '\t'))
|
2009-10-17 14:31:38 +00:00
|
|
|
{
|
|
|
|
/*
|
|
|
|
* We reached the end of the option or
|
2024-11-28 19:07:25 +00:00
|
|
|
* the end of the string, break out.
|
2009-10-17 14:31:38 +00:00
|
|
|
*/
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* Move on to the next character */
|
|
|
|
DebugOptionEnd++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Calculate the length of the current option */
|
[HAL/NDK]
- Make Vector parameter in HalEnableSystemInterrupt, HalDisableSystemInterrupt and HalBeginSystemInterrupt an ULONG, not an UCHAR
[NDK]
- 64bit fixes for HANDLE_TABLE, KPROCESS, SECTION_IMAGE_INFORMATION, MMADDRESS_LIST, MMVAD_FLAGS, MMVAD, MMVAD_LONG, MMVAD_SHORT, MEMORY_DESCRIPTOR, MEMORY_ALLOCATION_DESCRIPTOR, LdrVerifyMappedImageMatchesChecksum
- KDPC_DATA::DpcQueueDepth is signed on amd64, unsigned on x86
[NTOSKRNL]
- Fix hundreds of MSVC and amd64 warnings
- add a pragma message to FstubFixupEfiPartition, since it looks broken
- Move portable Ke constants from <arch>/cpu.c to krnlinit.c
- Fixed a bug in amd64 KiGeneralProtectionFaultHandler
svn path=/trunk/; revision=53734
2011-09-18 13:11:45 +00:00
|
|
|
DebugOptionLength = (DebugOptionEnd - DebugOptionStart);
|
2009-10-17 14:31:38 +00:00
|
|
|
|
2024-11-28 19:07:25 +00:00
|
|
|
/*
|
|
|
|
* Break out if we reached the last option
|
|
|
|
* or if there were no options at all.
|
|
|
|
*/
|
|
|
|
if (!DebugOptionLength)
|
|
|
|
break;
|
2009-10-17 14:31:38 +00:00
|
|
|
|
|
|
|
/* Now check which option this is */
|
|
|
|
if ((DebugOptionLength == 10) &&
|
|
|
|
!(strncmp(DebugOptionStart, "AUTOENABLE", 10)))
|
|
|
|
{
|
2024-11-28 19:07:25 +00:00
|
|
|
/* Disable the debugger, but
|
|
|
|
* allow to re-enable it later */
|
2009-10-17 14:31:38 +00:00
|
|
|
DisableKdAfterInit = TRUE;
|
|
|
|
BlockEnable = FALSE;
|
|
|
|
KdAutoEnableOnEvent = TRUE;
|
|
|
|
}
|
|
|
|
else if ((DebugOptionLength == 7) &&
|
|
|
|
!(strncmp(DebugOptionStart, "DISABLE", 7)))
|
|
|
|
{
|
|
|
|
/* Disable the debugger */
|
|
|
|
DisableKdAfterInit = TRUE;
|
|
|
|
BlockEnable = TRUE;
|
|
|
|
KdAutoEnableOnEvent = FALSE;
|
|
|
|
}
|
|
|
|
else if ((DebugOptionLength == 6) &&
|
|
|
|
!(strncmp(DebugOptionStart, "NOUMEX", 6)))
|
|
|
|
{
|
|
|
|
/* Ignore user mode exceptions */
|
|
|
|
KdIgnoreUmExceptions = TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
2024-11-28 19:07:25 +00:00
|
|
|
* If there are more options then the next character
|
|
|
|
* should be a comma. Break out if it isn't.
|
2009-10-17 14:31:38 +00:00
|
|
|
*/
|
|
|
|
if (*DebugOptionEnd != ',')
|
|
|
|
break;
|
|
|
|
|
|
|
|
/* Move on to the next option */
|
|
|
|
DebugOptionEnd++;
|
|
|
|
DebugOptionStart = DebugOptionEnd;
|
|
|
|
}
|
2009-10-12 03:35:35 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* No command line options? Disable debugger by default */
|
|
|
|
KdPitchDebugger = TRUE;
|
|
|
|
EnableKd = FALSE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2019-11-17 15:44:22 +00:00
|
|
|
/* Called from a bugcheck or a re-enable. Save the Kernel Base. */
|
2009-10-12 03:35:35 +00:00
|
|
|
KdVersionBlock.KernBase = (ULONG64)(LONG_PTR)PsNtosImageBase;
|
|
|
|
|
|
|
|
/* Unconditionally enable KD */
|
|
|
|
EnableKd = TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Set the Kernel Base in the Data Block */
|
|
|
|
KdDebuggerDataBlock.KernBase = (ULONG_PTR)KdVersionBlock.KernBase;
|
|
|
|
|
|
|
|
/* Initialize the debugger if requested */
|
2015-08-28 03:03:26 +00:00
|
|
|
if (EnableKd && (NT_SUCCESS(KdDebuggerInitialize0(LoaderBlock))))
|
2009-10-12 03:35:35 +00:00
|
|
|
{
|
|
|
|
/* Now set our real KD routine */
|
|
|
|
KiDebugRoutine = KdpTrap;
|
|
|
|
|
|
|
|
/* Check if we've already initialized our structures */
|
|
|
|
if (!KdpDebuggerStructuresInitialized)
|
|
|
|
{
|
2023-12-07 19:27:44 +00:00
|
|
|
/* Set Retries */
|
2009-10-22 15:25:37 +00:00
|
|
|
KdpContext.KdpDefaultRetries = 20;
|
2009-10-12 03:35:35 +00:00
|
|
|
|
2015-08-28 03:03:26 +00:00
|
|
|
/* 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;
|
|
|
|
}
|
|
|
|
|
2009-10-12 03:35:35 +00:00
|
|
|
/* 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;
|
|
|
|
|
2024-11-28 20:52:22 +00:00
|
|
|
/* Display separator + ReactOS version at the start of the debug log */
|
|
|
|
KdpPrintBanner();
|
2016-10-06 19:01:33 +00:00
|
|
|
|
2009-10-17 14:31:38 +00:00
|
|
|
/* Check if the debugger should be disabled initially */
|
|
|
|
if (DisableKdAfterInit)
|
|
|
|
{
|
|
|
|
/* Disable it */
|
|
|
|
KdDisableDebuggerWithLock(FALSE);
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Save the enable block state and return initialized
|
|
|
|
* (the debugger is active but disabled).
|
|
|
|
*/
|
|
|
|
KdBlockEnable = BlockEnable;
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
2009-10-12 03:35:35 +00:00
|
|
|
/* Check if we have a loader block */
|
|
|
|
if (LoaderBlock)
|
|
|
|
{
|
2024-11-28 19:07:25 +00:00
|
|
|
PLIST_ENTRY NextEntry;
|
|
|
|
ULONG j, Length;
|
|
|
|
PWCHAR Name;
|
|
|
|
STRING ImageName;
|
|
|
|
CHAR NameBuffer[256];
|
|
|
|
|
|
|
|
/* Loop over the first two boot images: HAL and kernel */
|
|
|
|
for (NextEntry = LoaderBlock->LoadOrderListHead.Flink, i = 0;
|
|
|
|
NextEntry != &LoaderBlock->LoadOrderListHead && (i < 2);
|
|
|
|
NextEntry = NextEntry->Flink, ++i)
|
2009-10-12 03:35:35 +00:00
|
|
|
{
|
|
|
|
/* Get the image entry */
|
|
|
|
LdrEntry = CONTAINING_RECORD(NextEntry,
|
|
|
|
LDR_DATA_TABLE_ENTRY,
|
|
|
|
InLoadOrderLinks);
|
|
|
|
|
|
|
|
/* Generate the image name */
|
|
|
|
Name = LdrEntry->FullDllName.Buffer;
|
|
|
|
Length = LdrEntry->FullDllName.Length / sizeof(WCHAR);
|
|
|
|
j = 0;
|
|
|
|
do
|
|
|
|
{
|
|
|
|
/* Do cheap Unicode to ANSI conversion */
|
|
|
|
NameBuffer[j++] = (CHAR)*Name++;
|
|
|
|
} while (j < Length);
|
|
|
|
|
|
|
|
/* Null-terminate */
|
|
|
|
NameBuffer[j] = ANSI_NULL;
|
|
|
|
|
2024-11-28 19:07:25 +00:00
|
|
|
/* Load the symbols */
|
2009-10-25 15:56:38 +00:00
|
|
|
RtlInitString(&ImageName, NameBuffer);
|
|
|
|
DbgLoadImageSymbols(&ImageName,
|
|
|
|
LdrEntry->DllBase,
|
2014-05-22 10:18:22 +00:00
|
|
|
(ULONG_PTR)PsGetCurrentProcessId());
|
2009-10-12 03:35:35 +00:00
|
|
|
}
|
|
|
|
|
2024-11-28 18:42:06 +00:00
|
|
|
/* Check for incoming break-in and break on symbol load
|
|
|
|
* if requested, see ex/init.c!ExpLoadBootSymbols() */
|
|
|
|
KdBreakAfterSymbolLoad = KdPollBreakIn();
|
|
|
|
}
|
2009-10-12 03:35:35 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* Disable debugger */
|
|
|
|
KdDebuggerNotPresent = TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Return initialized */
|
|
|
|
return TRUE;
|
|
|
|
}
|