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