[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