3 * Copyright (C) 1998, 1999, 2000, 2001 ReactOS Team
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 * PROJECT: ReactOS kernel
21 * FILE: ntoskrnl/ke/i386/exp.c
22 * PURPOSE: Handling exceptions
23 * PROGRAMMER: David Welch (welch@cwcom.net)
28 /* INCLUDES *****************************************************************/
30 #include <ddk/ntddk.h>
32 #include <internal/ntoskrnl.h>
33 #include <internal/ke.h>
34 #include <internal/i386/segment.h>
35 #include <internal/i386/mm.h>
36 #include <internal/module.h>
37 #include <internal/mm.h>
38 #include <internal/ps.h>
39 #include <internal/trap.h>
40 #include <ntdll/ldr.h>
41 #include <internal/safe.h>
42 #include <internal/kd.h>
45 #include <internal/debug.h>
47 /* GLOBALS ******************************************************************/
49 typedef struct _SYMBOLFILE_HEADER
{
50 unsigned long StabsOffset
;
51 unsigned long StabsLength
;
52 unsigned long StabstrOffset
;
53 unsigned long StabstrLength
;
54 } SYMBOLFILE_HEADER
, *PSYMBOLFILE_HEADER
;
56 typedef struct _IMAGE_SYMBOL_INFO_CACHE
{
58 UNICODE_STRING FullName
;
62 PVOID SymbolStringsBase
;
63 ULONG SymbolStringsLength
;
64 } IMAGE_SYMBOL_INFO_CACHE
, *PIMAGE_SYMBOL_INFO_CACHE
;
67 typedef struct _STAB_ENTRY
{
68 unsigned long n_strx
; /* index into string table of name */
69 unsigned char n_type
; /* type of symbol */
70 unsigned char n_other
; /* misc info (usually empty) */
71 unsigned short n_desc
; /* description field */
72 unsigned long n_value
; /* value of symbol */
73 } _STAB_ENTRY
, *PSTAB_ENTRY
;
77 * Value - Relative virtual address
83 * Value - Relative virtual address
88 * String - First containing a '/' is the compillation directory (CD)
89 * Not containing a '/' is a source file relative to CD
93 static LIST_ENTRY SymbolListHead
;
94 static KSPIN_LOCK SymbolListLock
;
97 LdrGetAddressInformation(IN PIMAGE_SYMBOL_INFO SymbolInfo
,
98 IN ULONG_PTR RelativeAddress
,
99 OUT PULONG LineNumber
,
100 OUT PCH FileName OPTIONAL
,
101 OUT PCH FunctionName OPTIONAL
);
104 KdbLdrUnloadModuleSymbols(PIMAGE_SYMBOL_INFO SymbolInfo
);
106 /* FUNCTIONS ****************************************************************/
109 KdbPrintUserAddress(PVOID address
)
111 PLIST_ENTRY current_entry
;
113 PEPROCESS CurrentProcess
;
115 ULONG_PTR RelativeAddress
;
119 CHAR FunctionName
[256];
121 CurrentProcess
= PsGetCurrentProcess();
122 if (NULL
!= CurrentProcess
)
124 Peb
= CurrentProcess
->Peb
;
129 DbgPrint("<%x>", address
);
133 current_entry
= Peb
->Ldr
->InLoadOrderModuleList
.Flink
;
135 while (current_entry
!= &Peb
->Ldr
->InLoadOrderModuleList
&&
136 current_entry
!= NULL
)
139 CONTAINING_RECORD(current_entry
, LDR_MODULE
, InLoadOrderModuleList
);
141 if (address
>= (PVOID
)current
->BaseAddress
&&
142 address
< (PVOID
)(current
->BaseAddress
+ current
->SizeOfImage
))
144 RelativeAddress
= (ULONG_PTR
) address
- (ULONG_PTR
)current
->BaseAddress
;
145 Status
= LdrGetAddressInformation(¤t
->SymbolInfo
,
150 if (NT_SUCCESS(Status
))
152 DbgPrint("<%wZ: %x (%s:%d (%s))>",
153 ¤t
->BaseDllName
, RelativeAddress
, FileName
, LineNumber
, FunctionName
);
157 DbgPrint("<%wZ: %x>", ¤t
->BaseDllName
, RelativeAddress
);
162 current_entry
= current_entry
->Flink
;
168 KdbPrintAddress(PVOID address
)
170 PLIST_ENTRY current_entry
;
171 MODULE_TEXT_SECTION
* current
;
172 extern LIST_ENTRY ModuleTextListHead
;
173 ULONG_PTR RelativeAddress
;
177 CHAR FunctionName
[256];
179 current_entry
= ModuleTextListHead
.Flink
;
181 while (current_entry
!= &ModuleTextListHead
&&
182 current_entry
!= NULL
)
185 CONTAINING_RECORD(current_entry
, MODULE_TEXT_SECTION
, ListEntry
);
187 if (address
>= (PVOID
)current
->Base
&&
188 address
< (PVOID
)(current
->Base
+ current
->Length
))
190 RelativeAddress
= (ULONG_PTR
) address
- current
->Base
;
191 Status
= LdrGetAddressInformation(¤t
->SymbolInfo
,
196 if (NT_SUCCESS(Status
))
198 DbgPrint("<%ws: %x (%s:%d (%s))>",
199 current
->Name
, RelativeAddress
, FileName
, LineNumber
, FunctionName
);
203 DbgPrint("<%ws: %x>", current
->Name
, RelativeAddress
);
207 current_entry
= current_entry
->Flink
;
213 KdbFreeSymbolsProcess(PPEB Peb
)
215 PLIST_ENTRY CurrentEntry
;
217 PIMAGE_SYMBOL_INFO SymbolInfo
;
222 CurrentEntry
= Peb
->Ldr
->InLoadOrderModuleList
.Flink
;
223 while (CurrentEntry
!= &Peb
->Ldr
->InLoadOrderModuleList
&&
224 CurrentEntry
!= NULL
)
226 Current
= CONTAINING_RECORD(CurrentEntry
, LDR_MODULE
,
227 InLoadOrderModuleList
);
229 SymbolInfo
= &Current
->SymbolInfo
;
230 KdbLdrUnloadModuleSymbols(SymbolInfo
);
232 CurrentEntry
= CurrentEntry
->Flink
;
237 KdbLdrInit(MODULE_TEXT_SECTION
* NtoskrnlTextSection
,
238 MODULE_TEXT_SECTION
* LdrHalTextSection
)
240 RtlZeroMemory(&NtoskrnlTextSection
->SymbolInfo
,
241 sizeof(NtoskrnlTextSection
->SymbolInfo
));
242 NtoskrnlTextSection
->SymbolInfo
.ImageBase
=
243 NtoskrnlTextSection
->OptionalHeader
->ImageBase
;
244 NtoskrnlTextSection
->SymbolInfo
.ImageSize
= NtoskrnlTextSection
->Length
;
246 RtlZeroMemory(&LdrHalTextSection
->SymbolInfo
,
247 sizeof(LdrHalTextSection
->SymbolInfo
));
248 LdrHalTextSection
->SymbolInfo
.ImageBase
=
249 LdrHalTextSection
->OptionalHeader
->ImageBase
;
250 LdrHalTextSection
->SymbolInfo
.ImageSize
= LdrHalTextSection
->Length
;
252 InitializeListHead(&SymbolListHead
);
253 KeInitializeSpinLock(&SymbolListLock
);
257 LdrpParseImageSymbols(PIMAGE_SYMBOL_INFO SymbolInfo
)
258 /* Note: It is important that the symbol strings buffer not be released after
259 this function is called because the strings are still referenced */
261 PSYMBOL CurrentFileNameSymbol
;
262 PSYMBOL CurrentFunctionSymbol
;
263 PSYMBOL CurrentLineNumberSymbol
;
265 PSTAB_ENTRY StabEntry
;
268 ULONG_PTR FunRelativeAddress
;
274 DPRINT("Parsing symbols.\n");
276 SymbolInfo
->FileNameSymbols
.SymbolCount
= 0;
277 SymbolInfo
->FileNameSymbols
.Symbols
= NULL
;
278 SymbolInfo
->FunctionSymbols
.SymbolCount
= 0;
279 SymbolInfo
->FunctionSymbols
.Symbols
= NULL
;
280 SymbolInfo
->LineNumberSymbols
.SymbolCount
= 0;
281 SymbolInfo
->LineNumberSymbols
.Symbols
= NULL
;
282 StabsEnd
= SymbolInfo
->SymbolsBase
+ SymbolInfo
->SymbolsLength
;
283 StabEntry
= (PSTAB_ENTRY
) SymbolInfo
->SymbolsBase
;
284 ImageBase
= SymbolInfo
->ImageBase
;
285 FunRelativeAddress
= 0;
287 CurrentFileNameSymbol
= NULL
;
288 CurrentFunctionSymbol
= NULL
;
289 CurrentLineNumberSymbol
= NULL
;
290 while ((ULONG_PTR
) StabEntry
< (ULONG_PTR
) StabsEnd
)
294 if (StabEntry
->n_type
== N_FUN
)
296 if (StabEntry
->n_desc
> 0)
298 assert(StabEntry
->n_value
>= ImageBase
);
300 FunRelativeAddress
= StabEntry
->n_value
- ImageBase
;
301 FunLineNumber
= StabEntry
->n_desc
;
303 Symbol
= ExAllocatePool(NonPagedPool
, sizeof(SYMBOL
));
306 Symbol
->SymbolType
= ST_FUNCTION
;
307 Symbol
->RelativeAddress
= FunRelativeAddress
;
308 Symbol
->LineNumber
= FunLineNumber
;
309 String
= (PCHAR
)SymbolInfo
->SymbolStringsBase
+ StabEntry
->n_strx
;
310 RtlInitAnsiString(&Symbol
->Name
, String
);
312 DPRINT("FUN found. '%s' %d @ %x\n",
313 Symbol
->Name
.Buffer
, FunLineNumber
, FunRelativeAddress
);
316 else if (StabEntry
->n_type
== N_SLINE
)
318 Symbol
= ExAllocatePool(NonPagedPool
, sizeof(SYMBOL
));
321 Symbol
->SymbolType
= ST_LINENUMBER
;
322 Symbol
->RelativeAddress
= FunRelativeAddress
+ StabEntry
->n_value
;
323 Symbol
->LineNumber
= StabEntry
->n_desc
;
325 DPRINT("SLINE found. %d @ %x\n",
326 Symbol
->LineNumber
, Symbol
->RelativeAddress
);
328 else if (StabEntry
->n_type
== N_SO
)
330 Symbol
= ExAllocatePool(NonPagedPool
, sizeof(SYMBOL
));
333 Symbol
->SymbolType
= ST_FILENAME
;
334 Symbol
->RelativeAddress
= StabEntry
->n_value
- ImageBase
;
335 Symbol
->LineNumber
= 0;
336 String
= (PCHAR
)SymbolInfo
->SymbolStringsBase
+ StabEntry
->n_strx
;
337 RtlInitAnsiString(&Symbol
->Name
, String
);
339 DPRINT("SO found. '%s' @ %x\n",
340 Symbol
->Name
.Buffer
, Symbol
->RelativeAddress
);
345 switch (Symbol
->SymbolType
)
348 if (SymbolInfo
->FileNameSymbols
.Symbols
== NULL
)
349 SymbolInfo
->FileNameSymbols
.Symbols
= Symbol
;
351 CurrentFileNameSymbol
->Next
= Symbol
;
353 CurrentFileNameSymbol
= Symbol
;
355 SymbolInfo
->FileNameSymbols
.SymbolCount
++;
358 if (SymbolInfo
->FunctionSymbols
.Symbols
== NULL
)
359 SymbolInfo
->FunctionSymbols
.Symbols
= Symbol
;
361 CurrentFunctionSymbol
->Next
= Symbol
;
363 CurrentFunctionSymbol
= Symbol
;
365 SymbolInfo
->FunctionSymbols
.SymbolCount
++;
368 if (SymbolInfo
->LineNumberSymbols
.Symbols
== NULL
)
369 SymbolInfo
->LineNumberSymbols
.Symbols
= Symbol
;
371 CurrentLineNumberSymbol
->Next
= Symbol
;
373 CurrentLineNumberSymbol
= Symbol
;
375 SymbolInfo
->LineNumberSymbols
.SymbolCount
++;
385 LdrpGetFileName(IN PIMAGE_SYMBOL_INFO SymbolInfo
,
386 IN ULONG_PTR RelativeAddress
,
390 ULONG_PTR NextAddress
;
393 Symbol
= SymbolInfo
->FileNameSymbols
.Symbols
;
394 while (Symbol
!= NULL
)
396 NextSymbol
= Symbol
->Next
;
397 if (NextSymbol
!= NULL
)
398 NextAddress
= NextSymbol
->RelativeAddress
;
400 NextAddress
= SymbolInfo
->ImageSize
;
402 DPRINT("FN SEARCH: Type %d RelativeAddress %x >= Symbol->RelativeAddress %x < NextAddress %x\n",
403 Symbol
->SymbolType
, RelativeAddress
, Symbol
->RelativeAddress
, NextAddress
);
405 if ((Symbol
->SymbolType
== ST_FILENAME
) &&
406 (RelativeAddress
>= Symbol
->RelativeAddress
) &&
407 (RelativeAddress
< NextAddress
))
409 DPRINT("FN found\n");
410 strcpy(FileName
, Symbol
->Name
.Buffer
);
411 return STATUS_SUCCESS
;
416 DPRINT("FN not found\n");
418 return STATUS_UNSUCCESSFUL
;
422 LdrpGetFunctionName(IN PIMAGE_SYMBOL_INFO SymbolInfo
,
423 IN ULONG_PTR RelativeAddress
,
424 OUT PCH FunctionName
)
427 ULONG_PTR NextAddress
;
430 Symbol
= SymbolInfo
->FunctionSymbols
.Symbols
;
431 while (Symbol
!= NULL
)
433 NextSymbol
= Symbol
->Next
;
434 if (NextSymbol
!= NULL
)
435 NextAddress
= NextSymbol
->RelativeAddress
;
437 NextAddress
= SymbolInfo
->ImageSize
;
439 DPRINT("FUN SEARCH: Type %d RelativeAddress %x >= Symbol->RelativeAddress %x < NextAddress %x\n",
440 Symbol
->SymbolType
, RelativeAddress
, Symbol
->RelativeAddress
, NextAddress
);
442 if ((Symbol
->SymbolType
== ST_FUNCTION
) &&
443 (RelativeAddress
>= Symbol
->RelativeAddress
) &&
444 (RelativeAddress
< NextAddress
))
449 DPRINT("FUN found\n");
451 /* Remove the extra information from the function name */
452 ExtraInfo
= strchr(Symbol
->Name
.Buffer
, ':');
453 if (ExtraInfo
!= NULL
)
454 Length
= ExtraInfo
- Symbol
->Name
.Buffer
;
456 Length
= strlen(Symbol
->Name
.Buffer
);
458 strncpy(FunctionName
, Symbol
->Name
.Buffer
, Length
);
459 return STATUS_SUCCESS
;
464 DPRINT("FUN not found\n");
466 return STATUS_UNSUCCESSFUL
;
470 LdrpGetLineNumber(IN PIMAGE_SYMBOL_INFO SymbolInfo
,
471 IN ULONG_PTR RelativeAddress
,
472 OUT PULONG LineNumber
)
475 ULONG_PTR NextAddress
;
478 Symbol
= SymbolInfo
->LineNumberSymbols
.Symbols
;
479 while (Symbol
!= NULL
)
481 NextSymbol
= Symbol
->Next
;
482 if (NextSymbol
!= NULL
)
483 NextAddress
= NextSymbol
->RelativeAddress
;
485 NextAddress
= SymbolInfo
->ImageSize
;
487 DPRINT("LN SEARCH: Type %d RelativeAddress %x >= Symbol->RelativeAddress %x < NextAddress %x\n",
488 Symbol
->SymbolType
, RelativeAddress
, Symbol
->RelativeAddress
, NextAddress
);
490 if ((Symbol
->SymbolType
== ST_LINENUMBER
) &&
491 (RelativeAddress
>= Symbol
->RelativeAddress
) &&
492 (RelativeAddress
< NextAddress
))
494 DPRINT("LN found\n");
495 *LineNumber
= Symbol
->LineNumber
;
496 return STATUS_SUCCESS
;
501 DPRINT("LN not found\n");
503 return STATUS_UNSUCCESSFUL
;
507 LdrGetAddressInformation(IN PIMAGE_SYMBOL_INFO SymbolInfo
,
508 IN ULONG_PTR RelativeAddress
,
509 OUT PULONG LineNumber
,
510 OUT PCH FileName OPTIONAL
,
511 OUT PCH FunctionName OPTIONAL
)
517 DPRINT("RelativeAddress %p\n", RelativeAddress
);
519 if (RelativeAddress
>= SymbolInfo
->ImageSize
)
521 DPRINT("Address is not within .text section. RelativeAddress %p Length 0x%x\n",
522 RelativeAddress
, SymbolInfo
->ImageSize
);
523 return STATUS_UNSUCCESSFUL
;
526 if (!AreSymbolsParsed(SymbolInfo
))
528 LdrpParseImageSymbols(SymbolInfo
);
531 Status
= LdrpGetLineNumber(SymbolInfo
, RelativeAddress
, LineNumber
);
532 if (!NT_SUCCESS(Status
))
539 Status
= LdrpGetFileName(SymbolInfo
, RelativeAddress
, FileName
);
540 if (!NT_SUCCESS(Status
))
542 strcpy(FileName
, "");
548 Status
= LdrpGetFunctionName(SymbolInfo
, RelativeAddress
, FunctionName
);
549 if (!NT_SUCCESS(Status
))
551 strcpy(FunctionName
, "");
555 return STATUS_SUCCESS
;
559 LdrpLoadModuleSymbols(PUNICODE_STRING FileName
,
560 PIMAGE_SYMBOL_INFO SymbolInfo
)
562 FILE_STANDARD_INFORMATION FileStdInfo
;
563 OBJECT_ATTRIBUTES ObjectAttributes
;
564 WCHAR TmpFileName
[MAX_PATH
];
565 UNICODE_STRING SymFileName
;
571 IO_STATUS_BLOCK IoStatusBlock
;
572 PSYMBOLFILE_HEADER SymbolFileHeader
;
574 /* Get the path to the symbol store */
575 wcscpy(TmpFileName
, L
"\\SystemRoot\\symbols\\");
577 /* Get the symbol filename from the module name */
578 Start
= wcsrchr(FileName
->Buffer
, L
'\\');
580 Start
= FileName
->Buffer
;
584 Ext
= wcsrchr(FileName
->Buffer
, L
'.');
586 Length
= Ext
- Start
;
588 Length
= wcslen(Start
);
590 wcsncat(TmpFileName
, Start
, Length
);
591 wcscat(TmpFileName
, L
".sym");
592 RtlInitUnicodeString(&SymFileName
, TmpFileName
);
595 InitializeObjectAttributes(&ObjectAttributes
,
601 Status
= ZwOpenFile(&FileHandle
,
606 FILE_SYNCHRONOUS_IO_NONALERT
);
607 if (!NT_SUCCESS(Status
))
609 DPRINT("Could not open symbol file: %wZ\n", &SymFileName
);
613 CPRINT("Loading symbols from %wZ...\n", &SymFileName
);
615 /* Get the size of the file */
616 Status
= ZwQueryInformationFile(FileHandle
,
620 FileStandardInformation
);
621 if (!NT_SUCCESS(Status
))
623 DPRINT("Could not get file size\n");
628 /* Allocate nonpageable memory for symbol file */
629 FileBuffer
= ExAllocatePool(NonPagedPool
,
630 FileStdInfo
.EndOfFile
.u
.LowPart
);
632 if (FileBuffer
== NULL
)
634 DPRINT("Could not allocate memory for symbol file\n");
639 /* Load file into memory chunk */
640 Status
= ZwReadFile(FileHandle
,
644 FileStdInfo
.EndOfFile
.u
.LowPart
,
646 if (!NT_SUCCESS(Status
))
648 DPRINT("Could not read symbol file into memory (Status 0x%x)\n", Status
);
649 ExFreePool(FileBuffer
);
656 SymbolFileHeader
= (PSYMBOLFILE_HEADER
) FileBuffer
;
657 SymbolInfo
->FileBuffer
= FileBuffer
;
658 SymbolInfo
->SymbolsBase
= FileBuffer
+ SymbolFileHeader
->StabsOffset
;
659 SymbolInfo
->SymbolsLength
= SymbolFileHeader
->StabsLength
;
660 SymbolInfo
->SymbolStringsBase
= FileBuffer
+ SymbolFileHeader
->StabstrOffset
;
661 SymbolInfo
->SymbolStringsLength
= SymbolFileHeader
->StabstrLength
;
665 KdbLdrUnloadModuleSymbols(PIMAGE_SYMBOL_INFO SymbolInfo
)
670 DPRINT("Unloading symbols\n");
672 if (SymbolInfo
!= NULL
)
674 Symbol
= SymbolInfo
->FileNameSymbols
.Symbols
;
675 while (Symbol
!= NULL
)
677 NextSymbol
= Symbol
->Next
;
678 RtlFreeAnsiString(&Symbol
->Name
);
683 SymbolInfo
->FileNameSymbols
.SymbolCount
= 0;
684 SymbolInfo
->FileNameSymbols
.Symbols
= NULL
;
686 Symbol
= SymbolInfo
->FunctionSymbols
.Symbols
;
687 while (Symbol
!= NULL
)
689 NextSymbol
= Symbol
->Next
;
690 RtlFreeAnsiString(&Symbol
->Name
);
695 SymbolInfo
->FunctionSymbols
.SymbolCount
= 0;
696 SymbolInfo
->FunctionSymbols
.Symbols
= NULL
;
698 Symbol
= SymbolInfo
->LineNumberSymbols
.Symbols
;
699 while (Symbol
!= NULL
)
701 NextSymbol
= Symbol
->Next
;
702 RtlFreeAnsiString(&Symbol
->Name
);
707 SymbolInfo
->LineNumberSymbols
.SymbolCount
= 0;
708 SymbolInfo
->LineNumberSymbols
.Symbols
= NULL
;
710 /* Don't free buffers because we cache symbol buffers
711 (eg. they are shared across processes) */
712 /* FIXME: We can free them if we do reference counting */
713 if (SymbolInfo
->FileBuffer
!= NULL
)
715 ExFreePool(SymbolInfo
->FileBuffer
);
716 SymbolInfo
->FileBuffer
= NULL
;
717 SymbolInfo
->SymbolsBase
= NULL
;
718 SymbolInfo
->SymbolsLength
= 0;
725 PIMAGE_SYMBOL_INFO_CACHE
726 LdrpLookupUserSymbolInfo(PLDR_MODULE LdrModule
)
728 PIMAGE_SYMBOL_INFO_CACHE Current
;
729 PLIST_ENTRY CurrentEntry
;
732 DPRINT("Searching symbols for %S\n", LdrModule
->FullDllName
.Buffer
);
734 KeAcquireSpinLock(&SymbolListLock
, &Irql
);
736 CurrentEntry
= SymbolListHead
.Flink
;
737 while (CurrentEntry
!= (&SymbolListHead
))
739 Current
= CONTAINING_RECORD(CurrentEntry
, IMAGE_SYMBOL_INFO_CACHE
, ListEntry
);
741 if (RtlEqualUnicodeString(&Current
->FullName
, &LdrModule
->FullDllName
, TRUE
))
743 KeReleaseSpinLock(&SymbolListLock
, Irql
);
747 CurrentEntry
= CurrentEntry
->Flink
;
750 KeReleaseSpinLock(&SymbolListLock
, Irql
);
756 KdbLdrLoadUserModuleSymbols(PLDR_MODULE LdrModule
)
758 PIMAGE_SYMBOL_INFO_CACHE CacheEntry
;
760 DPRINT("LdrModule %p\n", LdrModule
);
762 RtlZeroMemory(&LdrModule
->SymbolInfo
, sizeof(LdrModule
->SymbolInfo
));
763 LdrModule
->SymbolInfo
.ImageBase
= (ULONG_PTR
) LdrModule
->BaseAddress
;
764 LdrModule
->SymbolInfo
.ImageSize
= LdrModule
->SizeOfImage
;
766 CacheEntry
= LdrpLookupUserSymbolInfo(LdrModule
);
767 if (CacheEntry
!= NULL
)
769 DPRINT("Symbol cache hit for %S\n", CacheEntry
->FullName
.Buffer
);
771 LdrModule
->SymbolInfo
.FileBuffer
= CacheEntry
->FileBuffer
;
772 LdrModule
->SymbolInfo
.SymbolsBase
= CacheEntry
->SymbolsBase
;
773 LdrModule
->SymbolInfo
.SymbolsLength
= CacheEntry
->SymbolsLength
;
774 LdrModule
->SymbolInfo
.SymbolStringsBase
= CacheEntry
->SymbolStringsBase
;
775 LdrModule
->SymbolInfo
.SymbolStringsLength
= CacheEntry
->SymbolStringsLength
;
779 CacheEntry
= ExAllocatePool(NonPagedPool
, sizeof(IMAGE_SYMBOL_INFO_CACHE
));
781 RtlZeroMemory(CacheEntry
, sizeof(IMAGE_SYMBOL_INFO_CACHE
));
783 RtlCreateUnicodeString(&CacheEntry
->FullName
, LdrModule
->FullDllName
.Buffer
);
784 assert(CacheEntry
->FullName
.Buffer
);
785 LdrpLoadModuleSymbols(&LdrModule
->FullDllName
, &LdrModule
->SymbolInfo
);
786 InsertTailList(&SymbolListHead
, &CacheEntry
->ListEntry
);
791 KdbLoadDriver(PUNICODE_STRING Filename
, PMODULE_OBJECT Module
)
793 /* Load symbols for the image if available */
794 LdrpLoadModuleSymbols(Filename
, &Module
->TextSection
->SymbolInfo
);
798 KdbUnloadDriver(PMODULE_OBJECT ModuleObject
)
800 /* Unload symbols for module if available */
801 KdbLdrUnloadModuleSymbols(&ModuleObject
->TextSection
->SymbolInfo
);
805 KdbProcessSymbolFile(PVOID ModuleLoadBase
, PCHAR FileName
, ULONG Length
)
807 PMODULE_OBJECT ModuleObject
;
808 UNICODE_STRING ModuleName
;
809 CHAR TmpBaseName
[MAX_PATH
];
810 CHAR TmpFileName
[MAX_PATH
];
811 PSYMBOLFILE_HEADER SymbolFileHeader
;
812 PIMAGE_SYMBOL_INFO SymbolInfo
;
813 ANSI_STRING AnsiString
;
815 DPRINT("Module %s is a symbol file\n", FileName
);
817 strncpy(TmpBaseName
, FileName
, Length
);
818 TmpBaseName
[Length
] = '\0';
820 DPRINT("base: %s (Length %d)\n", TmpBaseName
, Length
);
822 strcpy(TmpFileName
, TmpBaseName
);
823 strcat(TmpFileName
, ".sys");
824 RtlInitAnsiString(&AnsiString
, TmpFileName
);
826 RtlAnsiStringToUnicodeString(&ModuleName
, &AnsiString
, TRUE
);
827 ModuleObject
= LdrGetModuleObject(&ModuleName
);
828 RtlFreeUnicodeString(&ModuleName
);
829 if (ModuleObject
== NULL
)
831 strcpy(TmpFileName
, TmpBaseName
);
832 strcat(TmpFileName
, ".exe");
833 RtlInitAnsiString(&AnsiString
, TmpFileName
);
834 RtlAnsiStringToUnicodeString(&ModuleName
, &AnsiString
, TRUE
);
835 ModuleObject
= LdrGetModuleObject(&ModuleName
);
836 RtlFreeUnicodeString(&ModuleName
);
838 if (ModuleObject
!= NULL
)
840 SymbolInfo
= (PIMAGE_SYMBOL_INFO
) &ModuleObject
->TextSection
->SymbolInfo
;
841 SymbolFileHeader
= (PSYMBOLFILE_HEADER
) ModuleLoadBase
;
842 SymbolInfo
->FileBuffer
= ModuleLoadBase
;
843 SymbolInfo
->SymbolsBase
= ModuleLoadBase
+ SymbolFileHeader
->StabsOffset
;
844 SymbolInfo
->SymbolsLength
= SymbolFileHeader
->StabsLength
;
845 SymbolInfo
->SymbolStringsBase
= ModuleLoadBase
+ SymbolFileHeader
->StabstrOffset
;
846 SymbolInfo
->SymbolStringsLength
= SymbolFileHeader
->StabstrLength
;
851 KdbInitializeDriver(PMODULE_TEXT_SECTION ModuleTextSection
)
853 RtlZeroMemory(&ModuleTextSection
->SymbolInfo
, sizeof(ModuleTextSection
->SymbolInfo
));
854 ModuleTextSection
->SymbolInfo
.ImageBase
=
855 ModuleTextSection
->OptionalHeader
->ImageBase
;
856 ModuleTextSection
->SymbolInfo
.ImageSize
= ModuleTextSection
->Length
;
860 KdbLdrLoadAutoConfigDrivers(VOID
)
862 UNICODE_STRING ModuleName
;
863 PMODULE_OBJECT ModuleObject
;
866 * Load symbols for ntoskrnl.exe and hal.dll because \SystemRoot
867 * is created after their module entries
870 RtlInitUnicodeStringFromLiteral(&ModuleName
, KERNEL_MODULE_NAME
);
871 ModuleObject
= LdrGetModuleObject(&ModuleName
);
872 if (ModuleObject
!= NULL
)
874 LdrpLoadModuleSymbols(&ModuleName
,
875 &ModuleObject
->TextSection
->SymbolInfo
);
878 RtlInitUnicodeStringFromLiteral(&ModuleName
, HAL_MODULE_NAME
);
879 ModuleObject
= LdrGetModuleObject(&ModuleName
);
880 if (ModuleObject
!= NULL
)
882 LdrpLoadModuleSymbols(&ModuleName
,
883 &ModuleObject
->TextSection
->SymbolInfo
);