LLVM API Documentation
00001 //===-- DynamicLibrary.cpp - Runtime link/load libraries --------*- 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 header file implements the operating system DynamicLibrary concept. 00011 // 00012 //===----------------------------------------------------------------------===// 00013 00014 #include "llvm/System/DynamicLibrary.h" 00015 #include "llvm/Config/config.h" 00016 #include <cstdio> 00017 #include <cstring> 00018 #include <map> 00019 00020 // Collection of symbol name/value pairs to be searched prior to any libraries. 00021 std::map<std::string, void *> &g_symbols() { 00022 static std::map<std::string, void *> symbols; 00023 return symbols; 00024 } 00025 00026 void llvm::sys::DynamicLibrary::AddSymbol(const char* symbolName, 00027 void *symbolValue) { 00028 g_symbols()[symbolName] = symbolValue; 00029 } 00030 00031 // It is not possible to use ltdl.c on VC++ builds as the terms of its LGPL 00032 // license and special exception would cause all of LLVM to be placed under 00033 // the LGPL. This is because the exception applies only when libtool is 00034 // used, and obviously libtool is not used with Visual Studio. An entirely 00035 // separate implementation is provided in win32/DynamicLibrary.cpp. 00036 00037 #ifdef LLVM_ON_WIN32 00038 00039 #include "Win32/DynamicLibrary.inc" 00040 00041 #else 00042 00043 //#include "ltdl.h" 00044 #include <dlfcn.h> 00045 #include <cassert> 00046 using namespace llvm; 00047 using namespace llvm::sys; 00048 00049 //===----------------------------------------------------------------------===// 00050 //=== WARNING: Implementation here must contain only TRULY operating system 00051 //=== independent code. 00052 //===----------------------------------------------------------------------===// 00053 00054 //static std::vector<lt_dlhandle> OpenedHandles; 00055 static std::vector<void *> OpenedHandles; 00056 00057 DynamicLibrary::DynamicLibrary() {} 00058 00059 DynamicLibrary::~DynamicLibrary() { 00060 while(!OpenedHandles.empty()) { 00061 void *H = OpenedHandles.back(); OpenedHandles.pop_back(); 00062 dlclose(H); 00063 } 00064 } 00065 00066 bool DynamicLibrary::LoadLibraryPermanently(const char *Filename, 00067 std::string *ErrMsg) { 00068 void *H = dlopen(Filename, RTLD_LAZY|RTLD_GLOBAL); 00069 if (H == 0) { 00070 if (ErrMsg) 00071 *ErrMsg = dlerror(); 00072 return true; 00073 } 00074 OpenedHandles.push_back(H); 00075 return false; 00076 } 00077 00078 void* DynamicLibrary::SearchForAddressOfSymbol(const char* symbolName) { 00079 // check_ltdl_initialization(); 00080 00081 // First check symbols added via AddSymbol(). 00082 std::map<std::string, void *>::iterator I = g_symbols().find(symbolName); 00083 if (I != g_symbols().end()) 00084 return I->second; 00085 00086 // Now search the libraries. 00087 for (std::vector<void *>::iterator I = OpenedHandles.begin(), 00088 E = OpenedHandles.end(); I != E; ++I) { 00089 //lt_ptr ptr = lt_dlsym(*I, symbolName); 00090 void *ptr = dlsym(*I, symbolName); 00091 if (ptr) 00092 return ptr; 00093 } 00094 00095 #define EXPLICIT_SYMBOL(SYM) \ 00096 extern void *SYM; if (!strcmp(symbolName, #SYM)) return &SYM 00097 00098 // If this is darwin, it has some funky issues, try to solve them here. Some 00099 // important symbols are marked 'private external' which doesn't allow 00100 // SearchForAddressOfSymbol to find them. As such, we special case them here, 00101 // there is only a small handful of them. 00102 00103 #ifdef __APPLE__ 00104 { 00105 EXPLICIT_SYMBOL(__ashldi3); 00106 EXPLICIT_SYMBOL(__ashrdi3); 00107 EXPLICIT_SYMBOL(__cmpdi2); 00108 EXPLICIT_SYMBOL(__divdi3); 00109 EXPLICIT_SYMBOL(__eprintf); 00110 EXPLICIT_SYMBOL(__fixdfdi); 00111 EXPLICIT_SYMBOL(__fixsfdi); 00112 EXPLICIT_SYMBOL(__fixunsdfdi); 00113 EXPLICIT_SYMBOL(__fixunssfdi); 00114 EXPLICIT_SYMBOL(__floatdidf); 00115 EXPLICIT_SYMBOL(__floatdisf); 00116 EXPLICIT_SYMBOL(__lshrdi3); 00117 EXPLICIT_SYMBOL(__moddi3); 00118 EXPLICIT_SYMBOL(__udivdi3); 00119 EXPLICIT_SYMBOL(__umoddi3); 00120 } 00121 #endif 00122 00123 #ifdef __CYGWIN__ 00124 { 00125 EXPLICIT_SYMBOL(_alloca); 00126 EXPLICIT_SYMBOL(__main); 00127 } 00128 #endif 00129 00130 #undef EXPLICIT_SYMBOL 00131 00132 // This macro returns the address of a well-known, explicit symbol 00133 #define EXPLICIT_SYMBOL(SYM) \ 00134 if (!strcmp(symbolName, #SYM)) return &SYM 00135 00136 // On linux we have a weird situation. The stderr/out/in symbols are both 00137 // macros and global variables because of standards requirements. So, we 00138 // boldly use the EXPLICIT_SYMBOL macro without checking for a #define first. 00139 #if defined(__linux__) 00140 { 00141 EXPLICIT_SYMBOL(stderr); 00142 EXPLICIT_SYMBOL(stdout); 00143 EXPLICIT_SYMBOL(stdin); 00144 } 00145 #else 00146 // For everything else, we want to check to make sure the symbol isn't defined 00147 // as a macro before using EXPLICIT_SYMBOL. 00148 { 00149 #ifndef stdin 00150 EXPLICIT_SYMBOL(stdin); 00151 #endif 00152 #ifndef stdout 00153 EXPLICIT_SYMBOL(stdout); 00154 #endif 00155 #ifndef stderr 00156 EXPLICIT_SYMBOL(stderr); 00157 #endif 00158 } 00159 #endif 00160 #undef EXPLICIT_SYMBOL 00161 00162 return 0; 00163 } 00164 00165 #endif // LLVM_ON_WIN32