2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS kernel
4 * FILE: ntoskrnl/kdbg/kdb_symbols.cmake.c
5 * PURPOSE: Getting symbol information...
7 * PROGRAMMERS: David Welch (welch@cwcom.net)
8 * Colin Finck (colin@reactos.org)
11 /* INCLUDES *****************************************************************/
16 #include <cache/section/newmm.h>
19 /* GLOBALS ******************************************************************/
21 typedef struct _IMAGE_SYMBOL_INFO_CACHE
25 UNICODE_STRING FileName
;
26 PROSSYM_INFO RosSymInfo
;
28 IMAGE_SYMBOL_INFO_CACHE
, *PIMAGE_SYMBOL_INFO_CACHE
;
30 typedef struct _ROSSYM_KM_OWN_CONTEXT
{
31 LARGE_INTEGER FileOffset
;
32 PFILE_OBJECT FileObject
;
33 } ROSSYM_KM_OWN_CONTEXT
, *PROSSYM_KM_OWN_CONTEXT
;
35 static BOOLEAN LoadSymbols
;
36 static LIST_ENTRY SymbolFileListHead
;
37 static KSPIN_LOCK SymbolFileListLock
;
38 //static PROSSYM_INFO KdbpRosSymInfo;
39 //static ULONG_PTR KdbpImageBase;
40 BOOLEAN KdbpSymbolsInitialized
= FALSE
;
42 /* FUNCTIONS ****************************************************************/
45 KdbpSeekSymFile(PVOID FileContext
, ULONG_PTR Target
)
47 PROSSYM_KM_OWN_CONTEXT Context
= (PROSSYM_KM_OWN_CONTEXT
)FileContext
;
48 Context
->FileOffset
.QuadPart
= Target
;
53 KdbpReadSymFile(PVOID FileContext
, PVOID Buffer
, ULONG Length
)
55 PROSSYM_KM_OWN_CONTEXT Context
= (PROSSYM_KM_OWN_CONTEXT
)FileContext
;
57 NTSTATUS Status
= MiSimpleRead
64 return NT_SUCCESS(Status
);
67 static PROSSYM_KM_OWN_CONTEXT
68 KdbpCaptureFileForSymbols(PFILE_OBJECT FileObject
)
70 PROSSYM_KM_OWN_CONTEXT Context
= ExAllocatePool(NonPagedPool
, sizeof(*Context
));
71 if (!Context
) return NULL
;
72 ObReferenceObject(FileObject
);
73 Context
->FileOffset
.QuadPart
= 0;
74 Context
->FileObject
= FileObject
;
79 KdbpReleaseFileForSymbols(PROSSYM_KM_OWN_CONTEXT Context
)
81 ObDereferenceObject(Context
->FileObject
);
86 KdbpSymSearchModuleList(
87 IN PLIST_ENTRY current_entry
,
88 IN PLIST_ENTRY end_entry
,
93 OUT PLDR_DATA_TABLE_ENTRY
* pLdrEntry
)
95 while (current_entry
&& current_entry
!= end_entry
)
97 *pLdrEntry
= CONTAINING_RECORD(current_entry
, LDR_DATA_TABLE_ENTRY
, InLoadOrderLinks
);
99 if ((Address
&& Address
>= (PVOID
)(*pLdrEntry
)->DllBase
&& Address
< (PVOID
)((ULONG_PTR
)(*pLdrEntry
)->DllBase
+ (*pLdrEntry
)->SizeOfImage
)) ||
100 (Name
&& !_wcsnicmp((*pLdrEntry
)->BaseDllName
.Buffer
, Name
, (*pLdrEntry
)->BaseDllName
.Length
/ sizeof(WCHAR
))) ||
101 (Index
>= 0 && (*Count
)++ == Index
))
106 current_entry
= current_entry
->Flink
;
112 /*! \brief Find a module...
114 * \param Address If \a Address is not NULL the module containing \a Address
116 * \param Name If \a Name is not NULL the module named \a Name will be
118 * \param Index If \a Index is >= 0 the Index'th module will be returned.
119 * \param pLdrEntry Pointer to a PLDR_DATA_TABLE_ENTRY which is filled.
121 * \retval TRUE Module was found, \a pLdrEntry was filled.
122 * \retval FALSE No module was found.
126 IN PVOID Address OPTIONAL
,
127 IN LPCWSTR Name OPTIONAL
,
128 IN INT Index OPTIONAL
,
129 OUT PLDR_DATA_TABLE_ENTRY
* pLdrEntry
)
132 PEPROCESS CurrentProcess
;
134 /* First try to look up the module in the kernel module list. */
135 if(KdbpSymSearchModuleList(PsLoadedModuleList
.Flink
,
146 /* That didn't succeed. Try the module list of the current process now. */
147 CurrentProcess
= PsGetCurrentProcess();
149 if(!CurrentProcess
|| !CurrentProcess
->Peb
|| !CurrentProcess
->Peb
->Ldr
)
152 return KdbpSymSearchModuleList(CurrentProcess
->Peb
->Ldr
->InLoadOrderModuleList
.Flink
,
153 &CurrentProcess
->Peb
->Ldr
->InLoadOrderModuleList
,
161 /*! \brief Print address...
163 * Tries to lookup line number, file name and function name for the given
164 * address and prints it.
165 * If no such information is found the address is printed in the format
166 * <module: offset>, otherwise the format will be
167 * <module: offset (filename:linenumber (functionname))>
169 * \retval TRUE Module containing \a Address was found, \a Address was printed.
170 * \retval FALSE No module containing \a Address was found, nothing was printed.
175 IN PKTRAP_FRAME Context
)
178 PMEMORY_AREA MemoryArea
= NULL
;
179 PROS_SECTION_OBJECT SectionObject
;
180 PLDR_DATA_TABLE_ENTRY LdrEntry
;
182 PROSSYM_KM_OWN_CONTEXT FileContext
;
184 ULONG_PTR RelativeAddress
;
186 ROSSYM_LINEINFO LineInfo
= {0};
189 enum _ROSSYM_REGNAME regname
;
192 { ROSSYM_X86_EDX
, FIELD_OFFSET(KTRAP_FRAME
, Edx
) },
193 { ROSSYM_X86_EAX
, FIELD_OFFSET(KTRAP_FRAME
, Eax
) },
194 { ROSSYM_X86_ECX
, FIELD_OFFSET(KTRAP_FRAME
, Ecx
) },
195 { ROSSYM_X86_EBX
, FIELD_OFFSET(KTRAP_FRAME
, Ebx
) },
196 { ROSSYM_X86_ESI
, FIELD_OFFSET(KTRAP_FRAME
, Esi
) },
197 { ROSSYM_X86_EDI
, FIELD_OFFSET(KTRAP_FRAME
, Edi
) },
198 { ROSSYM_X86_EBP
, FIELD_OFFSET(KTRAP_FRAME
, Ebp
) },
199 { ROSSYM_X86_ESP
, FIELD_OFFSET(KTRAP_FRAME
, HardwareEsp
) }
205 // Disable arguments for now
206 DPRINT("Has Context %x (EBP %x)\n", Context
, Context
->Ebp
);
207 LineInfo
.Flags
= ROSSYM_LINEINFO_HAS_REGISTERS
;
210 for (i
= 0; i
< sizeof(regmap
) / sizeof(regmap
[0]); i
++) {
212 (&LineInfo
.Registers
.Registers
[regmap
[i
].regname
],
213 ((PCHAR
)Context
)+regmap
[i
].ctx_offset
,
215 DPRINT("DWARF REG[%d] -> %x\n", regmap
[i
].regname
, LineInfo
.Registers
.Registers
[regmap
[i
].regname
]);
219 if (!KdbpSymbolsInitialized
|| !KdbpSymFindModule(Address
, NULL
, -1, &LdrEntry
))
222 RelativeAddress
= (ULONG_PTR
)Address
- (ULONG_PTR
)LdrEntry
->DllBase
;
223 Status
= KdbSymGetAddressInformation
224 (LdrEntry
->PatchInformation
,
228 if (NT_SUCCESS(Status
))
230 DbgPrint("<%wZ:%x (%s:%d (%s))>",
231 &LdrEntry
->BaseDllName
, RelativeAddress
, LineInfo
.FileName
, LineInfo
.LineNumber
, LineInfo
.FunctionName
);
232 if (Context
&& LineInfo
.NumParams
)
237 for (i
= 0; i
< LineInfo
.NumParams
; i
++) {
241 LineInfo
.Parameters
[i
].ValueName
,
242 LineInfo
.Parameters
[i
].Value
);
250 else if (Address
< MmSystemRangeStart
)
252 MemoryArea
= MmLocateMemoryAreaByAddress(&PsGetCurrentProcess()->Vm
, Address
);
253 if (!MemoryArea
|| MemoryArea
->Type
!= MEMORY_AREA_SECTION_VIEW
)
258 SectionObject
= MemoryArea
->Data
.SectionData
.Section
;
259 if (!(SectionObject
->AllocationAttributes
& SEC_IMAGE
)) goto end
;
261 if (MemoryArea
->StartingAddress
!= (PVOID
)KdbpImageBase
)
265 RosSymDelete(KdbpRosSymInfo
);
266 KdbpRosSymInfo
= NULL
;
270 if ((FileContext
= KdbpCaptureFileForSymbols(SectionObject
->FileObject
)))
272 if (RosSymCreateFromFile(FileContext
, &KdbpRosSymInfo
))
273 KdbpImageBase
= (ULONG_PTR
)MemoryArea
->StartingAddress
;
275 KdbpReleaseFileForSymbols(FileContext
);
281 RelativeAddress
= (ULONG_PTR
)Address
- KdbpImageBase
;
282 RosSymFreeInfo(&LineInfo
);
283 Status
= KdbSymGetAddressInformation
287 if (NT_SUCCESS(Status
))
290 ("<%wZ:%x (%s:%d (%s))>",
291 &SectionObject
->FileObject
->FileName
,
295 LineInfo
.FunctionName
);
297 if (Context
&& LineInfo
.NumParams
)
302 for (i
= 0; i
< LineInfo
.NumParams
; i
++) {
306 LineInfo
.Parameters
[i
].ValueName
,
307 LineInfo
.Parameters
[i
].Value
);
320 DbgPrint("<%wZ:%x>", &LdrEntry
->BaseDllName
, RelativeAddress
);
326 /*! \brief Get information for an address (source file, line number,
329 * \param SymbolInfo Pointer to ROSSYM_INFO.
330 * \param RelativeAddress Relative address to look up.
331 * \param LineNumber Pointer to an ULONG which is filled with the line
332 * number (can be NULL)
333 * \param FileName Pointer to an array of CHARs which gets filled with
334 * the filename (can be NULL)
335 * \param FunctionName Pointer to an array of CHARs which gets filled with
336 * the function name (can be NULL)
338 * \returns NTSTATUS error code.
339 * \retval STATUS_SUCCESS At least one of the requested informations was found.
340 * \retval STATUS_UNSUCCESSFUL None of the requested information was found.
343 KdbSymGetAddressInformation(
344 IN PROSSYM_INFO RosSymInfo
,
345 IN ULONG_PTR RelativeAddress
,
346 IN PROSSYM_LINEINFO LineInfo
)
348 if (!KdbpSymbolsInitialized
||
350 !RosSymGetAddressInformation(RosSymInfo
, RelativeAddress
, LineInfo
))
352 return STATUS_UNSUCCESSFUL
;
355 return STATUS_SUCCESS
;
358 /*! \brief Find cached symbol file.
360 * Looks through the list of cached symbol files and tries to find an already
363 * \param FileName FileName of the symbol file to look for.
365 * \returns A pointer to the cached symbol info.
366 * \retval NULL No cached info found.
368 * \sa KdbpSymAddCachedFile
371 KdbpSymFindCachedFile(
372 IN PUNICODE_STRING FileName
)
374 PIMAGE_SYMBOL_INFO_CACHE Current
;
375 PLIST_ENTRY CurrentEntry
;
378 KeAcquireSpinLock(&SymbolFileListLock
, &Irql
);
380 CurrentEntry
= SymbolFileListHead
.Flink
;
381 while (CurrentEntry
!= (&SymbolFileListHead
))
383 Current
= CONTAINING_RECORD(CurrentEntry
, IMAGE_SYMBOL_INFO_CACHE
, ListEntry
);
385 if (RtlEqualUnicodeString(&Current
->FileName
, FileName
, TRUE
))
388 KeReleaseSpinLock(&SymbolFileListLock
, Irql
);
389 DPRINT("Found cached file!\n");
390 return Current
->RosSymInfo
;
393 CurrentEntry
= CurrentEntry
->Flink
;
396 KeReleaseSpinLock(&SymbolFileListLock
, Irql
);
398 DPRINT("Cached file not found!\n");
402 /*! \brief Add a symbol file to the cache.
404 * \param FileName Filename of the symbol file.
405 * \param RosSymInfo Pointer to the symbol info.
407 * \sa KdbpSymRemoveCachedFile
410 KdbpSymAddCachedFile(
411 IN PUNICODE_STRING FileName
,
412 IN PROSSYM_INFO RosSymInfo
)
414 PIMAGE_SYMBOL_INFO_CACHE CacheEntry
;
416 DPRINT("Adding symbol file: %wZ RosSymInfo = %p\n", FileName
, RosSymInfo
);
419 CacheEntry
= ExAllocatePoolWithTag(NonPagedPool
, sizeof (IMAGE_SYMBOL_INFO_CACHE
), TAG_KDBS
);
421 RtlZeroMemory(CacheEntry
, sizeof (IMAGE_SYMBOL_INFO_CACHE
));
424 CacheEntry
->FileName
.Buffer
= ExAllocatePoolWithTag(NonPagedPool
,
427 CacheEntry
->FileName
.MaximumLength
= FileName
->Length
;
428 RtlCopyUnicodeString(&CacheEntry
->FileName
, FileName
);
429 ASSERT(CacheEntry
->FileName
.Buffer
);
430 CacheEntry
->RefCount
= 1;
431 CacheEntry
->RosSymInfo
= RosSymInfo
;
432 InsertTailList(&SymbolFileListHead
, &CacheEntry
->ListEntry
); /* FIXME: Lock list? */
435 /*! \brief Remove a symbol file (reference) from the cache.
437 * Tries to find a cache entry matching the given symbol info and decreases
438 * it's reference count. If the refcount is 0 after decreasing it the cache
439 * entry will be removed from the list and freed.
441 * \param RosSymInfo Pointer to the symbol info.
443 * \sa KdbpSymAddCachedFile
446 KdbpSymRemoveCachedFile(
447 IN PROSSYM_INFO RosSymInfo
)
449 PIMAGE_SYMBOL_INFO_CACHE Current
;
450 PLIST_ENTRY CurrentEntry
;
453 KeAcquireSpinLock(&SymbolFileListLock
, &Irql
);
455 CurrentEntry
= SymbolFileListHead
.Flink
;
456 while (CurrentEntry
!= (&SymbolFileListHead
))
458 Current
= CONTAINING_RECORD(CurrentEntry
, IMAGE_SYMBOL_INFO_CACHE
, ListEntry
);
460 if (Current
->RosSymInfo
== RosSymInfo
) /* found */
462 ASSERT(Current
->RefCount
> 0);
464 if (Current
->RefCount
< 1)
466 RemoveEntryList(&Current
->ListEntry
);
467 RosSymDelete(Current
->RosSymInfo
);
471 KeReleaseSpinLock(&SymbolFileListLock
, Irql
);
475 CurrentEntry
= CurrentEntry
->Flink
;
478 KeReleaseSpinLock(&SymbolFileListLock
, Irql
);
481 /*! \brief Loads a symbol file.
483 * \param FileName Filename of the symbol file to load.
484 * \param RosSymInfo Pointer to a ROSSYM_INFO which gets filled.
486 * \sa KdbpSymUnloadModuleSymbols
489 KdbpSymLoadModuleSymbols(
490 IN PUNICODE_STRING FileName
,
491 OUT PROSSYM_INFO
*RosSymInfo
)
493 OBJECT_ATTRIBUTES ObjectAttributes
;
496 IO_STATUS_BLOCK IoStatusBlock
;
497 PFILE_OBJECT FileObject
;
498 PROSSYM_KM_OWN_CONTEXT FileContext
;
500 /* Allow KDB to break on module load */
501 KdbModuleLoaded(FileName
);
509 /* Try to find cached (already loaded) symbol file */
510 *RosSymInfo
= KdbpSymFindCachedFile(FileName
);
513 DPRINT("Found cached symbol file %wZ\n", FileName
);
518 InitializeObjectAttributes(&ObjectAttributes
,
520 OBJ_CASE_INSENSITIVE
| OBJ_KERNEL_HANDLE
,
524 DPRINT("Attempting to open image: %wZ\n", FileName
);
526 Status
= ZwOpenFile(&FileHandle
,
527 FILE_READ_ACCESS
| SYNCHRONIZE
,
530 FILE_SHARE_READ
| FILE_SHARE_WRITE
,
531 FILE_NON_DIRECTORY_FILE
| FILE_SYNCHRONOUS_IO_NONALERT
);
532 if (!NT_SUCCESS(Status
))
534 DPRINT("Could not open image file(%x): %wZ\n", Status
, FileName
);
538 DPRINT("Loading symbols from %wZ...\n", FileName
);
540 Status
= ObReferenceObjectByHandle
542 FILE_READ_DATA
| SYNCHRONIZE
,
548 if (!NT_SUCCESS(Status
))
550 DPRINT("Could not get the file object\n");
555 if ((FileContext
= KdbpCaptureFileForSymbols(FileObject
)))
557 if (RosSymCreateFromFile(FileContext
, RosSymInfo
))
559 /* add file to cache */
561 UNICODE_STRING TruncatedName
= *FileName
;
562 for (i
= (TruncatedName
.Length
/ sizeof(WCHAR
)) - 1; i
>= 0; i
--)
563 if (TruncatedName
.Buffer
[i
] == '\\') {
564 TruncatedName
.Buffer
+= i
+1;
565 TruncatedName
.Length
-= (i
+1)*sizeof(WCHAR
);
566 TruncatedName
.MaximumLength
-= (i
+1)*sizeof(WCHAR
);
569 KdbpSymAddCachedFile(&TruncatedName
, *RosSymInfo
);
570 DPRINT("Installed symbols: %wZ %p\n", &TruncatedName
, *RosSymInfo
);
572 KdbpReleaseFileForSymbols(FileContext
);
575 ObDereferenceObject(FileObject
);
580 KdbSymProcessSymbols(
581 IN PLDR_DATA_TABLE_ENTRY LdrEntry
)
585 LdrEntry
->PatchInformation
= NULL
;
589 /* Remove symbol info if it already exists */
590 if (LdrEntry
->PatchInformation
) {
591 KdbpSymRemoveCachedFile(LdrEntry
->PatchInformation
);
594 /* Error loading symbol info, try to load it from file */
595 KdbpSymLoadModuleSymbols(&LdrEntry
->FullDllName
,
596 (PROSSYM_INFO
*)&LdrEntry
->PatchInformation
);
598 if (!LdrEntry
->PatchInformation
) {
599 // HACK: module dll names don't identify the real files
600 UNICODE_STRING SystemRoot
;
601 UNICODE_STRING ModuleNameCopy
;
602 RtlInitUnicodeString(&SystemRoot
, L
"\\SystemRoot\\System32\\Drivers\\");
603 ModuleNameCopy
.Length
= 0;
604 ModuleNameCopy
.MaximumLength
=
605 LdrEntry
->BaseDllName
.MaximumLength
+ SystemRoot
.MaximumLength
;
606 ModuleNameCopy
.Buffer
= ExAllocatePool(NonPagedPool
, SystemRoot
.MaximumLength
+ LdrEntry
->BaseDllName
.MaximumLength
);
607 RtlCopyUnicodeString(&ModuleNameCopy
, &SystemRoot
);
609 (ModuleNameCopy
.Buffer
+ ModuleNameCopy
.Length
/ sizeof(WCHAR
),
610 LdrEntry
->BaseDllName
.Buffer
,
611 LdrEntry
->BaseDllName
.Length
);
612 ModuleNameCopy
.Length
+= LdrEntry
->BaseDllName
.Length
;
613 KdbpSymLoadModuleSymbols(&ModuleNameCopy
,
614 (PROSSYM_INFO
*)&LdrEntry
->PatchInformation
);
615 if (!LdrEntry
->PatchInformation
) {
616 SystemRoot
.Length
-= strlen("Drivers\\") * sizeof(WCHAR
);
617 RtlCopyUnicodeString(&ModuleNameCopy
, &SystemRoot
);
619 (ModuleNameCopy
.Buffer
+ ModuleNameCopy
.Length
/ sizeof(WCHAR
),
620 LdrEntry
->BaseDllName
.Buffer
,
621 LdrEntry
->BaseDllName
.Length
);
622 ModuleNameCopy
.Length
+= LdrEntry
->BaseDllName
.Length
;
623 KdbpSymLoadModuleSymbols(&ModuleNameCopy
,
624 (PROSSYM_INFO
*)&LdrEntry
->PatchInformation
);
626 RtlFreeUnicodeString(&ModuleNameCopy
);
629 /* It already added symbols to cache */
630 DPRINT("Installed symbols: %wZ@%p-%p %p\n",
631 &LdrEntry
->BaseDllName
,
633 (PVOID
)(LdrEntry
->SizeOfImage
+ (ULONG_PTR
)LdrEntry
->DllBase
),
634 LdrEntry
->PatchInformation
);
646 static PVOID
KdbpSymAllocMem(ULONG_PTR size
)
648 return ExAllocatePoolWithTag(NonPagedPool
, size
, 'RSYM');
651 static VOID
KdbpSymFreeMem(PVOID Area
)
653 return ExFreePool(Area
);
656 static BOOLEAN
KdbpSymReadMem(PVOID FileContext
, ULONG_PTR
* TargetDebug
, PVOID SourceMem
, ULONG Size
)
658 return NT_SUCCESS(KdbpSafeReadMemory(TargetDebug
, SourceMem
, Size
));
661 static ROSSYM_CALLBACKS KdbpRosSymCallbacks
= {
662 KdbpSymAllocMem
, KdbpSymFreeMem
,
663 KdbpReadSymFile
, KdbpSeekSymFile
,
667 /*! \brief Initializes the KDB symbols implementation.
669 * \param DispatchTable Pointer to the KD dispatch table
670 * \param BootPhase Phase of initialization
675 PKD_DISPATCH_TABLE DispatchTable
,
681 PLDR_DATA_TABLE_ENTRY LdrEntry
;
683 DPRINT("KdbSymInit() BootPhase=%d\n", BootPhase
);
688 /* Load symbols only if we have 96Mb of RAM or more */
689 if (MmNumberOfPhysicalPages
>= 0x6000)
695 /* Write out the functions that we support for now */
696 DispatchTable
->KdpInitRoutine
= KdpKdbgInit
;
697 DispatchTable
->KdpPrintRoutine
= KdbDebugPrint
;
699 /* Register as a Provider */
700 InsertTailList(&KdProviders
, &DispatchTable
->KdProvidersList
);
702 /* Perform actual initialization of symbol module */
703 //NtoskrnlModuleObject->PatchInformation = NULL;
704 //LdrHalModuleObject->PatchInformation = NULL;
706 InitializeListHead(&SymbolFileListHead
);
707 KeInitializeSpinLock(&SymbolFileListLock
);
709 /* Check the command line for /LOADSYMBOLS, /NOLOADSYMBOLS,
710 * /LOADSYMBOLS={YES|NO}, /NOLOADSYMBOLS={YES|NO} */
711 ASSERT(KeLoaderBlock
);
712 p1
= KeLoaderBlock
->LoadOptions
;
713 while('\0' != *p1
&& NULL
!= (p2
= strchr(p1
, '/')))
717 if (0 == _strnicmp(p2
, "LOADSYMBOLS", 11))
722 else if (0 == _strnicmp(p2
, "NOLOADSYMBOLS", 13))
740 YesNo
= toupper(*p2
);
741 if ('N' == YesNo
|| 'F' == YesNo
|| '0' == YesNo
)
746 LoadSymbols
= (0 < Found
);
751 RosSymInit(&KdbpRosSymCallbacks
);
753 else if (BootPhase
== 3)
755 /* Load symbols for NTOSKRNL.EXE.
756 It is always the first module in PsLoadedModuleList. KeLoaderBlock can't be used here as its content is just temporary. */
757 LdrEntry
= CONTAINING_RECORD(PsLoadedModuleList
.Flink
, LDR_DATA_TABLE_ENTRY
, InLoadOrderLinks
);
758 KdbSymProcessSymbols(LdrEntry
);
760 /* Also load them for HAL.DLL. */
761 LdrEntry
= CONTAINING_RECORD(PsLoadedModuleList
.Flink
->Flink
, LDR_DATA_TABLE_ENTRY
, InLoadOrderLinks
);
762 KdbSymProcessSymbols(LdrEntry
);
764 KdbpSymbolsInitialized
= TRUE
;