summaryrefslogtreecommitdiff
path: root/lib/Support/DynamicLibrary.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Support/DynamicLibrary.cpp')
-rw-r--r--lib/Support/DynamicLibrary.cpp43
1 files changed, 32 insertions, 11 deletions
diff --git a/lib/Support/DynamicLibrary.cpp b/lib/Support/DynamicLibrary.cpp
index 9398789cea87..d8422115eae8 100644
--- a/lib/Support/DynamicLibrary.cpp
+++ b/lib/Support/DynamicLibrary.cpp
@@ -14,6 +14,7 @@
#include "llvm/Support/DynamicLibrary.h"
#include "llvm-c/Support.h"
#include "llvm/ADT/DenseSet.h"
+#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/Config/config.h"
#include "llvm/Support/ManagedStatic.h"
@@ -73,19 +74,37 @@ public:
return true;
}
- void *Lookup(const char *Symbol) {
- // Process handle gets first try.
+ void *LibLookup(const char *Symbol, DynamicLibrary::SearchOrdering Order) {
+ if (Order & SO_LoadOrder) {
+ for (void *Handle : Handles) {
+ if (void *Ptr = DLSym(Handle, Symbol))
+ return Ptr;
+ }
+ } else {
+ for (void *Handle : llvm::reverse(Handles)) {
+ if (void *Ptr = DLSym(Handle, Symbol))
+ return Ptr;
+ }
+ }
+ return nullptr;
+ }
+
+ void *Lookup(const char *Symbol, DynamicLibrary::SearchOrdering Order) {
+ assert(!((Order & SO_LoadedFirst) && (Order & SO_LoadedLast)) &&
+ "Invalid Ordering");
+
+ if (!Process || (Order & SO_LoadedFirst)) {
+ if (void *Ptr = LibLookup(Symbol, Order))
+ return Ptr;
+ }
if (Process) {
+ // Use OS facilities to search the current binary and all loaded libs.
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))
+
+ // Search any libs that might have been skipped because of RTLD_LOCAL.
+ if (Order & SO_LoadedLast) {
+ if (void *Ptr = LibLookup(Symbol, Order))
return Ptr;
}
}
@@ -113,6 +132,8 @@ static llvm::ManagedStatic<llvm::sys::SmartMutex<true>> SymbolsMutex;
#endif
char DynamicLibrary::Invalid;
+DynamicLibrary::SearchOrdering DynamicLibrary::SearchOrder =
+ DynamicLibrary::SO_Linker;
namespace llvm {
void *SearchForAddressOfSpecialSymbol(const char *SymbolName) {
@@ -170,7 +191,7 @@ void *DynamicLibrary::SearchForAddressOfSymbol(const char *SymbolName) {
// Now search the libraries.
if (OpenedHandles.isConstructed()) {
- if (void *Ptr = OpenedHandles->Lookup(SymbolName))
+ if (void *Ptr = OpenedHandles->Lookup(SymbolName, SearchOrder))
return Ptr;
}
}