- Rewrite KdbSymProcessSymbols to use the KD_SYMBOLS_INFO structure kernel sends us. This removes the need for ugly names operations (maybe buggy!), and presents an elegant solution: just finding the needed module by its base address.

- As a result, ALL modules get their symbols loaded now.
- TODO: Remove KdbSymProcessBootSymbols(), it's used right now to load ntoskrnl and hal symbols during boot process.

svn path=/trunk/; revision=30576
This commit is contained in:
Aleksey Bragin 2007-11-19 11:26:52 +00:00
parent 49fd02d478
commit 735f6dcf69
3 changed files with 63 additions and 35 deletions

View file

@ -89,7 +89,7 @@ KdbSymProcessBootSymbols(IN PANSI_STRING AnsiFileName,
IN BOOLEAN LoadFromFile); IN BOOLEAN LoadFromFile);
VOID VOID
KdbSymProcessSymbols(IN PANSI_STRING FileName); KdbSymProcessSymbols(IN PANSI_STRING FileName, IN PKD_SYMBOLS_INFO SymbolInfo);
BOOLEAN BOOLEAN
KdbSymPrintAddress(IN PVOID Address); KdbSymPrintAddress(IN PVOID Address);
@ -119,12 +119,12 @@ typedef struct _KDB_MODULE_INFO
# define KDB_LOADUSERMODULE_HOOK(LDRMOD) KdbSymLoadUserModuleSymbols(LDRMOD) # define KDB_LOADUSERMODULE_HOOK(LDRMOD) KdbSymLoadUserModuleSymbols(LDRMOD)
# define KDB_LOADDRIVER_HOOK(FILENAME, MODULE) KdbSymLoadDriverSymbols(FILENAME, MODULE) # define KDB_LOADDRIVER_HOOK(FILENAME, MODULE) KdbSymLoadDriverSymbols(FILENAME, MODULE)
# define KDB_UNLOADDRIVER_HOOK(MODULE) KdbSymUnloadDriverSymbols(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 #else
# define KDB_LOADUSERMODULE_HOOK(LDRMOD) do { } while (0) # define KDB_LOADUSERMODULE_HOOK(LDRMOD) do { } while (0)
# define KDB_LOADDRIVER_HOOK(FILENAME, MODULE) do { } while (0) # define KDB_LOADDRIVER_HOOK(FILENAME, MODULE) do { } while (0)
# define KDB_UNLOADDRIVER_HOOK(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) # define KDB_CREATE_THREAD_HOOK(CONTEXT) do { } while (0)
#endif #endif

View file

@ -131,7 +131,8 @@ KdpEnterDebuggerException(IN PKTRAP_FRAME TrapFrame,
else if (ExceptionCommand == BREAKPOINT_LOAD_SYMBOLS) else if (ExceptionCommand == BREAKPOINT_LOAD_SYMBOLS)
{ {
/* Load symbols. Currently implemented only for KDBG! */ /* 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 */ /* This we can handle: simply bump EIP */

View file

@ -578,50 +578,77 @@ KdbSymUnloadDriverSymbols(IN PLDR_DATA_TABLE_ENTRY ModuleObject)
} }
VOID VOID
KdbSymProcessSymbols(IN PANSI_STRING AnsiFileName) KdbSymProcessSymbols(IN PANSI_STRING AnsiFileName, IN PKD_SYMBOLS_INFO SymbolInfo)
{ {
ANSI_STRING SystemPrefix, RealPathPrefix, ProperName; BOOLEAN Found = FALSE;
CHAR Buffer[MAX_PATH], RealPathBuffer[MAX_PATH]; PLIST_ENTRY ListHead, NextEntry;
PLDR_DATA_TABLE_ENTRY LdrEntry = NULL;
/* Init our strings for compare operations */ //DPRINT("KdbSymProcessSymbols(%Z)\n", AnsiFileName);
RtlInitAnsiString(&SystemPrefix, "\\SystemRoot");
/* Convert system root to ansi */ /* We use PsLoadedModuleList here, otherwise (in case of
sprintf(RealPathBuffer, "%S", (PWCHAR)&SharedUserData->NtSystemRoot[2]); using KeLoaderBlock) all our data will be just lost */
RtlInitAnsiString(&RealPathPrefix, RealPathBuffer); ListHead = &PsLoadedModuleList;
RealPathPrefix.MaximumLength = MAX_PATH;
/* There are 3 cases: /* Found module we are interested in */
1) \SystemRoot\System32\ -> no change NextEntry = ListHead->Flink;
2) \ReactOS\System32 -> \SystemRoot\System32 while (ListHead != NextEntry)
3) module.dll -> \??\C:\ReactOS\system32\module.dll
*/
if (RtlPrefixString(&SystemPrefix, AnsiFileName, FALSE))
{ {
/* Case: \SystemRoot\System32\ , just directly load it */ /* Get the entry */
KdbSymProcessBootSymbols(AnsiFileName, TRUE, FALSE); 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. LdrEntry->PatchInformation = NULL;
So build a new, proper name. */ return;
RtlZeroMemory(Buffer, MAX_PATH); }
strcpy(Buffer, "\\SystemRoot");
strncat(Buffer,
AnsiFileName->Buffer + RealPathPrefix.Length,
AnsiFileName->Length - RealPathPrefix.Length);
/* Convert it to ANSI_STRING */ /* Remove symbol info if it already exists */
RtlInitAnsiString(&ProperName, Buffer); if (LdrEntry->PatchInformation != NULL)
{
KdbpSymRemoveCachedFile(LdrEntry->PatchInformation);
}
/* Process symbols */ /* Load new symbol information */
KdbSymProcessBootSymbols(&ProperName, TRUE, TRUE); 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 else
{ {
/* Just a bare filename, nothing else. Why? Who knows... */ /* Add file to cache */
KdbSymProcessBootSymbols(AnsiFileName, FALSE, TRUE); KdbpSymAddCachedFile(&LdrEntry->FullDllName, LdrEntry->PatchInformation);
} }
DPRINT("Installed symbols: %wZ@%08x-%08x %p\n",
&LdrEntry->BaseDllName,
LdrEntry->DllBase,
LdrEntry->SizeOfImage + (ULONG)LdrEntry->DllBase,
LdrEntry->PatchInformation);
} }