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>
43 #include <rosrtl/string.h>
46 #include <internal/debug.h>
48 /* GLOBALS ******************************************************************/
50 typedef struct _SYMBOLFILE_HEADER
{
51 unsigned long StabsOffset
;
52 unsigned long StabsLength
;
53 unsigned long StabstrOffset
;
54 unsigned long StabstrLength
;
55 } SYMBOLFILE_HEADER
, *PSYMBOLFILE_HEADER
;
57 typedef struct _IMAGE_SYMBOL_INFO_CACHE
{
59 UNICODE_STRING FullName
;
63 PVOID SymbolStringsBase
;
64 ULONG SymbolStringsLength
;
65 } IMAGE_SYMBOL_INFO_CACHE
, *PIMAGE_SYMBOL_INFO_CACHE
;
68 typedef struct _STAB_ENTRY
{
69 unsigned long n_strx
; /* index into string table of name */
70 unsigned char n_type
; /* type of symbol */
71 unsigned char n_other
; /* misc info (usually empty) */
72 unsigned short n_desc
; /* description field */
73 unsigned long n_value
; /* value of symbol */
74 } _STAB_ENTRY
, *PSTAB_ENTRY
;
78 * Value - Relative virtual address
84 * Value - Relative virtual address
89 * String - First containing a '/' is the compillation directory (CD)
90 * Not containing a '/' is a source file relative to CD
94 static LIST_ENTRY SymbolListHead
;
95 static KSPIN_LOCK SymbolListLock
;
98 LdrGetAddressInformation(IN PIMAGE_SYMBOL_INFO SymbolInfo
,
99 IN ULONG_PTR RelativeAddress
,
100 OUT PULONG LineNumber
,
101 OUT PCH FileName OPTIONAL
,
102 OUT PCH FunctionName OPTIONAL
);
105 KdbLdrUnloadModuleSymbols(PIMAGE_SYMBOL_INFO SymbolInfo
);
107 /* FUNCTIONS ****************************************************************/
110 KdbPrintUserAddress(PVOID address
)
112 PLIST_ENTRY current_entry
;
114 PEPROCESS CurrentProcess
;
116 ULONG_PTR RelativeAddress
;
120 CHAR FunctionName
[256];
122 CurrentProcess
= PsGetCurrentProcess();
123 if (NULL
!= CurrentProcess
)
125 Peb
= CurrentProcess
->Peb
;
130 DbgPrint("<%x>", address
);
134 current_entry
= Peb
->Ldr
->InLoadOrderModuleList
.Flink
;
136 while (current_entry
!= &Peb
->Ldr
->InLoadOrderModuleList
&&
137 current_entry
!= NULL
)
140 CONTAINING_RECORD(current_entry
, LDR_MODULE
, InLoadOrderModuleList
);
142 if (address
>= (PVOID
)current
->BaseAddress
&&
143 address
< (PVOID
)((char*)current
->BaseAddress
+ current
->SizeOfImage
))
145 RelativeAddress
= (ULONG_PTR
) address
- (ULONG_PTR
)current
->BaseAddress
;
146 Status
= LdrGetAddressInformation(¤t
->SymbolInfo
,
151 if (NT_SUCCESS(Status
))
153 DbgPrint("<%wZ: %x (%s:%d (%s))>",
154 ¤t
->BaseDllName
, RelativeAddress
, FileName
, LineNumber
, FunctionName
);
158 DbgPrint("<%wZ: %x>", ¤t
->BaseDllName
, RelativeAddress
);
163 current_entry
= current_entry
->Flink
;
169 KdbPrintAddress(PVOID address
)
171 PLIST_ENTRY current_entry
;
172 MODULE_TEXT_SECTION
* current
;
173 extern LIST_ENTRY ModuleTextListHead
;
174 ULONG_PTR RelativeAddress
;
178 CHAR FunctionName
[256];
180 current_entry
= ModuleTextListHead
.Flink
;
182 while (current_entry
!= &ModuleTextListHead
&&
183 current_entry
!= NULL
)
186 CONTAINING_RECORD(current_entry
, MODULE_TEXT_SECTION
, ListEntry
);
188 if (address
>= (PVOID
)current
->Base
&&
189 address
< (PVOID
)(current
->Base
+ current
->Length
))
191 RelativeAddress
= (ULONG_PTR
) address
- current
->Base
;
192 Status
= LdrGetAddressInformation(¤t
->SymbolInfo
,
197 if (NT_SUCCESS(Status
))
199 DbgPrint("<%ws: %x (%s:%d (%s))>",
200 current
->Name
, RelativeAddress
, FileName
, LineNumber
, FunctionName
);
204 DbgPrint("<%ws: %x>", current
->Name
, RelativeAddress
);
208 current_entry
= current_entry
->Flink
;
214 KdbFreeSymbolsProcess(PEPROCESS Process
)
216 PLIST_ENTRY CurrentEntry
;
218 PIMAGE_SYMBOL_INFO SymbolInfo
;
219 PEPROCESS CurrentProcess
;
222 CurrentProcess
= PsGetCurrentProcess();
223 if (CurrentProcess
!= Process
)
225 KeAttachProcess(Process
);
231 CurrentEntry
= Peb
->Ldr
->InLoadOrderModuleList
.Flink
;
232 while (CurrentEntry
!= &Peb
->Ldr
->InLoadOrderModuleList
&&
233 CurrentEntry
!= NULL
)
235 Current
= CONTAINING_RECORD(CurrentEntry
, LDR_MODULE
,
236 InLoadOrderModuleList
);
238 SymbolInfo
= &Current
->SymbolInfo
;
239 KdbLdrUnloadModuleSymbols(SymbolInfo
);
241 CurrentEntry
= CurrentEntry
->Flink
;
243 if (CurrentProcess
!= Process
)
250 KdbLdrInit(MODULE_TEXT_SECTION
* NtoskrnlTextSection
,
251 MODULE_TEXT_SECTION
* LdrHalTextSection
)
253 RtlZeroMemory(&NtoskrnlTextSection
->SymbolInfo
,
254 sizeof(NtoskrnlTextSection
->SymbolInfo
));
255 NtoskrnlTextSection
->SymbolInfo
.ImageBase
=
256 NtoskrnlTextSection
->OptionalHeader
->ImageBase
;
257 NtoskrnlTextSection
->SymbolInfo
.ImageSize
= NtoskrnlTextSection
->Length
;
259 RtlZeroMemory(&LdrHalTextSection
->SymbolInfo
,
260 sizeof(LdrHalTextSection
->SymbolInfo
));
261 LdrHalTextSection
->SymbolInfo
.ImageBase
=
262 LdrHalTextSection
->OptionalHeader
->ImageBase
;
263 LdrHalTextSection
->SymbolInfo
.ImageSize
= LdrHalTextSection
->Length
;
265 InitializeListHead(&SymbolListHead
);
266 KeInitializeSpinLock(&SymbolListLock
);
270 LdrpParseImageSymbols(PIMAGE_SYMBOL_INFO SymbolInfo
)
271 /* Note: It is important that the symbol strings buffer not be released after
272 this function is called because the strings are still referenced */
274 PSYMBOL CurrentFileNameSymbol
;
275 PSYMBOL CurrentFunctionSymbol
;
276 PSYMBOL CurrentLineNumberSymbol
;
278 PSTAB_ENTRY StabEntry
;
281 ULONG_PTR FunRelativeAddress
;
287 DPRINT("Parsing symbols.\n");
289 SymbolInfo
->FileNameSymbols
.SymbolCount
= 0;
290 SymbolInfo
->FileNameSymbols
.Symbols
= NULL
;
291 SymbolInfo
->FunctionSymbols
.SymbolCount
= 0;
292 SymbolInfo
->FunctionSymbols
.Symbols
= NULL
;
293 SymbolInfo
->LineNumberSymbols
.SymbolCount
= 0;
294 SymbolInfo
->LineNumberSymbols
.Symbols
= NULL
;
295 StabsEnd
= SymbolInfo
->SymbolsBase
+ SymbolInfo
->SymbolsLength
;
296 StabEntry
= (PSTAB_ENTRY
) SymbolInfo
->SymbolsBase
;
297 ImageBase
= SymbolInfo
->ImageBase
;
298 FunRelativeAddress
= 0;
300 CurrentFileNameSymbol
= NULL
;
301 CurrentFunctionSymbol
= NULL
;
302 CurrentLineNumberSymbol
= NULL
;
303 while ((ULONG_PTR
) StabEntry
< (ULONG_PTR
) StabsEnd
)
307 if (StabEntry
->n_type
== N_FUN
)
309 if (StabEntry
->n_desc
> 0)
311 assert(StabEntry
->n_value
>= ImageBase
);
313 FunRelativeAddress
= StabEntry
->n_value
- ImageBase
;
314 FunLineNumber
= StabEntry
->n_desc
;
316 Symbol
= ExAllocatePool(NonPagedPool
, sizeof(SYMBOL
));
319 Symbol
->SymbolType
= ST_FUNCTION
;
320 Symbol
->RelativeAddress
= FunRelativeAddress
;
321 Symbol
->LineNumber
= FunLineNumber
;
322 String
= (PCHAR
)SymbolInfo
->SymbolStringsBase
+ StabEntry
->n_strx
;
323 RtlInitAnsiString(&Symbol
->Name
, String
);
325 DPRINT("FUN found. '%s' %d @ %x\n",
326 Symbol
->Name
.Buffer
, FunLineNumber
, FunRelativeAddress
);
329 else if (StabEntry
->n_type
== N_SLINE
)
331 Symbol
= ExAllocatePool(NonPagedPool
, sizeof(SYMBOL
));
334 Symbol
->SymbolType
= ST_LINENUMBER
;
335 Symbol
->RelativeAddress
= FunRelativeAddress
+ StabEntry
->n_value
;
336 Symbol
->LineNumber
= StabEntry
->n_desc
;
338 DPRINT("SLINE found. %d @ %x\n",
339 Symbol
->LineNumber
, Symbol
->RelativeAddress
);
341 else if (StabEntry
->n_type
== N_SO
)
343 Symbol
= ExAllocatePool(NonPagedPool
, sizeof(SYMBOL
));
346 Symbol
->SymbolType
= ST_FILENAME
;
347 Symbol
->RelativeAddress
= StabEntry
->n_value
- ImageBase
;
348 Symbol
->LineNumber
= 0;
349 String
= (PCHAR
)SymbolInfo
->SymbolStringsBase
+ StabEntry
->n_strx
;
350 RtlInitAnsiString(&Symbol
->Name
, String
);
352 DPRINT("SO found. '%s' @ %x\n",
353 Symbol
->Name
.Buffer
, Symbol
->RelativeAddress
);
358 switch (Symbol
->SymbolType
)
361 if (SymbolInfo
->FileNameSymbols
.Symbols
== NULL
)
362 SymbolInfo
->FileNameSymbols
.Symbols
= Symbol
;
364 CurrentFileNameSymbol
->Next
= Symbol
;
366 CurrentFileNameSymbol
= Symbol
;
368 SymbolInfo
->FileNameSymbols
.SymbolCount
++;
371 if (SymbolInfo
->FunctionSymbols
.Symbols
== NULL
)
372 SymbolInfo
->FunctionSymbols
.Symbols
= Symbol
;
374 CurrentFunctionSymbol
->Next
= Symbol
;
376 CurrentFunctionSymbol
= Symbol
;
378 SymbolInfo
->FunctionSymbols
.SymbolCount
++;
381 if (SymbolInfo
->LineNumberSymbols
.Symbols
== NULL
)
382 SymbolInfo
->LineNumberSymbols
.Symbols
= Symbol
;
384 CurrentLineNumberSymbol
->Next
= Symbol
;
386 CurrentLineNumberSymbol
= Symbol
;
388 SymbolInfo
->LineNumberSymbols
.SymbolCount
++;
398 LdrpGetFileName(IN PIMAGE_SYMBOL_INFO SymbolInfo
,
399 IN ULONG_PTR RelativeAddress
,
403 ULONG_PTR NextAddress
;
406 Symbol
= SymbolInfo
->FileNameSymbols
.Symbols
;
407 while (Symbol
!= NULL
)
409 NextSymbol
= Symbol
->Next
;
410 if (NextSymbol
!= NULL
)
411 NextAddress
= NextSymbol
->RelativeAddress
;
413 NextAddress
= SymbolInfo
->ImageSize
;
415 DPRINT("FN SEARCH: Type %d RelativeAddress %x >= Symbol->RelativeAddress %x < NextAddress %x\n",
416 Symbol
->SymbolType
, RelativeAddress
, Symbol
->RelativeAddress
, NextAddress
);
418 if ((Symbol
->SymbolType
== ST_FILENAME
) &&
419 (RelativeAddress
>= Symbol
->RelativeAddress
) &&
420 (RelativeAddress
< NextAddress
))
422 DPRINT("FN found\n");
423 strcpy(FileName
, Symbol
->Name
.Buffer
);
424 return STATUS_SUCCESS
;
429 DPRINT("FN not found\n");
431 return STATUS_UNSUCCESSFUL
;
435 LdrpGetFunctionName(IN PIMAGE_SYMBOL_INFO SymbolInfo
,
436 IN ULONG_PTR RelativeAddress
,
437 OUT PCH FunctionName
)
440 ULONG_PTR NextAddress
;
443 Symbol
= SymbolInfo
->FunctionSymbols
.Symbols
;
444 while (Symbol
!= NULL
)
446 NextSymbol
= Symbol
->Next
;
447 if (NextSymbol
!= NULL
)
448 NextAddress
= NextSymbol
->RelativeAddress
;
450 NextAddress
= SymbolInfo
->ImageSize
;
452 DPRINT("FUN SEARCH: Type %d RelativeAddress %x >= Symbol->RelativeAddress %x < NextAddress %x\n",
453 Symbol
->SymbolType
, RelativeAddress
, Symbol
->RelativeAddress
, NextAddress
);
455 if ((Symbol
->SymbolType
== ST_FUNCTION
) &&
456 (RelativeAddress
>= Symbol
->RelativeAddress
) &&
457 (RelativeAddress
< NextAddress
))
462 DPRINT("FUN found\n");
464 /* Remove the extra information from the function name */
465 ExtraInfo
= strchr(Symbol
->Name
.Buffer
, ':');
466 if (ExtraInfo
!= NULL
)
467 Length
= ExtraInfo
- Symbol
->Name
.Buffer
;
469 Length
= strlen(Symbol
->Name
.Buffer
);
471 strncpy(FunctionName
, Symbol
->Name
.Buffer
, Length
);
472 FunctionName
[Length
]=0;
473 return STATUS_SUCCESS
;
478 DPRINT("FUN not found\n");
480 return STATUS_UNSUCCESSFUL
;
484 LdrpGetLineNumber(IN PIMAGE_SYMBOL_INFO SymbolInfo
,
485 IN ULONG_PTR RelativeAddress
,
486 OUT PULONG LineNumber
)
489 ULONG_PTR NextAddress
;
492 Symbol
= SymbolInfo
->LineNumberSymbols
.Symbols
;
493 while (Symbol
!= NULL
)
495 NextSymbol
= Symbol
->Next
;
496 if (NextSymbol
!= NULL
)
497 NextAddress
= NextSymbol
->RelativeAddress
;
499 NextAddress
= SymbolInfo
->ImageSize
;
501 DPRINT("LN SEARCH: Type %d RelativeAddress %x >= Symbol->RelativeAddress %x < NextAddress %x\n",
502 Symbol
->SymbolType
, RelativeAddress
, Symbol
->RelativeAddress
, NextAddress
);
504 if ((Symbol
->SymbolType
== ST_LINENUMBER
) &&
505 (RelativeAddress
>= Symbol
->RelativeAddress
) &&
506 (RelativeAddress
< NextAddress
))
508 DPRINT("LN found\n");
509 *LineNumber
= Symbol
->LineNumber
;
510 return STATUS_SUCCESS
;
515 DPRINT("LN not found\n");
517 return STATUS_UNSUCCESSFUL
;
521 LdrGetAddressInformation(IN PIMAGE_SYMBOL_INFO SymbolInfo
,
522 IN ULONG_PTR RelativeAddress
,
523 OUT PULONG LineNumber
,
524 OUT PCH FileName OPTIONAL
,
525 OUT PCH FunctionName OPTIONAL
)
531 DPRINT("RelativeAddress %p\n", RelativeAddress
);
533 if (RelativeAddress
>= SymbolInfo
->ImageSize
)
535 DPRINT("Address is not within .text section. RelativeAddress %p Length 0x%x\n",
536 RelativeAddress
, SymbolInfo
->ImageSize
);
537 return STATUS_UNSUCCESSFUL
;
540 if (!AreSymbolsParsed(SymbolInfo
))
542 LdrpParseImageSymbols(SymbolInfo
);
545 Status
= LdrpGetLineNumber(SymbolInfo
, RelativeAddress
, LineNumber
);
546 if (!NT_SUCCESS(Status
))
548 DPRINT("LdrpGetLineNumber failed (%08x)\n", Status
);
554 Status
= LdrpGetFileName(SymbolInfo
, RelativeAddress
, FileName
);
555 if (!NT_SUCCESS(Status
))
557 strcpy(FileName
, "");
563 Status
= LdrpGetFunctionName(SymbolInfo
, RelativeAddress
, FunctionName
);
564 if (!NT_SUCCESS(Status
))
566 strcpy(FunctionName
, "");
570 return STATUS_SUCCESS
;
574 LdrpLoadModuleSymbols(PUNICODE_STRING FileName
,
575 PIMAGE_SYMBOL_INFO SymbolInfo
)
577 FILE_STANDARD_INFORMATION FileStdInfo
;
578 OBJECT_ATTRIBUTES ObjectAttributes
;
579 WCHAR TmpFileName
[MAX_PATH
];
580 UNICODE_STRING SymFileName
;
586 IO_STATUS_BLOCK IoStatusBlock
;
587 PSYMBOLFILE_HEADER SymbolFileHeader
;
589 /* Get the path to the symbol store */
590 wcscpy(TmpFileName
, L
"\\SystemRoot\\symbols\\");
592 /* Get the symbol filename from the module name */
593 Start
= wcsrchr(FileName
->Buffer
, L
'\\');
595 Start
= FileName
->Buffer
;
599 Ext
= wcsrchr(FileName
->Buffer
, L
'.');
601 Length
= Ext
- Start
;
603 Length
= wcslen(Start
);
605 wcsncat(TmpFileName
, Start
, Length
);
606 wcscat(TmpFileName
, L
".sym");
607 RtlInitUnicodeString(&SymFileName
, TmpFileName
);
610 InitializeObjectAttributes(&ObjectAttributes
,
616 Status
= ZwOpenFile(&FileHandle
,
621 FILE_SYNCHRONOUS_IO_NONALERT
);
622 if (!NT_SUCCESS(Status
))
624 DPRINT("Could not open symbol file: %wZ\n", &SymFileName
);
628 CPRINT("Loading symbols from %wZ...\n", &SymFileName
);
630 /* Get the size of the file */
631 Status
= ZwQueryInformationFile(FileHandle
,
635 FileStandardInformation
);
636 if (!NT_SUCCESS(Status
))
638 DPRINT("Could not get file size\n");
643 /* Allocate nonpageable memory for symbol file */
644 FileBuffer
= ExAllocatePool(NonPagedPool
,
645 FileStdInfo
.EndOfFile
.u
.LowPart
);
647 if (FileBuffer
== NULL
)
649 DPRINT("Could not allocate memory for symbol file\n");
654 /* Load file into memory chunk */
655 Status
= ZwReadFile(FileHandle
,
659 FileStdInfo
.EndOfFile
.u
.LowPart
,
661 if (!NT_SUCCESS(Status
))
663 DPRINT("Could not read symbol file into memory (Status 0x%x)\n", Status
);
664 ExFreePool(FileBuffer
);
671 SymbolFileHeader
= (PSYMBOLFILE_HEADER
) FileBuffer
;
672 SymbolInfo
->FileBuffer
= FileBuffer
;
673 SymbolInfo
->SymbolsBase
= FileBuffer
+ SymbolFileHeader
->StabsOffset
;
674 SymbolInfo
->SymbolsLength
= SymbolFileHeader
->StabsLength
;
675 SymbolInfo
->SymbolStringsBase
= FileBuffer
+ SymbolFileHeader
->StabstrOffset
;
676 SymbolInfo
->SymbolStringsLength
= SymbolFileHeader
->StabstrLength
;
680 KdbLdrUnloadModuleSymbols(PIMAGE_SYMBOL_INFO SymbolInfo
)
685 DPRINT("Unloading symbols\n");
687 if (SymbolInfo
!= NULL
)
689 Symbol
= SymbolInfo
->FileNameSymbols
.Symbols
;
690 while (Symbol
!= NULL
)
692 NextSymbol
= Symbol
->Next
;
693 RtlFreeAnsiString(&Symbol
->Name
);
698 SymbolInfo
->FileNameSymbols
.SymbolCount
= 0;
699 SymbolInfo
->FileNameSymbols
.Symbols
= NULL
;
701 Symbol
= SymbolInfo
->FunctionSymbols
.Symbols
;
702 while (Symbol
!= NULL
)
704 NextSymbol
= Symbol
->Next
;
705 RtlFreeAnsiString(&Symbol
->Name
);
710 SymbolInfo
->FunctionSymbols
.SymbolCount
= 0;
711 SymbolInfo
->FunctionSymbols
.Symbols
= NULL
;
713 Symbol
= SymbolInfo
->LineNumberSymbols
.Symbols
;
714 while (Symbol
!= NULL
)
716 NextSymbol
= Symbol
->Next
;
717 RtlFreeAnsiString(&Symbol
->Name
);
722 SymbolInfo
->LineNumberSymbols
.SymbolCount
= 0;
723 SymbolInfo
->LineNumberSymbols
.Symbols
= NULL
;
725 /* Don't free buffers because we cache symbol buffers
726 (eg. they are shared across processes) */
727 /* FIXME: We can free them if we do reference counting */
728 if (SymbolInfo
->FileBuffer
!= NULL
)
730 ExFreePool(SymbolInfo
->FileBuffer
);
731 SymbolInfo
->FileBuffer
= NULL
;
732 SymbolInfo
->SymbolsBase
= NULL
;
733 SymbolInfo
->SymbolsLength
= 0;
740 PIMAGE_SYMBOL_INFO_CACHE
741 LdrpLookupUserSymbolInfo(PLDR_MODULE LdrModule
)
743 PIMAGE_SYMBOL_INFO_CACHE Current
;
744 PLIST_ENTRY CurrentEntry
;
747 DPRINT("Searching symbols for %S\n", LdrModule
->FullDllName
.Buffer
);
749 KeAcquireSpinLock(&SymbolListLock
, &Irql
);
751 CurrentEntry
= SymbolListHead
.Flink
;
752 while (CurrentEntry
!= (&SymbolListHead
))
754 Current
= CONTAINING_RECORD(CurrentEntry
, IMAGE_SYMBOL_INFO_CACHE
, ListEntry
);
756 if (RtlEqualUnicodeString(&Current
->FullName
, &LdrModule
->FullDllName
, TRUE
))
758 KeReleaseSpinLock(&SymbolListLock
, Irql
);
762 CurrentEntry
= CurrentEntry
->Flink
;
765 KeReleaseSpinLock(&SymbolListLock
, Irql
);
771 KdbLdrLoadUserModuleSymbols(PLDR_MODULE LdrModule
)
773 PIMAGE_SYMBOL_INFO_CACHE CacheEntry
;
775 DPRINT("LdrModule %p\n", LdrModule
);
777 RtlZeroMemory(&LdrModule
->SymbolInfo
, sizeof(LdrModule
->SymbolInfo
));
778 LdrModule
->SymbolInfo
.ImageBase
= (ULONG_PTR
) LdrModule
->BaseAddress
;
779 LdrModule
->SymbolInfo
.ImageSize
= LdrModule
->SizeOfImage
;
781 CacheEntry
= LdrpLookupUserSymbolInfo(LdrModule
);
782 if (CacheEntry
!= NULL
)
784 DPRINT("Symbol cache hit for %S\n", CacheEntry
->FullName
.Buffer
);
786 LdrModule
->SymbolInfo
.FileBuffer
= CacheEntry
->FileBuffer
;
787 LdrModule
->SymbolInfo
.SymbolsBase
= CacheEntry
->SymbolsBase
;
788 LdrModule
->SymbolInfo
.SymbolsLength
= CacheEntry
->SymbolsLength
;
789 LdrModule
->SymbolInfo
.SymbolStringsBase
= CacheEntry
->SymbolStringsBase
;
790 LdrModule
->SymbolInfo
.SymbolStringsLength
= CacheEntry
->SymbolStringsLength
;
794 CacheEntry
= ExAllocatePool(NonPagedPool
, sizeof(IMAGE_SYMBOL_INFO_CACHE
));
796 RtlZeroMemory(CacheEntry
, sizeof(IMAGE_SYMBOL_INFO_CACHE
));
798 RtlCreateUnicodeString(&CacheEntry
->FullName
, LdrModule
->FullDllName
.Buffer
);
799 assert(CacheEntry
->FullName
.Buffer
);
800 LdrpLoadModuleSymbols(&LdrModule
->FullDllName
, &LdrModule
->SymbolInfo
);
801 CacheEntry
->FileBuffer
= LdrModule
->SymbolInfo
.FileBuffer
;
802 CacheEntry
->SymbolsBase
= LdrModule
->SymbolInfo
.SymbolsBase
;
803 CacheEntry
->SymbolsLength
= LdrModule
->SymbolInfo
.SymbolsLength
;
804 CacheEntry
->SymbolStringsBase
= LdrModule
->SymbolInfo
.SymbolStringsBase
;
805 CacheEntry
->SymbolStringsLength
= LdrModule
->SymbolInfo
.SymbolStringsLength
;
806 InsertTailList(&SymbolListHead
, &CacheEntry
->ListEntry
);
811 KdbLoadDriver(PUNICODE_STRING Filename
, PMODULE_OBJECT Module
)
813 /* Load symbols for the image if available */
814 LdrpLoadModuleSymbols(Filename
, &Module
->TextSection
->SymbolInfo
);
818 KdbUnloadDriver(PMODULE_OBJECT ModuleObject
)
820 /* Unload symbols for module if available */
821 KdbLdrUnloadModuleSymbols(&ModuleObject
->TextSection
->SymbolInfo
);
824 /* Length here is the length of the loaded module, not the file name. */
827 KdbProcessSymbolFile(PVOID ModuleLoadBase
, PCHAR FileName
, ULONG Length
)
829 PMODULE_OBJECT ModuleObject
;
830 UNICODE_STRING ModuleName
;
831 CHAR TmpBaseName
[MAX_PATH
];
832 CHAR TmpFileName
[MAX_PATH
];
833 PSYMBOLFILE_HEADER SymbolFileHeader
;
834 PIMAGE_SYMBOL_INFO SymbolInfo
;
835 ANSI_STRING AnsiString
;
837 DPRINT("Module %s is a symbol file\n", FileName
);
839 strncpy(TmpBaseName
, FileName
, MAX_PATH
-1);
840 TmpBaseName
[MAX_PATH
-1] = '\0';
842 DPRINT("base: %s (Length %d)\n", TmpBaseName
, Length
);
844 strcpy(TmpFileName
, TmpBaseName
);
845 strcat(TmpFileName
, ".sys");
846 RtlInitAnsiString(&AnsiString
, TmpFileName
);
848 RtlAnsiStringToUnicodeString(&ModuleName
, &AnsiString
, TRUE
);
849 ModuleObject
= LdrGetModuleObject(&ModuleName
);
850 RtlFreeUnicodeString(&ModuleName
);
851 if (ModuleObject
== NULL
)
853 strcpy(TmpFileName
, TmpBaseName
);
854 strcat(TmpFileName
, ".exe");
855 RtlInitAnsiString(&AnsiString
, TmpFileName
);
856 RtlAnsiStringToUnicodeString(&ModuleName
, &AnsiString
, TRUE
);
857 ModuleObject
= LdrGetModuleObject(&ModuleName
);
858 RtlFreeUnicodeString(&ModuleName
);
860 if (ModuleObject
!= NULL
)
862 SymbolInfo
= (PIMAGE_SYMBOL_INFO
) &ModuleObject
->TextSection
->SymbolInfo
;
863 SymbolFileHeader
= (PSYMBOLFILE_HEADER
) ModuleLoadBase
;
864 SymbolInfo
->FileBuffer
= ModuleLoadBase
;
865 SymbolInfo
->SymbolsBase
= ModuleLoadBase
+ SymbolFileHeader
->StabsOffset
;
866 SymbolInfo
->SymbolsLength
= SymbolFileHeader
->StabsLength
;
867 SymbolInfo
->SymbolStringsBase
= ModuleLoadBase
+ SymbolFileHeader
->StabstrOffset
;
868 SymbolInfo
->SymbolStringsLength
= SymbolFileHeader
->StabstrLength
;
873 KdbInitializeDriver(PMODULE_TEXT_SECTION ModuleTextSection
)
875 RtlZeroMemory(&ModuleTextSection
->SymbolInfo
, sizeof(ModuleTextSection
->SymbolInfo
));
876 ModuleTextSection
->SymbolInfo
.ImageBase
=
877 ModuleTextSection
->OptionalHeader
->ImageBase
;
878 ModuleTextSection
->SymbolInfo
.ImageSize
= ModuleTextSection
->Length
;
882 KdbLdrLoadAutoConfigDrivers(VOID
)
884 UNICODE_STRING ModuleName
;
885 PMODULE_OBJECT ModuleObject
;
888 * Load symbols for ntoskrnl.exe and hal.dll because \SystemRoot
889 * is created after their module entries
892 RtlRosInitUnicodeStringFromLiteral(&ModuleName
, KERNEL_MODULE_NAME
);
893 ModuleObject
= LdrGetModuleObject(&ModuleName
);
894 if (ModuleObject
!= NULL
)
896 LdrpLoadModuleSymbols(&ModuleName
,
897 &ModuleObject
->TextSection
->SymbolInfo
);
900 RtlRosInitUnicodeStringFromLiteral(&ModuleName
, HAL_MODULE_NAME
);
901 ModuleObject
= LdrGetModuleObject(&ModuleName
);
902 if (ModuleObject
!= NULL
)
904 LdrpLoadModuleSymbols(&ModuleName
,
905 &ModuleObject
->TextSection
->SymbolInfo
);