From 19cd4a9e6bb0ddbe0c2c7855d687236ed4dcbf31 Mon Sep 17 00:00:00 2001 From: Reid Spencer Date: Mon, 29 Nov 2004 13:33:28 +0000 Subject: [PATCH] Implement two new functions: LoadLibraryPermanently and SearchForAddressOfSymbol. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@18355 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/System/DynamicLibrary.cpp | 90 ++++++++++++++++++++++++----------- 1 file changed, 62 insertions(+), 28 deletions(-) diff --git a/lib/System/DynamicLibrary.cpp b/lib/System/DynamicLibrary.cpp index 0e1c0a30b5c..cad07abd75a 100644 --- a/lib/System/DynamicLibrary.cpp +++ b/lib/System/DynamicLibrary.cpp @@ -20,59 +20,93 @@ //=== independent code. //===----------------------------------------------------------------------===// +static bool did_initialize_ltdl = false; + +static inline void check_ltdl_initialization() { + if (!did_initialize_ltdl) { + if (0 != lt_dlinit()) + throw std::string(lt_dlerror()); + did_initialize_ltdl = true; + } +} + +static std::vector OpenedHandles; + namespace llvm { using namespace sys; DynamicLibrary::DynamicLibrary() : handle(0) { - if (0 != lt_dlinit()) - throw std::string(lt_dlerror()); + check_ltdl_initialization(); - handle = lt_dlopen(0); + lt_dlhandle a_handle = lt_dlopen(0); - if (handle == 0) + if (a_handle == 0) throw std::string("Can't open program as dynamic library"); + + handle = a_handle; + OpenedHandles.push_back(a_handle); } DynamicLibrary::DynamicLibrary(const char*filename) : handle(0) { - if (0 != lt_dlinit()) - throw std::string(lt_dlerror()); + check_ltdl_initialization(); - handle = lt_dlopen(filename); + lt_dlhandle a_handle = lt_dlopen(filename); - if (handle == 0) - handle = lt_dlopenext(filename); + if (a_handle == 0) + a_handle = lt_dlopenext(filename); - if (handle == 0) - throw std::string("Can't open dynamic library:") + filename; + if (a_handle == 0) + throw std::string("Can't open :") + filename + ": " + lt_dlerror(); + + handle = a_handle; + OpenedHandles.push_back(a_handle); } DynamicLibrary::~DynamicLibrary() { - if (handle) - lt_dlclose((lt_dlhandle)handle); - - lt_dlexit(); + lt_dlhandle a_handle = (lt_dlhandle) handle; + if (a_handle) { + lt_dlclose(a_handle); + + for (std::vector::iterator I = OpenedHandles.begin(), + E = OpenedHandles.end(); I != E; ++I) { + if (*I == a_handle) { + // Note: don't use the swap/pop_back trick here. Order is important. + OpenedHandles.erase(I); + } + } + } } -void *DynamicLibrary::GetAddressOfSymbol(const char *symbolName) { - assert(handle != 0 && "Invalid DynamicLibrary handle"); - return lt_dlsym((lt_dlhandle) handle,symbolName); -} +void DynamicLibrary::LoadLibraryPermanently(const char* filename) { + check_ltdl_initialization(); + lt_dlhandle a_handle = lt_dlopen(filename); -#if 0 -DynamicLibrary::DynamicLibrary(const char*filename) : handle(0) { - assert(!"Have ltdl.h but not libltdl.a!"); -} + if (a_handle == 0) + a_handle = lt_dlopenext(filename); -DynamicLibrary::~DynamicLibrary() { - assert(!"Have ltdl.h but not libltdl.a!"); + if (a_handle == 0) + throw std::string("Can't open :") + filename + ": " + lt_dlerror(); + + lt_dlmakeresident(a_handle); + + OpenedHandles.push_back(a_handle); } -void *DynamicLibrary::GetAddressOfSymbol(const char *symbolName) { - assert(!"Have ltdl.h but not libltdl.a!"); +void* DynamicLibrary::SearchForAddressOfSymbol(const char* symbolName) { + check_ltdl_initialization(); + for (std::vector::iterator I = OpenedHandles.begin(), + E = OpenedHandles.end(); I != E; ++I) { + lt_ptr ptr = lt_dlsym(*I, symbolName); + if (ptr) + return ptr; + } return 0; } -#endif +void *DynamicLibrary::GetAddressOfSymbol(const char *symbolName) { + assert(handle != 0 && "Invalid DynamicLibrary handle"); + return lt_dlsym((lt_dlhandle) handle, symbolName); +} } // namespace llvm -- 2.34.1