2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS kernel
4 * FILE: ntoskrnl/dbg/kdb_symbols.c
5 * PURPOSE: Getting symbol information...
7 * PROGRAMMERS: David Welch (welch@cwcom.net)
10 /* INCLUDES *****************************************************************/
15 #include <internal/debug.h>
17 /* GLOBALS ******************************************************************/
19 typedef struct _IMAGE_SYMBOL_INFO_CACHE
{
22 UNICODE_STRING FileName
;
23 PROSSYM_INFO RosSymInfo
;
24 } IMAGE_SYMBOL_INFO_CACHE
, *PIMAGE_SYMBOL_INFO_CACHE
;
26 static BOOLEAN LoadSymbols
;
27 static LIST_ENTRY SymbolFileListHead
;
28 static KSPIN_LOCK SymbolFileListLock
;
31 /* FUNCTIONS ****************************************************************/
33 /*! \brief Find a user-mode module...
35 * \param Address If \a Address is not NULL the module containing \a Address
37 * \param Name If \a Name is not NULL the module named \a Name will be
39 * \param Index If \a Index is >= 0 the Index'th module will be returned.
40 * \param pInfo Pointer to a KDB_MODULE_INFO which is filled.
42 * \retval TRUE Module was found, \a pInfo was filled.
43 * \retval FALSE No module was found.
45 * \sa KdbpSymFindModule
48 KdbpSymFindUserModule(IN PVOID Address OPTIONAL
,
49 IN LPCWSTR Name OPTIONAL
,
50 IN INT Index OPTIONAL
,
51 OUT PKDB_MODULE_INFO pInfo
)
53 PLIST_ENTRY current_entry
;
54 PLDR_DATA_TABLE_ENTRY current
;
55 PEPROCESS CurrentProcess
;
60 CurrentProcess
= PsGetCurrentProcess();
61 if (CurrentProcess
!= NULL
)
63 Peb
= CurrentProcess
->Peb
;
66 if (Peb
== NULL
|| Peb
->Ldr
== NULL
)
71 current_entry
= Peb
->Ldr
->InLoadOrderModuleList
.Flink
;
73 while (current_entry
!= &Peb
->Ldr
->InLoadOrderModuleList
&&
74 current_entry
!= NULL
)
76 current
= CONTAINING_RECORD(current_entry
, LDR_DATA_TABLE_ENTRY
, InLoadOrderLinks
);
77 Length
= min(current
->BaseDllName
.Length
/ sizeof(WCHAR
), 255);
78 if ((Address
!= NULL
&& (Address
>= (PVOID
)current
->DllBase
&&
79 Address
< (PVOID
)((char *)current
->DllBase
+ current
->SizeOfImage
))) ||
80 (Name
!= NULL
&& _wcsnicmp(current
->BaseDllName
.Buffer
, Name
, Length
) == 0) ||
81 (Index
>= 0 && Count
++ == Index
))
83 wcsncpy(pInfo
->Name
, current
->BaseDllName
.Buffer
, Length
);
84 pInfo
->Name
[Length
] = L
'\0';
85 pInfo
->Base
= (ULONG_PTR
)current
->DllBase
;
86 pInfo
->Size
= current
->SizeOfImage
;
87 pInfo
->RosSymInfo
= current
->PatchInformation
;
90 current_entry
= current_entry
->Flink
;
96 /*! \brief Find a kernel-mode module...
98 * Works like \a KdbpSymFindUserModule.
100 * \sa KdbpSymFindUserModule
103 KdbpSymFindModule(IN PVOID Address OPTIONAL
,
104 IN LPCWSTR Name OPTIONAL
,
105 IN INT Index OPTIONAL
,
106 OUT PKDB_MODULE_INFO pInfo
)
108 PLIST_ENTRY current_entry
;
109 PLDR_DATA_TABLE_ENTRY current
;
113 current_entry
= PsLoadedModuleList
.Flink
;
115 while (current_entry
!= &PsLoadedModuleList
)
117 current
= CONTAINING_RECORD(current_entry
, LDR_DATA_TABLE_ENTRY
, InLoadOrderLinks
);
119 Length
= min(current
->BaseDllName
.Length
/ sizeof(WCHAR
), 255);
120 if ((Address
!= NULL
&& (Address
>= (PVOID
)current
->DllBase
&&
121 Address
< (PVOID
)((ULONG_PTR
)current
->DllBase
+ current
->SizeOfImage
))) ||
122 (Name
!= NULL
&& _wcsnicmp(current
->BaseDllName
.Buffer
, Name
, Length
) == 0) ||
123 (Index
>= 0 && Count
++ == Index
))
125 wcsncpy(pInfo
->Name
, current
->BaseDllName
.Buffer
, Length
);
126 pInfo
->Name
[Length
] = L
'\0';
127 pInfo
->Base
= (ULONG_PTR
)current
->DllBase
;
128 pInfo
->Size
= current
->SizeOfImage
;
129 pInfo
->RosSymInfo
= current
->PatchInformation
;
132 current_entry
= current_entry
->Flink
;
135 return KdbpSymFindUserModule(Address
, Name
, Index
-Count
, pInfo
);
138 /*! \brief Find module by address...
140 * \param Address Any address inside the module to look for.
141 * \param pInfo Pointer to a KDB_MODULE_INFO struct which is filled on
144 * \retval TRUE Success - module found.
145 * \retval FALSE Failure - module not found.
147 * \sa KdbpSymFindModuleByName
148 * \sa KdbpSymFindModuleByIndex
151 KdbpSymFindModuleByAddress(IN PVOID Address
,
152 OUT PKDB_MODULE_INFO pInfo
)
154 return KdbpSymFindModule(Address
, NULL
, -1, pInfo
);
157 /*! \brief Find module by name...
159 * \param Name Name of the module to look for.
160 * \param pInfo Pointer to a KDB_MODULE_INFO struct which is filled on
163 * \retval TRUE Success - module found.
164 * \retval FALSE Failure - module not found.
166 * \sa KdbpSymFindModuleByAddress
167 * \sa KdbpSymFindModuleByIndex
170 KdbpSymFindModuleByName(IN LPCWSTR Name
,
171 OUT PKDB_MODULE_INFO pInfo
)
173 return KdbpSymFindModule(NULL
, Name
, -1, pInfo
);
176 /*! \brief Find module by index...
178 * \param Index Index of the module to return.
179 * \param pInfo Pointer to a KDB_MODULE_INFO struct which is filled on
182 * \retval TRUE Success - module found.
183 * \retval FALSE Failure - module not found.
185 * \sa KdbpSymFindModuleByName
186 * \sa KdbpSymFindModuleByAddress
189 KdbpSymFindModuleByIndex(IN INT Index
,
190 OUT PKDB_MODULE_INFO pInfo
)
192 return KdbpSymFindModule(NULL
, NULL
, Index
, pInfo
);
195 /*! \brief Print address...
197 * Tries to lookup line number, file name and function name for the given
198 * address and prints it.
199 * If no such information is found the address is printed in the format
200 * <module: offset>, otherwise the format will be
201 * <module: offset (filename:linenumber (functionname))>
203 * \retval TRUE Module containing \a Address was found, \a Address was printed.
204 * \retval FALSE No module containing \a Address was found, nothing was printed.
207 KdbSymPrintAddress(IN PVOID Address
)
209 KDB_MODULE_INFO Info
;
210 ULONG_PTR RelativeAddress
;
214 CHAR FunctionName
[256];
216 if (!KdbpSymFindModuleByAddress(Address
, &Info
))
219 RelativeAddress
= (ULONG_PTR
) Address
- Info
.Base
;
220 Status
= KdbSymGetAddressInformation(Info
.RosSymInfo
,
225 if (NT_SUCCESS(Status
))
227 DbgPrint("<%ws:%x (%s:%d (%s))>",
228 Info
.Name
, RelativeAddress
, FileName
, LineNumber
, FunctionName
);
232 DbgPrint("<%ws:%x>", Info
.Name
, RelativeAddress
);
239 /*! \brief Get information for an address (source file, line number,
242 * \param SymbolInfo Pointer to ROSSYM_INFO.
243 * \param RelativeAddress Relative address to look up.
244 * \param LineNumber Pointer to an ULONG which is filled with the line
245 * number (can be NULL)
246 * \param FileName Pointer to an array of CHARs which gets filled with
247 * the filename (can be NULL)
248 * \param FunctionName Pointer to an array of CHARs which gets filled with
249 * the function name (can be NULL)
251 * \returns NTSTATUS error code.
252 * \retval STATUS_SUCCESS At least one of the requested informations was found.
253 * \retval STATUS_UNSUCCESSFUL None of the requested information was found.
256 KdbSymGetAddressInformation(IN PROSSYM_INFO RosSymInfo
,
257 IN ULONG_PTR RelativeAddress
,
258 OUT PULONG LineNumber OPTIONAL
,
259 OUT PCH FileName OPTIONAL
,
260 OUT PCH FunctionName OPTIONAL
)
262 if (NULL
== RosSymInfo
)
264 return STATUS_UNSUCCESSFUL
;
267 if (! RosSymGetAddressInformation(RosSymInfo
, RelativeAddress
, LineNumber
,
268 FileName
, FunctionName
))
270 return STATUS_UNSUCCESSFUL
;
273 return STATUS_SUCCESS
;
276 /*! \brief Find cached symbol file.
278 * Looks through the list of cached symbol files and tries to find an already
281 * \param FileName FileName of the symbol file to look for.
283 * \returns A pointer to the cached symbol info.
284 * \retval NULL No cached info found.
286 * \sa KdbpSymAddCachedFile
289 KdbpSymFindCachedFile(IN PUNICODE_STRING FileName
)
291 PIMAGE_SYMBOL_INFO_CACHE Current
;
292 PLIST_ENTRY CurrentEntry
;
295 DPRINT("Looking for cached symbol file %wZ\n", FileName
);
297 KeAcquireSpinLock(&SymbolFileListLock
, &Irql
);
299 CurrentEntry
= SymbolFileListHead
.Flink
;
300 while (CurrentEntry
!= (&SymbolFileListHead
))
302 Current
= CONTAINING_RECORD(CurrentEntry
, IMAGE_SYMBOL_INFO_CACHE
, ListEntry
);
304 DPRINT("Current->FileName %wZ FileName %wZ\n", &Current
->FileName
, FileName
);
305 if (RtlEqualUnicodeString(&Current
->FileName
, FileName
, TRUE
))
308 KeReleaseSpinLock(&SymbolFileListLock
, Irql
);
309 DPRINT("Found cached file!\n");
310 return Current
->RosSymInfo
;
313 CurrentEntry
= CurrentEntry
->Flink
;
316 KeReleaseSpinLock(&SymbolFileListLock
, Irql
);
318 DPRINT("Cached file not found!\n");
322 /*! \brief Add a symbol file to the cache.
324 * \param FileName Filename of the symbol file.
325 * \param RosSymInfo Pointer to the symbol info.
327 * \sa KdbpSymRemoveCachedFile
330 KdbpSymAddCachedFile(IN PUNICODE_STRING FileName
,
331 IN PROSSYM_INFO RosSymInfo
)
333 PIMAGE_SYMBOL_INFO_CACHE CacheEntry
;
335 DPRINT("Adding symbol file: RosSymInfo = %p\n", RosSymInfo
);
338 CacheEntry
= ExAllocatePoolWithTag(NonPagedPool
, sizeof (IMAGE_SYMBOL_INFO_CACHE
), TAG_KDBS
);
340 RtlZeroMemory(CacheEntry
, sizeof (IMAGE_SYMBOL_INFO_CACHE
));
343 CacheEntry
->FileName
.Buffer
= ExAllocatePoolWithTag(NonPagedPool
,
346 RtlInitUnicodeString(&CacheEntry
->FileName
, FileName
->Buffer
);
347 ASSERT(CacheEntry
->FileName
.Buffer
);
348 CacheEntry
->RefCount
= 1;
349 CacheEntry
->RosSymInfo
= RosSymInfo
;
350 InsertTailList(&SymbolFileListHead
, &CacheEntry
->ListEntry
); /* FIXME: Lock list? */
353 /*! \brief Remove a symbol file (reference) from the cache.
355 * Tries to find a cache entry matching the given symbol info and decreases
356 * it's reference count. If the refcount is 0 after decreasing it the cache
357 * entry will be removed from the list and freed.
359 * \param RosSymInfo Pointer to the symbol info.
361 * \sa KdbpSymAddCachedFile
364 KdbpSymRemoveCachedFile(IN PROSSYM_INFO RosSymInfo
)
366 PIMAGE_SYMBOL_INFO_CACHE Current
;
367 PLIST_ENTRY CurrentEntry
;
370 KeAcquireSpinLock(&SymbolFileListLock
, &Irql
);
372 CurrentEntry
= SymbolFileListHead
.Flink
;
373 while (CurrentEntry
!= (&SymbolFileListHead
))
375 Current
= CONTAINING_RECORD(CurrentEntry
, IMAGE_SYMBOL_INFO_CACHE
, ListEntry
);
377 if (Current
->RosSymInfo
== RosSymInfo
) /* found */
379 ASSERT(Current
->RefCount
> 0);
381 if (Current
->RefCount
< 1)
383 RemoveEntryList(&Current
->ListEntry
);
384 RosSymDelete(Current
->RosSymInfo
);
387 KeReleaseSpinLock(&SymbolFileListLock
, Irql
);
391 CurrentEntry
= CurrentEntry
->Flink
;
394 KeReleaseSpinLock(&SymbolFileListLock
, Irql
);
395 DPRINT1("Warning: Removing unknown symbol file: RosSymInfo = %p\n", RosSymInfo
);
398 /*! \brief Loads a symbol file.
400 * \param FileName Filename of the symbol file to load.
401 * \param RosSymInfo Pointer to a ROSSYM_INFO which gets filled.
403 * \sa KdbpSymUnloadModuleSymbols
406 KdbpSymLoadModuleSymbols(IN PUNICODE_STRING FileName
,
407 OUT PROSSYM_INFO
*RosSymInfo
)
409 OBJECT_ATTRIBUTES ObjectAttributes
;
412 IO_STATUS_BLOCK IoStatusBlock
;
414 /* Allow KDB to break on module load */
415 KdbModuleLoaded(FileName
);
423 /* Try to find cached (already loaded) symbol file */
424 *RosSymInfo
= KdbpSymFindCachedFile(FileName
);
425 if (*RosSymInfo
!= NULL
)
427 DPRINT("Found cached symbol file %wZ\n", FileName
);
432 InitializeObjectAttributes(&ObjectAttributes
,
438 DPRINT("Attempting to open image: %wZ\n", FileName
);
440 Status
= ZwOpenFile(&FileHandle
,
444 FILE_SHARE_READ
|FILE_SHARE_WRITE
,
445 FILE_SYNCHRONOUS_IO_NONALERT
);
446 if (!NT_SUCCESS(Status
))
448 DPRINT("Could not open image file: %wZ\n", FileName
);
452 DPRINT("Loading symbols from %wZ...\n", FileName
);
454 if (! RosSymCreateFromFile(&FileHandle
, RosSymInfo
))
456 DPRINT("Failed to load symbols from %wZ\n", FileName
);
462 DPRINT("Symbols loaded.\n");
464 /* add file to cache */
465 KdbpSymAddCachedFile(FileName
, *RosSymInfo
);
467 DPRINT("Installed symbols: %wZ %p\n", FileName
, *RosSymInfo
);
470 /*! \brief Unloads symbol info.
472 * \param RosSymInfo Pointer to the symbol info to unload.
474 * \sa KdbpSymLoadModuleSymbols
477 KdbpSymUnloadModuleSymbols(IN PROSSYM_INFO RosSymInfo
)
479 DPRINT("Unloading symbols\n");
481 if (RosSymInfo
!= NULL
)
483 KdbpSymRemoveCachedFile(RosSymInfo
);
487 /*! \brief Load symbol info for a user module.
489 * \param LdrModule Pointer to the module to load symbols for.
492 KdbSymLoadUserModuleSymbols(IN PLDR_DATA_TABLE_ENTRY LdrModule
)
494 static WCHAR Prefix
[] = L
"\\??\\";
495 UNICODE_STRING KernelName
;
496 DPRINT("LdrModule %p\n", LdrModule
);
498 LdrModule
->PatchInformation
= NULL
;
500 KernelName
.MaximumLength
= sizeof(Prefix
) + LdrModule
->FullDllName
.Length
;
501 KernelName
.Length
= KernelName
.MaximumLength
- sizeof(WCHAR
);
502 KernelName
.Buffer
= ExAllocatePoolWithTag(PagedPool
, KernelName
.MaximumLength
, TAG_KDBS
);
503 if (NULL
== KernelName
.Buffer
)
507 memcpy(KernelName
.Buffer
, Prefix
, sizeof(Prefix
) - sizeof(WCHAR
));
508 memcpy(KernelName
.Buffer
+ sizeof(Prefix
) / sizeof(WCHAR
) - 1, LdrModule
->FullDllName
.Buffer
,
509 LdrModule
->FullDllName
.Length
);
510 KernelName
.Buffer
[KernelName
.Length
/ sizeof(WCHAR
)] = L
'\0';
512 KdbpSymLoadModuleSymbols(&KernelName
, (PROSSYM_INFO
*)&LdrModule
->PatchInformation
);
514 ExFreePool(KernelName
.Buffer
);
517 /*! \brief Frees all symbols loaded for a process.
519 * \param Process Pointer to a process.
522 KdbSymFreeProcessSymbols(IN PEPROCESS Process
)
524 PLIST_ENTRY CurrentEntry
;
525 PLDR_DATA_TABLE_ENTRY Current
;
526 PEPROCESS CurrentProcess
;
529 CurrentProcess
= PsGetCurrentProcess();
530 if (CurrentProcess
!= Process
)
532 KeAttachProcess(&Process
->Pcb
);
538 CurrentEntry
= Peb
->Ldr
->InLoadOrderModuleList
.Flink
;
539 while (CurrentEntry
!= &Peb
->Ldr
->InLoadOrderModuleList
&&
540 CurrentEntry
!= NULL
)
542 Current
= CONTAINING_RECORD(CurrentEntry
, LDR_DATA_TABLE_ENTRY
, InLoadOrderLinks
);
544 KdbpSymUnloadModuleSymbols(Current
->PatchInformation
);
546 CurrentEntry
= CurrentEntry
->Flink
;
548 if (CurrentProcess
!= Process
)
554 /*! \brief Load symbol info for a driver.
556 * \param Filename Filename of the driver.
557 * \param Module Pointer to the driver LDR_DATA_TABLE_ENTRY.
560 KdbSymLoadDriverSymbols(IN PUNICODE_STRING Filename
,
561 IN PLDR_DATA_TABLE_ENTRY Module
)
563 /* Load symbols for the image if available */
564 DPRINT("Loading driver %wZ symbols (driver @ %08x)\n", Filename
, Module
->DllBase
);
566 Module
->PatchInformation
= NULL
;
568 KdbpSymLoadModuleSymbols(Filename
, (PROSSYM_INFO
*)&Module
->PatchInformation
);
571 /*! \brief Unloads symbol info for a driver.
573 * \param ModuleObject Pointer to the driver LDR_DATA_TABLE_ENTRY.
576 KdbSymUnloadDriverSymbols(IN PLDR_DATA_TABLE_ENTRY ModuleObject
)
578 /* Unload symbols for module if available */
579 KdbpSymUnloadModuleSymbols(ModuleObject
->PatchInformation
);
580 ModuleObject
->PatchInformation
= NULL
;
584 KdbSymProcessSymbols(IN PANSI_STRING AnsiFileName
, IN PKD_SYMBOLS_INFO SymbolInfo
)
586 BOOLEAN Found
= FALSE
;
587 PLIST_ENTRY ListHead
, NextEntry
;
588 PLDR_DATA_TABLE_ENTRY LdrEntry
= NULL
;
590 //DPRINT("KdbSymProcessSymbols(%Z)\n", AnsiFileName);
592 /* We use PsLoadedModuleList here, otherwise (in case of
593 using KeLoaderBlock) all our data will be just lost */
594 ListHead
= &PsLoadedModuleList
;
596 /* Found module we are interested in */
597 NextEntry
= ListHead
->Flink
;
598 while (ListHead
!= NextEntry
)
601 LdrEntry
= CONTAINING_RECORD(NextEntry
,
602 LDR_DATA_TABLE_ENTRY
,
605 if (SymbolInfo
->BaseOfDll
== LdrEntry
->DllBase
)
611 /* Go to the next one */
612 NextEntry
= NextEntry
->Flink
;
615 /* Exit if we didn't find the module requested */
619 DPRINT("Found LdrEntry=%p\n", LdrEntry
);
622 LdrEntry
->PatchInformation
= NULL
;
626 /* Remove symbol info if it already exists */
627 if (LdrEntry
->PatchInformation
!= NULL
)
629 KdbpSymRemoveCachedFile(LdrEntry
->PatchInformation
);
632 /* Load new symbol information */
633 if (! RosSymCreateFromMem(LdrEntry
->DllBase
,
634 LdrEntry
->SizeOfImage
,
635 (PROSSYM_INFO
*)&LdrEntry
->PatchInformation
))
637 /* Error loading symbol info, try to load it from file */
638 KdbpSymLoadModuleSymbols(&LdrEntry
->FullDllName
,
639 (PROSSYM_INFO
*)&LdrEntry
->PatchInformation
);
641 /* It already added symbols to cache */
645 /* Add file to cache */
646 KdbpSymAddCachedFile(&LdrEntry
->FullDllName
, LdrEntry
->PatchInformation
);
649 DPRINT("Installed symbols: %wZ@%08x-%08x %p\n",
650 &LdrEntry
->BaseDllName
,
652 LdrEntry
->SizeOfImage
+ (ULONG
)LdrEntry
->DllBase
,
653 LdrEntry
->PatchInformation
);
659 KdbDebugPrint(PCH Message
, ULONG Length
)
665 /*! \brief Initializes the KDB symbols implementation.
667 * \param DispatchTable Pointer to the KD dispatch table
668 * \param BootPhase Phase of initialization
672 KdbInitialize(PKD_DISPATCH_TABLE DispatchTable
,
678 LIST_ENTRY
*ModuleEntry
;
679 PLDR_DATA_TABLE_ENTRY DataTableEntry
;
680 KD_SYMBOLS_INFO SymbolsInfo
;
682 DPRINT("KdbSymInit() BootPhase=%d\n", BootPhase
);
686 /* Write out the functions that we support for now */
687 DispatchTable
->KdpInitRoutine
= KdpKdbgInit
;
688 DispatchTable
->KdpPrintRoutine
= KdbDebugPrint
;
690 /* Register as a Provider */
691 InsertTailList(&KdProviders
, &DispatchTable
->KdProvidersList
);
693 /* Perform actual initialization of symbol module */
694 //NtoskrnlModuleObject->PatchInformation = NULL;
695 //LdrHalModuleObject->PatchInformation = NULL;
697 InitializeListHead(&SymbolFileListHead
);
698 KeInitializeSpinLock(&SymbolFileListLock
);
706 /* Check the command line for /LOADSYMBOLS, /NOLOADSYMBOLS,
707 * /LOADSYMBOLS={YES|NO}, /NOLOADSYMBOLS={YES|NO} */
708 ASSERT(KeLoaderBlock
);
709 p1
= KeLoaderBlock
->LoadOptions
;
710 while('\0' != *p1
&& NULL
!= (p2
= strchr(p1
, '/')))
714 if (0 == _strnicmp(p2
, "LOADSYMBOLS", 11))
719 else if (0 == _strnicmp(p2
, "NOLOADSYMBOLS", 13))
737 YesNo
= toupper(*p2
);
738 if ('N' == YesNo
|| 'F' == YesNo
|| '0' == YesNo
)
743 LoadSymbols
= (0 < Found
);
748 RosSymInitKernelMode();
750 else if (BootPhase
== 1)
752 /* Load symbols for NTOSKRNL.EXE */
753 ModuleEntry
= &KeLoaderBlock
->LoadOrderListHead
;
754 DataTableEntry
= CONTAINING_RECORD(ModuleEntry
,
755 LDR_DATA_TABLE_ENTRY
, InLoadOrderLinks
);
757 SymbolsInfo
.BaseOfDll
= DataTableEntry
->DllBase
;
758 SymbolsInfo
.CheckSum
= DataTableEntry
->CheckSum
;
759 SymbolsInfo
.ProcessId
= 0;
760 SymbolsInfo
.SizeOfImage
= DataTableEntry
->SizeOfImage
;
762 KdbSymProcessSymbols(NULL
, &SymbolsInfo
);
765 ModuleEntry
= ModuleEntry
->Flink
;
766 DataTableEntry
= CONTAINING_RECORD(ModuleEntry
,
767 LDR_DATA_TABLE_ENTRY
, InLoadOrderLinks
);
769 SymbolsInfo
.BaseOfDll
= DataTableEntry
->DllBase
;
770 SymbolsInfo
.CheckSum
= DataTableEntry
->CheckSum
;
771 SymbolsInfo
.ProcessId
= 0;
772 SymbolsInfo
.SizeOfImage
= DataTableEntry
->SizeOfImage
;
774 KdbSymProcessSymbols(NULL
, &SymbolsInfo
);