DynamicLibrary.inc revision 218893
1//===- Win32/DynamicLibrary.cpp - Win32 DL Implementation -------*- C++ -*-===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9// 10// This file provides the Win32 specific implementation of DynamicLibrary. 11// 12//===----------------------------------------------------------------------===// 13 14#include "Windows.h" 15 16#ifdef __MINGW32__ 17 #include <imagehlp.h> 18#else 19 #include <dbghelp.h> 20#endif 21 22#ifdef _MSC_VER 23 #include <ntverp.h> 24#endif 25 26#ifdef __MINGW32__ 27 #if (HAVE_LIBIMAGEHLP != 1) 28 #error "libimagehlp.a should be present" 29 #endif 30#else 31 #pragma comment(lib, "dbghelp.lib") 32#endif 33 34namespace llvm { 35using namespace sys; 36 37//===----------------------------------------------------------------------===// 38//=== WARNING: Implementation here must contain only Win32 specific code 39//=== and must not be UNIX code. 40//===----------------------------------------------------------------------===// 41 42static std::vector<HMODULE> OpenedHandles; 43 44#ifdef _WIN64 45 typedef DWORD64 ModuleBaseType; 46#else 47 typedef ULONG ModuleBaseType; 48#endif 49 50extern "C" { 51// Use old callback if: 52// - Not using Visual Studio 53// - Visual Studio 2005 or earlier but only if we are not using the Windows SDK 54// or Windows SDK version is older than 6.0 55// Use new callback if: 56// - Newer Visual Studio (comes with newer SDK). 57// - Visual Studio 2005 with Windows SDK 6.0+ 58#if defined(_MSC_VER) 59 #if _MSC_VER < 1500 && (!defined(VER_PRODUCTBUILD) || VER_PRODUCTBUILD < 6000) 60 #define OLD_ELM_CALLBACK_DECL 1 61 #endif 62#elif defined(__MINGW64__) 63 // Use new callback. 64#elif defined(__MINGW32__) 65 #define OLD_ELM_CALLBACK_DECL 1 66#endif 67 68#ifdef OLD_ELM_CALLBACK_DECL 69 static BOOL CALLBACK ELM_Callback(PSTR ModuleName, 70 ModuleBaseType ModuleBase, 71 ULONG ModuleSize, 72 PVOID UserContext) 73#else 74 static BOOL CALLBACK ELM_Callback(PCSTR ModuleName, 75 ModuleBaseType ModuleBase, 76 ULONG ModuleSize, 77 PVOID UserContext) 78#endif 79 { 80 // Ignore VC++ runtimes prior to 7.1. Somehow some of them get loaded 81 // into the process. 82 if (stricmp(ModuleName, "msvci70") != 0 && 83 stricmp(ModuleName, "msvcirt") != 0 && 84 stricmp(ModuleName, "msvcp50") != 0 && 85 stricmp(ModuleName, "msvcp60") != 0 && 86 stricmp(ModuleName, "msvcp70") != 0 && 87 stricmp(ModuleName, "msvcr70") != 0 && 88#ifndef __MINGW32__ 89 // Mingw32 uses msvcrt.dll by default. Don't ignore it. 90 // Otherwise, user should be aware, what he's doing :) 91 stricmp(ModuleName, "msvcrt") != 0 && 92#endif 93 stricmp(ModuleName, "msvcrt20") != 0 && 94 stricmp(ModuleName, "msvcrt40") != 0) { 95 OpenedHandles.push_back((HMODULE)ModuleBase); 96 } 97 return TRUE; 98 } 99} 100 101bool DynamicLibrary::LoadLibraryPermanently(const char *filename, 102 std::string *ErrMsg) { 103 if (filename) { 104 HMODULE a_handle = LoadLibrary(filename); 105 106 if (a_handle == 0) 107 return MakeErrMsg(ErrMsg, std::string(filename) + ": Can't open : "); 108 109 OpenedHandles.push_back(a_handle); 110 } else { 111 // When no file is specified, enumerate all DLLs and EXEs in the 112 // process. 113 EnumerateLoadedModules(GetCurrentProcess(), ELM_Callback, 0); 114 } 115 116 // Because we don't remember the handle, we will never free it; hence, 117 // it is loaded permanently. 118 return false; 119} 120 121// Stack probing routines are in the support library (e.g. libgcc), but we don't 122// have dynamic linking on windows. Provide a hook. 123#define EXPLICIT_SYMBOL(SYM) \ 124 extern "C" { extern void *SYM; } 125#define EXPLICIT_SYMBOL2(SYMFROM, SYMTO) EXPLICIT_SYMBOL(SYMTO) 126 127#include "explicit_symbols.inc" 128 129#undef EXPLICIT_SYMBOL 130#undef EXPLICIT_SYMBOL2 131 132void* DynamicLibrary::SearchForAddressOfSymbol(const char* symbolName) { 133 // First check symbols added via AddSymbol(). 134 if (ExplicitSymbols) { 135 std::map<std::string, void *>::iterator I = 136 ExplicitSymbols->find(symbolName); 137 std::map<std::string, void *>::iterator E = ExplicitSymbols->end(); 138 if (I != E) 139 return I->second; 140 } 141 142 // Now search the libraries. 143 for (std::vector<HMODULE>::iterator I = OpenedHandles.begin(), 144 E = OpenedHandles.end(); I != E; ++I) { 145 FARPROC ptr = GetProcAddress((HMODULE)*I, symbolName); 146 if (ptr) { 147 return (void *) ptr; 148 } 149 } 150 151 #define EXPLICIT_SYMBOL(SYM) \ 152 if (!strcmp(symbolName, #SYM)) return (void*)&SYM; 153 #define EXPLICIT_SYMBOL2(SYMFROM, SYMTO) \ 154 if (!strcmp(symbolName, #SYMFROM)) return (void*)&SYMTO; 155 156 { 157 #include "explicit_symbols.inc" 158 } 159 160 #undef EXPLICIT_SYMBOL 161 #undef EXPLICIT_SYMBOL2 162 163 return 0; 164} 165 166} 167