LLVM API Documentation
00001 //===- Win32/DynamicLibrary.cpp - Win32 DL Implementation -------*- C++ -*-===// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file was developed by Jeff Cohen and is distributed under the 00006 // University of Illinois Open Source 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 extern "C" { 00041 static BOOL CALLBACK ELM_Callback(PSTR ModuleName, 00042 ULONG ModuleBase, 00043 ULONG ModuleSize, 00044 PVOID UserContext) 00045 { 00046 // Ignore VC++ runtimes prior to 7.1. Somehow some of them get loaded 00047 // into the process. 00048 if (stricmp(ModuleName, "msvci70") != 0 && 00049 stricmp(ModuleName, "msvcirt") != 0 && 00050 stricmp(ModuleName, "msvcp50") != 0 && 00051 stricmp(ModuleName, "msvcp60") != 0 && 00052 stricmp(ModuleName, "msvcp70") != 0 && 00053 stricmp(ModuleName, "msvcr70") != 0 && 00054 stricmp(ModuleName, "msvcrt") != 0 && 00055 stricmp(ModuleName, "msvcrt20") != 0 && 00056 stricmp(ModuleName, "msvcrt40") != 0) { 00057 OpenedHandles.push_back((HMODULE)ModuleBase); 00058 } 00059 return TRUE; 00060 } 00061 } 00062 00063 DynamicLibrary::DynamicLibrary() : handle(0) { 00064 handle = GetModuleHandle(NULL); 00065 OpenedHandles.push_back((HMODULE)handle); 00066 } 00067 00068 DynamicLibrary::DynamicLibrary(const char*filename) : handle(0) { 00069 HMODULE a_handle = LoadLibrary(filename); 00070 00071 if (a_handle == 0) 00072 ThrowError(std::string(filename) + ": Can't open : "); 00073 00074 handle = a_handle; 00075 OpenedHandles.push_back(a_handle); 00076 } 00077 00078 DynamicLibrary::~DynamicLibrary() { 00079 if (handle == 0) 00080 return; 00081 00082 // GetModuleHandle() does not increment the ref count, so we must not free 00083 // the handle to the executable. 00084 if (handle != GetModuleHandle(NULL)) 00085 FreeLibrary((HMODULE)handle); 00086 handle = 0; 00087 00088 for (std::vector<HMODULE>::iterator I = OpenedHandles.begin(), 00089 E = OpenedHandles.end(); I != E; ++I) { 00090 if (*I == handle) { 00091 // Note: don't use the swap/pop_back trick here. Order is important. 00092 OpenedHandles.erase(I); 00093 } 00094 } 00095 } 00096 00097 bool DynamicLibrary::LoadLibraryPermanently(const char *filename, 00098 std::string *ErrMsg) { 00099 if (filename) { 00100 HMODULE a_handle = LoadLibrary(filename); 00101 00102 if (a_handle == 0) 00103 return GetError(std::string(filename) + ": Can't open : ", ErrMsg); 00104 00105 OpenedHandles.push_back(a_handle); 00106 } else { 00107 // When no file is specified, enumerate all DLLs and EXEs in the 00108 // process. 00109 EnumerateLoadedModules(GetCurrentProcess(), ELM_Callback, 0); 00110 } 00111 00112 // Because we don't remember the handle, we will never free it; hence, 00113 // it is loaded permanently. 00114 return false; 00115 } 00116 00117 void* DynamicLibrary::SearchForAddressOfSymbol(const char* symbolName) { 00118 // First check symbols added via AddSymbol(). 00119 std::map<std::string, void *>::iterator I = g_symbols.find(symbolName); 00120 if (I != g_symbols.end()) 00121 return I->second; 00122 00123 // Now search the libraries. 00124 for (std::vector<HMODULE>::iterator I = OpenedHandles.begin(), 00125 E = OpenedHandles.end(); I != E; ++I) { 00126 FARPROC ptr = GetProcAddress((HMODULE)*I, symbolName); 00127 if (ptr) 00128 return (void *) ptr; 00129 } 00130 00131 return 0; 00132 } 00133 00134 void *DynamicLibrary::GetAddressOfSymbol(const char *symbolName) { 00135 assert(handle != 0 && "Invalid DynamicLibrary handle"); 00136 return (void *) GetProcAddress((HMODULE)handle, symbolName); 00137 } 00138 00139 } 00140