|
|
//
// defines for symbol file searching
//
#include <dbgimage.h>
// this private API is in msdia20-msvcrt.lib
HRESULT __cdecl CompareRE( const wchar_t* pStr, const wchar_t* pRE, BOOL fCase );
#define SYMBOL_PATH "_NT_SYMBOL_PATH"
#define ALTERNATE_SYMBOL_PATH "_NT_ALT_SYMBOL_PATH"
#define SYMBOL_SERVER "_NT_SYMBOL_SERVER"
#define SYMSRV "SYMSRV"
#define WINDIR "windir"
#define DEBUG_TOKEN "DBGHELP_TOKEN"
#define HASH_MODULO 253
#define OMAP_SYM_EXTRA 1024
#define CPP_EXTRA 2
#define OMAP_SYM_STRINGS (OMAP_SYM_EXTRA * 256)
#define TMP_SYM_LEN 4096
// Possibly truncates and sign-extends a value to 64 bits.
#define EXTEND64(Val) ((ULONG64)(LONG64)(LONG)(Val))
//
// structures
//
typedef struct _LOADED_MODULE { PENUMLOADED_MODULES_CALLBACK EnumLoadedModulesCallback32; PENUMLOADED_MODULES_CALLBACK64 EnumLoadedModulesCallback64; PVOID Context; } LOADED_MODULE, *PLOADED_MODULE;
#define SYMF_DUPLICATE 0x80000000
#define SYMF_OMAP_GENERATED 0x00000001
#define SYMF_OMAP_MODIFIED 0x00000002
#ifndef _DBGHELP_USER_GENERATED_SYMBOLS_NOTSUPPORTED
#define SYMF_USER_GENERATED 0x00000004
#endif // !_DBGHELP_USER_GENERATED_SYMBOLS_NOTSUPPORTED
typedef struct _SYMBOL_ENTRY { struct _SYMBOL_ENTRY *Next; DWORD Size; DWORD Flags; DWORD64 Address; LPSTR Name; ULONG NameLength;
ULONG Segment; ULONG64 Offset; ULONG TypeIndex; ULONG64 ModBase; ULONG Register; } SYMBOL_ENTRY, *PSYMBOL_ENTRY;
typedef struct _SECTION_START { ULONG64 Offset; DWORD Size; DWORD Flags; } SECTION_START, *PSECTION_START;
//
// source file and line number information
//
typedef struct _SOURCE_LINE { DWORD64 Addr; DWORD Line; } SOURCE_LINE, *PSOURCE_LINE;
typedef struct _SOURCE_ENTRY { struct _SOURCE_ENTRY *Next; struct _SOURCE_ENTRY *Prev; DWORD64 MinAddr; DWORD64 MaxAddr; LPSTR File; DWORD Lines; PSOURCE_LINE LineInfo; ULONG ModuleId; } SOURCE_ENTRY, *PSOURCE_ENTRY;
//
// Error values for failed symbol load
//
#define SYMLOAD_OK 0x0000
#define SYMLOAD_PDBUNMATCHED 0x0001
#define SYMLOAD_PDBNOTFOUND 0x0002
#define SYMLOAD_DBGNOTFOUND 0x0003
#define SYMLOAD_OTHERERROR 0x0004
#define SYMLOAD_OUTOFMEMORY 0x0005
#define SYMLOAD_HEADERPAGEDOUT 0x0006
#define SYMLOAD_PDBERRORMASK 0xff00
#define SYMLOAD_DEFERRED 0x80000000
//
// module flags
//
#define MIF_DEFERRED_LOAD 0x00000001
#define MIF_NO_SYMBOLS 0x00000002
#define MIF_ROM_IMAGE 0x00000004
// for ImageSrc and PdbSrc elements
typedef enum { srcNone = 0, srcSearchPath, srcImagePath, srcDbgPath, srcSymSrv, srcCVRec, srcHandle, srcMemory };
typedef struct _MODULE_ENTRY { LIST_ENTRY ListEntry; ULONG64 BaseOfDll; ULONG DllSize; ULONG TimeDateStamp; ULONG CheckSum; USHORT MachineType; CHAR ModuleName[64]; CHAR AliasName[64]; PSTR ImageName; PSTR LoadedImageName; PSTR LoadedPdbName; ULONG ImageType; ULONG ImageSrc; ULONG PdbSrc; PSYMBOL_ENTRY symbolTable; LPSTR SymStrings; PSYMBOL_ENTRY NameHashTable[HASH_MODULO]; ULONG numsyms; ULONG MaxSyms; ULONG StringSize; SYM_TYPE SymType; PDB * pdb; DBI * dbi; GSI * gsi; GSI * globals; TPI * ptpi; PIMAGE_SECTION_HEADER SectionHdrs; ULONG NumSections; PFPO_DATA pFpoData; // pointer to fpo data (x86)
PFPO_DATA pFpoDataOmap; // pointer to fpo data (x86)
PIMGHLP_RVA_FUNCTION_DATA pExceptionData; // pointer to pdata (risc)
PVOID pPData; // pdata acquired from pdb
PVOID pXData; // xdata acquired from pdb
ULONG dwEntries; // # of fpo or pdata recs
ULONG cPData; // number of pdb pdata entries
ULONG cXData; // number of pdb xdata entries
ULONG cbPData; // size of pdb xdata blob
ULONG cbXData; // size of pdb xdata blob
POMAP pOmapFrom; // pointer to omap data
ULONG cOmapFrom; // count of omap entries
POMAP pOmapTo; // pointer to omap data
ULONG cOmapTo; // count of omap entries
SYMBOL_ENTRY TmpSym; // used only for pdb symbols
SYMBOL_INFO si; // used for dia symbols
UCHAR siName[2048]; // must be contiguous with si
ULONG Flags; HANDLE hFile; PIMAGE_SECTION_HEADER OriginalSectionHdrs; ULONG OriginalNumSections; PSOURCE_ENTRY SourceFiles; PSOURCE_ENTRY SourceFilesTail;
HANDLE hProcess; ULONG64 InProcImageBase; BOOL fInProcHeader; DWORD dsExceptions; Mod *mod; USHORT imod; PBYTE pPdbSymbols; DWORD cbPdbSymbols; ULONG SymLoadError; ULONG code; // used to pass back info to wrappers
PVOID dia; CHAR SrcFile[_MAX_PATH + 1]; DWORD CallerFlags; MODLOAD_DATA mld; PVOID CallerData; } MODULE_ENTRY, *PMODULE_ENTRY;
typedef VOID DBG_CONTEXT, *PDBG_CONTEXT;
#ifdef USE_CACHE
#define CACHE_BLOCK 40
#define CACHE_SIZE CACHE_BLOCK*CACHE_BLOCK
typedef struct _DIA_LARGE_DATA { BOOL Used; ULONG Index; ULONG LengthUsed; CHAR Bytes[500]; } DIA_LARGE_DATA, *PDIA_LARGE_DATA;
#define DIACH_ULVAL 0
#define DIACH_ULLVAL 1
#define DIACH_PLVAL 2
typedef struct _DIA_CACHE_DATA { ULONG type; union { ULONG ulVal; ULONGLONG ullVal; PDIA_LARGE_DATA plVal; }; } DIA_CACHE_DATA, *PDIA_CACHE_DATA;
typedef struct _DIA_CACHE_ENTRY { ULONG Age; union { struct { ULONG TypeId; IMAGEHLP_SYMBOL_TYPE_INFO DataType; } s; ULONGLONG SearchId; }; ULONGLONG Module; DIA_CACHE_DATA Data; } DIA_CACHE_ENTRY, *PDIA_CACHE_ENTRY; #endif // USE_CACHE
typedef struct _PROCESS_ENTRY { LIST_ENTRY ListEntry; LIST_ENTRY ModuleList; ULONG Count; HANDLE hProcess; DWORD pid; LPSTR SymbolSearchPath; PSYMBOL_REGISTERED_CALLBACK pCallbackFunction32; PSYMBOL_REGISTERED_CALLBACK64 pCallbackFunction64; ULONG64 CallbackUserContext; PSYMBOL_FUNCENTRY_CALLBACK pFunctionEntryCallback32; PSYMBOL_FUNCENTRY_CALLBACK64 pFunctionEntryCallback64; ULONG64 FunctionEntryUserContext; PIMAGEHLP_CONTEXT pContext; IMAGEHLP_STACK_FRAME StackFrame; PMODULE_ENTRY ipmi; #ifdef USE_CACHE
DIA_LARGE_DATA DiaLargeData[2*CACHE_BLOCK]; DIA_CACHE_ENTRY DiaCache[CACHE_SIZE]; #endif // USE_CACHE
} PROCESS_ENTRY, *PPROCESS_ENTRY;
// debug trace facility
int WINAPIV _pprint( PPROCESS_ENTRY ProcessEntry, LPSTR Format, ... );
int WINAPIV _peprint( PPROCESS_ENTRY ProcessEntry, LPSTR Format, ... );
int WINAPIV _dprint( LPSTR format, ... );
int WINAPIV _eprint( LPSTR Format, ... );
#define dprint ((g.SymOptions & SYMOPT_DEBUG) == SYMOPT_DEBUG)&&_dprint
#define eprint ((g.SymOptions & SYMOPT_DEBUG) == SYMOPT_DEBUG)&&_eprint
#define cprint _dprint
#define pprint ((g.SymOptions & SYMOPT_DEBUG) == SYMOPT_DEBUG)&&_pprint
#define peprint ((g.SymOptions & SYMOPT_DEBUG) == SYMOPT_DEBUG)&&_peprint
#define pcprint _pprint
BOOL WINAPIV evtprint( PPROCESS_ENTRY pe, DWORD severity, DWORD code, PVOID object, LPSTR format, ... );
BOOL traceAddr( DWORD64 addr );
BOOL traceName( PCHAR name );
BOOL traceSubName( PCHAR name );
// for use with cvtype.h
typedef SYMTYPE *SYMPTR;
__inline DWORD64 GetIP( PPROCESS_ENTRY pe ) { return pe->StackFrame.InstructionOffset; }
typedef struct _PDB_INFO { CHAR Signature[4]; // "NBxx"
ULONG Offset; // always zero
ULONG sig; ULONG age; CHAR PdbName[_MAX_PATH]; } PDB_INFO, *PPDB_INFO;
#define n_name N.ShortName
#define n_zeroes N.Name.Short
#define n_nptr N.LongName[1]
#define n_offset N.Name.Long
//
// internal prototypes
//
BOOL IsImageMachineType64( DWORD MachineType );
void InitModuleEntry( PMODULE_ENTRY mi );
PMODULE_ENTRY GetModFromAddr( PPROCESS_ENTRY pe, IN DWORD64 addr );
DWORD_PTR GetPID( HANDLE hProcess );
DWORD GetProcessModules( HANDLE hProcess, PINTERNAL_GET_MODULE InternalGetModule, PVOID Context );
BOOL InternalGetModule( HANDLE hProcess, LPSTR ModuleName, DWORD64 ImageBase, DWORD ImageSize, PVOID Context );
VOID FreeModuleEntry( PPROCESS_ENTRY pe, PMODULE_ENTRY mi );
PPROCESS_ENTRY FindProcessEntry( HANDLE hProcess );
PPROCESS_ENTRY FindFirstProcessEntry( );
VOID GetSymName( PIMAGE_SYMBOL Symbol, PUCHAR StringTable, LPSTR s, DWORD size );
BOOL ProcessOmapSymbol( PMODULE_ENTRY mi, PSYMBOL_ENTRY sym );
DWORD64 ConvertOmapFromSrc( PMODULE_ENTRY mi, DWORD64 addr, LPDWORD bias );
DWORD64 ConvertOmapToSrc( PMODULE_ENTRY mi, DWORD64 addr, LPDWORD bias, BOOL fBackup );
POMAP GetOmapFromSrcEntry( PMODULE_ENTRY mi, DWORD64 addr );
VOID DumpOmapForModule( PMODULE_ENTRY mi );
VOID ProcessOmapForModule( PMODULE_ENTRY mi, PIMGHLP_DEBUG_DATA pIDD );
BOOL LoadCoffSymbols( HANDLE hProcess, PMODULE_ENTRY mi, PIMGHLP_DEBUG_DATA pIDD );
BOOL LoadCodeViewSymbols( HANDLE hProcess, PMODULE_ENTRY mi, PIMGHLP_DEBUG_DATA pIDD );
ULONG LoadExportSymbols( PMODULE_ENTRY mi, PIMGHLP_DEBUG_DATA pIDD );
PMODULE_ENTRY GetModuleForPC( PPROCESS_ENTRY ProcessEntry, DWORD64 dwPcAddr, BOOL ExactMatch );
PSYMBOL_ENTRY GetSymFromAddr( DWORD64 dwAddr, PDWORD64 pqwDisplacement, PMODULE_ENTRY mi );
LPSTR StringDup( LPSTR str );
DWORD64 InternalLoadModule( IN HANDLE hProcess, IN PSTR ImageName, IN PSTR ModuleName, IN DWORD64 BaseOfDll, IN DWORD SizeOfDll, IN HANDLE hFile, IN PMODLOAD_DATA data, IN DWORD flags );
DWORD ComputeHash( LPSTR lpname, ULONG cb );
PSYMBOL_ENTRY FindSymbolByName( PPROCESS_ENTRY pe, PMODULE_ENTRY mi, LPSTR SymName );
PFPO_DATA SwSearchFpoData( DWORD key, PFPO_DATA base, DWORD num );
PIMGHLP_RVA_FUNCTION_DATA GetFunctionEntryFromDebugInfo ( PPROCESS_ENTRY ProcessEntry, DWORD64 ControlPc );
PIMAGE_FUNCTION_ENTRY LookupFunctionEntryAxp32 ( HANDLE hProcess, DWORD ControlPc );
PIMAGE_FUNCTION_ENTRY64 LookupFunctionEntryAxp64 ( HANDLE hProcess, DWORD64 ControlPc );
PIMAGE_IA64_RUNTIME_FUNCTION_ENTRY LookupFunctionEntryIa64 ( HANDLE hProcess, DWORD64 ControlPc );
_PIMAGE_RUNTIME_FUNCTION_ENTRY LookupFunctionEntryAmd64 ( HANDLE hProcess, DWORD64 ControlPc );
BOOL LoadedModuleEnumerator( HANDLE hProcess, LPSTR ModuleName, DWORD64 ImageBase, DWORD ImageSize, PLOADED_MODULE lm );
BOOL load( IN HANDLE hProcess, IN PMODULE_ENTRY mi );
LPSTR symfmt( LPSTR DstName, LPSTR SrcName, ULONG Length );
BOOL MatchSymName( LPSTR matchName, LPSTR symName );
BOOL strcmpre( LPSTR pStr, LPSTR pRE, BOOL fCase );
PIMAGEHLP_SYMBOL symcpy32( PIMAGEHLP_SYMBOL External, PSYMBOL_ENTRY Internal );
PIMAGEHLP_SYMBOL64 symcpy64( PIMAGEHLP_SYMBOL64 External, PSYMBOL_ENTRY Internal );
BOOL SympConvertSymbol32To64( PIMAGEHLP_SYMBOL Symbol32, PIMAGEHLP_SYMBOL64 Symbol64 );
BOOL SympConvertSymbol64To32( PIMAGEHLP_SYMBOL64 Symbol64, PIMAGEHLP_SYMBOL Symbol32 );
BOOL SympConvertLine32To64( PIMAGEHLP_LINE Line32, PIMAGEHLP_LINE64 Line64 );
BOOL SympConvertLine64To32( PIMAGEHLP_LINE64 Line64, PIMAGEHLP_LINE Line32 );
BOOL SympConvertAnsiModule32ToUnicodeModule32( PIMAGEHLP_MODULE A_Symbol32, PIMAGEHLP_MODULEW W_Symbol32 );
BOOL SympConvertUnicodeModule32ToAnsiModule32( PIMAGEHLP_MODULEW W_Symbol32, PIMAGEHLP_MODULE A_Symbol32 );
BOOL SympConvertAnsiModule64ToUnicodeModule64( PIMAGEHLP_MODULE64 A_Symbol64, PIMAGEHLP_MODULEW64 W_Symbol64 );
BOOL SympConvertUnicodeModule64ToAnsiModule64( PIMAGEHLP_MODULEW64 W_Symbol64, PIMAGEHLP_MODULE64 A_Symbol64 );
BOOL CopySymbolEntryFromSymbolInfo( PSYMBOL_ENTRY se, PSYMBOL_INFO si );
PMODULE_ENTRY FindModule( HANDLE hModule, PPROCESS_ENTRY ProcessEntry, LPSTR ModuleName, BOOL fLoad );
BOOL ToggleFailCriticalErrors( BOOL reset );
DWORD fnGetFileAttributes( LPCTSTR lpFileName );
#define SetCriticalErrorMode() ToggleFailCriticalErrors(FALSE)
#define ResetCriticalErrorMode() ToggleFailCriticalErrors(TRUE)
#define fileexists(path) (fnGetFileAttributes(path) != 0xFFFFFFFF)
LPSTR SymUnDNameInternal( LPSTR UnDecName, DWORD UnDecNameLength, LPSTR DecName, DWORD MaxDecNameLength, DWORD MachineType, BOOL IsPublic );
BOOL GetLineFromAddr( PMODULE_ENTRY mi, DWORD64 Addr, PDWORD Displacement, PIMAGEHLP_LINE64 Line );
BOOL FindLineByName( PMODULE_ENTRY mi, LPSTR FileName, DWORD LineNumber, PLONG Displacement, PIMAGEHLP_LINE64 Line );
BOOL AddLinesForCoff( PMODULE_ENTRY mi, PIMAGE_SYMBOL allSymbols, DWORD numberOfSymbols, PIMAGE_LINENUMBER LineNumbers );
BOOL AddLinesForOmfSourceModule( PMODULE_ENTRY mi, BYTE *Base, OMFSourceModule *OmfSrcMod, PVOID PdbModule );
PSOURCE_ENTRY FindNextSourceEntryForFile( PMODULE_ENTRY mi, LPSTR File, PSOURCE_ENTRY SearchFrom );
PSOURCE_ENTRY FindPrevSourceEntryForFile( PMODULE_ENTRY mi, LPSTR File, PSOURCE_ENTRY SearchFrom );
BOOL __stdcall ReadInProcMemory( HANDLE hProcess, DWORD64 addr, PVOID buf, DWORD bytes, DWORD *bytesread );
BOOL GetPData( HANDLE hp, PMODULE_ENTRY mi );
BOOL GetXData( HANDLE hp, PMODULE_ENTRY mi );
PVOID GetXDataFromBase( HANDLE hp, DWORD64 base, ULONG_PTR* size );
PVOID GetUnwindInfoFromSymbols( HANDLE hProcess, DWORD64 ModuleBase, ULONG UnwindInfoAddress, ULONG_PTR* Size );
VOID SympSendDebugString( PPROCESS_ENTRY ProcessEntry, LPSTR String );
BOOL DoEnumCallback( PPROCESS_ENTRY pe, PSYMBOL_INFO pSymInfo, ULONG SymSize, PROC EnumCallback, PVOID UserContext, BOOL Use64, BOOL UsesUnicode );
#ifdef __cpluspluss
extern "C" { #endif
BOOL MatchSymbolName( PSYMBOL_ENTRY sym, LPSTR SymName );
BOOL LoadSymbols( HANDLE hp, PMODULE_ENTRY mi, DWORD flags );
// flags parameter to LoadSymbols
#define LS_QUALIFIED 0x1
#define LS_LOAD_LINES 0x2
#define LS_JUST_TEST 0x4
#define LS_FAIL_IF_LOADED 0x8
// flags indicate Next or Previous for many functions
#define NP_NEXT 1
#define NP_PREV -1
BOOL DoSymbolCallback ( PPROCESS_ENTRY ProcessEntry, ULONG CallbackType, IN PMODULE_ENTRY mi, PIMAGEHLP_DEFERRED_SYMBOL_LOAD64 idsl64, LPSTR FileName );
BOOL DoCallback( PPROCESS_ENTRY pe, ULONG type, PVOID data );
#define lengthof(a) (sizeof(a) / sizeof(a[0]))
BOOL wcs2ansi( PWSTR pwsz, PSTR psz, DWORD pszlen );
BOOL ansi2wcs( PSTR psz, PWSTR pwsz, DWORD pwszlen );
PWSTR AnsiToUnicode(PSTR); PSTR UnicodeToAnsi(PWSTR); #if 0
BOOL CopyAnsiToUnicode(PWSTR, PSTR, DWORD); BOOL CopyUnicodeToAnsi(PSTR, PWSTR, DWORD); #endif
BOOL LookupRegID ( IN ULONG CVReg, IN ULONG MachineType, OUT PULONG pDbgReg );
ULONG GetAddressFromOffset( PMODULE_ENTRY mi, ULONG section, ULONG64 Offset, PULONG64 pAddress );
VOID AddSourceEntry( PMODULE_ENTRY mi, PSOURCE_ENTRY Src );
BOOL diaInit( VOID );
void diaRelease( PVOID dia );
BOOL diaOpenPdb( PIMGHLP_DEBUG_DATA pIDD );
BOOL diaEnumSourceFiles( IN PMODULE_ENTRY mi, IN PCHAR mask, IN PSYM_ENUMSOURCFILES_CALLBACK cbSrcFiles, IN PVOID context );
BOOL diaGetPData( PMODULE_ENTRY mi );
BOOL diaGetXData( PMODULE_ENTRY mi );
PSYMBOL_ENTRY diaFindSymbolByName( PPROCESS_ENTRY pe, PMODULE_ENTRY mi, LPSTR SymName );
BOOL diaEnumerateSymbols( IN PPROCESS_ENTRY pe, IN PMODULE_ENTRY mi, IN LPSTR mask, IN PROC callback, IN PVOID UserContext, IN BOOL Use64, IN BOOL CallBackUsesUnicode );
PSYMBOL_ENTRY diaGetSymFromAddr( DWORD64 dwAddr, PMODULE_ENTRY mi, PDWORD64 disp );
BOOL diaGetLineFromAddr( PMODULE_ENTRY mi, DWORD64 addr, PDWORD displacement, PIMAGEHLP_LINE64 Line );
BOOL diaGetLineNextPrev( PMODULE_ENTRY mi, PIMAGEHLP_LINE64 line, DWORD direction );
#define diaGetLineNext(mi, line) diaGetLineNextPrev(mi, line, NP_NEXT);
#define diaGetLinePrev(mi, line) diaGetLineNextPrev(mi, line, NP_PREV);
BOOL diaGetLineFromName( PMODULE_ENTRY mi, LPSTR filename, DWORD linenumber, PLONG displacement, PIMAGEHLP_LINE64 line );
PSYMBOL_ENTRY diaGetSymNextPrev( PMODULE_ENTRY mi, DWORD64 addr, int direction );
DWORD diaVersion( VOID );
BOOL diaSetModFromIP( PPROCESS_ENTRY pe );
HRESULT diaGetSymbolInfo( IN HANDLE hProcess, IN DWORD64 ModBase, IN ULONG TypeId, IN IMAGEHLP_SYMBOL_TYPE_INFO GetType, OUT PVOID pInfo );
BOOL diaGetTiForUDT( PMODULE_ENTRY ModuleEntry, LPSTR name, PSYMBOL_INFO psi );
BOOL diaEnumUDT( PMODULE_ENTRY ModuleEntry, LPSTR name, PSYM_ENUMERATESYMBOLS_CALLBACK EnumSymbolsCallback, PVOID EnumContext );
BOOL diaGetFrameData( IN HANDLE Process, IN ULONGLONG Offset, OUT interface IDiaFrameData** FrameData ); DWORD mdSet( PMODULE_DATA md, DWORD id, DWORD hint, DWORD src );
BOOL InitOutputString( PCHAR sz );
BOOL TestOutputString( PCHAR sz );
#ifdef __cpluspluss
} #endif
|