LLVM API Documentation
00001 //===- Win32/DynamicLibrary.cpp - Win32 DL Implementation -------*- C++ -*-===// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file is distributed under the University of Illinois Open Source 00006 // License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 // 00010 // This file provides the Win32 specific implementation of DynamicLibrary. 00011 // 00012 //===----------------------------------------------------------------------===// 00013 00014 #include "Win32.h" 00015 00016 #ifdef __MINGW32__ 00017 #include <imagehlp.h> 00018 #else 00019 #include <dbghelp.h> 00020 #endif 00021 00022 #ifdef __MINGW32__ 00023 #if (HAVE_LIBIMAGEHLP != 1) 00024 #error "libimagehlp.a should be present" 00025 #endif 00026 #else 00027 #pragma comment(lib, "dbghelp.lib") 00028 #endif 00029 00030 namespace llvm { 00031 using namespace sys; 00032 00033 //===----------------------------------------------------------------------===// 00034 //=== WARNING: Implementation here must contain only Win32 specific code 00035 //=== and must not be UNIX code. 00036 //===----------------------------------------------------------------------===// 00037 00038 static std::vector<HMODULE> OpenedHandles; 00039 00040 #ifdef _WIN64 00041 typedef DWORD64 ModuleBaseType; 00042 #else 00043 typedef ULONG ModuleBaseType; 00044 #endif 00045 00046 extern "C" { 00047 #if !defined(_MSC_VER) || _MSC_VER < 1500 00048 static BOOL CALLBACK ELM_Callback(PSTR ModuleName, 00049 ModuleBaseType ModuleBase, 00050 ULONG ModuleSize, 00051 PVOID UserContext) 00052 #else 00053 static BOOL CALLBACK ELM_Callback(PCSTR ModuleName, 00054 ModuleBaseType ModuleBase, 00055 ULONG ModuleSize, 00056 PVOID UserContext) 00057 #endif 00058 { 00059 // Ignore VC++ runtimes prior to 7.1. Somehow some of them get loaded 00060 // into the process. 00061 if (stricmp(ModuleName, "msvci70") != 0 && 00062 stricmp(ModuleName, "msvcirt") != 0 && 00063 stricmp(ModuleName, "msvcp50") != 0 && 00064 stricmp(ModuleName, "msvcp60") != 0 && 00065 stricmp(ModuleName, "msvcp70") != 0 && 00066 stricmp(ModuleName, "msvcr70") != 0 && 00067 #ifndef __MINGW32__ 00068 // Mingw32 uses msvcrt.dll by default. Don't ignore it. 00069 // Otherwise, user should be aware, what he's doing :) 00070 stricmp(ModuleName, "msvcrt") != 0 && 00071 #endif 00072 stricmp(ModuleName, "msvcrt20") != 0 && 00073 stricmp(ModuleName, "msvcrt40") != 0) { 00074 OpenedHandles.push_back((HMODULE)ModuleBase); 00075 } 00076 return TRUE; 00077 } 00078 } 00079 00080 DynamicLibrary::DynamicLibrary() : handle(0) { 00081 handle = GetModuleHandle(NULL); 00082 OpenedHandles.push_back((HMODULE)handle); 00083 } 00084 00085 DynamicLibrary::~DynamicLibrary() { 00086 if (handle == 0) 00087 return; 00088 00089 // GetModuleHandle() does not increment the ref count, so we must not free 00090 // the handle to the executable. 00091 if (handle != GetModuleHandle(NULL)) 00092 FreeLibrary((HMODULE)handle); 00093 handle = 0; 00094 00095 for (std::vector<HMODULE>::iterator I = OpenedHandles.begin(), 00096 E = OpenedHandles.end(); I != E; ++I) { 00097 if (*I == handle) { 00098 // Note: don't use the swap/pop_back trick here. Order is important. 00099 OpenedHandles.erase(I); 00100 } 00101 } 00102 } 00103 00104 bool DynamicLibrary::LoadLibraryPermanently(const char *filename, 00105 std::string *ErrMsg) { 00106 if (filename) { 00107 HMODULE a_handle = LoadLibrary(filename); 00108 00109 if (a_handle == 0) 00110 return MakeErrMsg(ErrMsg, std::string(filename) + ": Can't open : "); 00111 00112 OpenedHandles.push_back(a_handle); 00113 } else { 00114 // When no file is specified, enumerate all DLLs and EXEs in the 00115 // process. 00116 EnumerateLoadedModules(GetCurrentProcess(), ELM_Callback, 0); 00117 } 00118 00119 // Because we don't remember the handle, we will never free it; hence, 00120 // it is loaded permanently. 00121 return false; 00122 } 00123 00124 // Stack probing routines are in the support library (e.g. libgcc), but we don't 00125 // have dynamic linking on windows. Provide a hook. 00126 #if defined(__MINGW32__) || defined (_MSC_VER) 00127 #define EXPLICIT_SYMBOL(SYM) \ 00128 if (!strcmp(symbolName, #SYM)) return (void*)&SYM 00129 #define EXPLICIT_SYMBOL2(SYMFROM, SYMTO) \ 00130 if (!strcmp(symbolName, #SYMFROM)) return (void*)&SYMTO 00131 #define EXPLICIT_SYMBOL_DEF(SYM) \ 00132 extern "C" { extern void *SYM; } 00133 00134 #if defined(__MINGW32__) 00135 EXPLICIT_SYMBOL_DEF(_alloca); 00136 EXPLICIT_SYMBOL_DEF(__main); 00137 EXPLICIT_SYMBOL_DEF(__ashldi3); 00138 EXPLICIT_SYMBOL_DEF(__ashrdi3); 00139 EXPLICIT_SYMBOL_DEF(__cmpdi2); 00140 EXPLICIT_SYMBOL_DEF(__divdi3); 00141 EXPLICIT_SYMBOL_DEF(__eprintf); 00142 EXPLICIT_SYMBOL_DEF(__fixdfdi); 00143 EXPLICIT_SYMBOL_DEF(__fixsfdi); 00144 EXPLICIT_SYMBOL_DEF(__fixunsdfdi); 00145 EXPLICIT_SYMBOL_DEF(__fixunssfdi); 00146 EXPLICIT_SYMBOL_DEF(__floatdidf); 00147 EXPLICIT_SYMBOL_DEF(__floatdisf); 00148 EXPLICIT_SYMBOL_DEF(__lshrdi3); 00149 EXPLICIT_SYMBOL_DEF(__moddi3); 00150 EXPLICIT_SYMBOL_DEF(__udivdi3); 00151 EXPLICIT_SYMBOL_DEF(__umoddi3); 00152 #elif defined(_MSC_VER) 00153 EXPLICIT_SYMBOL_DEF(_alloca_probe); 00154 #endif 00155 #endif 00156 00157 void* DynamicLibrary::SearchForAddressOfSymbol(const char* symbolName) { 00158 // First check symbols added via AddSymbol(). 00159 std::map<std::string, void *>::iterator I = g_symbols().find(symbolName); 00160 if (I != g_symbols().end()) 00161 return I->second; 00162 00163 // Now search the libraries. 00164 for (std::vector<HMODULE>::iterator I = OpenedHandles.begin(), 00165 E = OpenedHandles.end(); I != E; ++I) { 00166 FARPROC ptr = GetProcAddress((HMODULE)*I, symbolName); 00167 if (ptr) 00168 return (void *) ptr; 00169 } 00170 00171 #if defined(__MINGW32__) 00172 { 00173 EXPLICIT_SYMBOL(_alloca); 00174 EXPLICIT_SYMBOL(__main); 00175 EXPLICIT_SYMBOL(__ashldi3); 00176 EXPLICIT_SYMBOL(__ashrdi3); 00177 EXPLICIT_SYMBOL(__cmpdi2); 00178 EXPLICIT_SYMBOL(__divdi3); 00179 EXPLICIT_SYMBOL(__eprintf); 00180 EXPLICIT_SYMBOL(__fixdfdi); 00181 EXPLICIT_SYMBOL(__fixsfdi); 00182 EXPLICIT_SYMBOL(__fixunsdfdi); 00183 EXPLICIT_SYMBOL(__fixunssfdi); 00184 EXPLICIT_SYMBOL(__floatdidf); 00185 EXPLICIT_SYMBOL(__floatdisf); 00186 EXPLICIT_SYMBOL(__lshrdi3); 00187 EXPLICIT_SYMBOL(__moddi3); 00188 EXPLICIT_SYMBOL(__udivdi3); 00189 EXPLICIT_SYMBOL(__umoddi3); 00190 00191 EXPLICIT_SYMBOL2(alloca, _alloca); 00192 #undef EXPLICIT_SYMBOL 00193 #undef EXPLICIT_SYMBOL2 00194 #undef EXPLICIT_SYMBOL_DEF 00195 } 00196 #elif defined(_MSC_VER) 00197 { 00198 EXPLICIT_SYMBOL2(alloca, _alloca_probe); 00199 EXPLICIT_SYMBOL2(_alloca, _alloca_probe); 00200 #undef EXPLICIT_SYMBOL 00201 #undef EXPLICIT_SYMBOL2 00202 #undef EXPLICIT_SYMBOL_DEF 00203 } 00204 #endif 00205 00206 return 0; 00207 } 00208 00209 } 00210