Listing 3: Lookup logic pseudocode
void DumpDebugInfo( const BYTE* caller,
HINSTANCE hInstance )
{
// retrieve filename
const char* fname =
GetModuleFilename( module ) ;
// offset 0 is DOS header
PIMAGE_DOS_HEADER fileBase =
MapFileInMemory( fname ) ;
// retrieve NT header
PIMAGE_NT_HEADER NT_Header =
fileBase + filebase->e_lfanew ;
// Get debug header
// Borland:
PIMAGE_SECTION_HEADER debugHeader =
SectionHeaderFromName( ".debug" ) ;
PIMAGE_DEBUG_DIRECTORY debugDir =
fileBase + debugHeader->PointerToRawData ;
// Microsoft
debugHeader = SectionHeaderFromName( ".rdata" ) ;
debugDir = fileBase +
debugHeader->PointerToRawData +
debugDirRVA - debugHeader->VirtualAddress ;
// Get COFF debug directory and COFF debug header
Look for an entry in the debug directory table
with Type == IMAGE_DEBUG_TYPE_COFF ;
PIMAGE_COFF_SYMBOLS_HEADER COFFdebug =
fileBase + debugDir->PointerToRawData ;
// Get symbol table, symbol count, string table;
// the string table starts right after the symbol table
PIMAGE_SYMBOL COFFsymbol =
filebase + NT_Header->FileHeader.PointerToSymbolTable ;
int COFFcount =
NT_Header->FileHeader.NumberOfSymbols ;
const char* stringTable =
COFFsymbolTable + COFFsymbolCount ;
// Dump info about caller
int RVA = caller - (BYTE*)hInstance ;
if( COFFcount && COFFsymbolTable )
{
// Lookup source file name
Search in COFFsymbolTable a ".text"
(or "CODE") section which includes RVA:
that gives the filename ;
// Lookup function name
Search in COFFsymbolTable the function symbol
with the biggest address <= RVA ;
Lookup the function name in stringTable
given the function symbol ;
// Lookup line number
PIMAGE_LINENUMBER lineTable =
COFFDebugInfo +
COFFDebugInfo->LvaToFirstLinenumber ;
Search in lineTable the line number
with the biggest address <= RVA ;
Dump file/function/line info ;
}
else
only module name and caller address available ;
}
//End of File