/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
- * FILE: ntoskrnl/dbg/kdb_symbols.c
+ * FILE: ntoskrnl/kdbg/kdb_symbols.c
* PURPOSE: Getting symbol information...
*
* PROGRAMMERS: David Welch (welch@cwcom.net)
/* INCLUDES *****************************************************************/
#include <ntoskrnl.h>
+#include "kdb.h"
#define NDEBUG
-#include <debug.h>
+#include "debug.h"
/* GLOBALS ******************************************************************/
}
IMAGE_SYMBOL_INFO_CACHE, *PIMAGE_SYMBOL_INFO_CACHE;
-static BOOLEAN LoadSymbols;
-static LIST_ENTRY SymbolFileListHead;
-static KSPIN_LOCK SymbolFileListLock;
-BOOLEAN KdbpSymbolsInitialized = FALSE;
+static BOOLEAN LoadSymbols = FALSE;
+static LIST_ENTRY SymbolsToLoad;
+static KSPIN_LOCK SymbolsToLoadLock;
+static KEVENT SymbolsToLoadEvent;
/* FUNCTIONS ****************************************************************/
-static BOOLEAN
+static
+BOOLEAN
KdbpSymSearchModuleList(
IN PLIST_ENTRY current_entry,
IN PLIST_ENTRY end_entry,
IN PLONG Count,
IN PVOID Address,
- IN LPCWSTR Name,
IN INT Index,
OUT PLDR_DATA_TABLE_ENTRY* pLdrEntry)
{
*pLdrEntry = CONTAINING_RECORD(current_entry, LDR_DATA_TABLE_ENTRY, InLoadOrderLinks);
if ((Address && Address >= (PVOID)(*pLdrEntry)->DllBase && Address < (PVOID)((ULONG_PTR)(*pLdrEntry)->DllBase + (*pLdrEntry)->SizeOfImage)) ||
- (Name && !_wcsnicmp((*pLdrEntry)->BaseDllName.Buffer, Name, (*pLdrEntry)->BaseDllName.Length / sizeof(WCHAR))) ||
(Index >= 0 && (*Count)++ == Index))
{
return TRUE;
BOOLEAN
KdbpSymFindModule(
IN PVOID Address OPTIONAL,
- IN LPCWSTR Name OPTIONAL,
IN INT Index OPTIONAL,
OUT PLDR_DATA_TABLE_ENTRY* pLdrEntry)
{
PEPROCESS CurrentProcess;
/* First try to look up the module in the kernel module list. */
+ KeAcquireSpinLockAtDpcLevel(&PsLoadedModuleSpinLock);
if(KdbpSymSearchModuleList(PsLoadedModuleList.Flink,
&PsLoadedModuleList,
&Count,
Address,
- Name,
Index,
pLdrEntry))
{
+ KeReleaseSpinLockFromDpcLevel(&PsLoadedModuleSpinLock);
return TRUE;
}
+ KeReleaseSpinLockFromDpcLevel(&PsLoadedModuleSpinLock);
/* That didn't succeed. Try the module list of the current process now. */
CurrentProcess = PsGetCurrentProcess();
&CurrentProcess->Peb->Ldr->InLoadOrderModuleList,
&Count,
Address,
- Name,
Index,
pLdrEntry);
}
+static
PCHAR
NTAPI
KdbpSymUnicodeToAnsi(IN PUNICODE_STRING Unicode,
BOOLEAN
KdbSymPrintAddress(
IN PVOID Address,
- IN PKTRAP_FRAME Context)
+ IN PCONTEXT Context)
{
PLDR_DATA_TABLE_ENTRY LdrEntry;
ULONG_PTR RelativeAddress;
- NTSTATUS Status;
- ULONG LineNumber;
- CHAR FileName[256];
- CHAR FunctionName[256];
+ BOOLEAN Printed = FALSE;
CHAR ModuleNameAnsi[64];
- if (!KdbpSymbolsInitialized || !KdbpSymFindModule(Address, NULL, -1, &LdrEntry))
+ if (!KdbpSymFindModule(Address, -1, &LdrEntry))
return FALSE;
-
- KdbpSymUnicodeToAnsi(&LdrEntry->BaseDllName,
- ModuleNameAnsi,
- sizeof(ModuleNameAnsi));
RelativeAddress = (ULONG_PTR)Address - (ULONG_PTR)LdrEntry->DllBase;
- Status = KdbSymGetAddressInformation(LdrEntry->PatchInformation,
- RelativeAddress,
- &LineNumber,
- FileName,
- FunctionName);
- if (NT_SUCCESS(Status))
- {
- DbgPrint("<%s:%x (%s:%d (%s))>",
- ModuleNameAnsi, RelativeAddress, FileName, LineNumber, FunctionName);
- }
- else
- {
- DbgPrint("<%s:%x>", ModuleNameAnsi, RelativeAddress);
- }
-
- return TRUE;
-}
-
-
-/*! \brief Get information for an address (source file, line number,
- * function name)
- *
- * \param SymbolInfo Pointer to ROSSYM_INFO.
- * \param RelativeAddress Relative address to look up.
- * \param LineNumber Pointer to an ULONG which is filled with the line
- * number (can be NULL)
- * \param FileName Pointer to an array of CHARs which gets filled with
- * the filename (can be NULL)
- * \param FunctionName Pointer to an array of CHARs which gets filled with
- * the function name (can be NULL)
- *
- * \returns NTSTATUS error code.
- * \retval STATUS_SUCCESS At least one of the requested informations was found.
- * \retval STATUS_UNSUCCESSFUL None of the requested information was found.
- */
-NTSTATUS
-KdbSymGetAddressInformation(
- IN PROSSYM_INFO RosSymInfo,
- IN ULONG_PTR RelativeAddress,
- OUT PULONG LineNumber OPTIONAL,
- OUT PCH FileName OPTIONAL,
- OUT PCH FunctionName OPTIONAL)
-{
- if (!KdbpSymbolsInitialized ||
- !RosSymInfo ||
- !RosSymGetAddressInformation(RosSymInfo, RelativeAddress, LineNumber, FileName, FunctionName))
- {
- return STATUS_UNSUCCESSFUL;
- }
- return STATUS_SUCCESS;
-}
-
-/*! \brief Find cached symbol file.
- *
- * Looks through the list of cached symbol files and tries to find an already
- * loaded one.
- *
- * \param FileName FileName of the symbol file to look for.
- *
- * \returns A pointer to the cached symbol info.
- * \retval NULL No cached info found.
- *
- * \sa KdbpSymAddCachedFile
- */
-static PROSSYM_INFO
-KdbpSymFindCachedFile(
- IN PUNICODE_STRING FileName)
-{
- PIMAGE_SYMBOL_INFO_CACHE Current;
- PLIST_ENTRY CurrentEntry;
- KIRQL Irql;
-
- DPRINT("Looking for cached symbol file %wZ\n", FileName);
-
- KeAcquireSpinLock(&SymbolFileListLock, &Irql);
+ KdbpSymUnicodeToAnsi(&LdrEntry->BaseDllName,
+ ModuleNameAnsi,
+ sizeof(ModuleNameAnsi));
- CurrentEntry = SymbolFileListHead.Flink;
- while (CurrentEntry != (&SymbolFileListHead))
+ if (LdrEntry->PatchInformation)
{
- Current = CONTAINING_RECORD(CurrentEntry, IMAGE_SYMBOL_INFO_CACHE, ListEntry);
-
- DPRINT("Current->FileName %wZ FileName %wZ\n", &Current->FileName, FileName);
- if (RtlEqualUnicodeString(&Current->FileName, FileName, TRUE))
+ ULONG LineNumber;
+ CHAR FileName[256];
+ CHAR FunctionName[256];
+
+ if (RosSymGetAddressInformation(LdrEntry->PatchInformation,
+ RelativeAddress,
+ &LineNumber,
+ FileName,
+ FunctionName))
{
- Current->RefCount++;
- KeReleaseSpinLock(&SymbolFileListLock, Irql);
- DPRINT("Found cached file!\n");
- return Current->RosSymInfo;
+ KdbPrintf("<%s:%x (%s:%d (%s))>",
+ ModuleNameAnsi, RelativeAddress,
+ FileName, LineNumber, FunctionName);
+ Printed = TRUE;
}
-
- CurrentEntry = CurrentEntry->Flink;
}
- KeReleaseSpinLock(&SymbolFileListLock, Irql);
-
- DPRINT("Cached file not found!\n");
- return NULL;
-}
+ if (!Printed)
+ {
+ /* Just print module & address */
+ KdbPrintf("<%s:%x>", ModuleNameAnsi, RelativeAddress);
+ }
-/*! \brief Add a symbol file to the cache.
- *
- * \param FileName Filename of the symbol file.
- * \param RosSymInfo Pointer to the symbol info.
- *
- * \sa KdbpSymRemoveCachedFile
- */
-static VOID
-KdbpSymAddCachedFile(
- IN PUNICODE_STRING FileName,
- IN PROSSYM_INFO RosSymInfo)
-{
- PIMAGE_SYMBOL_INFO_CACHE CacheEntry;
- KIRQL Irql;
-
- DPRINT("Adding symbol file: RosSymInfo = %p\n", RosSymInfo);
-
- /* allocate entry */
- CacheEntry = ExAllocatePoolWithTag(NonPagedPool, sizeof (IMAGE_SYMBOL_INFO_CACHE), TAG_KDBS);
- ASSERT(CacheEntry);
- RtlZeroMemory(CacheEntry, sizeof (IMAGE_SYMBOL_INFO_CACHE));
-
- /* fill entry */
- CacheEntry->FileName.Buffer = ExAllocatePoolWithTag(NonPagedPool,
- FileName->Length,
- TAG_KDBS);
- RtlCopyUnicodeString(&CacheEntry->FileName, FileName);
- ASSERT(CacheEntry->FileName.Buffer);
- CacheEntry->RefCount = 1;
- CacheEntry->RosSymInfo = RosSymInfo;
- KeAcquireSpinLock(&SymbolFileListLock, &Irql);
- InsertTailList(&SymbolFileListHead, &CacheEntry->ListEntry);
- KeReleaseSpinLock(&SymbolFileListLock, Irql);
+ return TRUE;
}
-/*! \brief Remove a symbol file (reference) from the cache.
- *
- * Tries to find a cache entry matching the given symbol info and decreases
- * it's reference count. If the refcount is 0 after decreasing it the cache
- * entry will be removed from the list and freed.
+static KSTART_ROUTINE LoadSymbolsRoutine;
+/*! \brief The symbol loader thread routine.
+ * This opens the image file for reading and loads the symbols
+ * section from there.
*
- * \param RosSymInfo Pointer to the symbol info.
+ * \note We must do this because KdbSymProcessSymbols is
+ * called at high IRQL and we can't set the event from here
*
- * \sa KdbpSymAddCachedFile
+ * \param Context Unused
*/
-static VOID
-KdbpSymRemoveCachedFile(
- IN PROSSYM_INFO RosSymInfo)
+_Use_decl_annotations_
+VOID
+NTAPI
+LoadSymbolsRoutine(
+ _In_ PVOID Context)
{
- PIMAGE_SYMBOL_INFO_CACHE Current;
- PLIST_ENTRY CurrentEntry;
- KIRQL Irql;
+ UNREFERENCED_PARAMETER(Context);
- KeAcquireSpinLock(&SymbolFileListLock, &Irql);
-
- CurrentEntry = SymbolFileListHead.Flink;
- while (CurrentEntry != (&SymbolFileListHead))
+ while (TRUE)
{
- Current = CONTAINING_RECORD(CurrentEntry, IMAGE_SYMBOL_INFO_CACHE, ListEntry);
+ PLIST_ENTRY ListEntry;
+ NTSTATUS Status = KeWaitForSingleObject(&SymbolsToLoadEvent, WrKernel, KernelMode, FALSE, NULL);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("KeWaitForSingleObject failed?! 0x%08x\n", Status);
+ LoadSymbols = FALSE;
+ return;
+ }
- if (Current->RosSymInfo == RosSymInfo) /* found */
+ while ((ListEntry = ExInterlockedRemoveHeadList(&SymbolsToLoad, &SymbolsToLoadLock)))
{
- ASSERT(Current->RefCount > 0);
- Current->RefCount--;
- if (Current->RefCount < 1)
+ PLDR_DATA_TABLE_ENTRY LdrEntry = CONTAINING_RECORD(ListEntry, LDR_DATA_TABLE_ENTRY, InInitializationOrderLinks);
+ HANDLE FileHandle;
+ OBJECT_ATTRIBUTES Attrib;
+ IO_STATUS_BLOCK Iosb;
+ InitializeObjectAttributes(&Attrib, &LdrEntry->FullDllName, OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, NULL, NULL);
+ DPRINT1("Trying %wZ\n", &LdrEntry->FullDllName);
+ Status = ZwOpenFile(&FileHandle,
+ FILE_READ_ACCESS | SYNCHRONIZE,
+ &Attrib,
+ &Iosb,
+ FILE_SHARE_READ,
+ FILE_SYNCHRONOUS_IO_NONALERT);
+ if (!NT_SUCCESS(Status))
+ {
+ /* Try system paths */
+ static const UNICODE_STRING System32Dir = RTL_CONSTANT_STRING(L"\\SystemRoot\\system32\\");
+ UNICODE_STRING ImagePath;
+ WCHAR ImagePathBuffer[256];
+ RtlInitEmptyUnicodeString(&ImagePath, ImagePathBuffer, sizeof(ImagePathBuffer));
+ RtlCopyUnicodeString(&ImagePath, &System32Dir);
+ RtlAppendUnicodeStringToString(&ImagePath, &LdrEntry->BaseDllName);
+ InitializeObjectAttributes(&Attrib, &ImagePath, OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, NULL, NULL);
+ DPRINT1("Trying %wZ\n", &ImagePath);
+ Status = ZwOpenFile(&FileHandle,
+ FILE_READ_ACCESS | SYNCHRONIZE,
+ &Attrib,
+ &Iosb,
+ FILE_SHARE_READ,
+ FILE_SYNCHRONOUS_IO_NONALERT);
+ if (!NT_SUCCESS(Status))
+ {
+ static const UNICODE_STRING DriversDir= RTL_CONSTANT_STRING(L"\\SystemRoot\\system32\\drivers\\");
+
+ RtlInitEmptyUnicodeString(&ImagePath, ImagePathBuffer, sizeof(ImagePathBuffer));
+ RtlCopyUnicodeString(&ImagePath, &DriversDir);
+ RtlAppendUnicodeStringToString(&ImagePath, &LdrEntry->BaseDllName);
+ InitializeObjectAttributes(&Attrib, &ImagePath, OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, NULL, NULL);
+ DPRINT1("Trying %wZ\n", &ImagePath);
+ Status = ZwOpenFile(&FileHandle,
+ FILE_READ_ACCESS | SYNCHRONIZE,
+ &Attrib,
+ &Iosb,
+ FILE_SHARE_READ,
+ FILE_SYNCHRONOUS_IO_NONALERT);
+ }
+ }
+
+ if (!NT_SUCCESS(Status))
{
- RemoveEntryList(&Current->ListEntry);
- RosSymDelete(Current->RosSymInfo);
- ExFreePool(Current);
+ DPRINT1("Failed opening file %wZ (%wZ) for reading symbols (0x%08x)\n", &LdrEntry->FullDllName, &LdrEntry->BaseDllName, Status);
+ /* We took a ref previously */
+ MmUnloadSystemImage(LdrEntry);
+ continue;
}
- KeReleaseSpinLock(&SymbolFileListLock, Irql);
- return;
- }
+ /* Hand it to Rossym */
+ if (!RosSymCreateFromFile(&FileHandle, (PROSSYM_INFO*)&LdrEntry->PatchInformation))
+ LdrEntry->PatchInformation = NULL;
- CurrentEntry = CurrentEntry->Flink;
+ /* We're done for this one. */
+ NtClose(FileHandle);
+ MmUnloadSystemImage(LdrEntry);
+ }
}
-
- KeReleaseSpinLock(&SymbolFileListLock, Irql);
- DPRINT1("Warning: Removing unknown symbol file: RosSymInfo = %p\n", RosSymInfo);
}
-/*! \brief Loads a symbol file.
- *
- * \param FileName Filename of the symbol file to load.
- * \param RosSymInfo Pointer to a ROSSYM_INFO which gets filled.
+/*! \brief Load symbols from image mapping. If this fails,
*
- * \sa KdbpSymUnloadModuleSymbols
+ * \param LdrEntry The entry to load symbols from
*/
-static VOID
-KdbpSymLoadModuleSymbols(
- IN PUNICODE_STRING FileName,
- OUT PROSSYM_INFO *RosSymInfo)
+VOID
+KdbSymProcessSymbols(
+ _Inout_ PLDR_DATA_TABLE_ENTRY LdrEntry,
+ _In_ BOOLEAN Load)
{
- OBJECT_ATTRIBUTES ObjectAttributes;
- HANDLE FileHandle;
- NTSTATUS Status;
- IO_STATUS_BLOCK IoStatusBlock;
-
- /* Allow KDB to break on module load */
- KdbModuleLoaded(FileName);
-
if (!LoadSymbols)
- {
- *RosSymInfo = NULL;
return;
- }
- /* Try to find cached (already loaded) symbol file */
- *RosSymInfo = KdbpSymFindCachedFile(FileName);
- if (*RosSymInfo)
+ /* Check if this is unload */
+ if (!Load)
{
- DPRINT("Found cached symbol file %wZ\n", FileName);
- return;
- }
-
- /* Open the file */
- InitializeObjectAttributes(&ObjectAttributes,
- FileName,
- 0,
- NULL,
- NULL);
-
- DPRINT("Attempting to open image: %wZ\n", FileName);
-
- Status = ZwOpenFile(&FileHandle,
- FILE_READ_ACCESS | SYNCHRONIZE,
- &ObjectAttributes,
- &IoStatusBlock,
- FILE_SHARE_READ | FILE_SHARE_WRITE,
- FILE_SYNCHRONOUS_IO_NONALERT);
- if (!NT_SUCCESS(Status))
- {
- DPRINT("Could not open image file: %wZ\n", FileName);
- return;
- }
-
- DPRINT("Loading symbols from %wZ...\n", FileName);
-
- if (!RosSymCreateFromFile(&FileHandle, RosSymInfo))
- {
- DPRINT("Failed to load symbols from %wZ\n", FileName);
+ /* Did we process it */
+ if (LdrEntry->PatchInformation)
+ {
+ RosSymDelete(LdrEntry->PatchInformation);
+ LdrEntry->PatchInformation = NULL;
+ }
return;
}
- ZwClose(FileHandle);
-
- DPRINT("Symbols loaded.\n");
-
- /* add file to cache */
- KdbpSymAddCachedFile(FileName, *RosSymInfo);
-
- DPRINT("Installed symbols: %wZ %p\n", FileName, *RosSymInfo);
-}
-
-VOID
-KdbSymProcessSymbols(
- IN PLDR_DATA_TABLE_ENTRY LdrEntry)
-{
- if (!LoadSymbols)
+ if (RosSymCreateFromMem(LdrEntry->DllBase, LdrEntry->SizeOfImage, (PROSSYM_INFO*)&LdrEntry->PatchInformation))
{
- LdrEntry->PatchInformation = NULL;
return;
}
- /* Remove symbol info if it already exists */
- if (LdrEntry->PatchInformation)
- KdbpSymRemoveCachedFile(LdrEntry->PatchInformation);
-
- /* Load new symbol information */
- if (! RosSymCreateFromMem(LdrEntry->DllBase,
- LdrEntry->SizeOfImage,
- (PROSSYM_INFO*)&LdrEntry->PatchInformation))
- {
- /* Error loading symbol info, try to load it from file */
- KdbpSymLoadModuleSymbols(&LdrEntry->FullDllName,
- (PROSSYM_INFO*)&LdrEntry->PatchInformation);
-
- /* It already added symbols to cache */
- }
- else
- {
- /* Add file to cache */
- KdbpSymAddCachedFile(&LdrEntry->FullDllName, LdrEntry->PatchInformation);
- }
-
- DPRINT("Installed symbols: %wZ@%p-%p %p\n",
- &LdrEntry->BaseDllName,
- LdrEntry->DllBase,
- (PVOID)(LdrEntry->SizeOfImage + (ULONG_PTR)LdrEntry->DllBase),
- LdrEntry->PatchInformation);
+ /* Add a ref until we really process it */
+ LdrEntry->LoadCount++;
-}
+ /* Tell our worker thread to read from it */
+ KeAcquireSpinLockAtDpcLevel(&SymbolsToLoadLock);
+ InsertTailList(&SymbolsToLoad, &LdrEntry->InInitializationOrderLinks);
+ KeReleaseSpinLockFromDpcLevel(&SymbolsToLoadLock);
-VOID
-NTAPI
-KdbDebugPrint(
- PCH Message,
- ULONG Length)
-{
- /* Nothing here */
+ KeSetEvent(&SymbolsToLoadEvent, IO_NO_INCREMENT, FALSE);
}
-/*! \brief Initializes the KDB symbols implementation.
+/**
+ * @brief Initializes the KDB symbols implementation.
*
- * \param DispatchTable Pointer to the KD dispatch table
- * \param BootPhase Phase of initialization
- */
-VOID
-NTAPI
-KdbInitialize(
- PKD_DISPATCH_TABLE DispatchTable,
- ULONG BootPhase)
+ * @param[in] BootPhase
+ * Phase of initialization.
+ *
+ * @return
+ * TRUE if symbols are to be loaded at this given BootPhase; FALSE if not.
+ **/
+BOOLEAN
+KdbSymInit(
+ _In_ ULONG BootPhase)
{
- PCHAR p1, p2;
- SHORT Found = FALSE;
- CHAR YesNo;
- PLDR_DATA_TABLE_ENTRY LdrEntry;
+#if 1 // FIXME: This is a workaround HACK!!
+ static BOOLEAN OrigLoadSymbols = FALSE;
+#endif
DPRINT("KdbSymInit() BootPhase=%d\n", BootPhase);
- LoadSymbols = FALSE;
-
-#if DBG
- /* Load symbols only if we have 96Mb of RAM or more */
- if (MmNumberOfPhysicalPages >= 0x6000)
- LoadSymbols = TRUE;
-#endif
-
if (BootPhase == 0)
{
- /* Write out the functions that we support for now */
- DispatchTable->KdpInitRoutine = KdpKdbgInit;
- DispatchTable->KdpPrintRoutine = KdbDebugPrint;
-
- /* Register as a Provider */
- InsertTailList(&KdProviders, &DispatchTable->KdProvidersList);
-
- /* Perform actual initialization of symbol module */
- //NtoskrnlModuleObject->PatchInformation = NULL;
- //LdrHalModuleObject->PatchInformation = NULL;
-
- InitializeListHead(&SymbolFileListHead);
- KeInitializeSpinLock(&SymbolFileListLock);
+ PSTR CommandLine;
+ SHORT Found = FALSE;
+ CHAR YesNo;
+
+ /* By default, load symbols in DBG builds, but not in REL builds
+ or anything other than x86, because they only work on x86
+ and can cause the system to hang on x64. */
+#if DBG && defined(_M_IX86)
+ LoadSymbols = TRUE;
+#else
+ LoadSymbols = FALSE;
+#endif
- /* Check the command line for /LOADSYMBOLS, /NOLOADSYMBOLS,
- * /LOADSYMBOLS={YES|NO}, /NOLOADSYMBOLS={YES|NO} */
+ /* Check the command line for LOADSYMBOLS, NOLOADSYMBOLS,
+ * LOADSYMBOLS={YES|NO}, NOLOADSYMBOLS={YES|NO} */
ASSERT(KeLoaderBlock);
- p1 = KeLoaderBlock->LoadOptions;
- while('\0' != *p1 && NULL != (p2 = strchr(p1, '/')))
+ CommandLine = KeLoaderBlock->LoadOptions;
+ while (*CommandLine)
{
- p2++;
+ /* Skip any whitespace */
+ while (isspace(*CommandLine))
+ ++CommandLine;
+
Found = 0;
- if (0 == _strnicmp(p2, "LOADSYMBOLS", 11))
+ if (_strnicmp(CommandLine, "LOADSYMBOLS", 11) == 0)
{
Found = +1;
- p2 += 11;
+ CommandLine += 11;
}
- else if (0 == _strnicmp(p2, "NOLOADSYMBOLS", 13))
+ else if (_strnicmp(CommandLine, "NOLOADSYMBOLS", 13) == 0)
{
Found = -1;
- p2 += 13;
+ CommandLine += 13;
}
- if (0 != Found)
+ if (Found != 0)
{
- while (isspace(*p2))
- {
- p2++;
- }
- if ('=' == *p2)
+ if (*CommandLine == '=')
{
- p2++;
- while (isspace(*p2))
- {
- p2++;
- }
- YesNo = toupper(*p2);
- if ('N' == YesNo || 'F' == YesNo || '0' == YesNo)
+ ++CommandLine;
+ YesNo = toupper(*CommandLine);
+ if (YesNo == 'N' || YesNo == '0')
{
Found = -1 * Found;
}
}
LoadSymbols = (0 < Found);
}
- p1 = p2;
+
+ /* Move on to the next option */
+ while (*CommandLine && !isspace(*CommandLine))
+ ++CommandLine;
}
- RosSymInitKernelMode();
+#if 1 // FIXME: This is a workaround HACK!!
+// Save the actual value of LoadSymbols but disable it for BootPhase 0.
+ OrigLoadSymbols = LoadSymbols;
+ LoadSymbols = FALSE;
+ return OrigLoadSymbols;
+#endif
}
else if (BootPhase == 1)
{
- /* Load symbols for NTOSKRNL.EXE.
- It is always the first module in PsLoadedModuleList. KeLoaderBlock can't be used here as its content is just temporary. */
- LdrEntry = CONTAINING_RECORD(PsLoadedModuleList.Flink, LDR_DATA_TABLE_ENTRY, InLoadOrderLinks);
- KdbSymProcessSymbols(LdrEntry);
+ HANDLE Thread;
+ NTSTATUS Status;
+ KIRQL OldIrql;
+ PLIST_ENTRY ListEntry;
+
+#if 1 // FIXME: This is a workaround HACK!!
+// Now, restore the actual value of LoadSymbols.
+ LoadSymbols = OrigLoadSymbols;
+#endif
+
+ /* Do not continue loading symbols if we have less than 96MB of RAM */
+ if (MmNumberOfPhysicalPages < (96 * 1024 * 1024 / PAGE_SIZE))
+ LoadSymbols = FALSE;
+
+ /* Continue this phase only if we need to load symbols */
+ if (!LoadSymbols)
+ return LoadSymbols;
+
+ /* Launch our worker thread */
+ InitializeListHead(&SymbolsToLoad);
+ KeInitializeSpinLock(&SymbolsToLoadLock);
+ KeInitializeEvent(&SymbolsToLoadEvent, SynchronizationEvent, FALSE);
+
+ Status = PsCreateSystemThread(&Thread,
+ THREAD_ALL_ACCESS,
+ NULL, NULL, NULL,
+ LoadSymbolsRoutine,
+ NULL);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("Failed starting symbols loader thread: 0x%08x\n", Status);
+ LoadSymbols = FALSE;
+ return LoadSymbols;
+ }
+
+ RosSymInitKernelMode();
- /* Also load them for HAL.DLL. */
- LdrEntry = CONTAINING_RECORD(PsLoadedModuleList.Flink->Flink, LDR_DATA_TABLE_ENTRY, InLoadOrderLinks);
- KdbSymProcessSymbols(LdrEntry);
+ KeAcquireSpinLock(&PsLoadedModuleSpinLock, &OldIrql);
- KdbpSymbolsInitialized = TRUE;
+ for (ListEntry = PsLoadedModuleList.Flink;
+ ListEntry != &PsLoadedModuleList;
+ ListEntry = ListEntry->Flink)
+ {
+ PLDR_DATA_TABLE_ENTRY LdrEntry = CONTAINING_RECORD(ListEntry, LDR_DATA_TABLE_ENTRY, InLoadOrderLinks);
+ KdbSymProcessSymbols(LdrEntry, TRUE);
+ }
+
+ KeReleaseSpinLock(&PsLoadedModuleSpinLock, OldIrql);
}
+
+ return LoadSymbols;
}
/* EOF */