DynamicLibrary.inc revision 221345
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 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.push_back((HMODULE)ModuleBase); 67 } 68 return TRUE; 69 } 70} 71 72bool DynamicLibrary::LoadLibraryPermanently(const char *filename, 73 std::string *ErrMsg) { 74 if (filename) { 75 HMODULE a_handle = LoadLibrary(filename); 76 77 if (a_handle == 0) 78 return MakeErrMsg(ErrMsg, std::string(filename) + ": Can't open : "); 79 80 OpenedHandles.push_back(a_handle); 81 } else { 82 // When no file is specified, enumerate all DLLs and EXEs in the 83 // process. 84 EnumerateLoadedModules(GetCurrentProcess(), ELM_Callback, 0); 85 } 86 87 // Because we don't remember the handle, we will never free it; hence, 88 // it is loaded permanently. 89 return false; 90} 91 92// Stack probing routines are in the support library (e.g. libgcc), but we don't 93// have dynamic linking on windows. Provide a hook. 94#define EXPLICIT_SYMBOL(SYM) \ 95 extern "C" { extern void *SYM; } 96#define EXPLICIT_SYMBOL2(SYMFROM, SYMTO) EXPLICIT_SYMBOL(SYMTO) 97 98#include "explicit_symbols.inc" 99 100#undef EXPLICIT_SYMBOL 101#undef EXPLICIT_SYMBOL2 102 103void* DynamicLibrary::SearchForAddressOfSymbol(const char* symbolName) { 104 // First check symbols added via AddSymbol(). 105 if (ExplicitSymbols) { 106 std::map<std::string, void *>::iterator I = 107 ExplicitSymbols->find(symbolName); 108 std::map<std::string, void *>::iterator E = ExplicitSymbols->end(); 109 if (I != E) 110 return I->second; 111 } 112 113 // Now search the libraries. 114 for (std::vector<HMODULE>::iterator I = OpenedHandles.begin(), 115 E = OpenedHandles.end(); I != E; ++I) { 116 FARPROC ptr = GetProcAddress((HMODULE)*I, symbolName); 117 if (ptr) { 118 return (void *) ptr; 119 } 120 } 121 122 #define EXPLICIT_SYMBOL(SYM) \ 123 if (!strcmp(symbolName, #SYM)) return (void*)&SYM; 124 #define EXPLICIT_SYMBOL2(SYMFROM, SYMTO) \ 125 if (!strcmp(symbolName, #SYMFROM)) return (void*)&SYMTO; 126 127 { 128 #include "explicit_symbols.inc" 129 } 130 131 #undef EXPLICIT_SYMBOL 132 #undef EXPLICIT_SYMBOL2 133 134 return 0; 135} 136 137} 138