[llvm] r307849 - Allow clients to specify search order of DynamicLibraries.
Frederich Munch via llvm-commits
llvm-commits at lists.llvm.org
Wed Jul 12 14:22:45 PDT 2017
Author: marsupial
Date: Wed Jul 12 14:22:45 2017
New Revision: 307849
URL: http://llvm.org/viewvc/llvm-project?rev=307849&view=rev
Log:
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
Modified:
llvm/trunk/include/llvm/Support/DynamicLibrary.h
llvm/trunk/lib/Support/DynamicLibrary.cpp
llvm/trunk/lib/Support/Unix/DynamicLibrary.inc
llvm/trunk/lib/Support/Windows/DynamicLibrary.inc
llvm/trunk/unittests/Support/DynamicLibrary/DynamicLibraryTest.cpp
Modified: llvm/trunk/include/llvm/Support/DynamicLibrary.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Support/DynamicLibrary.h?rev=307849&r1=307848&r2=307849&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Support/DynamicLibrary.h (original)
+++ llvm/trunk/include/llvm/Support/DynamicLibrary.h Wed Jul 12 14:22:45 2017
@@ -88,6 +88,22 @@ namespace sys {
return !getPermanentLibrary(Filename, ErrMsg).isValid();
}
+ enum SearchOrdering {
+ /// SO_Linker - Search as a call to dlsym(dlopen(NULL)) would when
+ /// DynamicLibrary::getPermanentLibrary(NULL) has been called or
+ /// search the list of explcitly loaded symbols if not.
+ SO_Linker,
+ /// SO_LoadedFirst - Search all loaded libraries, then as SO_Linker would.
+ SO_LoadedFirst,
+ /// SO_LoadedLast - Search as SO_Linker would, then loaded libraries.
+ /// Only useful to search if libraries with RTLD_LOCAL have been added.
+ SO_LoadedLast,
+ /// SO_LoadOrder - Or this in to search libraries in the ordered loaded.
+ /// The default bahaviour is to search loaded libraries in reverse.
+ SO_LoadOrder = 4
+ };
+ static SearchOrdering SearchOrder; // = SO_Linker
+
/// This function will search through all previously loaded dynamic
/// libraries for the symbol \p symbolName. If it is found, the address of
/// that symbol is returned. If not, null is returned. Note that this will
Modified: llvm/trunk/lib/Support/DynamicLibrary.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/DynamicLibrary.cpp?rev=307849&r1=307848&r2=307849&view=diff
==============================================================================
--- llvm/trunk/lib/Support/DynamicLibrary.cpp (original)
+++ llvm/trunk/lib/Support/DynamicLibrary.cpp Wed Jul 12 14:22:45 2017
@@ -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::Sm
#endif
char DynamicLibrary::Invalid;
+DynamicLibrary::SearchOrdering DynamicLibrary::SearchOrder =
+ DynamicLibrary::SO_Linker;
namespace llvm {
void *SearchForAddressOfSpecialSymbol(const char *SymbolName) {
@@ -170,7 +191,7 @@ void *DynamicLibrary::SearchForAddressOf
// Now search the libraries.
if (OpenedHandles.isConstructed()) {
- if (void *Ptr = OpenedHandles->Lookup(SymbolName))
+ if (void *Ptr = OpenedHandles->Lookup(SymbolName, SearchOrder))
return Ptr;
}
}
Modified: llvm/trunk/lib/Support/Unix/DynamicLibrary.inc
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/Unix/DynamicLibrary.inc?rev=307849&r1=307848&r2=307849&view=diff
==============================================================================
--- llvm/trunk/lib/Support/Unix/DynamicLibrary.inc (original)
+++ llvm/trunk/lib/Support/Unix/DynamicLibrary.inc Wed Jul 12 14:22:45 2017
@@ -20,6 +20,9 @@ DynamicLibrary::HandleSet::~HandleSet()
::dlclose(Handle);
if (Process)
::dlclose(Process);
+
+ // llvm_shutdown called, Return to default
+ DynamicLibrary::SearchOrder = DynamicLibrary::SO_Linker;
}
void *DynamicLibrary::HandleSet::DLOpen(const char *File, std::string *Err) {
Modified: llvm/trunk/lib/Support/Windows/DynamicLibrary.inc
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/Windows/DynamicLibrary.inc?rev=307849&r1=307848&r2=307849&view=diff
==============================================================================
--- llvm/trunk/lib/Support/Windows/DynamicLibrary.inc (original)
+++ llvm/trunk/lib/Support/Windows/DynamicLibrary.inc Wed Jul 12 14:22:45 2017
@@ -28,6 +28,8 @@ DynamicLibrary::HandleSet::~HandleSet()
// 'Process' should not be released on Windows.
assert((!Process || Process==this) && "Bad Handle");
+ // llvm_shutdown called, Return to default
+ DynamicLibrary::SearchOrder = DynamicLibrary::SO_Linker;
}
void *DynamicLibrary::HandleSet::DLOpen(const char *File, std::string *Err) {
Modified: llvm/trunk/unittests/Support/DynamicLibrary/DynamicLibraryTest.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/Support/DynamicLibrary/DynamicLibraryTest.cpp?rev=307849&r1=307848&r2=307849&view=diff
==============================================================================
--- llvm/trunk/unittests/Support/DynamicLibrary/DynamicLibraryTest.cpp (original)
+++ llvm/trunk/unittests/Support/DynamicLibrary/DynamicLibraryTest.cpp Wed Jul 12 14:22:45 2017
@@ -77,6 +77,7 @@ TEST(DynamicLibrary, Overload) {
EXPECT_TRUE(DL.isValid());
EXPECT_TRUE(Err.empty());
+ // Test overloading local symbols does not occur by default
GS = FuncPtr<GetString>(DynamicLibrary::SearchForAddressOfSymbol("TestA"));
EXPECT_TRUE(GS != nullptr && GS == &TestA);
EXPECT_EQ(StdString(GS()), "ProcessCall");
@@ -85,6 +86,12 @@ TEST(DynamicLibrary, Overload) {
EXPECT_TRUE(GS != nullptr && GS == &TestA);
EXPECT_EQ(StdString(GS()), "ProcessCall");
+ // Test overloading by forcing library priority when searching for a symbol
+ DynamicLibrary::SearchOrder = DynamicLibrary::SO_LoadedFirst;
+ GS = FuncPtr<GetString>(DynamicLibrary::SearchForAddressOfSymbol("TestA"));
+ EXPECT_TRUE(GS != nullptr && GS != &TestA);
+ EXPECT_EQ(StdString(GS()), "LibCall");
+
DynamicLibrary::AddSymbol("TestA", PtrFunc(&OverloadTestA));
GS = FuncPtr<GetString>(DL.getAddressOfSymbol("TestA"));
EXPECT_TRUE(GS != nullptr && GS != &OverloadTestA);
@@ -95,6 +102,9 @@ TEST(DynamicLibrary, Overload) {
}
EXPECT_TRUE(FuncPtr<GetString>(DynamicLibrary::SearchForAddressOfSymbol(
"TestA")) == nullptr);
+
+ // Check serach ordering is reset to default after call to llvm_shutdown
+ EXPECT_TRUE(DynamicLibrary::SearchOrder == DynamicLibrary::SO_Linker);
}
TEST(DynamicLibrary, Shutdown) {
More information about the llvm-commits
mailing list