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 is distributed under the University of Illinois Open Source
00006 // 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 #ifdef _WIN64
00041   typedef DWORD64 ModuleBaseType;
00042 #else
00043   typedef ULONG ModuleBaseType;
00044 #endif
00045 
00046 extern "C" {
00047 #if !defined(_MSC_VER) || _MSC_VER < 1500
00048   static BOOL CALLBACK ELM_Callback(PSTR  ModuleName,
00049                                     ModuleBaseType ModuleBase,
00050                                     ULONG ModuleSize,
00051                                     PVOID UserContext)
00052 #else
00053   static BOOL CALLBACK ELM_Callback(PCSTR  ModuleName,
00054                                     ModuleBaseType ModuleBase,
00055                                     ULONG ModuleSize,
00056                                     PVOID UserContext)
00057 #endif
00058   {
00059     // Ignore VC++ runtimes prior to 7.1.  Somehow some of them get loaded
00060     // into the process.
00061     if (stricmp(ModuleName, "msvci70") != 0 &&
00062         stricmp(ModuleName, "msvcirt") != 0 &&
00063         stricmp(ModuleName, "msvcp50") != 0 &&
00064         stricmp(ModuleName, "msvcp60") != 0 &&
00065         stricmp(ModuleName, "msvcp70") != 0 &&
00066         stricmp(ModuleName, "msvcr70") != 0 &&
00067 #ifndef __MINGW32__
00068         // Mingw32 uses msvcrt.dll by default. Don't ignore it.
00069         // Otherwise, user should be aware, what he's doing :)
00070         stricmp(ModuleName, "msvcrt") != 0 &&
00071 #endif        
00072         stricmp(ModuleName, "msvcrt20") != 0 &&
00073         stricmp(ModuleName, "msvcrt40") != 0) {
00074       OpenedHandles.push_back((HMODULE)ModuleBase);
00075     }
00076     return TRUE;
00077   }
00078 }
00079 
00080 DynamicLibrary::DynamicLibrary() : handle(0) {
00081   handle = GetModuleHandle(NULL);
00082   OpenedHandles.push_back((HMODULE)handle);
00083 }
00084 
00085 DynamicLibrary::~DynamicLibrary() {
00086   if (handle == 0)
00087     return;
00088 
00089   // GetModuleHandle() does not increment the ref count, so we must not free
00090   // the handle to the executable.
00091   if (handle != GetModuleHandle(NULL))
00092     FreeLibrary((HMODULE)handle);
00093   handle = 0;
00094 
00095   for (std::vector<HMODULE>::iterator I = OpenedHandles.begin(),
00096        E = OpenedHandles.end(); I != E; ++I) {
00097     if (*I == handle) {
00098       // Note: don't use the swap/pop_back trick here. Order is important.
00099       OpenedHandles.erase(I);
00100     }
00101   }
00102 }
00103  
00104 bool DynamicLibrary::LoadLibraryPermanently(const char *filename,
00105                                             std::string *ErrMsg) {
00106   if (filename) {
00107     HMODULE a_handle = LoadLibrary(filename);
00108 
00109     if (a_handle == 0)
00110       return MakeErrMsg(ErrMsg, std::string(filename) + ": Can't open : ");
00111 
00112     OpenedHandles.push_back(a_handle);
00113   } else {
00114     // When no file is specified, enumerate all DLLs and EXEs in the
00115     // process.
00116     EnumerateLoadedModules(GetCurrentProcess(), ELM_Callback, 0);
00117   }
00118 
00119   // Because we don't remember the handle, we will never free it; hence,
00120   // it is loaded permanently.
00121   return false;
00122 }
00123 
00124 // Stack probing routines are in the support library (e.g. libgcc), but we don't
00125 // have dynamic linking on windows. Provide a hook.
00126 #if defined(__MINGW32__) || defined (_MSC_VER)
00127   #define EXPLICIT_SYMBOL(SYM)                    \
00128     if (!strcmp(symbolName, #SYM)) return (void*)&SYM
00129   #define EXPLICIT_SYMBOL2(SYMFROM, SYMTO)        \
00130     if (!strcmp(symbolName, #SYMFROM)) return (void*)&SYMTO
00131   #define EXPLICIT_SYMBOL_DEF(SYM)                \
00132     extern "C" { extern void *SYM; }
00133 
00134   #if defined(__MINGW32__)
00135     EXPLICIT_SYMBOL_DEF(_alloca);
00136     EXPLICIT_SYMBOL_DEF(__main);
00137     EXPLICIT_SYMBOL_DEF(__ashldi3);
00138     EXPLICIT_SYMBOL_DEF(__ashrdi3);
00139     EXPLICIT_SYMBOL_DEF(__cmpdi2);
00140     EXPLICIT_SYMBOL_DEF(__divdi3);
00141     EXPLICIT_SYMBOL_DEF(__eprintf);
00142     EXPLICIT_SYMBOL_DEF(__fixdfdi);
00143     EXPLICIT_SYMBOL_DEF(__fixsfdi);
00144     EXPLICIT_SYMBOL_DEF(__fixunsdfdi);
00145     EXPLICIT_SYMBOL_DEF(__fixunssfdi);
00146     EXPLICIT_SYMBOL_DEF(__floatdidf);
00147     EXPLICIT_SYMBOL_DEF(__floatdisf);
00148     EXPLICIT_SYMBOL_DEF(__lshrdi3);
00149     EXPLICIT_SYMBOL_DEF(__moddi3);
00150     EXPLICIT_SYMBOL_DEF(__udivdi3);
00151     EXPLICIT_SYMBOL_DEF(__umoddi3);
00152   #elif defined(_MSC_VER)
00153     EXPLICIT_SYMBOL_DEF(_alloca_probe);
00154   #endif
00155 #endif
00156 
00157 void* DynamicLibrary::SearchForAddressOfSymbol(const char* symbolName) {
00158   // First check symbols added via AddSymbol().
00159   std::map<std::string, void *>::iterator I = g_symbols().find(symbolName);
00160   if (I != g_symbols().end())
00161     return I->second;
00162 
00163   // Now search the libraries.
00164   for (std::vector<HMODULE>::iterator I = OpenedHandles.begin(),
00165        E = OpenedHandles.end(); I != E; ++I) {
00166     FARPROC ptr = GetProcAddress((HMODULE)*I, symbolName);
00167     if (ptr)
00168       return (void *) ptr;
00169   }
00170 
00171 #if defined(__MINGW32__)
00172   {
00173     EXPLICIT_SYMBOL(_alloca);
00174     EXPLICIT_SYMBOL(__main);
00175     EXPLICIT_SYMBOL(__ashldi3);
00176     EXPLICIT_SYMBOL(__ashrdi3);
00177     EXPLICIT_SYMBOL(__cmpdi2);
00178     EXPLICIT_SYMBOL(__divdi3);
00179     EXPLICIT_SYMBOL(__eprintf);
00180     EXPLICIT_SYMBOL(__fixdfdi);
00181     EXPLICIT_SYMBOL(__fixsfdi);
00182     EXPLICIT_SYMBOL(__fixunsdfdi);
00183     EXPLICIT_SYMBOL(__fixunssfdi);
00184     EXPLICIT_SYMBOL(__floatdidf);
00185     EXPLICIT_SYMBOL(__floatdisf);
00186     EXPLICIT_SYMBOL(__lshrdi3);
00187     EXPLICIT_SYMBOL(__moddi3);
00188     EXPLICIT_SYMBOL(__udivdi3);
00189     EXPLICIT_SYMBOL(__umoddi3);
00190 
00191     EXPLICIT_SYMBOL2(alloca, _alloca);
00192 #undef EXPLICIT_SYMBOL
00193 #undef EXPLICIT_SYMBOL2
00194 #undef EXPLICIT_SYMBOL_DEF    
00195   }
00196 #elif defined(_MSC_VER)
00197   {
00198     EXPLICIT_SYMBOL2(alloca, _alloca_probe);
00199     EXPLICIT_SYMBOL2(_alloca, _alloca_probe);
00200 #undef EXPLICIT_SYMBOL
00201 #undef EXPLICIT_SYMBOL2
00202 #undef EXPLICIT_SYMBOL_DEF    
00203   }  
00204 #endif
00205 
00206   return 0;
00207 }
00208 
00209 }
00210