KDB stabs file.

svn path=/trunk/; revision=3246
This commit is contained in:
David Welch 2002-07-17 22:57:18 +00:00
parent e646abc58c
commit bbeb8dbe36

View file

@ -0,0 +1,899 @@
/*
* ReactOS kernel
* Copyright (C) 1998, 1999, 2000, 2001 ReactOS Team
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/*
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/ke/i386/exp.c
* PURPOSE: Handling exceptions
* PROGRAMMER: David Welch (welch@cwcom.net)
* REVISION HISTORY:
* ??/??/??: Created
*/
/* INCLUDES *****************************************************************/
#include <ddk/ntddk.h>
#include <roscfg.h>
#include <internal/ntoskrnl.h>
#include <internal/ke.h>
#include <internal/i386/segment.h>
#include <internal/i386/mm.h>
#include <internal/module.h>
#include <internal/mm.h>
#include <internal/ps.h>
#include <internal/trap.h>
#include <ntdll/ldr.h>
#include <internal/safe.h>
#define NDEBUG
#include <internal/debug.h>
/* GLOBALS ******************************************************************/
#ifdef DBG
typedef struct _SYMBOLFILE_HEADER {
unsigned long StabsOffset;
unsigned long StabsLength;
unsigned long StabstrOffset;
unsigned long StabstrLength;
} SYMBOLFILE_HEADER, *PSYMBOLFILE_HEADER;
typedef struct _IMAGE_SYMBOL_INFO_CACHE {
LIST_ENTRY ListEntry;
UNICODE_STRING FullName;
PVOID FileBuffer;
PVOID SymbolsBase;
ULONG SymbolsLength;
PVOID SymbolStringsBase;
ULONG SymbolStringsLength;
} IMAGE_SYMBOL_INFO_CACHE, *PIMAGE_SYMBOL_INFO_CACHE;
typedef struct _STAB_ENTRY {
unsigned long n_strx; /* index into string table of name */
unsigned char n_type; /* type of symbol */
unsigned char n_other; /* misc info (usually empty) */
unsigned short n_desc; /* description field */
unsigned long n_value; /* value of symbol */
} _STAB_ENTRY, *PSTAB_ENTRY;
/*
* Desc - Line number
* Value - Relative virtual address
*/
#define N_FUN 0x24
/*
* Desc - Line number
* Value - Relative virtual address
*/
#define N_SLINE 0x44
/*
* String - First containing a '/' is the compillation directory (CD)
* Not containing a '/' is a source file relative to CD
*/
#define N_SO 0x64
LIST_ENTRY SymbolListHead;
#endif /* DBG */
#ifdef DBG
NTSTATUS
LdrGetAddressInformation(IN PIMAGE_SYMBOL_INFO SymbolInfo,
IN ULONG_PTR RelativeAddress,
OUT PULONG LineNumber,
OUT PCH FileName OPTIONAL,
OUT PCH FunctionName OPTIONAL);
#endif /* DBG */
/* FUNCTIONS ****************************************************************/
STATIC BOOLEAN
print_user_address(PVOID address)
{
PLIST_ENTRY current_entry;
PLDR_MODULE current;
PEPROCESS CurrentProcess;
PPEB Peb = NULL;
ULONG_PTR RelativeAddress;
#ifdef DBG
NTSTATUS Status;
ULONG LineNumber;
CHAR FileName[256];
CHAR FunctionName[256];
#endif
CurrentProcess = PsGetCurrentProcess();
if (NULL != CurrentProcess)
{
Peb = CurrentProcess->Peb;
}
if (NULL == Peb)
{
DbgPrint("<%x>", address);
return(TRUE);
}
current_entry = Peb->Ldr->InLoadOrderModuleList.Flink;
while (current_entry != &Peb->Ldr->InLoadOrderModuleList &&
current_entry != NULL)
{
current =
CONTAINING_RECORD(current_entry, LDR_MODULE, InLoadOrderModuleList);
if (address >= (PVOID)current->BaseAddress &&
address < (PVOID)(current->BaseAddress + current->SizeOfImage))
{
RelativeAddress = (ULONG_PTR) address - (ULONG_PTR)current->BaseAddress;
#ifdef DBG
Status = LdrGetAddressInformation(&current->SymbolInfo,
RelativeAddress,
&LineNumber,
FileName,
FunctionName);
if (NT_SUCCESS(Status))
{
DbgPrint("<%wZ: %x (%s:%d (%s))>",
&current->BaseDllName, RelativeAddress, FileName, LineNumber, FunctionName);
}
else
{
DbgPrint("<%wZ: %x>", &current->BaseDllName, RelativeAddress);
}
#else /* !DBG */
DbgPrint("<%wZ: %x>", &current->BaseDllName, RelativeAddress);
#endif /* !DBG */
return(TRUE);
}
current_entry = current_entry->Flink;
}
return(FALSE);
}
STATIC BOOLEAN
print_address(PVOID address)
{
PLIST_ENTRY current_entry;
MODULE_TEXT_SECTION* current;
extern LIST_ENTRY ModuleTextListHead;
ULONG_PTR RelativeAddress;
#ifdef DBG
NTSTATUS Status;
ULONG LineNumber;
CHAR FileName[256];
CHAR FunctionName[256];
#endif
current_entry = ModuleTextListHead.Flink;
while (current_entry != &ModuleTextListHead &&
current_entry != NULL)
{
current =
CONTAINING_RECORD(current_entry, MODULE_TEXT_SECTION, ListEntry);
if (address >= (PVOID)current->Base &&
address < (PVOID)(current->Base + current->Length))
{
RelativeAddress = (ULONG_PTR) address - current->Base;
#ifdef kDBG
Status = LdrGetAddressInformation(&current->SymbolInfo,
RelativeAddress,
&LineNumber,
FileName,
FunctionName);
if (NT_SUCCESS(Status))
{
DbgPrint("<%ws: %x (%s:%d (%s))>",
current->Name, RelativeAddress, FileName, LineNumber, FunctionName);
}
else
{
DbgPrint("<%ws: %x>", current->Name, RelativeAddress);
}
#else /* !DBG */
DbgPrint("<%ws: %x>", current->Name, RelativeAddress);
#endif /* !DBG */
return(TRUE);
}
current_entry = current_entry->Flink;
}
return(FALSE);
}
#ifdef DBG
VOID
PiFreeSymbols(PPEB Peb)
{
PLIST_ENTRY CurrentEntry;
PLDR_MODULE Current;
PIMAGE_SYMBOL_INFO SymbolInfo;
assert (Peb);
assert (Peb->Ldr);
CurrentEntry = Peb->Ldr->InLoadOrderModuleList.Flink;
while (CurrentEntry != &Peb->Ldr->InLoadOrderModuleList &&
CurrentEntry != NULL)
{
Current = CONTAINING_RECORD(CurrentEntry, LDR_MODULE,
InLoadOrderModuleList);
SymbolInfo = &Current->SymbolInfo;
LdrUnloadModuleSymbols(SymbolInfo);
CurrentEntry = CurrentEntry->Flink;
}
}
VOID
KdbLdrInit(VOID)
{
#ifdef DBG
RtlZeroMemory(&NtoskrnlTextSection.SymbolInfo, sizeof(NtoskrnlTextSection.SymbolInfo));
NtoskrnlTextSection.SymbolInfo.ImageBase = OptionalHeader->ImageBase;
NtoskrnlTextSection.SymbolInfo.ImageSize = NtoskrnlTextSection.Length;
#endif
#ifdef DBG
RtlZeroMemory(&LdrHalTextSection.SymbolInfo, sizeof(LdrHalTextSection.SymbolInfo));
LdrHalTextSection.SymbolInfo.ImageBase = OptionalHeader->ImageBase;
LdrHalTextSection.SymbolInfo.ImageSize = LdrHalTextSection.Length;
#endif
#ifdef DBG
InitializeListHead(&SymbolListHead);
#endif
}
#ifdef DBG
VOID
LdrpParseImageSymbols(PIMAGE_SYMBOL_INFO SymbolInfo)
/* Note: It is important that the symbol strings buffer not be released after
this function is called because the strings are still referenced */
{
PSYMBOL CurrentFileNameSymbol;
PSYMBOL CurrentFunctionSymbol;
PSYMBOL CurrentLineNumberSymbol;
PSYMBOL Symbol;
PSTAB_ENTRY StabEntry;
PVOID StabsEnd;
PCHAR String;
ULONG_PTR FunRelativeAddress;
ULONG FunLineNumber;
ULONG_PTR ImageBase;
assert(SymbolInfo);
DPRINT("Parsing symbols.\n");
SymbolInfo->FileNameSymbols.SymbolCount = 0;
SymbolInfo->FileNameSymbols.Symbols = NULL;
SymbolInfo->FunctionSymbols.SymbolCount = 0;
SymbolInfo->FunctionSymbols.Symbols = NULL;
SymbolInfo->LineNumberSymbols.SymbolCount = 0;
SymbolInfo->LineNumberSymbols.Symbols = NULL;
StabsEnd = SymbolInfo->SymbolsBase + SymbolInfo->SymbolsLength;
StabEntry = (PSTAB_ENTRY) SymbolInfo->SymbolsBase;
ImageBase = SymbolInfo->ImageBase;
FunRelativeAddress = 0;
FunLineNumber = 0;
CurrentFileNameSymbol = NULL;
CurrentFunctionSymbol = NULL;
CurrentLineNumberSymbol = NULL;
while ((ULONG_PTR) StabEntry < (ULONG_PTR) StabsEnd)
{
Symbol = NULL;
if (StabEntry->n_type == N_FUN)
{
if (StabEntry->n_desc > 0)
{
assert(StabEntry->n_value >= ImageBase);
FunRelativeAddress = StabEntry->n_value - ImageBase;
FunLineNumber = StabEntry->n_desc;
Symbol = ExAllocatePool(NonPagedPool, sizeof(SYMBOL));
assert(Symbol);
Symbol->Next = NULL;
Symbol->SymbolType = ST_FUNCTION;
Symbol->RelativeAddress = FunRelativeAddress;
Symbol->LineNumber = FunLineNumber;
String = (PCHAR)SymbolInfo->SymbolStringsBase + StabEntry->n_strx;
RtlInitAnsiString(&Symbol->Name, String);
DPRINT("FUN found. '%s' %d @ %x\n",
Symbol->Name.Buffer, FunLineNumber, FunRelativeAddress);
}
}
else if (StabEntry->n_type == N_SLINE)
{
Symbol = ExAllocatePool(NonPagedPool, sizeof(SYMBOL));
assert(Symbol);
Symbol->Next = NULL;
Symbol->SymbolType = ST_LINENUMBER;
Symbol->RelativeAddress = FunRelativeAddress + StabEntry->n_value;
Symbol->LineNumber = StabEntry->n_desc;
DPRINT("SLINE found. %d @ %x\n",
Symbol->LineNumber, Symbol->RelativeAddress);
}
else if (StabEntry->n_type == N_SO)
{
Symbol = ExAllocatePool(NonPagedPool, sizeof(SYMBOL));
assert(Symbol);
Symbol->Next = NULL;
Symbol->SymbolType = ST_FILENAME;
Symbol->RelativeAddress = StabEntry->n_value - ImageBase;
Symbol->LineNumber = 0;
String = (PCHAR)SymbolInfo->SymbolStringsBase + StabEntry->n_strx;
RtlInitAnsiString(&Symbol->Name, String);
DPRINT("SO found. '%s' @ %x\n",
Symbol->Name.Buffer, Symbol->RelativeAddress);
}
if (Symbol != NULL)
{
switch (Symbol->SymbolType)
{
case ST_FILENAME:
if (SymbolInfo->FileNameSymbols.Symbols == NULL)
SymbolInfo->FileNameSymbols.Symbols = Symbol;
else
CurrentFileNameSymbol->Next = Symbol;
CurrentFileNameSymbol = Symbol;
SymbolInfo->FileNameSymbols.SymbolCount++;
break;
case ST_FUNCTION:
if (SymbolInfo->FunctionSymbols.Symbols == NULL)
SymbolInfo->FunctionSymbols.Symbols = Symbol;
else
CurrentFunctionSymbol->Next = Symbol;
CurrentFunctionSymbol = Symbol;
SymbolInfo->FunctionSymbols.SymbolCount++;
break;
case ST_LINENUMBER:
if (SymbolInfo->LineNumberSymbols.Symbols == NULL)
SymbolInfo->LineNumberSymbols.Symbols = Symbol;
else
CurrentLineNumberSymbol->Next = Symbol;
CurrentLineNumberSymbol = Symbol;
SymbolInfo->LineNumberSymbols.SymbolCount++;
break;
}
}
StabEntry++;
}
}
static NTSTATUS
LdrpGetFileName(IN PIMAGE_SYMBOL_INFO SymbolInfo,
IN ULONG_PTR RelativeAddress,
OUT PCH FileName)
{
PSYMBOL NextSymbol;
ULONG_PTR NextAddress;
PSYMBOL Symbol;
Symbol = SymbolInfo->FileNameSymbols.Symbols;
while (Symbol != NULL)
{
NextSymbol = Symbol->Next;
if (NextSymbol != NULL)
NextAddress = NextSymbol->RelativeAddress;
else
NextAddress = SymbolInfo->ImageSize;
DPRINT("FN SEARCH: Type %d RelativeAddress %x >= Symbol->RelativeAddress %x < NextAddress %x\n",
Symbol->SymbolType, RelativeAddress, Symbol->RelativeAddress, NextAddress);
if ((Symbol->SymbolType == ST_FILENAME) &&
(RelativeAddress >= Symbol->RelativeAddress) &&
(RelativeAddress < NextAddress))
{
DPRINT("FN found\n");
strcpy(FileName, Symbol->Name.Buffer);
return STATUS_SUCCESS;
}
Symbol = NextSymbol;
}
DPRINT("FN not found\n");
return STATUS_UNSUCCESSFUL;
}
static NTSTATUS
LdrpGetFunctionName(IN PIMAGE_SYMBOL_INFO SymbolInfo,
IN ULONG_PTR RelativeAddress,
OUT PCH FunctionName)
{
PSYMBOL NextSymbol;
ULONG_PTR NextAddress;
PSYMBOL Symbol;
Symbol = SymbolInfo->FunctionSymbols.Symbols;
while (Symbol != NULL)
{
NextSymbol = Symbol->Next;
if (NextSymbol != NULL)
NextAddress = NextSymbol->RelativeAddress;
else
NextAddress = SymbolInfo->ImageSize;
DPRINT("FUN SEARCH: Type %d RelativeAddress %x >= Symbol->RelativeAddress %x < NextAddress %x\n",
Symbol->SymbolType, RelativeAddress, Symbol->RelativeAddress, NextAddress);
if ((Symbol->SymbolType == ST_FUNCTION) &&
(RelativeAddress >= Symbol->RelativeAddress) &&
(RelativeAddress < NextAddress))
{
PCHAR ExtraInfo;
ULONG Length;
DPRINT("FUN found\n");
/* Remove the extra information from the function name */
ExtraInfo = strchr(Symbol->Name.Buffer, ':');
if (ExtraInfo != NULL)
Length = ExtraInfo - Symbol->Name.Buffer;
else
Length = strlen(Symbol->Name.Buffer);
strncpy(FunctionName, Symbol->Name.Buffer, Length);
return STATUS_SUCCESS;
}
Symbol = NextSymbol;
}
DPRINT("FUN not found\n");
return STATUS_UNSUCCESSFUL;
}
static NTSTATUS
LdrpGetLineNumber(IN PIMAGE_SYMBOL_INFO SymbolInfo,
IN ULONG_PTR RelativeAddress,
OUT PULONG LineNumber)
{
PSYMBOL NextSymbol;
ULONG_PTR NextAddress;
PSYMBOL Symbol;
Symbol = SymbolInfo->LineNumberSymbols.Symbols;
while (Symbol != NULL)
{
NextSymbol = Symbol->Next;
if (NextSymbol != NULL)
NextAddress = NextSymbol->RelativeAddress;
else
NextAddress = SymbolInfo->ImageSize;
DPRINT("LN SEARCH: Type %d RelativeAddress %x >= Symbol->RelativeAddress %x < NextAddress %x\n",
Symbol->SymbolType, RelativeAddress, Symbol->RelativeAddress, NextAddress);
if ((Symbol->SymbolType == ST_LINENUMBER) &&
(RelativeAddress >= Symbol->RelativeAddress) &&
(RelativeAddress < NextAddress))
{
DPRINT("LN found\n");
*LineNumber = Symbol->LineNumber;
return STATUS_SUCCESS;
}
Symbol = NextSymbol;
}
DPRINT("LN not found\n");
return STATUS_UNSUCCESSFUL;
}
NTSTATUS
LdrGetAddressInformation(IN PIMAGE_SYMBOL_INFO SymbolInfo,
IN ULONG_PTR RelativeAddress,
OUT PULONG LineNumber,
OUT PCH FileName OPTIONAL,
OUT PCH FunctionName OPTIONAL)
{
NTSTATUS Status;
*LineNumber = 0;
DPRINT("RelativeAddress %p\n", RelativeAddress);
if (RelativeAddress >= SymbolInfo->ImageSize)
{
DPRINT("Address is not within .text section. RelativeAddress %p Length 0x%x\n",
RelativeAddress, SymbolInfo->ImageSize);
return STATUS_UNSUCCESSFUL;
}
if (!AreSymbolsParsed(SymbolInfo))
{
LdrpParseImageSymbols(SymbolInfo);
}
Status = LdrpGetLineNumber(SymbolInfo, RelativeAddress, LineNumber);
if (!NT_SUCCESS(Status))
{
return Status;
}
if (FileName)
{
Status = LdrpGetFileName(SymbolInfo, RelativeAddress, FileName);
if (!NT_SUCCESS(Status))
{
strcpy(FileName, "");
}
}
if (FunctionName)
{
Status = LdrpGetFunctionName(SymbolInfo, RelativeAddress, FunctionName);
if (!NT_SUCCESS(Status))
{
strcpy(FunctionName, "");
}
}
return STATUS_SUCCESS;
}
VOID
LdrpLoadModuleSymbols(PUNICODE_STRING FileName,
PIMAGE_SYMBOL_INFO SymbolInfo)
{
FILE_STANDARD_INFORMATION FileStdInfo;
OBJECT_ATTRIBUTES ObjectAttributes;
WCHAR TmpFileName[MAX_PATH];
UNICODE_STRING SymFileName;
LPWSTR Start, Ext;
HANDLE FileHandle;
PVOID FileBuffer;
NTSTATUS Status;
ULONG Length;
IO_STATUS_BLOCK IoStatusBlock;
PSYMBOLFILE_HEADER SymbolFileHeader;
/* Get the path to the symbol store */
wcscpy(TmpFileName, L"\\SystemRoot\\symbols\\");
/* Get the symbol filename from the module name */
Start = wcsrchr(FileName->Buffer, L'\\');
if (Start == NULL)
Start = FileName->Buffer;
else
Start++;
Ext = wcsrchr(FileName->Buffer, L'.');
if (Ext != NULL)
Length = Ext - Start;
else
Length = wcslen(Start);
wcsncat(TmpFileName, Start, Length);
wcscat(TmpFileName, L".sym");
RtlInitUnicodeString(&SymFileName, TmpFileName);
/* Open the file */
InitializeObjectAttributes(&ObjectAttributes,
&SymFileName,
0,
NULL,
NULL);
Status = ZwOpenFile(&FileHandle,
FILE_ALL_ACCESS,
&ObjectAttributes,
&IoStatusBlock,
0,
0);
if (!NT_SUCCESS(Status))
{
DPRINT("Could not open symbol file: %wZ\n", &SymFileName);
return;
}
CPRINT("Loading symbols from %wZ...\n", &SymFileName);
/* Get the size of the file */
Status = ZwQueryInformationFile(FileHandle,
&IoStatusBlock,
&FileStdInfo,
sizeof(FileStdInfo),
FileStandardInformation);
if (!NT_SUCCESS(Status))
{
DPRINT("Could not get file size\n");
ZwClose(FileHandle);
return;
}
/* Allocate nonpageable memory for symbol file */
FileBuffer = ExAllocatePool(NonPagedPool,
FileStdInfo.EndOfFile.u.LowPart);
if (FileBuffer == NULL)
{
DPRINT("Could not allocate memory for symbol file\n");
ZwClose(FileHandle);
return;
}
/* Load file into memory chunk */
Status = ZwReadFile(FileHandle,
0, 0, 0,
&IoStatusBlock,
FileBuffer,
FileStdInfo.EndOfFile.u.LowPart,
0, 0);
if (!NT_SUCCESS(Status))
{
DPRINT("Could not read symbol file into memory (Status 0x%x)\n", Status);
ExFreePool(FileBuffer);
ZwClose(FileHandle);
return;
}
ZwClose(FileHandle);
SymbolFileHeader = (PSYMBOLFILE_HEADER) FileBuffer;
SymbolInfo->FileBuffer = FileBuffer;
SymbolInfo->SymbolsBase = FileBuffer + SymbolFileHeader->StabsOffset;
SymbolInfo->SymbolsLength = SymbolFileHeader->StabsLength;
SymbolInfo->SymbolStringsBase = FileBuffer + SymbolFileHeader->StabstrOffset;
SymbolInfo->SymbolStringsLength = SymbolFileHeader->StabstrLength;
}
VOID
LdrUnloadModuleSymbols(PIMAGE_SYMBOL_INFO SymbolInfo)
{
PSYMBOL NextSymbol;
PSYMBOL Symbol;
DPRINT("Unloading symbols\n");
if (SymbolInfo != NULL)
{
Symbol = SymbolInfo->FileNameSymbols.Symbols;
while (Symbol != NULL)
{
NextSymbol = Symbol->Next;
RtlFreeAnsiString(&Symbol->Name);
ExFreePool(Symbol);
Symbol = NextSymbol;
}
SymbolInfo->FileNameSymbols.SymbolCount = 0;
SymbolInfo->FileNameSymbols.Symbols = NULL;
Symbol = SymbolInfo->FunctionSymbols.Symbols;
while (Symbol != NULL)
{
NextSymbol = Symbol->Next;
RtlFreeAnsiString(&Symbol->Name);
ExFreePool(Symbol);
Symbol = NextSymbol;
}
SymbolInfo->FunctionSymbols.SymbolCount = 0;
SymbolInfo->FunctionSymbols.Symbols = NULL;
Symbol = SymbolInfo->LineNumberSymbols.Symbols;
while (Symbol != NULL)
{
NextSymbol = Symbol->Next;
RtlFreeAnsiString(&Symbol->Name);
ExFreePool(Symbol);
Symbol = NextSymbol;
}
SymbolInfo->LineNumberSymbols.SymbolCount = 0;
SymbolInfo->LineNumberSymbols.Symbols = NULL;
#if 0
/* Don't free buffers because we cache symbol buffers
(eg. they are shared across processes) */
/* FIXME: We can free them if we do reference counting */
if (SymbolInfo->FileBuffer != NULL)
{
ExFreePool(SymbolInfo->FileBuffer);
SymbolInfo->FileBuffer = NULL;
SymbolInfo->SymbolsBase = NULL;
SymbolInfo->SymbolsLength = 0;
}
#endif
}
}
PIMAGE_SYMBOL_INFO_CACHE
LdrpLookupUserSymbolInfo(PLDR_MODULE LdrModule)
{
PIMAGE_SYMBOL_INFO_CACHE Current;
PLIST_ENTRY CurrentEntry;
KIRQL Irql;
DPRINT("Searching symbols for %S\n", LdrModule->FullDllName.Buffer);
KeAcquireSpinLock(&ModuleListLock,&Irql);
CurrentEntry = SymbolListHead.Flink;
while (CurrentEntry != (&SymbolListHead))
{
Current = CONTAINING_RECORD(CurrentEntry, IMAGE_SYMBOL_INFO_CACHE, ListEntry);
if (RtlEqualUnicodeString(&Current->FullName, &LdrModule->FullDllName, TRUE))
{
KeReleaseSpinLock(&ModuleListLock, Irql);
return Current;
}
CurrentEntry = CurrentEntry->Flink;
}
KeReleaseSpinLock(&ModuleListLock, Irql);
return(NULL);
}
VOID
LdrLoadUserModuleSymbols(PLDR_MODULE LdrModule)
{
PIMAGE_SYMBOL_INFO_CACHE CacheEntry;
DPRINT("LdrModule %p\n", LdrModule);
RtlZeroMemory(&LdrModule->SymbolInfo, sizeof(LdrModule->SymbolInfo));
LdrModule->SymbolInfo.ImageBase = (ULONG_PTR) LdrModule->BaseAddress;
LdrModule->SymbolInfo.ImageSize = LdrModule->SizeOfImage;
CacheEntry = LdrpLookupUserSymbolInfo(LdrModule);
if (CacheEntry != NULL)
{
DPRINT("Symbol cache hit for %S\n", CacheEntry->FullName.Buffer);
LdrModule->SymbolInfo.FileBuffer = CacheEntry->FileBuffer;
LdrModule->SymbolInfo.SymbolsBase = CacheEntry->SymbolsBase;
LdrModule->SymbolInfo.SymbolsLength = CacheEntry->SymbolsLength;
LdrModule->SymbolInfo.SymbolStringsBase = CacheEntry->SymbolStringsBase;
LdrModule->SymbolInfo.SymbolStringsLength = CacheEntry->SymbolStringsLength;
}
else
{
CacheEntry = ExAllocatePool(NonPagedPool, sizeof(IMAGE_SYMBOL_INFO_CACHE));
assert(CacheEntry);
RtlZeroMemory(CacheEntry, sizeof(IMAGE_SYMBOL_INFO_CACHE));
RtlCreateUnicodeString(&CacheEntry->FullName, LdrModule->FullDllName.Buffer);
assert(CacheEntry->FullName.Buffer);
LdrpLoadModuleSymbols(&LdrModule->FullDllName, &LdrModule->SymbolInfo);
InsertTailList(&SymbolListHead, &CacheEntry->ListEntry);
}
}
#endif /* DBG */
VOID
KdbLoadDriver(VOID)
{
#ifdef DBG
/* Load symbols for the image if available */
LdrpLoadModuleSymbols(Filename, &Module->TextSection->SymbolInfo);
#endif /* DBG */
}
VOID
KdbUnloadDriver(VOID)
{
#ifdef DBG
/* Unload symbols for module if available */
LdrUnloadModuleSymbols(&ModuleObject->TextSection->SymbolInfo);
#endif /* DBG */
}
VOID
KdbInitializeDriver(VOID)
{
#ifdef DBG
PSYMBOLFILE_HEADER SymbolFileHeader;
PIMAGE_SYMBOL_INFO SymbolInfo;
#endif /* DBG */
#ifdef DBG
CHAR TmpBaseName[MAX_PATH];
CHAR TmpFileName[MAX_PATH];
ANSI_STRING AnsiString;
#endif /* DBG */
#ifdef DBG
if ((FileExt != NULL) && (strcmp(FileExt, ".sym") == 0))
{
DPRINT("Module %s is a symbol file\n", FileName);
strncpy(TmpBaseName, FileName, Length);
TmpBaseName[Length] = '\0';
DPRINT("base: %s (Length %d)\n", TmpBaseName, Length);
strcpy(TmpFileName, TmpBaseName);
strcat(TmpFileName, ".sys");
RtlInitAnsiString(&AnsiString, TmpFileName);
RtlAnsiStringToUnicodeString(&ModuleName, &AnsiString, TRUE);
ModuleObject = LdrGetModuleObject(&ModuleName);
RtlFreeUnicodeString(&ModuleName);
if (ModuleObject == NULL)
{
strcpy(TmpFileName, TmpBaseName);
strcat(TmpFileName, ".exe");
RtlInitAnsiString(&AnsiString, TmpFileName);
RtlAnsiStringToUnicodeString(&ModuleName, &AnsiString, TRUE);
ModuleObject = LdrGetModuleObject(&ModuleName);
RtlFreeUnicodeString(&ModuleName);
}
if (ModuleObject != NULL)
{
SymbolInfo = (PIMAGE_SYMBOL_INFO) &ModuleObject->TextSection->SymbolInfo;
SymbolFileHeader = (PSYMBOLFILE_HEADER) ModuleLoadBase;
SymbolInfo->FileBuffer = ModuleLoadBase;
SymbolInfo->SymbolsBase = ModuleLoadBase + SymbolFileHeader->StabsOffset;
SymbolInfo->SymbolsLength = SymbolFileHeader->StabsLength;
SymbolInfo->SymbolStringsBase = ModuleLoadBase + SymbolFileHeader->StabstrOffset;
SymbolInfo->SymbolStringsLength = SymbolFileHeader->StabstrLength;
}
return(STATUS_SUCCESS);
}
else
{
DPRINT("Module %s is non-symbol file\n", FileName);
}
#endif /* !DBG */
#ifdef DBG
RtlZeroMemory(&ModuleTextSection->SymbolInfo, sizeof(ModuleTextSection->SymbolInfo));
ModuleTextSection->SymbolInfo.ImageBase = PEOptionalHeader->ImageBase;
ModuleTextSection->SymbolInfo.ImageSize = ModuleTextSection->Length;
#endif /* DBG */
}
#endif /* DBG */