X-Git-Url: https://git.reactos.org/?p=reactos.git;a=blobdiff_plain;f=ntoskrnl%2Fkdbg%2Fkdb_symbols.c;h=1b2d8f695c829675c96dab64809e2e7b14056770;hp=feb0fb1de731a9482a3249712faa7004ab7ca3a0;hb=HEAD;hpb=bf136052c03c99980cc89269f5934c9922f10532 diff --git a/ntoskrnl/kdbg/kdb_symbols.c b/ntoskrnl/kdbg/kdb_symbols.c index feb0fb1de73..11ccd572219 100644 --- a/ntoskrnl/kdbg/kdb_symbols.c +++ b/ntoskrnl/kdbg/kdb_symbols.c @@ -1,7 +1,7 @@ /* * 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) @@ -11,9 +11,10 @@ /* INCLUDES *****************************************************************/ #include +#include "kdb.h" #define NDEBUG -#include +#include "debug.h" /* GLOBALS ******************************************************************/ @@ -26,20 +27,20 @@ typedef struct _IMAGE_SYMBOL_INFO_CACHE } 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) { @@ -48,7 +49,6 @@ KdbpSymSearchModuleList( *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; @@ -75,7 +75,6 @@ KdbpSymSearchModuleList( BOOLEAN KdbpSymFindModule( IN PVOID Address OPTIONAL, - IN LPCWSTR Name OPTIONAL, IN INT Index OPTIONAL, OUT PLDR_DATA_TABLE_ENTRY* pLdrEntry) { @@ -83,16 +82,18 @@ KdbpSymFindModule( 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(); @@ -104,11 +105,11 @@ KdbpSymFindModule( &CurrentProcess->Peb->Ldr->InLoadOrderModuleList, &Count, Address, - Name, Index, pLdrEntry); } +static PCHAR NTAPI KdbpSymUnicodeToAnsi(IN PUNICODE_STRING Unicode, @@ -147,427 +148,322 @@ 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 */