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 DenseSet<HMODULE> *OpenedHandles; 43 44extern "C" { 45 46 static BOOL CALLBACK ELM_Callback(WIN32_ELMCB_PCSTR ModuleName, 47 ULONG_PTR ModuleBase, 48 ULONG ModuleSize, 49 PVOID UserContext) 50 { 51 // Ignore VC++ runtimes prior to 7.1. Somehow some of them get loaded 52 // into the process. 53 if (stricmp(ModuleName, "msvci70") != 0 && 54 stricmp(ModuleName, "msvcirt") != 0 && 55 stricmp(ModuleName, "msvcp50") != 0 && 56 stricmp(ModuleName, "msvcp60") != 0 && 57 stricmp(ModuleName, "msvcp70") != 0 && 58 stricmp(ModuleName, "msvcr70") != 0 && 59#ifndef __MINGW32__ 60 // Mingw32 uses msvcrt.dll by default. Don't ignore it. 61 // Otherwise, user should be aware, what he's doing :) 62 stricmp(ModuleName, "msvcrt") != 0 && 63#endif 64 stricmp(ModuleName, "msvcrt20") != 0 && 65 stricmp(ModuleName, "msvcrt40") != 0) { 66 OpenedHandles->insert((HMODULE)ModuleBase); 67 } 68 return TRUE; 69 } 70} 71 72DynamicLibrary DynamicLibrary::getPermanentLibrary(const char *filename, 73 std::string *errMsg) { 74 SmartScopedLock<true> lock(getMutex()); 75 76 if (!filename) { 77 // When no file is specified, enumerate all DLLs and EXEs in the process. 78 if (OpenedHandles == 0) 79 OpenedHandles = new DenseSet<HMODULE>(); 80 81 EnumerateLoadedModules(GetCurrentProcess(), ELM_Callback, 0); 82 // Dummy library that represents "search all handles". 83 // This is mostly to ensure that the return value still shows up as "valid". 84 return DynamicLibrary(&OpenedHandles); 85 } 86 87 HMODULE a_handle = LoadLibrary(filename); 88 89 if (a_handle == 0) { 90 MakeErrMsg(errMsg, std::string(filename) + ": Can't open : "); 91 return DynamicLibrary(); 92 } 93 94 if (OpenedHandles == 0) 95 OpenedHandles = new DenseSet<HMODULE>(); 96 97 // If we've already loaded this library, FreeLibrary() the handle in order to 98 // keep the internal refcount at +1. 99 if (!OpenedHandles->insert(a_handle).second) 100 FreeLibrary(a_handle); 101 102 return DynamicLibrary(a_handle); 103} 104 105// Stack probing routines are in the support library (e.g. libgcc), but we don't 106// have dynamic linking on windows. Provide a hook. 107#define EXPLICIT_SYMBOL(SYM) \ 108 extern "C" { extern void *SYM; } 109#define EXPLICIT_SYMBOL2(SYMFROM, SYMTO) EXPLICIT_SYMBOL(SYMTO) 110 111#include "explicit_symbols.inc" 112 113#undef EXPLICIT_SYMBOL 114#undef EXPLICIT_SYMBOL2 115 116void* DynamicLibrary::SearchForAddressOfSymbol(const char* symbolName) { 117 SmartScopedLock<true> Lock(getMutex()); 118 119 // First check symbols added via AddSymbol(). 120 if (ExplicitSymbols) { 121 StringMap<void *>::iterator i = ExplicitSymbols->find(symbolName); 122 123 if (i != ExplicitSymbols->end()) 124 return i->second; 125 } 126 127 // Now search the libraries. 128 if (OpenedHandles) { 129 for (DenseSet<HMODULE>::iterator I = OpenedHandles->begin(), 130 E = OpenedHandles->end(); I != E; ++I) { 131 FARPROC ptr = GetProcAddress((HMODULE)*I, symbolName); 132 if (ptr) { 133 return (void *)(intptr_t)ptr; 134 } 135 } 136 } 137 138 #define EXPLICIT_SYMBOL(SYM) \ 139 if (!strcmp(symbolName, #SYM)) return (void*)&SYM; 140 #define EXPLICIT_SYMBOL2(SYMFROM, SYMTO) \ 141 if (!strcmp(symbolName, #SYMFROM)) return (void*)&SYMTO; 142 143 { 144 #include "explicit_symbols.inc" 145 } 146 147 #undef EXPLICIT_SYMBOL 148 #undef EXPLICIT_SYMBOL2 149 150 return 0; 151} 152 153 154void *DynamicLibrary::getAddressOfSymbol(const char *symbolName) { 155 if (!isValid()) 156 return NULL; 157 if (Data == &OpenedHandles) 158 return SearchForAddressOfSymbol(symbolName); 159 return (void *)(intptr_t)GetProcAddress((HMODULE)Data, symbolName); 160} 161 162 163} 164