Index: include/llvm/Support/DynamicLibrary.h =================================================================== --- include/llvm/Support/DynamicLibrary.h +++ include/llvm/Support/DynamicLibrary.h @@ -14,6 +14,8 @@ #ifndef LLVM_SUPPORT_DYNAMICLIBRARY_H #define LLVM_SUPPORT_DYNAMICLIBRARY_H +#include "llvm/ADT/SmallString.h" + #include namespace llvm { @@ -43,10 +45,16 @@ // Opaque data used to interface with OS-specific dynamic library handling. void *Data; - explicit DynamicLibrary(void *data = &Invalid) : Data(data) {} + llvm::SmallString<128> Filename; + + DynamicLibrary(llvm::StringRef filename, void *data = &Invalid) + : Data(data), Filename(filename) {} + public: + DynamicLibrary() { Data = &Invalid; } + /// Returns true if the object refers to a valid library. - bool isValid() { return Data != &Invalid; } + bool isValid() const { return Data != &Invalid; } /// Searches through the library for the symbol \p symbolName. If it is /// found, the address of that symbol is returned. If not, NULL is returned. Index: lib/Support/DynamicLibrary.cpp =================================================================== --- lib/Support/DynamicLibrary.cpp +++ lib/Support/DynamicLibrary.cpp @@ -56,8 +56,11 @@ DynamicLibrary DynamicLibrary::getPermanentLibrary(const char *filename, std::string *errMsg) { SmartScopedLock lock(*SymbolsMutex); - - void *handle = dlopen(filename, RTLD_LAZY|RTLD_GLOBAL); + int flags = RTLD_LAZY | RTLD_GLOBAL; +#if defined(__APPLE__) + flags |= RTLD_FIRST; +#endif + void *handle = dlopen(filename, flags); if (!handle) { if (errMsg) *errMsg = dlerror(); return DynamicLibrary(); @@ -78,13 +81,28 @@ if (!OpenedHandles->insert(handle).second) dlclose(handle); - return DynamicLibrary(handle); + return DynamicLibrary(filename, handle); } void *DynamicLibrary::getAddressOfSymbol(const char *symbolName) { if (!isValid()) return nullptr; - return dlsym(Data, symbolName); + void *symbol_addr = dlsym(Data, symbolName); + if (!symbol_addr) + return nullptr; + +#if !defined(__APPLE__) + // This platform doesn't support limiting searches only to this shared + // library, so manually limit the search to this library by checking + // that the path of the module that this symbol lives in matches that + // which the module was dlopen'ed with. + Dl_info info; + if (!dladdr(symbol_addr, &info) || !info.dli_fname) + return nullptr; + if (0 != strcmp(info.dli_fname, Filename.c_str())) + return nullptr; +#endif + return symbol_addr; } #else Index: lib/Support/Windows/DynamicLibrary.inc =================================================================== --- lib/Support/Windows/DynamicLibrary.inc +++ lib/Support/Windows/DynamicLibrary.inc @@ -81,7 +81,7 @@ EnumerateLoadedModules(GetCurrentProcess(), ELM_Callback, 0); // Dummy library that represents "search all handles". // This is mostly to ensure that the return value still shows up as "valid". - return DynamicLibrary(&OpenedHandles); + return DynamicLibrary(filename, &OpenedHandles); } SmallVector filenameUnicode; @@ -106,7 +106,7 @@ if (!OpenedHandles->insert(a_handle).second) FreeLibrary(a_handle); - return DynamicLibrary(a_handle); + return DynamicLibrary(filename, a_handle); } // Stack probing routines are in the support library (e.g. libgcc), but we don't