LLVM API Documentation

DynamicLibrary.inc

Go to the documentation of this file.
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