llvm.org GIT mirror llvm / 9d9b7c8
Allow clients to specify search order of DynamicLibraries. Summary: Different JITs and other clients of LLVM may have different needs in how symbol resolution should occur. Reviewers: v.g.vassilev, lhames, karies Reviewed By: v.g.vassilev Subscribers: pcanal, llvm-commits Differential Revision: https://reviews.llvm.org/D33529 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@307849 91177308-0d34-0410-b5e6-96231b3b80d8 Frederich Munch 2 years ago
5 changed file(s) with 63 addition(s) and 11 deletion(s). Raw diff Collapse all Expand all
8787 return !getPermanentLibrary(Filename, ErrMsg).isValid();
8888 }
8989
90 enum SearchOrdering {
91 /// SO_Linker - Search as a call to dlsym(dlopen(NULL)) would when
92 /// DynamicLibrary::getPermanentLibrary(NULL) has been called or
93 /// search the list of explcitly loaded symbols if not.
94 SO_Linker,
95 /// SO_LoadedFirst - Search all loaded libraries, then as SO_Linker would.
96 SO_LoadedFirst,
97 /// SO_LoadedLast - Search as SO_Linker would, then loaded libraries.
98 /// Only useful to search if libraries with RTLD_LOCAL have been added.
99 SO_LoadedLast,
100 /// SO_LoadOrder - Or this in to search libraries in the ordered loaded.
101 /// The default bahaviour is to search loaded libraries in reverse.
102 SO_LoadOrder = 4
103 };
104 static SearchOrdering SearchOrder; // = SO_Linker
105
90106 /// This function will search through all previously loaded dynamic
91107 /// libraries for the symbol \p symbolName. If it is found, the address of
92108 /// that symbol is returned. If not, null is returned. Note that this will
1313 #include "llvm/Support/DynamicLibrary.h"
1414 #include "llvm-c/Support.h"
1515 #include "llvm/ADT/DenseSet.h"
16 #include "llvm/ADT/STLExtras.h"
1617 #include "llvm/ADT/StringMap.h"
1718 #include "llvm/Config/config.h"
1819 #include "llvm/Support/ManagedStatic.h"
7273 return true;
7374 }
7475
75 void *Lookup(const char *Symbol) {
76 // Process handle gets first try.
76 void *LibLookup(const char *Symbol, DynamicLibrary::SearchOrdering Order) {
77 if (Order & SO_LoadOrder) {
78 for (void *Handle : Handles) {
79 if (void *Ptr = DLSym(Handle, Symbol))
80 return Ptr;
81 }
82 } else {
83 for (void *Handle : llvm::reverse(Handles)) {
84 if (void *Ptr = DLSym(Handle, Symbol))
85 return Ptr;
86 }
87 }
88 return nullptr;
89 }
90
91 void *Lookup(const char *Symbol, DynamicLibrary::SearchOrdering Order) {
92 assert(!((Order & SO_LoadedFirst) && (Order & SO_LoadedLast)) &&
93 "Invalid Ordering");
94
95 if (!Process || (Order & SO_LoadedFirst)) {
96 if (void *Ptr = LibLookup(Symbol, Order))
97 return Ptr;
98 }
7799 if (Process) {
100 // Use OS facilities to search the current binary and all loaded libs.
78101 if (void *Ptr = DLSym(Process, Symbol))
79102 return Ptr;
80 #ifndef NDEBUG
81 for (void *Handle : Handles)
82 assert(!DLSym(Handle, Symbol) && "Symbol exists in non process handle");
83 #endif
84 } else {
85 // Iterate in reverse, so newer libraries/symbols override older.
86 for (auto &&I = Handles.rbegin(), E = Handles.rend(); I != E; ++I) {
87 if (void *Ptr = DLSym(*I, Symbol))
103
104 // Search any libs that might have been skipped because of RTLD_LOCAL.
105 if (Order & SO_LoadedLast) {
106 if (void *Ptr = LibLookup(Symbol, Order))
88107 return Ptr;
89108 }
90109 }
112131 #endif
113132
114133 char DynamicLibrary::Invalid;
134 DynamicLibrary::SearchOrdering DynamicLibrary::SearchOrder =
135 DynamicLibrary::SO_Linker;
115136
116137 namespace llvm {
117138 void *SearchForAddressOfSpecialSymbol(const char *SymbolName) {
169190
170191 // Now search the libraries.
171192 if (OpenedHandles.isConstructed()) {
172 if (void *Ptr = OpenedHandles->Lookup(SymbolName))
193 if (void *Ptr = OpenedHandles->Lookup(SymbolName, SearchOrder))
173194 return Ptr;
174195 }
175196 }
1919 ::dlclose(Handle);
2020 if (Process)
2121 ::dlclose(Process);
22
23 // llvm_shutdown called, Return to default
24 DynamicLibrary::SearchOrder = DynamicLibrary::SO_Linker;
2225 }
2326
2427 void *DynamicLibrary::HandleSet::DLOpen(const char *File, std::string *Err) {
2727
2828 // 'Process' should not be released on Windows.
2929 assert((!Process || Process==this) && "Bad Handle");
30 // llvm_shutdown called, Return to default
31 DynamicLibrary::SearchOrder = DynamicLibrary::SO_Linker;
3032 }
3133
3234 void *DynamicLibrary::HandleSet::DLOpen(const char *File, std::string *Err) {
7676 EXPECT_TRUE(DL.isValid());
7777 EXPECT_TRUE(Err.empty());
7878
79 // Test overloading local symbols does not occur by default
7980 GS = FuncPtr(DynamicLibrary::SearchForAddressOfSymbol("TestA"));
8081 EXPECT_TRUE(GS != nullptr && GS == &TestA);
8182 EXPECT_EQ(StdString(GS()), "ProcessCall");
8384 GS = FuncPtr(DL.getAddressOfSymbol("TestA"));
8485 EXPECT_TRUE(GS != nullptr && GS == &TestA);
8586 EXPECT_EQ(StdString(GS()), "ProcessCall");
87
88 // Test overloading by forcing library priority when searching for a symbol
89 DynamicLibrary::SearchOrder = DynamicLibrary::SO_LoadedFirst;
90 GS = FuncPtr(DynamicLibrary::SearchForAddressOfSymbol("TestA"));
91 EXPECT_TRUE(GS != nullptr && GS != &TestA);
92 EXPECT_EQ(StdString(GS()), "LibCall");
8693
8794 DynamicLibrary::AddSymbol("TestA", PtrFunc(&OverloadTestA));
8895 GS = FuncPtr(DL.getAddressOfSymbol("TestA"));
94101 }
95102 EXPECT_TRUE(FuncPtr(DynamicLibrary::SearchForAddressOfSymbol(
96103 "TestA")) == nullptr);
104
105 // Check serach ordering is reset to default after call to llvm_shutdown
106 EXPECT_TRUE(DynamicLibrary::SearchOrder == DynamicLibrary::SO_Linker);
97107 }
98108
99109 TEST(DynamicLibrary, Shutdown) {