diff --git a/reactos/ntoskrnl/include/internal/kd.h b/reactos/ntoskrnl/include/internal/kd.h index d5c450a190f..26d4a334d05 100644 --- a/reactos/ntoskrnl/include/internal/kd.h +++ b/reactos/ntoskrnl/include/internal/kd.h @@ -89,7 +89,7 @@ KdbSymProcessBootSymbols(IN PANSI_STRING AnsiFileName, IN BOOLEAN LoadFromFile); VOID -KdbSymProcessSymbols(IN PANSI_STRING FileName); +KdbSymProcessSymbols(IN PANSI_STRING FileName, IN PKD_SYMBOLS_INFO SymbolInfo); BOOLEAN KdbSymPrintAddress(IN PVOID Address); @@ -119,12 +119,12 @@ typedef struct _KDB_MODULE_INFO # define KDB_LOADUSERMODULE_HOOK(LDRMOD) KdbSymLoadUserModuleSymbols(LDRMOD) # define KDB_LOADDRIVER_HOOK(FILENAME, MODULE) KdbSymLoadDriverSymbols(FILENAME, MODULE) # define KDB_UNLOADDRIVER_HOOK(MODULE) KdbSymUnloadDriverSymbols(MODULE) -# define KDB_SYMBOLFILE_HOOK(FILENAME) KdbSymProcessSymbols(FILENAME) +# define KDB_SYMBOLFILE_HOOK(FILENAME, SYMBOLINFO) KdbSymProcessSymbols((FILENAME), (SYMBOLINFO)) #else # define KDB_LOADUSERMODULE_HOOK(LDRMOD) do { } while (0) # define KDB_LOADDRIVER_HOOK(FILENAME, MODULE) do { } while (0) # define KDB_UNLOADDRIVER_HOOK(MODULE) do { } while (0) -# define KDB_SYMBOLFILE_HOOK(FILENAME) do { } while (0) +# define KDB_SYMBOLFILE_HOOK(FILENAME, SYMBOLINFO) do { } while (0) # define KDB_CREATE_THREAD_HOOK(CONTEXT) do { } while (0) #endif diff --git a/reactos/ntoskrnl/kd/kdmain.c b/reactos/ntoskrnl/kd/kdmain.c index 08be860ae2d..3310d94e85f 100644 --- a/reactos/ntoskrnl/kd/kdmain.c +++ b/reactos/ntoskrnl/kd/kdmain.c @@ -131,7 +131,8 @@ KdpEnterDebuggerException(IN PKTRAP_FRAME TrapFrame, else if (ExceptionCommand == BREAKPOINT_LOAD_SYMBOLS) { /* Load symbols. Currently implemented only for KDBG! */ - KDB_SYMBOLFILE_HOOK((PANSI_STRING)ExceptionRecord->ExceptionInformation[1]); + KDB_SYMBOLFILE_HOOK((PANSI_STRING)ExceptionRecord->ExceptionInformation[1], + (PKD_SYMBOLS_INFO)ExceptionRecord->ExceptionInformation[2]); } /* This we can handle: simply bump EIP */ diff --git a/reactos/ntoskrnl/kdbg/kdb_symbols.c b/reactos/ntoskrnl/kdbg/kdb_symbols.c index 032dbc67bb0..0d567d7adb9 100644 --- a/reactos/ntoskrnl/kdbg/kdb_symbols.c +++ b/reactos/ntoskrnl/kdbg/kdb_symbols.c @@ -578,50 +578,77 @@ KdbSymUnloadDriverSymbols(IN PLDR_DATA_TABLE_ENTRY ModuleObject) } VOID -KdbSymProcessSymbols(IN PANSI_STRING AnsiFileName) +KdbSymProcessSymbols(IN PANSI_STRING AnsiFileName, IN PKD_SYMBOLS_INFO SymbolInfo) { - ANSI_STRING SystemPrefix, RealPathPrefix, ProperName; - CHAR Buffer[MAX_PATH], RealPathBuffer[MAX_PATH]; + BOOLEAN Found = FALSE; + PLIST_ENTRY ListHead, NextEntry; + PLDR_DATA_TABLE_ENTRY LdrEntry = NULL; - /* Init our strings for compare operations */ - RtlInitAnsiString(&SystemPrefix, "\\SystemRoot"); + //DPRINT("KdbSymProcessSymbols(%Z)\n", AnsiFileName); - /* Convert system root to ansi */ - sprintf(RealPathBuffer, "%S", (PWCHAR)&SharedUserData->NtSystemRoot[2]); - RtlInitAnsiString(&RealPathPrefix, RealPathBuffer); - RealPathPrefix.MaximumLength = MAX_PATH; + /* We use PsLoadedModuleList here, otherwise (in case of + using KeLoaderBlock) all our data will be just lost */ + ListHead = &PsLoadedModuleList; - /* There are 3 cases: - 1) \SystemRoot\System32\ -> no change - 2) \ReactOS\System32 -> \SystemRoot\System32 - 3) module.dll -> \??\C:\ReactOS\system32\module.dll - */ - if (RtlPrefixString(&SystemPrefix, AnsiFileName, FALSE)) + /* Found module we are interested in */ + NextEntry = ListHead->Flink; + while (ListHead != NextEntry) { - /* Case: \SystemRoot\System32\ , just directly load it */ - KdbSymProcessBootSymbols(AnsiFileName, TRUE, FALSE); + /* Get the entry */ + LdrEntry = CONTAINING_RECORD(NextEntry, + LDR_DATA_TABLE_ENTRY, + InLoadOrderLinks); + + if (SymbolInfo->BaseOfDll == LdrEntry->DllBase) + { + Found = TRUE; + break; + } + + /* Go to the next one */ + NextEntry = NextEntry->Flink; } - else if (RtlPrefixString(&RealPathPrefix, AnsiFileName, FALSE)) + + /* Exit if we didn't find the module requested */ + if (!Found) + return; + + DPRINT("Found LdrEntry=%p\n", LdrEntry); + if (!LoadSymbols) { - /* It's prefixed with a real path, instead of a \SystemRoot. - So build a new, proper name. */ - RtlZeroMemory(Buffer, MAX_PATH); - strcpy(Buffer, "\\SystemRoot"); - strncat(Buffer, - AnsiFileName->Buffer + RealPathPrefix.Length, - AnsiFileName->Length - RealPathPrefix.Length); + LdrEntry->PatchInformation = NULL; + return; + } - /* Convert it to ANSI_STRING */ - RtlInitAnsiString(&ProperName, Buffer); + /* Remove symbol info if it already exists */ + if (LdrEntry->PatchInformation != NULL) + { + KdbpSymRemoveCachedFile(LdrEntry->PatchInformation); + } - /* Process symbols */ - KdbSymProcessBootSymbols(&ProperName, TRUE, TRUE); + /* 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 { - /* Just a bare filename, nothing else. Why? Who knows... */ - KdbSymProcessBootSymbols(AnsiFileName, FALSE, TRUE); + /* Add file to cache */ + KdbpSymAddCachedFile(&LdrEntry->FullDllName, LdrEntry->PatchInformation); } + + DPRINT("Installed symbols: %wZ@%08x-%08x %p\n", + &LdrEntry->BaseDllName, + LdrEntry->DllBase, + LdrEntry->SizeOfImage + (ULONG)LdrEntry->DllBase, + LdrEntry->PatchInformation); + }