1/**
2 * ...
3 *
4 * Copyright: Copyright Benjamin Thaut 2010 - 2011.
5 * License: Distributed under the
6 *      $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost Software License 1.0).
7 *    (See accompanying file LICENSE)
8 * Authors:   Benjamin Thaut, Sean Kelly
9 * Source:    $(DRUNTIMESRC core/sys/windows/_stacktrace.d)
10 */
11
12module core.sys.windows.dbghelp;
13version (Windows):
14@system:
15
16import core.sys.windows.winbase /+: FreeLibrary, GetProcAddress, LoadLibraryA+/;
17import core.sys.windows.windef;
18
19public import core.sys.windows.dbghelp_types;
20
21extern(Windows)
22{
23    alias BOOL         function(HANDLE hProcess, DWORD64 lpBaseAddress, PVOID lpBuffer, DWORD nSize, LPDWORD lpNumberOfBytesRead) ReadProcessMemoryProc64;
24    alias PVOID        function(HANDLE hProcess, DWORD64 AddrBase) FunctionTableAccessProc64;
25    alias DWORD64      function(HANDLE hProcess, DWORD64 Address) GetModuleBaseProc64;
26    alias DWORD64      function(HANDLE hProcess, HANDLE hThread, ADDRESS64 *lpaddr) TranslateAddressProc64;
27
28    alias BOOL         function(HANDLE hProcess, PCSTR UserSearchPath, bool fInvadeProcess) SymInitializeFunc;
29    alias BOOL         function(HANDLE hProcess) SymCleanupFunc;
30    alias DWORD        function(DWORD SymOptions) SymSetOptionsFunc;
31    alias DWORD        function() SymGetOptionsFunc;
32    alias PVOID        function(HANDLE hProcess, DWORD64 AddrBase) SymFunctionTableAccess64Func;
33    alias BOOL         function(DWORD MachineType, HANDLE hProcess, HANDLE hThread, STACKFRAME64 *StackFrame, PVOID ContextRecord,
34                                ReadProcessMemoryProc64 ReadMemoryRoutine, FunctionTableAccessProc64 FunctoinTableAccess,
35                                GetModuleBaseProc64 GetModuleBaseRoutine, TranslateAddressProc64 TranslateAddress) StackWalk64Func;
36    alias BOOL         function(HANDLE hProcess, DWORD64 dwAddr, PDWORD pdwDisplacement, IMAGEHLP_LINEA64 *line) SymGetLineFromAddr64Func;
37    alias DWORD64      function(HANDLE hProcess, DWORD64 dwAddr) SymGetModuleBase64Func;
38    alias BOOL         function(HANDLE hProcess, DWORD64 dwAddr, IMAGEHLP_MODULEA64 *ModuleInfo) SymGetModuleInfo64Func;
39    alias BOOL         function(HANDLE hProcess, DWORD64 Address, DWORD64 *Displacement, IMAGEHLP_SYMBOLA64 *Symbol) SymGetSymFromAddr64Func;
40    alias DWORD        function(PCSTR DecoratedName, PSTR UnDecoratedName, DWORD UndecoratedLength, DWORD Flags) UnDecorateSymbolNameFunc;
41    alias DWORD64      function(HANDLE hProcess, HANDLE hFile, PCSTR ImageName, PCSTR ModuleName, DWORD64 BaseOfDll, DWORD SizeOfDll) SymLoadModule64Func;
42    alias BOOL         function(HANDLE hProcess, PSTR SearchPath, DWORD SearchPathLength) SymGetSearchPathFunc;
43    alias BOOL         function(HANDLE hProcess, PCSTR SearchPath) SymSetSearchPathFunc;
44    alias BOOL         function(HANDLE hProcess, DWORD64 Address) SymUnloadModule64Func;
45    alias BOOL         function(HANDLE hProcess, ULONG ActionCode, ulong CallbackContext, ulong UserContext) PSYMBOL_REGISTERED_CALLBACK64;
46    alias BOOL         function(HANDLE hProcess, PSYMBOL_REGISTERED_CALLBACK64 CallbackFunction, ulong UserContext) SymRegisterCallback64Func;
47    alias API_VERSION* function() ImagehlpApiVersionFunc;
48}
49
50struct DbgHelp
51{
52    SymInitializeFunc        SymInitialize;
53    SymCleanupFunc           SymCleanup;
54    StackWalk64Func          StackWalk64;
55    SymGetOptionsFunc        SymGetOptions;
56    SymSetOptionsFunc        SymSetOptions;
57    SymFunctionTableAccess64Func SymFunctionTableAccess64;
58    SymGetLineFromAddr64Func SymGetLineFromAddr64;
59    SymGetModuleBase64Func   SymGetModuleBase64;
60    SymGetModuleInfo64Func   SymGetModuleInfo64;
61    SymGetSymFromAddr64Func  SymGetSymFromAddr64;
62    UnDecorateSymbolNameFunc UnDecorateSymbolName;
63    SymLoadModule64Func      SymLoadModule64;
64    SymGetSearchPathFunc     SymGetSearchPath;
65    SymSetSearchPathFunc     SymSetSearchPath;
66    SymUnloadModule64Func    SymUnloadModule64;
67    SymRegisterCallback64Func SymRegisterCallback64;
68    ImagehlpApiVersionFunc   ImagehlpApiVersion;
69
70    static DbgHelp* get()
71    {
72        if ( sm_hndl != sm_hndl.init )
73            return &sm_inst;
74        if ( (sm_hndl = LoadLibraryA( "dbghelp.dll" )) != sm_hndl.init )
75        {
76            sm_inst.SymInitialize            = cast(SymInitializeFunc) GetProcAddress(sm_hndl,"SymInitialize");
77            sm_inst.SymCleanup               = cast(SymCleanupFunc) GetProcAddress(sm_hndl,"SymCleanup");
78            sm_inst.StackWalk64              = cast(StackWalk64Func) GetProcAddress(sm_hndl,"StackWalk64");
79            sm_inst.SymGetOptions            = cast(SymGetOptionsFunc) GetProcAddress(sm_hndl,"SymGetOptions");
80            sm_inst.SymSetOptions            = cast(SymSetOptionsFunc) GetProcAddress(sm_hndl,"SymSetOptions");
81            sm_inst.SymFunctionTableAccess64 = cast(SymFunctionTableAccess64Func) GetProcAddress(sm_hndl,"SymFunctionTableAccess64");
82            sm_inst.SymGetLineFromAddr64     = cast(SymGetLineFromAddr64Func) GetProcAddress(sm_hndl,"SymGetLineFromAddr64");
83            sm_inst.SymGetModuleBase64       = cast(SymGetModuleBase64Func) GetProcAddress(sm_hndl,"SymGetModuleBase64");
84            sm_inst.SymGetModuleInfo64       = cast(SymGetModuleInfo64Func) GetProcAddress(sm_hndl,"SymGetModuleInfo64");
85            sm_inst.SymGetSymFromAddr64      = cast(SymGetSymFromAddr64Func) GetProcAddress(sm_hndl,"SymGetSymFromAddr64");
86            sm_inst.UnDecorateSymbolName     = cast(UnDecorateSymbolNameFunc) GetProcAddress(sm_hndl,"UnDecorateSymbolName");
87            sm_inst.SymLoadModule64          = cast(SymLoadModule64Func) GetProcAddress(sm_hndl,"SymLoadModule64");
88            sm_inst.SymGetSearchPath         = cast(SymGetSearchPathFunc) GetProcAddress(sm_hndl,"SymGetSearchPath");
89            sm_inst.SymSetSearchPath         = cast(SymSetSearchPathFunc) GetProcAddress(sm_hndl,"SymSetSearchPath");
90            sm_inst.SymUnloadModule64        = cast(SymUnloadModule64Func) GetProcAddress(sm_hndl,"SymUnloadModule64");
91            sm_inst.SymRegisterCallback64    = cast(SymRegisterCallback64Func) GetProcAddress(sm_hndl, "SymRegisterCallback64");
92            sm_inst.ImagehlpApiVersion       = cast(ImagehlpApiVersionFunc) GetProcAddress(sm_hndl, "ImagehlpApiVersion");
93            assert( sm_inst.SymInitialize && sm_inst.SymCleanup && sm_inst.StackWalk64 && sm_inst.SymGetOptions &&
94                    sm_inst.SymSetOptions && sm_inst.SymFunctionTableAccess64 && sm_inst.SymGetLineFromAddr64 &&
95                    sm_inst.SymGetModuleBase64 && sm_inst.SymGetModuleInfo64 && sm_inst.SymGetSymFromAddr64 &&
96                    sm_inst.UnDecorateSymbolName && sm_inst.SymLoadModule64 && sm_inst.SymGetSearchPath &&
97                    sm_inst.SymSetSearchPath && sm_inst.SymUnloadModule64 && sm_inst.SymRegisterCallback64 &&
98                    sm_inst.ImagehlpApiVersion);
99
100            return &sm_inst;
101        }
102        return null;
103    }
104
105    shared static ~this()
106    {
107        if ( sm_hndl != sm_hndl.init )
108            FreeLibrary( sm_hndl );
109    }
110
111private:
112    __gshared DbgHelp sm_inst;
113    __gshared HANDLE  sm_hndl;
114}
115