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 #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