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 #pragma comment(lib, "dbghelp.lib") 00023 00024 namespace llvm { 00025 using namespace sys; 00026 00027 //===----------------------------------------------------------------------===// 00028 //=== WARNING: Implementation here must contain only Win32 specific code 00029 //=== and must not be UNIX code. 00030 //===----------------------------------------------------------------------===// 00031 00032 static std::vector<HMODULE> OpenedHandles; 00033 00034 extern "C" { 00035 static BOOL CALLBACK ELM_Callback(PSTR ModuleName, 00036 ULONG ModuleBase, 00037 ULONG ModuleSize, 00038 PVOID UserContext) 00039 { 00040 // Ignore VC++ runtimes prior to 7.1. Somehow some of them get loaded 00041 // into the process. 00042 if (stricmp(ModuleName, "msvci70") != 0 && 00043 stricmp(ModuleName, "msvcirt") != 0 && 00044 stricmp(ModuleName, "msvcp50") != 0 && 00045 stricmp(ModuleName, "msvcp60") != 0 && 00046 stricmp(ModuleName, "msvcp70") != 0 && 00047 stricmp(ModuleName, "msvcr70") != 0 && 00048 stricmp(ModuleName, "msvcrt") != 0 && 00049 stricmp(ModuleName, "msvcrt20") != 0 && 00050 stricmp(ModuleName, "msvcrt40") != 0) { 00051 OpenedHandles.push_back((HMODULE)ModuleBase); 00052 } 00053 return TRUE; 00054 } 00055 } 00056 00057 DynamicLibrary::DynamicLibrary() : handle(0) { 00058 handle = GetModuleHandle(NULL); 00059 OpenedHandles.push_back((HMODULE)handle); 00060 } 00061 00062 DynamicLibrary::DynamicLibrary(const char*filename) : handle(0) { 00063 HMODULE a_handle = LoadLibrary(filename); 00064 00065 if (a_handle == 0) 00066 ThrowError(std::string(filename) + ": Can't open : "); 00067 00068 handle = a_handle; 00069 OpenedHandles.push_back(a_handle); 00070 } 00071 00072 DynamicLibrary::~DynamicLibrary() { 00073 if (handle == 0) 00074 return; 00075 00076 // GetModuleHandle() does not increment the ref count, so we must not free 00077 // the handle to the executable. 00078 if (handle != GetModuleHandle(NULL)) 00079 FreeLibrary((HMODULE)handle); 00080 handle = 0; 00081 00082 for (std::vector<HMODULE>::iterator I = OpenedHandles.begin(), 00083 E = OpenedHandles.end(); I != E; ++I) { 00084 if (*I == handle) { 00085 // Note: don't use the swap/pop_back trick here. Order is important. 00086 OpenedHandles.erase(I); 00087 } 00088 } 00089 } 00090 00091 void DynamicLibrary::LoadLibraryPermanently(const char* filename) { 00092 if (filename) { 00093 HMODULE a_handle = LoadLibrary(filename); 00094 00095 if (a_handle == 0) 00096 ThrowError(std::string(filename) + ": Can't open : "); 00097 00098 OpenedHandles.push_back(a_handle); 00099 } else { 00100 // When no file is specified, enumerate all DLLs and EXEs in the 00101 // process. 00102 EnumerateLoadedModules(GetCurrentProcess(), ELM_Callback, 0); 00103 } 00104 00105 // Because we don't remember the handle, we will never free it; hence, 00106 // it is loaded permanently. 00107 } 00108 00109 void* DynamicLibrary::SearchForAddressOfSymbol(const char* symbolName) { 00110 // First check symbols added via AddSymbol(). 00111 std::map<std::string, void *>::iterator I = g_symbols.find(symbolName); 00112 if (I != g_symbols.end()) 00113 return I->second; 00114 00115 // Now search the libraries. 00116 for (std::vector<HMODULE>::iterator I = OpenedHandles.begin(), 00117 E = OpenedHandles.end(); I != E; ++I) { 00118 FARPROC ptr = GetProcAddress((HMODULE)*I, symbolName); 00119 if (ptr) 00120 return (void *) ptr; 00121 } 00122 00123 return 0; 00124 } 00125 00126 void *DynamicLibrary::GetAddressOfSymbol(const char *symbolName) { 00127 assert(handle != 0 && "Invalid DynamicLibrary handle"); 00128 return (void *) GetProcAddress((HMODULE)handle, symbolName); 00129 } 00130 00131 } 00132