LLVM API Documentation
00001 //===-- DynamicLibrary.cpp - Runtime link/load libraries --------*- C++ -*-===// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file was developed by Reid Spencer and is distributed under the 00006 // University of Illinois Open Source 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 "ltdl.h" 00016 #include <cassert> 00017 using namespace llvm; 00018 using namespace llvm::sys; 00019 00020 //===----------------------------------------------------------------------===// 00021 //=== WARNING: Implementation here must contain only TRULY operating system 00022 //=== independent code. 00023 //===----------------------------------------------------------------------===// 00024 00025 static bool did_initialize_ltdl = false; 00026 00027 static inline void check_ltdl_initialization() { 00028 if (!did_initialize_ltdl) { 00029 if (0 != lt_dlinit()) 00030 throw std::string(lt_dlerror()); 00031 did_initialize_ltdl = true; 00032 } 00033 } 00034 00035 static std::vector<lt_dlhandle> OpenedHandles; 00036 00037 DynamicLibrary::DynamicLibrary() : handle(0) { 00038 check_ltdl_initialization(); 00039 00040 lt_dlhandle a_handle = lt_dlopen(0); 00041 00042 if (a_handle == 0) 00043 throw std::string("Can't open program as dynamic library"); 00044 00045 handle = a_handle; 00046 OpenedHandles.push_back(a_handle); 00047 } 00048 00049 DynamicLibrary::DynamicLibrary(const char*filename) : handle(0) { 00050 check_ltdl_initialization(); 00051 00052 lt_dlhandle a_handle = lt_dlopen(filename); 00053 00054 if (a_handle == 0) 00055 a_handle = lt_dlopenext(filename); 00056 00057 if (a_handle == 0) 00058 throw std::string("Can't open :") + filename + ": " + lt_dlerror(); 00059 00060 handle = a_handle; 00061 OpenedHandles.push_back(a_handle); 00062 } 00063 00064 DynamicLibrary::~DynamicLibrary() { 00065 lt_dlhandle a_handle = (lt_dlhandle) handle; 00066 if (a_handle) { 00067 lt_dlclose(a_handle); 00068 00069 for (std::vector<lt_dlhandle>::iterator I = OpenedHandles.begin(), 00070 E = OpenedHandles.end(); I != E; ++I) { 00071 if (*I == a_handle) { 00072 // Note: don't use the swap/pop_back trick here. Order is important. 00073 OpenedHandles.erase(I); 00074 } 00075 } 00076 } 00077 } 00078 00079 void DynamicLibrary::LoadLibraryPermanently(const char* filename) { 00080 check_ltdl_initialization(); 00081 lt_dlhandle a_handle = lt_dlopen(filename); 00082 00083 if (a_handle == 0) 00084 a_handle = lt_dlopenext(filename); 00085 00086 if (a_handle == 0) 00087 throw std::string("Can't open :") + filename + ": " + lt_dlerror(); 00088 00089 lt_dlmakeresident(a_handle); 00090 00091 OpenedHandles.push_back(a_handle); 00092 } 00093 00094 void* DynamicLibrary::SearchForAddressOfSymbol(const char* symbolName) { 00095 check_ltdl_initialization(); 00096 for (std::vector<lt_dlhandle>::iterator I = OpenedHandles.begin(), 00097 E = OpenedHandles.end(); I != E; ++I) { 00098 lt_ptr ptr = lt_dlsym(*I, symbolName); 00099 if (ptr) 00100 return ptr; 00101 } 00102 00103 // If this is darwin, it has some funky issues, try to solve them here. Some 00104 // important symbols are marked 'private external' which doesn't allow 00105 // SearchForAddressOfSymbol to find them. As such, we special case them here, 00106 // there is only a small handful of them. 00107 #ifdef __APPLE__ 00108 { 00109 #define EXPLICIT_SYMBOL(SYM) \ 00110 extern void *SYM; if (!strcmp(symbolName, #SYM)) return &SYM 00111 EXPLICIT_SYMBOL(__ashldi3); 00112 EXPLICIT_SYMBOL(__ashrdi3); 00113 EXPLICIT_SYMBOL(__cmpdi2); 00114 EXPLICIT_SYMBOL(__divdi3); 00115 EXPLICIT_SYMBOL(__eprintf); 00116 EXPLICIT_SYMBOL(__fixdfdi); 00117 EXPLICIT_SYMBOL(__fixsfdi); 00118 EXPLICIT_SYMBOL(__fixunsdfdi); 00119 EXPLICIT_SYMBOL(__fixunssfdi); 00120 EXPLICIT_SYMBOL(__floatdidf); 00121 EXPLICIT_SYMBOL(__floatdisf); 00122 EXPLICIT_SYMBOL(__lshrdi3); 00123 EXPLICIT_SYMBOL(__moddi3); 00124 EXPLICIT_SYMBOL(__udivdi3); 00125 EXPLICIT_SYMBOL(__umoddi3); 00126 #undef EXPLICIT_SYMBOL 00127 } 00128 #endif 00129 00130 return 0; 00131 } 00132 00133 void *DynamicLibrary::GetAddressOfSymbol(const char *symbolName) { 00134 assert(handle != 0 && "Invalid DynamicLibrary handle"); 00135 return lt_dlsym((lt_dlhandle) handle, symbolName); 00136 } 00137