diff options
author | Frederich Munch <colsebas@hotmail.com> | 2017-04-24 20:16:01 +0000 |
---|---|---|
committer | Frederich Munch <colsebas@hotmail.com> | 2017-04-24 20:16:01 +0000 |
commit | fd96d5e1c962df374494f98ac4d684e43dcf26f5 (patch) | |
tree | 770255a055e8aef2c84ca505daf67ccdb2d89951 /llvm/lib/Support/DynamicLibrary.cpp | |
parent | 0f62eea7ff4a1c5888eecba930d87361430a053b (diff) | |
download | bcm5719-llvm-fd96d5e1c962df374494f98ac4d684e43dcf26f5.tar.gz bcm5719-llvm-fd96d5e1c962df374494f98ac4d684e43dcf26f5.zip |
Revert "Refactor DynamicLibrary so searching for a symbol will have a defined order"
The i686-mingw32-RA-on-linux bot is still having errors.
This reverts commit r301236.
llvm-svn: 301240
Diffstat (limited to 'llvm/lib/Support/DynamicLibrary.cpp')
-rw-r--r-- | llvm/lib/Support/DynamicLibrary.cpp | 237 |
1 files changed, 121 insertions, 116 deletions
diff --git a/llvm/lib/Support/DynamicLibrary.cpp b/llvm/lib/Support/DynamicLibrary.cpp index 1541a572630..22fb3f2cb9c 100644 --- a/llvm/lib/Support/DynamicLibrary.cpp +++ b/llvm/lib/Support/DynamicLibrary.cpp @@ -20,164 +20,169 @@ #include "llvm/Support/Mutex.h" #include <cstdio> #include <cstring> -#include <vector> +// Collection of symbol name/value pairs to be searched prior to any libraries. +static llvm::ManagedStatic<llvm::StringMap<void *> > ExplicitSymbols; +static llvm::ManagedStatic<llvm::sys::SmartMutex<true> > SymbolsMutex; + +void llvm::sys::DynamicLibrary::AddSymbol(StringRef symbolName, + void *symbolValue) { + SmartScopedLock<true> lock(*SymbolsMutex); + (*ExplicitSymbols)[symbolName] = symbolValue; +} + +char llvm::sys::DynamicLibrary::Invalid = 0; + +#ifdef LLVM_ON_WIN32 + +#include "Windows/DynamicLibrary.inc" + +#else + +#if defined(HAVE_DLFCN_H) && defined(HAVE_DLOPEN) +#include <dlfcn.h> using namespace llvm; using namespace llvm::sys; -// All methods for HandleSet should be used holding SymbolsMutex. -class DynamicLibrary::HandleSet { - typedef std::vector<void *> HandleList; - HandleList Handles; - void *Process; - -public: - static void *DLOpen(const char *Filename, std::string *Err); - static void DLClose(void *Handle); - static void *DLSym(void *Handle, const char *Symbol); +//===----------------------------------------------------------------------===// +//=== WARNING: Implementation here must contain only TRULY operating system +//=== independent code. +//===----------------------------------------------------------------------===// - HandleSet() : Process(nullptr) {} - ~HandleSet(); +static llvm::ManagedStatic<DenseSet<void *> > OpenedHandles; - HandleList::iterator Find(void *Handle) { - return std::find(Handles.begin(), Handles.end(), Handle); - } +DynamicLibrary DynamicLibrary::getPermanentLibrary(const char *filename, + std::string *errMsg) { + SmartScopedLock<true> lock(*SymbolsMutex); - bool Contains(void *Handle) { - return Handle == Process || Find(Handle) != Handles.end(); + void *handle = dlopen(filename, RTLD_LAZY|RTLD_GLOBAL); + if (!handle) { + if (errMsg) *errMsg = dlerror(); + return DynamicLibrary(); } - bool AddLibrary(void *Handle, bool IsProcess = false, bool CanClose = true) { -#ifdef LLVM_ON_WIN32 - assert((Handle == this ? IsProcess : !IsProcess) && "Bad Handle."); +#ifdef __CYGWIN__ + // Cygwin searches symbols only in the main + // with the handle of dlopen(NULL, RTLD_GLOBAL). + if (!filename) + handle = RTLD_DEFAULT; #endif - if (LLVM_LIKELY(!IsProcess)) { - if (Find(Handle) != Handles.end()) { - if (CanClose) - DLClose(Handle); - return false; - } - Handles.push_back(Handle); - } else { -#ifndef LLVM_ON_WIN32 - if (Process) { - if (CanClose) - DLClose(Process); - if (Process == Handle) - return false; - } -#endif - Process = Handle; - } - return true; - } + // If we've already loaded this library, dlclose() the handle in order to + // keep the internal refcount at +1. + if (!OpenedHandles->insert(handle).second) + dlclose(handle); - void *Lookup(const char *Symbol) { - // Process handle gets first try. - if (Process) { - if (void *Ptr = DLSym(Process, Symbol)) - return Ptr; -#ifndef NDEBUG - for (void *Handle : Handles) - assert(!DLSym(Handle, Symbol) && "Symbol exists in non process handle"); -#endif - } else { - // Iterate in reverse, so newer libraries/symbols override older. - for (auto &&I = Handles.rbegin(), E = Handles.rend(); I != E; ++I) { - if (void *Ptr = DLSym(*I, Symbol)) - return Ptr; - } - } - return nullptr; + return DynamicLibrary(handle); +} + +DynamicLibrary DynamicLibrary::addPermanentLibrary(void *handle, + std::string *errMsg) { + SmartScopedLock<true> lock(*SymbolsMutex); + // If we've already loaded this library, tell the caller. + if (!OpenedHandles->insert(handle).second) { + if (errMsg) *errMsg = "Library already loaded"; + return DynamicLibrary(); } -}; -namespace { -// Collection of symbol name/value pairs to be searched prior to any libraries. -static llvm::ManagedStatic<llvm::StringMap<void *>> ExplicitSymbols; -// Collection of known library handles. -static llvm::ManagedStatic<DynamicLibrary::HandleSet> OpenedHandles; -// Lock for ExplicitSymbols and OpenedHandles. -static llvm::ManagedStatic<llvm::sys::SmartMutex<true>> SymbolsMutex; + return DynamicLibrary(handle); } -#ifdef LLVM_ON_WIN32 - -#include "Windows/DynamicLibrary.inc" +void *DynamicLibrary::getAddressOfSymbol(const char *symbolName) { + if (!isValid()) + return nullptr; + return dlsym(Data, symbolName); +} #else -#include "Unix/DynamicLibrary.inc" - -#endif - -char DynamicLibrary::Invalid; +using namespace llvm; +using namespace llvm::sys; -namespace llvm { -void *SearchForAddressOfSpecialSymbol(const char *SymbolName) { - return DoSearch(SymbolName); // DynamicLibrary.inc -} +DynamicLibrary DynamicLibrary::getPermanentLibrary(const char *filename, + std::string *errMsg) { + if (errMsg) *errMsg = "dlopen() not supported on this platform"; + return DynamicLibrary(); } -void DynamicLibrary::AddSymbol(StringRef SymbolName, void *SymbolValue) { - SmartScopedLock<true> Lock(*SymbolsMutex); - (*ExplicitSymbols)[SymbolName] = SymbolValue; +void *DynamicLibrary::getAddressOfSymbol(const char *symbolName) { + return NULL; } -DynamicLibrary DynamicLibrary::getPermanentLibrary(const char *FileName, - std::string *Err) { - SmartScopedLock<true> Lock(*SymbolsMutex); - void *Handle = HandleSet::DLOpen(FileName, Err); - if (Handle != &Invalid) - OpenedHandles->AddLibrary(Handle, /*IsProcess*/ FileName == nullptr); +#endif - return DynamicLibrary(Handle); +namespace llvm { +void *SearchForAddressOfSpecialSymbol(const char* symbolName); } -DynamicLibrary DynamicLibrary::addPermanentLibrary(void *Handle, - std::string *Err) { +void* DynamicLibrary::SearchForAddressOfSymbol(const char *symbolName) { SmartScopedLock<true> Lock(*SymbolsMutex); - // If we've already loaded this library, tell the caller. - if (!OpenedHandles->AddLibrary(Handle, /*IsProcess*/false, /*CanClose*/false)) - *Err = "Library already loaded"; - return DynamicLibrary(Handle); -} + // First check symbols added via AddSymbol(). + if (ExplicitSymbols.isConstructed()) { + StringMap<void *>::iterator i = ExplicitSymbols->find(symbolName); -void *DynamicLibrary::getAddressOfSymbol(const char *SymbolName) { - if (!isValid()) - return nullptr; - return HandleSet::DLSym(Data, SymbolName); -} + if (i != ExplicitSymbols->end()) + return i->second; + } -void *DynamicLibrary::SearchForAddressOfSymbol(const char *SymbolName) { - { - SmartScopedLock<true> Lock(*SymbolsMutex); +#if defined(HAVE_DLFCN_H) && defined(HAVE_DLOPEN) + // Now search the libraries. + if (OpenedHandles.isConstructed()) { + for (DenseSet<void *>::iterator I = OpenedHandles->begin(), + E = OpenedHandles->end(); I != E; ++I) { + //lt_ptr ptr = lt_dlsym(*I, symbolName); + void *ptr = dlsym(*I, symbolName); + if (ptr) { + return ptr; + } + } + } +#endif - // First check symbols added via AddSymbol(). - if (ExplicitSymbols.isConstructed()) { - StringMap<void *>::iterator i = ExplicitSymbols->find(SymbolName); + if (void *Result = llvm::SearchForAddressOfSpecialSymbol(symbolName)) + return Result; - if (i != ExplicitSymbols->end()) - return i->second; - } +// This macro returns the address of a well-known, explicit symbol +#define EXPLICIT_SYMBOL(SYM) \ + if (!strcmp(symbolName, #SYM)) return &SYM - // Now search the libraries. - if (OpenedHandles.isConstructed()) { - if (void *Ptr = OpenedHandles->Lookup(SymbolName)) - return Ptr; - } +// On linux we have a weird situation. The stderr/out/in symbols are both +// macros and global variables because of standards requirements. So, we +// boldly use the EXPLICIT_SYMBOL macro without checking for a #define first. +#if defined(__linux__) and !defined(__ANDROID__) + { + EXPLICIT_SYMBOL(stderr); + EXPLICIT_SYMBOL(stdout); + EXPLICIT_SYMBOL(stdin); } +#else + // For everything else, we want to check to make sure the symbol isn't defined + // as a macro before using EXPLICIT_SYMBOL. + { +#ifndef stdin + EXPLICIT_SYMBOL(stdin); +#endif +#ifndef stdout + EXPLICIT_SYMBOL(stdout); +#endif +#ifndef stderr + EXPLICIT_SYMBOL(stderr); +#endif + } +#endif +#undef EXPLICIT_SYMBOL - return llvm::SearchForAddressOfSpecialSymbol(SymbolName); + return nullptr; } +#endif // LLVM_ON_WIN32 + //===----------------------------------------------------------------------===// // C API. //===----------------------------------------------------------------------===// -LLVMBool LLVMLoadLibraryPermanently(const char *Filename) { +LLVMBool LLVMLoadLibraryPermanently(const char* Filename) { return llvm::sys::DynamicLibrary::LoadLibraryPermanently(Filename); } |