diff --git a/ntoskrnl/include/internal/kd64.h b/ntoskrnl/include/internal/kd64.h index 4802c9c9f60..7e992e0b4ec 100644 --- a/ntoskrnl/include/internal/kd64.h +++ b/ntoskrnl/include/internal/kd64.h @@ -514,6 +514,11 @@ KdpDprintf( ... ); +BOOLEAN +NTAPI +KdpPrintString( + _In_ PSTRING Output); + // // Global KD Data // diff --git a/ntoskrnl/kd/kdio.c b/ntoskrnl/kd/kdio.c index 3dabd050d26..275971acd92 100644 --- a/ntoskrnl/kd/kdio.c +++ b/ntoskrnl/kd/kdio.c @@ -580,13 +580,10 @@ KdSendPacket( { #ifdef KDBG PLDR_DATA_TABLE_ENTRY LdrEntry; - if (!WaitStateChange->u.LoadSymbols.UnloadSymbols) + /* Load symbols. Currently implemented only for KDBG! */ + if (KdbpSymFindModule((PVOID)(ULONG_PTR)WaitStateChange->u.LoadSymbols.BaseOfDll, -1, &LdrEntry)) { - /* Load symbols. Currently implemented only for KDBG! */ - if (KdbpSymFindModule((PVOID)(ULONG_PTR)WaitStateChange->u.LoadSymbols.BaseOfDll, NULL, -1, &LdrEntry)) - { - KdbSymProcessSymbols(LdrEntry); - } + KdbSymProcessSymbols(LdrEntry, !WaitStateChange->u.LoadSymbols.UnloadSymbols); } #endif return; diff --git a/ntoskrnl/kd64/kdprint.c b/ntoskrnl/kd64/kdprint.c index a086652ddb3..83e2e2f3840 100644 --- a/ntoskrnl/kd64/kdprint.c +++ b/ntoskrnl/kd64/kdprint.c @@ -445,7 +445,7 @@ KdpDprintf( STRING String; USHORT Length; va_list ap; - CHAR Buffer[100]; + CHAR Buffer[512]; /* Format the string */ va_start(ap, Format); diff --git a/ntoskrnl/kd64/kdtrap.c b/ntoskrnl/kd64/kdtrap.c index b8314a94685..ed13f3f1971 100644 --- a/ntoskrnl/kd64/kdtrap.c +++ b/ntoskrnl/kd64/kdtrap.c @@ -144,10 +144,11 @@ KdpTrap(IN PKTRAP_FRAME TrapFrame, BOOLEAN Handled; NTSTATUS ReturnStatus; USHORT ReturnLength; - KIRQL OldIrql; + KIRQL OldIrql = DISPATCH_LEVEL; - /* Raise as high as we can. */ - KeRaiseIrql(HIGH_LEVEL, &OldIrql); + /* Raise if we have to. */ + if (KeGetCurrentIrql() < DISPATCH_LEVEL) + OldIrql = KeRaiseIrqlToDpcLevel(); /* * Check if we got a STATUS_BREAKPOINT with a SubID for Print, Prompt or @@ -261,7 +262,8 @@ KdpTrap(IN PKTRAP_FRAME TrapFrame, SecondChanceException); } - KeLowerIrql(OldIrql); + if (OldIrql < DISPATCH_LEVEL) + KeLowerIrql(OldIrql); /* Return TRUE or FALSE to caller */ return Handled; diff --git a/ntoskrnl/kdbg/kdb.c b/ntoskrnl/kdbg/kdb.c index 8ec2e3bef1d..df1da7da3d2 100644 --- a/ntoskrnl/kdbg/kdb.c +++ b/ntoskrnl/kdbg/kdb.c @@ -1531,10 +1531,10 @@ KdbEnterDebuggerException( OldEflags = __readeflags(); _disable(); - /* HACK: Save the current IRQL and pretend we are at passive level, - * although interrupts are off. Needed because KDBG calls pageable code. */ + /* HACK: Save the current IRQL and pretend we are at dispatch level */ OldIrql = KeGetCurrentIrql(); - KeLowerIrql(PASSIVE_LEVEL); + if (OldIrql > DISPATCH_LEVEL) + KeLowerIrql(DISPATCH_LEVEL); /* Exception inside the debugger? Game over. */ if (InterlockedIncrement(&KdbEntryCount) > 1) @@ -1579,7 +1579,8 @@ KdbEnterDebuggerException( InterlockedDecrement(&KdbEntryCount); /* HACK: Raise back to old IRQL */ - KeRaiseIrql(OldIrql, &OldIrql); + if (OldIrql > DISPATCH_LEVEL) + KeRaiseIrql(OldIrql, &OldIrql); /* Leave critical section */ __writeeflags(OldEflags); diff --git a/ntoskrnl/kdbg/kdb.h b/ntoskrnl/kdbg/kdb.h index a496cc4a7b5..3ccd6fc49e0 100644 --- a/ntoskrnl/kdbg/kdb.h +++ b/ntoskrnl/kdbg/kdb.h @@ -148,7 +148,6 @@ KdbpRpnEvaluateParsedExpression( BOOLEAN KdbpSymFindModule( IN PVOID Address OPTIONAL, - IN LPCWSTR Name OPTIONAL, IN INT Index OPTIONAL, OUT PLDR_DATA_TABLE_ENTRY* pLdrEntry); @@ -160,7 +159,8 @@ KdbSymPrintAddress( VOID KdbSymProcessSymbols( - IN PLDR_DATA_TABLE_ENTRY LdrEntry); + _Inout_ PLDR_DATA_TABLE_ENTRY LdrEntry, + _In_ BOOLEAN Load); /* from kdb.c */ diff --git a/ntoskrnl/kdbg/kdb_cli.c b/ntoskrnl/kdbg/kdb_cli.c index 228bebffd4d..6c903f93695 100644 --- a/ntoskrnl/kdbg/kdb_cli.c +++ b/ntoskrnl/kdbg/kdb_cli.c @@ -1977,7 +1977,7 @@ KdbpCmdMod( Address = (ULONG_PTR)Result; - if (!KdbpSymFindModule((PVOID)Address, NULL, -1, &LdrEntry)) + if (!KdbpSymFindModule((PVOID)Address, -1, &LdrEntry)) { KdbpPrint("No module containing address 0x%p found!\n", Address); return TRUE; @@ -1987,7 +1987,7 @@ KdbpCmdMod( } else { - if (!KdbpSymFindModule(NULL, NULL, 0, &LdrEntry)) + if (!KdbpSymFindModule(NULL, 0, &LdrEntry)) { ULONG_PTR ntoskrnlBase = ((ULONG_PTR)KdbpCmdMod) & 0xfff00000; KdbpPrint(" Base Size Name\n"); @@ -2003,7 +2003,7 @@ KdbpCmdMod( { KdbpPrint(" %08x %08x %wZ\n", LdrEntry->DllBase, LdrEntry->SizeOfImage, &LdrEntry->BaseDllName); - if(DisplayOnlyOneModule || !KdbpSymFindModule(NULL, NULL, i++, &LdrEntry)) + if(DisplayOnlyOneModule || !KdbpSymFindModule(NULL, i++, &LdrEntry)) break; } diff --git a/ntoskrnl/kdbg/kdb_symbols.c b/ntoskrnl/kdbg/kdb_symbols.c index a066e39d8b7..997b55e5516 100644 --- a/ntoskrnl/kdbg/kdb_symbols.c +++ b/ntoskrnl/kdbg/kdb_symbols.c @@ -27,27 +27,19 @@ 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 LIST_ENTRY SymbolsToLoad; +static KSPIN_LOCK SymbolsToLoadLock; +static KEVENT SymbolsToLoadEvent; /* FUNCTIONS ****************************************************************/ -static NTSTATUS -KdbSymGetAddressInformation( - IN PROSSYM_INFO RosSymInfo, - IN ULONG_PTR RelativeAddress, - OUT PULONG LineNumber OPTIONAL, - OUT PCH FileName OPTIONAL, - OUT PCH FunctionName OPTIONAL); - -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) { @@ -56,7 +48,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; @@ -83,7 +74,6 @@ KdbpSymSearchModuleList( BOOLEAN KdbpSymFindModule( IN PVOID Address OPTIONAL, - IN LPCWSTR Name OPTIONAL, IN INT Index OPTIONAL, OUT PLDR_DATA_TABLE_ENTRY* pLdrEntry) { @@ -91,16 +81,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(); @@ -112,11 +104,11 @@ KdbpSymFindModule( &CurrentProcess->Peb->Ldr->InLoadOrderModuleList, &Count, Address, - Name, Index, pLdrEntry); } +static PCHAR NTAPI KdbpSymUnicodeToAnsi(IN PUNICODE_STRING Unicode, @@ -159,233 +151,183 @@ KdbSymPrintAddress( { 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)) + + KdbpSymUnicodeToAnsi(&LdrEntry->BaseDllName, + ModuleNameAnsi, + sizeof(ModuleNameAnsi)); + + if (LdrEntry->PatchInformation) { - KdpDprintf("<%s:%x (%s:%d (%s))>", - ModuleNameAnsi, RelativeAddress, FileName, LineNumber, FunctionName); + ULONG LineNumber; + CHAR FileName[256]; + CHAR FunctionName[256]; + + if (RosSymGetAddressInformation(LdrEntry->PatchInformation, RelativeAddress, &LineNumber, FileName, FunctionName)) + { + STRING str; + /* Use KdpPrintString because KdpDprintf is limited wrt string size */ + KdpDprintf("<%s:%x (", ModuleNameAnsi, RelativeAddress); + str.Buffer = FileName; + str.Length = strnlen(FileName, sizeof(FileName)); + str.MaximumLength = sizeof(FileName); + KdpPrintString(&str); + KdpDprintf(":%d (%s))>", LineNumber, FunctionName); + + Printed = TRUE; + } } - else + + if (!Printed) { + /* Just print module & address */ KdpDprintf("<%s:%x>", ModuleNameAnsi, RelativeAddress); } return TRUE; } - -/*! \brief Get information for an address (source file, line number, - * function name) +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 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) + * \note We must do this because KdbSymProcessSymbols is + * called at high IRQL and we can't set the event from here * - * \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. + * \param Context Unused */ -static NTSTATUS -KdbSymGetAddressInformation( - IN PROSSYM_INFO RosSymInfo, - IN ULONG_PTR RelativeAddress, - OUT PULONG LineNumber OPTIONAL, - OUT PCH FileName OPTIONAL, - OUT PCH FunctionName OPTIONAL) +_Use_decl_annotations_ +VOID +NTAPI +LoadSymbolsRoutine( + _In_ PVOID Context) { - if (!KdbpSymbolsInitialized || - !RosSymInfo || - !RosSymGetAddressInformation(RosSymInfo, RelativeAddress, LineNumber, FileName, FunctionName)) + UNREFERENCED_PARAMETER(Context); + + while (TRUE) { - 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; - - DPRINT("Looking for cached symbol file %wZ\n", FileName); - - KeAcquireSpinLockAtDpcLevel(&SymbolFileListLock); - - CurrentEntry = SymbolFileListHead.Flink; - while (CurrentEntry != (&SymbolFileListHead)) - { - 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)) + PLIST_ENTRY ListEntry; + NTSTATUS Status = KeWaitForSingleObject(&SymbolsToLoadEvent, WrKernel, KernelMode, FALSE, NULL); + if (!NT_SUCCESS(Status)) { - Current->RefCount++; - KeReleaseSpinLockFromDpcLevel(&SymbolFileListLock); - DPRINT("Found cached file!\n"); - return Current->RosSymInfo; - } - - CurrentEntry = CurrentEntry->Flink; - } - - KeReleaseSpinLockFromDpcLevel(&SymbolFileListLock); - - DPRINT("Cached file not found!\n"); - return NULL; -} - -/*! \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); -} - -/*! \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. - * - * \param RosSymInfo Pointer to the symbol info. - * - * \sa KdbpSymAddCachedFile - */ -static VOID -KdbpSymRemoveCachedFile( - IN PROSSYM_INFO RosSymInfo) -{ - PIMAGE_SYMBOL_INFO_CACHE Current; - PLIST_ENTRY CurrentEntry; - KIRQL Irql; - - KeAcquireSpinLock(&SymbolFileListLock, &Irql); - - CurrentEntry = SymbolFileListHead.Flink; - while (CurrentEntry != (&SymbolFileListHead)) - { - Current = CONTAINING_RECORD(CurrentEntry, IMAGE_SYMBOL_INFO_CACHE, ListEntry); - - if (Current->RosSymInfo == RosSymInfo) /* found */ - { - ASSERT(Current->RefCount > 0); - Current->RefCount--; - if (Current->RefCount < 1) - { - RemoveEntryList(&Current->ListEntry); - RosSymDelete(Current->RosSymInfo); - ExFreePool(Current); - } - - KeReleaseSpinLock(&SymbolFileListLock, Irql); + DPRINT1("KeWaitForSingleObject failed?! 0x%08x\n", Status); + LoadSymbols = FALSE; return; } - CurrentEntry = CurrentEntry->Flink; - } + while ((ListEntry = ExInterlockedRemoveHeadList(&SymbolsToLoad, &SymbolsToLoadLock))) + { + 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\\"); - KeReleaseSpinLock(&SymbolFileListLock, Irql); - DPRINT1("Warning: Removing unknown symbol file: RosSymInfo = %p\n", RosSymInfo); + 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)) + { + 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; + } + + /* Hand it to Rossym */ + if (!RosSymCreateFromFile(&FileHandle, (PROSSYM_INFO*)&LdrEntry->PatchInformation)) + LdrEntry->PatchInformation = NULL; + + /* We're done for this one. */ + NtClose(FileHandle); + MmUnloadSystemImage(LdrEntry); + } + } } +/*! \brief Load symbols from image mapping. If this fails, + * + * \param LdrEntry The entry to load symbols from + */ VOID KdbSymProcessSymbols( - IN PLDR_DATA_TABLE_ENTRY LdrEntry) + _Inout_ PLDR_DATA_TABLE_ENTRY LdrEntry, + _In_ BOOLEAN Load) { if (!LoadSymbols) + return; + + /* Check if this is unload */ + if (!Load) { - LdrEntry->PatchInformation = NULL; + /* Did we process it */ + if (LdrEntry->PatchInformation) + { + RosSymDelete(LdrEntry->PatchInformation); + LdrEntry->PatchInformation = NULL; + } return; } - /* Remove symbol info if it already exists */ - if (LdrEntry->PatchInformation) - KdbpSymRemoveCachedFile(LdrEntry->PatchInformation); - - /* Check cache */ - LdrEntry->PatchInformation = KdbpSymFindCachedFile(&LdrEntry->FullDllName); - - if (!LdrEntry->PatchInformation) + if (RosSymCreateFromMem(LdrEntry->DllBase, LdrEntry->SizeOfImage, (PROSSYM_INFO*)&LdrEntry->PatchInformation)) { - /* Load new symbol information */ - if (RosSymCreateFromMem(LdrEntry->DllBase, LdrEntry->SizeOfImage, (PROSSYM_INFO*)&LdrEntry->PatchInformation)) - { - /* Add file to cache */ - KdbpSymAddCachedFile(&LdrEntry->FullDllName, LdrEntry->PatchInformation); - } + return; } - 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); + + KeSetEvent(&SymbolsToLoadEvent, IO_NO_INCREMENT, FALSE); } VOID @@ -412,7 +354,6 @@ KdbInitialize( PCHAR p1, p2; SHORT Found = FALSE; CHAR YesNo; - PLDR_DATA_TABLE_ENTRY LdrEntry; DPRINT("KdbSymInit() BootPhase=%d\n", BootPhase); @@ -437,9 +378,6 @@ KdbInitialize( //NtoskrnlModuleObject->PatchInformation = NULL; //LdrHalModuleObject->PatchInformation = NULL; - InitializeListHead(&SymbolFileListHead); - KeInitializeSpinLock(&SymbolFileListLock); - /* Check the command line for /LOADSYMBOLS, /NOLOADSYMBOLS, * /LOADSYMBOLS={YES|NO}, /NOLOADSYMBOLS={YES|NO} */ ASSERT(KeLoaderBlock); @@ -481,24 +419,39 @@ KdbInitialize( } p1 = p2; } + } + else if ((BootPhase == 1) && LoadSymbols) + { + HANDLE Thread; + NTSTATUS Status; + KIRQL OldIrql; + + /* 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; + } RosSymInitKernelMode(); - } - else if (BootPhase == 1) - { - KIRQL OldIrql; - /* 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. */ - OldIrql = KeRaiseIrqlToDpcLevel(); - LdrEntry = CONTAINING_RECORD(PsLoadedModuleList.Flink, LDR_DATA_TABLE_ENTRY, InLoadOrderLinks); - KdbSymProcessSymbols(LdrEntry); - /* Also load them for HAL.DLL. */ - LdrEntry = CONTAINING_RECORD(PsLoadedModuleList.Flink->Flink, LDR_DATA_TABLE_ENTRY, InLoadOrderLinks); - KdbSymProcessSymbols(LdrEntry); - KeLowerIrql(OldIrql); + KeAcquireSpinLock(&PsLoadedModuleSpinLock, &OldIrql); - KdbpSymbolsInitialized = TRUE; + PLIST_ENTRY ListEntry = PsLoadedModuleList.Flink; + while (ListEntry != &PsLoadedModuleList) + { + PLDR_DATA_TABLE_ENTRY LdrEntry = CONTAINING_RECORD(ListEntry, LDR_DATA_TABLE_ENTRY, InLoadOrderLinks); + KdbSymProcessSymbols(LdrEntry, TRUE); + ListEntry = ListEntry->Flink; + } + + KeReleaseSpinLock(&PsLoadedModuleSpinLock, OldIrql); } } diff --git a/sdk/include/reactos/rossym.h b/sdk/include/reactos/rossym.h index 91a7b9b0f02..e5e9e124a11 100644 --- a/sdk/include/reactos/rossym.h +++ b/sdk/include/reactos/rossym.h @@ -119,7 +119,12 @@ typedef struct _ROSSYM_OWN_FILECONTEXT { struct Dwarf; typedef struct Dwarf *PROSSYM_INFO; #else -typedef struct _ROSSYM_INFO *PROSSYM_INFO; +typedef struct _ROSSYM_INFO { + PROSSYM_ENTRY Symbols; + ULONG SymbolsCount; + PCHAR Strings; + ULONG StringsLength; +} ROSSYM_INFO, *PROSSYM_INFO; #endif VOID RosSymInit(PROSSYM_CALLBACKS Callbacks); diff --git a/sdk/lib/rossym/rossympriv.h b/sdk/lib/rossym/rossympriv.h index cc3f8ff2ff9..fb97019710a 100644 --- a/sdk/lib/rossym/rossympriv.h +++ b/sdk/lib/rossym/rossympriv.h @@ -9,13 +9,6 @@ #pragma once -typedef struct _ROSSYM_INFO { - PROSSYM_ENTRY Symbols; - ULONG SymbolsCount; - PCHAR Strings; - ULONG StringsLength; -} ROSSYM_INFO; - extern ROSSYM_CALLBACKS RosSymCallbacks; #define RosSymAllocMem(Size) (*RosSymCallbacks.AllocMemProc)(Size)