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
;
210 return KdbPrintUserAddress(address
);
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
;
304 DPRINT("Starting Parse: %08x to %08x\n", StabEntry
, StabsEnd
);
306 while ((ULONG_PTR
) StabEntry
< (ULONG_PTR
) StabsEnd
)
310 if (StabEntry
->n_type
== N_FUN
)
312 if (StabEntry
->n_desc
> 0)
314 assert(StabEntry
->n_value
>= ImageBase
);
316 FunRelativeAddress
= StabEntry
->n_value
- ImageBase
;
317 FunLineNumber
= StabEntry
->n_desc
;
319 Symbol
= ExAllocatePool(NonPagedPool
, sizeof(SYMBOL
));
322 Symbol
->SymbolType
= ST_FUNCTION
;
323 Symbol
->RelativeAddress
= FunRelativeAddress
;
324 Symbol
->LineNumber
= FunLineNumber
;
325 String
= (PCHAR
)SymbolInfo
->SymbolStringsBase
+ StabEntry
->n_strx
;
326 RtlInitAnsiString(&Symbol
->Name
, String
);
329 DPRINT("FUN found. '%s' %d @ %x\n",
330 Symbol
->Name
.Buffer
, FunLineNumber
, FunRelativeAddress
);
334 else if (StabEntry
->n_type
== N_SLINE
)
336 Symbol
= ExAllocatePool(NonPagedPool
, sizeof(SYMBOL
));
339 Symbol
->SymbolType
= ST_LINENUMBER
;
340 Symbol
->RelativeAddress
= FunRelativeAddress
+ StabEntry
->n_value
;
341 Symbol
->LineNumber
= StabEntry
->n_desc
;
344 DPRINT("SLINE found. %d @ %x\n",
345 Symbol
->LineNumber
, Symbol
->RelativeAddress
);
348 else if (StabEntry
->n_type
== N_SO
)
350 Symbol
= ExAllocatePool(NonPagedPool
, sizeof(SYMBOL
));
353 Symbol
->SymbolType
= ST_FILENAME
;
354 Symbol
->RelativeAddress
= StabEntry
->n_value
- ImageBase
;
355 Symbol
->LineNumber
= 0;
356 String
= (PCHAR
)SymbolInfo
->SymbolStringsBase
+ StabEntry
->n_strx
;
357 RtlInitAnsiString(&Symbol
->Name
, String
);
360 DPRINT("SO found. '%s' @ %x\n",
361 Symbol
->Name
.Buffer
, Symbol
->RelativeAddress
);
367 switch (Symbol
->SymbolType
)
370 if (SymbolInfo
->FileNameSymbols
.Symbols
== NULL
)
371 SymbolInfo
->FileNameSymbols
.Symbols
= Symbol
;
373 CurrentFileNameSymbol
->Next
= Symbol
;
375 CurrentFileNameSymbol
= Symbol
;
377 SymbolInfo
->FileNameSymbols
.SymbolCount
++;
380 if (SymbolInfo
->FunctionSymbols
.Symbols
== NULL
)
381 SymbolInfo
->FunctionSymbols
.Symbols
= Symbol
;
383 CurrentFunctionSymbol
->Next
= Symbol
;
385 CurrentFunctionSymbol
= Symbol
;
387 SymbolInfo
->FunctionSymbols
.SymbolCount
++;
390 if (SymbolInfo
->LineNumberSymbols
.Symbols
== NULL
)
391 SymbolInfo
->LineNumberSymbols
.Symbols
= Symbol
;
393 CurrentLineNumberSymbol
->Next
= Symbol
;
395 CurrentLineNumberSymbol
= Symbol
;
397 SymbolInfo
->LineNumberSymbols
.SymbolCount
++;
407 LdrpGetFileName(IN PIMAGE_SYMBOL_INFO SymbolInfo
,
408 IN ULONG_PTR RelativeAddress
,
412 ULONG_PTR NextAddress
;
413 ULONG_PTR AddrFound
= 0;
416 Symbol
= SymbolInfo
->FileNameSymbols
.Symbols
;
417 while (Symbol
!= NULL
)
419 NextSymbol
= Symbol
->Next
;
420 if (NextSymbol
!= NULL
)
421 NextAddress
= NextSymbol
->RelativeAddress
;
423 NextAddress
= SymbolInfo
->ImageSize
;
425 DPRINT("FN SEARCH: Type %d RelativeAddress %x >= Symbol->RelativeAddress %x < NextAddress %x\n",
426 Symbol
->SymbolType
, RelativeAddress
, Symbol
->RelativeAddress
, NextAddress
);
428 if ((Symbol
->SymbolType
== ST_FILENAME
) &&
429 (RelativeAddress
>= Symbol
->RelativeAddress
) &&
430 (RelativeAddress
< NextAddress
) &&
431 Symbol
->RelativeAddress
> AddrFound
)
433 DPRINT("FN found\n");
434 strcpy(FileName
, Symbol
->Name
.Buffer
);
435 AddrFound
= Symbol
->RelativeAddress
;
440 DPRINT("FN not found\n");
442 return AddrFound
? STATUS_SUCCESS
: STATUS_UNSUCCESSFUL
;
446 LdrpGetFunctionName(IN PIMAGE_SYMBOL_INFO SymbolInfo
,
447 IN ULONG_PTR RelativeAddress
,
448 OUT PCH FunctionName
)
451 ULONG_PTR NextAddress
;
452 ULONG_PTR AddrFound
= 0;
455 Symbol
= SymbolInfo
->FunctionSymbols
.Symbols
;
456 while (Symbol
!= NULL
)
458 NextSymbol
= Symbol
->Next
;
459 if (NextSymbol
!= NULL
)
460 NextAddress
= NextSymbol
->RelativeAddress
;
462 NextAddress
= SymbolInfo
->ImageSize
;
465 DPRINT("FUN SEARCH: Type %d RelativeAddress %x >= Symbol->RelativeAddress %x < NextAddress %x\n",
466 Symbol
->SymbolType
, RelativeAddress
, Symbol
->RelativeAddress
, NextAddress
);
469 if ((Symbol
->SymbolType
== ST_FUNCTION
) &&
470 (RelativeAddress
>= Symbol
->RelativeAddress
) &&
471 (RelativeAddress
< NextAddress
) &&
472 Symbol
->RelativeAddress
> AddrFound
)
477 DPRINT("FUN found\n");
479 /* Remove the extra information from the function name */
480 ExtraInfo
= strchr(Symbol
->Name
.Buffer
, ':');
481 if (ExtraInfo
!= NULL
)
482 Length
= ExtraInfo
- Symbol
->Name
.Buffer
;
484 Length
= strlen(Symbol
->Name
.Buffer
);
486 strncpy(FunctionName
, Symbol
->Name
.Buffer
, Length
);
487 FunctionName
[Length
]=0;
488 AddrFound
= Symbol
->RelativeAddress
;
493 DPRINT("FUN not found\n");
495 return AddrFound
? STATUS_SUCCESS
: STATUS_UNSUCCESSFUL
;
499 LdrpGetLineNumber(IN PIMAGE_SYMBOL_INFO SymbolInfo
,
500 IN ULONG_PTR RelativeAddress
,
501 OUT PULONG LineNumber
)
504 ULONG_PTR NextAddress
;
505 ULONG_PTR AddrFound
= 0;
508 Symbol
= SymbolInfo
->LineNumberSymbols
.Symbols
;
509 while (Symbol
!= NULL
)
511 NextSymbol
= Symbol
->Next
;
512 if (NextSymbol
!= NULL
)
513 NextAddress
= NextSymbol
->RelativeAddress
;
515 NextAddress
= SymbolInfo
->ImageSize
;
518 DPRINT("LN SEARCH: Type %d RelativeAddress %x >= Symbol->RelativeAddress %x < NextAddress %x\n",
519 Symbol
->SymbolType
, RelativeAddress
, Symbol
->RelativeAddress
, NextAddress
);
522 if ((Symbol
->SymbolType
== ST_LINENUMBER
) &&
523 (RelativeAddress
>= Symbol
->RelativeAddress
) &&
524 (RelativeAddress
< NextAddress
) &&
525 Symbol
->RelativeAddress
> AddrFound
)
527 DPRINT("LN found\n");
528 *LineNumber
= Symbol
->LineNumber
;
529 AddrFound
= Symbol
->RelativeAddress
;
534 DPRINT("LN not found\n");
536 return AddrFound
? STATUS_SUCCESS
: STATUS_UNSUCCESSFUL
;
540 LdrGetAddressInformation(IN PIMAGE_SYMBOL_INFO SymbolInfo
,
541 IN ULONG_PTR RelativeAddress
,
542 OUT PULONG LineNumber
,
543 OUT PCH FileName OPTIONAL
,
544 OUT PCH FunctionName OPTIONAL
)
550 DPRINT("RelativeAddress %p\n", RelativeAddress
);
552 #ifdef PEDANTIC_STABS
553 if (RelativeAddress
>= SymbolInfo
->ImageSize
)
555 DPRINT("Address is not within .text section. RelativeAddress %p Length 0x%x\n",
556 RelativeAddress
, SymbolInfo
->ImageSize
);
557 return STATUS_UNSUCCESSFUL
;
561 if (!AreSymbolsParsed(SymbolInfo
))
563 LdrpParseImageSymbols(SymbolInfo
);
566 Status
= LdrpGetLineNumber(SymbolInfo
, RelativeAddress
, LineNumber
);
567 if (!NT_SUCCESS(Status
))
569 DPRINT("LdrpGetLineNumber failed (%08x)\n", Status
);
575 Status
= LdrpGetFileName(SymbolInfo
, RelativeAddress
, FileName
);
576 if (!NT_SUCCESS(Status
))
578 strcpy(FileName
, "");
584 Status
= LdrpGetFunctionName(SymbolInfo
, RelativeAddress
, FunctionName
);
585 if (!NT_SUCCESS(Status
))
587 strcpy(FunctionName
, "");
591 return STATUS_SUCCESS
;
595 LdrpLoadModuleSymbols(PUNICODE_STRING FileName
,
596 PIMAGE_SYMBOL_INFO SymbolInfo
)
598 FILE_STANDARD_INFORMATION FileStdInfo
;
599 OBJECT_ATTRIBUTES ObjectAttributes
;
600 WCHAR TmpFileName
[MAX_PATH
];
601 UNICODE_STRING SymFileName
;
607 IO_STATUS_BLOCK IoStatusBlock
;
608 PSYMBOLFILE_HEADER SymbolFileHeader
;
610 /* Get the path to the symbol store */
611 wcscpy(TmpFileName
, L
"\\SystemRoot\\symbols\\");
613 /* Get the symbol filename from the module name */
614 Start
= wcsrchr(FileName
->Buffer
, L
'\\');
616 Start
= FileName
->Buffer
;
620 Ext
= wcsrchr(FileName
->Buffer
, L
'.');
622 Length
= Ext
- Start
;
624 Length
= wcslen(Start
);
626 wcsncat(TmpFileName
, Start
, Length
);
627 wcscat(TmpFileName
, L
".sym");
628 RtlInitUnicodeString(&SymFileName
, TmpFileName
);
631 InitializeObjectAttributes(&ObjectAttributes
,
637 DPRINT("Attempting to open symbols: %wZ\n", &SymFileName
);
639 Status
= ZwOpenFile(&FileHandle
,
644 FILE_SYNCHRONOUS_IO_NONALERT
|FILE_NO_INTERMEDIATE_BUFFERING
);
645 if (!NT_SUCCESS(Status
))
647 DPRINT("Could not open symbol file: %wZ\n", &SymFileName
);
651 DPRINT("Loading symbols from %wZ...\n", &SymFileName
);
653 /* Get the size of the file */
654 Status
= ZwQueryInformationFile(FileHandle
,
658 FileStandardInformation
);
659 if (!NT_SUCCESS(Status
))
661 DPRINT("Could not get file size\n");
666 DPRINT("Symbol file is %08x bytes\n", FileStdInfo
.EndOfFile
.u
.LowPart
);
668 /* Allocate nonpageable memory for symbol file */
669 FileBuffer
= ExAllocatePool(NonPagedPool
,
670 FileStdInfo
.AllocationSize
.u
.LowPart
);
672 if (FileBuffer
== NULL
)
674 DPRINT("Could not allocate memory for symbol file\n");
679 /* Load file into memory chunk */
680 Status
= ZwReadFile(FileHandle
,
684 FileStdInfo
.EndOfFile
.u
.LowPart
,
686 if (!NT_SUCCESS(Status
) && Status
!= STATUS_END_OF_FILE
)
688 DPRINT("Could not read symbol file into memory (Status 0x%x)\n", Status
);
689 ExFreePool(FileBuffer
);
696 DPRINT("Symbols loaded.\n");
698 SymbolFileHeader
= (PSYMBOLFILE_HEADER
) FileBuffer
;
699 SymbolInfo
->FileBuffer
= FileBuffer
;
700 SymbolInfo
->SymbolsBase
= FileBuffer
+ SymbolFileHeader
->StabsOffset
;
701 SymbolInfo
->SymbolsLength
= SymbolFileHeader
->StabsLength
;
702 SymbolInfo
->SymbolStringsBase
= FileBuffer
+ SymbolFileHeader
->StabstrOffset
;
703 SymbolInfo
->SymbolStringsLength
= SymbolFileHeader
->StabstrLength
;
705 DPRINT("Installed stabs: %wZ (%08x-%08x,%08x)\n",
707 SymbolInfo
->SymbolsBase
,
708 SymbolInfo
->SymbolsLength
+ SymbolInfo
->SymbolsBase
,
709 SymbolInfo
->SymbolStringsBase
);
713 KdbLdrUnloadModuleSymbols(PIMAGE_SYMBOL_INFO SymbolInfo
)
718 DPRINT("Unloading symbols\n");
720 if (SymbolInfo
!= NULL
)
722 Symbol
= SymbolInfo
->FileNameSymbols
.Symbols
;
723 while (Symbol
!= NULL
)
725 NextSymbol
= Symbol
->Next
;
726 RtlFreeAnsiString(&Symbol
->Name
);
731 SymbolInfo
->FileNameSymbols
.SymbolCount
= 0;
732 SymbolInfo
->FileNameSymbols
.Symbols
= NULL
;
734 Symbol
= SymbolInfo
->FunctionSymbols
.Symbols
;
735 while (Symbol
!= NULL
)
737 NextSymbol
= Symbol
->Next
;
738 RtlFreeAnsiString(&Symbol
->Name
);
743 SymbolInfo
->FunctionSymbols
.SymbolCount
= 0;
744 SymbolInfo
->FunctionSymbols
.Symbols
= NULL
;
746 Symbol
= SymbolInfo
->LineNumberSymbols
.Symbols
;
747 while (Symbol
!= NULL
)
749 NextSymbol
= Symbol
->Next
;
750 RtlFreeAnsiString(&Symbol
->Name
);
755 SymbolInfo
->LineNumberSymbols
.SymbolCount
= 0;
756 SymbolInfo
->LineNumberSymbols
.Symbols
= NULL
;
758 /* Don't free buffers because we cache symbol buffers
759 (eg. they are shared across processes) */
760 /* FIXME: We can free them if we do reference counting */
761 if (SymbolInfo
->FileBuffer
!= NULL
)
763 ExFreePool(SymbolInfo
->FileBuffer
);
764 SymbolInfo
->FileBuffer
= NULL
;
765 SymbolInfo
->SymbolsBase
= NULL
;
766 SymbolInfo
->SymbolsLength
= 0;
773 PIMAGE_SYMBOL_INFO_CACHE
774 LdrpLookupUserSymbolInfo(PLDR_MODULE LdrModule
)
776 PIMAGE_SYMBOL_INFO_CACHE Current
;
777 PLIST_ENTRY CurrentEntry
;
780 DPRINT("Searching symbols for %S\n", LdrModule
->FullDllName
.Buffer
);
782 KeAcquireSpinLock(&SymbolListLock
, &Irql
);
784 CurrentEntry
= SymbolListHead
.Flink
;
785 while (CurrentEntry
!= (&SymbolListHead
))
787 Current
= CONTAINING_RECORD(CurrentEntry
, IMAGE_SYMBOL_INFO_CACHE
, ListEntry
);
789 if (RtlEqualUnicodeString(&Current
->FullName
, &LdrModule
->FullDllName
, TRUE
))
791 KeReleaseSpinLock(&SymbolListLock
, Irql
);
795 CurrentEntry
= CurrentEntry
->Flink
;
798 KeReleaseSpinLock(&SymbolListLock
, Irql
);
804 KdbLdrLoadUserModuleSymbols(PLDR_MODULE LdrModule
)
806 PIMAGE_SYMBOL_INFO_CACHE CacheEntry
;
808 DPRINT("LdrModule %p\n", LdrModule
);
810 RtlZeroMemory(&LdrModule
->SymbolInfo
, sizeof(LdrModule
->SymbolInfo
));
811 LdrModule
->SymbolInfo
.ImageBase
= (ULONG_PTR
) LdrModule
->BaseAddress
;
812 LdrModule
->SymbolInfo
.ImageSize
= LdrModule
->SizeOfImage
;
814 CacheEntry
= LdrpLookupUserSymbolInfo(LdrModule
);
815 if (CacheEntry
!= NULL
)
817 DPRINT("Symbol cache hit for %S\n", CacheEntry
->FullName
.Buffer
);
819 LdrModule
->SymbolInfo
.FileBuffer
= CacheEntry
->FileBuffer
;
820 LdrModule
->SymbolInfo
.SymbolsBase
= CacheEntry
->SymbolsBase
;
821 LdrModule
->SymbolInfo
.SymbolsLength
= CacheEntry
->SymbolsLength
;
822 LdrModule
->SymbolInfo
.SymbolStringsBase
= CacheEntry
->SymbolStringsBase
;
823 LdrModule
->SymbolInfo
.SymbolStringsLength
= CacheEntry
->SymbolStringsLength
;
827 CacheEntry
= ExAllocatePool(NonPagedPool
, sizeof(IMAGE_SYMBOL_INFO_CACHE
));
829 RtlZeroMemory(CacheEntry
, sizeof(IMAGE_SYMBOL_INFO_CACHE
));
831 RtlCreateUnicodeString(&CacheEntry
->FullName
, LdrModule
->FullDllName
.Buffer
);
832 assert(CacheEntry
->FullName
.Buffer
);
833 LdrpLoadModuleSymbols(&LdrModule
->FullDllName
, &LdrModule
->SymbolInfo
);
834 CacheEntry
->FileBuffer
= LdrModule
->SymbolInfo
.FileBuffer
;
835 CacheEntry
->SymbolsBase
= LdrModule
->SymbolInfo
.SymbolsBase
;
836 CacheEntry
->SymbolsLength
= LdrModule
->SymbolInfo
.SymbolsLength
;
837 CacheEntry
->SymbolStringsBase
= LdrModule
->SymbolInfo
.SymbolStringsBase
;
838 CacheEntry
->SymbolStringsLength
= LdrModule
->SymbolInfo
.SymbolStringsLength
;
839 InsertTailList(&SymbolListHead
, &CacheEntry
->ListEntry
);
844 KdbLoadDriver(PUNICODE_STRING Filename
, PMODULE_OBJECT Module
)
846 /* Load symbols for the image if available */
847 DPRINT1("Loading driver %wZ symbols (driver @ %08x)\n",
848 Filename
, Module
->Base
);
849 LdrpLoadModuleSymbols(Filename
, &Module
->TextSection
->SymbolInfo
);
854 KdbUnloadDriver(PMODULE_OBJECT ModuleObject
)
856 /* Unload symbols for module if available */
857 KdbLdrUnloadModuleSymbols(&ModuleObject
->TextSection
->SymbolInfo
);
860 /* Length here is the length of the loaded module, not the file name. */
863 KdbProcessSymbolFile(PVOID ModuleLoadBase
, PCHAR FileName
, ULONG Length
)
865 PMODULE_OBJECT ModuleObject
;
866 UNICODE_STRING ModuleName
;
867 CHAR TmpBaseName
[MAX_PATH
];
868 CHAR TmpFileName
[MAX_PATH
];
869 PSYMBOLFILE_HEADER SymbolFileHeader
;
870 PIMAGE_SYMBOL_INFO SymbolInfo
;
871 ANSI_STRING AnsiString
;
874 DPRINT("Module %s is a symbol file\n", FileName
);
876 strncpy(TmpBaseName
, FileName
, MAX_PATH
-1);
877 TmpBaseName
[MAX_PATH
-1] = '\0';
878 /* remove the extension '.sym' */
879 Extension
= strrchr(TmpBaseName
, '.');
880 if (Extension
&& 0 == _stricmp(Extension
, ".sym"))
885 DPRINT("base: %s (Length %d)\n", TmpBaseName
, Length
);
887 strcpy(TmpFileName
, TmpBaseName
);
888 strcat(TmpFileName
, ".sys");
889 RtlInitAnsiString(&AnsiString
, TmpFileName
);
891 RtlAnsiStringToUnicodeString(&ModuleName
, &AnsiString
, TRUE
);
892 ModuleObject
= LdrGetModuleObject(&ModuleName
);
893 RtlFreeUnicodeString(&ModuleName
);
894 if (ModuleObject
== NULL
)
896 strcpy(TmpFileName
, TmpBaseName
);
897 strcat(TmpFileName
, ".exe");
898 RtlInitAnsiString(&AnsiString
, TmpFileName
);
899 RtlAnsiStringToUnicodeString(&ModuleName
, &AnsiString
, TRUE
);
900 ModuleObject
= LdrGetModuleObject(&ModuleName
);
901 RtlFreeUnicodeString(&ModuleName
);
903 if (ModuleObject
!= NULL
)
905 SymbolInfo
= (PIMAGE_SYMBOL_INFO
) &ModuleObject
->TextSection
->SymbolInfo
;
906 SymbolFileHeader
= (PSYMBOLFILE_HEADER
) ModuleLoadBase
;
907 SymbolInfo
->FileBuffer
= ModuleLoadBase
;
908 SymbolInfo
->SymbolsBase
= ModuleLoadBase
+ SymbolFileHeader
->StabsOffset
;
909 SymbolInfo
->SymbolsLength
= SymbolFileHeader
->StabsLength
;
910 SymbolInfo
->SymbolStringsBase
= ModuleLoadBase
+ SymbolFileHeader
->StabstrOffset
;
911 SymbolInfo
->SymbolStringsLength
= SymbolFileHeader
->StabstrLength
;
912 DPRINT("Installed stabs: %s@%08x-%08x (%08x-%08x,%08x)\n",
914 ModuleObject
->Base
, ModuleObject
->Length
+ ModuleObject
->Base
,
915 SymbolInfo
->SymbolsBase
,
916 SymbolInfo
->SymbolsLength
+ SymbolInfo
->SymbolsBase
,
917 SymbolInfo
->SymbolStringsBase
);
922 KdbInitializeDriver(PMODULE_TEXT_SECTION ModuleTextSection
)
924 RtlZeroMemory(&ModuleTextSection
->SymbolInfo
, sizeof(ModuleTextSection
->SymbolInfo
));
925 ModuleTextSection
->SymbolInfo
.ImageBase
=
926 ModuleTextSection
->OptionalHeader
->ImageBase
;
927 ModuleTextSection
->SymbolInfo
.ImageSize
= ModuleTextSection
->Length
;
931 KdbLdrLoadAutoConfigDrivers(VOID
)
933 UNICODE_STRING ModuleName
;
934 PMODULE_OBJECT ModuleObject
;
937 * Load symbols for ntoskrnl.exe and hal.dll because \SystemRoot
938 * is created after their module entries
941 RtlRosInitUnicodeStringFromLiteral(&ModuleName
, KERNEL_MODULE_NAME
);
942 ModuleObject
= LdrGetModuleObject(&ModuleName
);
943 if (ModuleObject
!= NULL
)
945 LdrpLoadModuleSymbols(&ModuleName
,
946 &ModuleObject
->TextSection
->SymbolInfo
);
949 RtlRosInitUnicodeStringFromLiteral(&ModuleName
, HAL_MODULE_NAME
);
950 ModuleObject
= LdrGetModuleObject(&ModuleName
);
951 if (ModuleObject
!= NULL
)
953 LdrpLoadModuleSymbols(&ModuleName
,
954 &ModuleObject
->TextSection
->SymbolInfo
);