[PATCH] D33529: Allow Unix libraries loaded with RTLD_LOCAL to be searched.

Frederich Munch via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Wed May 24 17:47:30 PDT 2017


marsupial created this revision.

**DynamicLibrary::SearchForAddressOfSymbol** will use the process handle to search for a symbol when available to avoid searching for a symbol twice in the most common use of LLVM.  ROOT; however, currently adds libraries via **DynamicLibrary::addPermanentLibrary** that have been loaded with the RTLD_LOCAL flag which means those symbols are skipped when scanning the process handle.

This adds an argument to allow all handles to be searched at the cost of possibly looking up a non existent symbol twice.


https://reviews.llvm.org/D33529

Files:
  include/llvm/Support/DynamicLibrary.h
  lib/Support/DynamicLibrary.cpp


Index: lib/Support/DynamicLibrary.cpp
===================================================================
--- lib/Support/DynamicLibrary.cpp
+++ lib/Support/DynamicLibrary.cpp
@@ -73,21 +73,26 @@
     return true;
   }
 
-  void *Lookup(const char *Symbol) {
+  void *Lookup(const char *Symbol, bool LongSearch) {
     // Process handle gets first try.
     if (Process) {
       if (void *Ptr = DLSym(Process, Symbol))
         return Ptr;
-#ifndef NDEBUG
+      // On Windows all loaded modules will have been searched at this point.
+      // On Unix there is a possibility of a Handle having it's symbols hidden
+      // from OS lookup via dlsym.
+#if defined(LLVM_ON_WIN32) && !defined(NDEBUG)
       for (void *Handle : Handles)
         assert(!DLSym(Handle, Symbol) && "Symbol exists in non process handle");
+#else
+      if (!LongSearch)
 #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))
-          return Ptr;
-      }
+        return nullptr;
+    }
+    // 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))
+        return Ptr;
     }
     return nullptr;
   }
@@ -112,6 +117,7 @@
 
 #endif
 
+
 char DynamicLibrary::Invalid;
 
 namespace llvm {
@@ -151,7 +157,8 @@
   return HandleSet::DLSym(Data, SymbolName);
 }
 
-void *DynamicLibrary::SearchForAddressOfSymbol(const char *SymbolName) {
+void *DynamicLibrary::SearchForAddressOfSymbol(const char *SymbolName,
+                                               bool LongSearch) {
   {
     SmartScopedLock<true> Lock(*SymbolsMutex);
 
@@ -165,7 +172,7 @@
 
     // Now search the libraries.
     if (OpenedHandles.isConstructed()) {
-      if (void *Ptr = OpenedHandles->Lookup(SymbolName))
+      if (void *Ptr = OpenedHandles->Lookup(SymbolName, LongSearch))
         return Ptr;
     }
   }
Index: include/llvm/Support/DynamicLibrary.h
===================================================================
--- include/llvm/Support/DynamicLibrary.h
+++ include/llvm/Support/DynamicLibrary.h
@@ -93,9 +93,17 @@
     /// that symbol is returned. If not, null is returned. Note that this will
     /// search permanently loaded libraries (getPermanentLibrary()) as well
     /// as explicitly registered symbols (AddSymbol()).
+    ///
     /// @throws std::string on error.
     /// @brief Search through libraries for address of a symbol
-    static void *SearchForAddressOfSymbol(const char *symbolName);
+    /// \param LongSearch On Unix it is possible to use addPermanentLibrary
+    /// to load a library handle that has been opened with RTLD_LOCAL.  In this
+    /// case passing true for LongSearch will allow the symbol to be found.
+    /// This avoids a 2x penalty for symbol lookup in more common cases where
+    /// RTLD_LOCAL has not been used or if DynamicLibrary::getPermanentLibrary
+    /// is solely used to load libraries.
+    static void *SearchForAddressOfSymbol(const char *SymbolName,
+                                          bool LongSearch = false);
 
     /// @brief Convenience function for C++ophiles.
     static void *SearchForAddressOfSymbol(const std::string &symbolName) {


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D33529.100188.patch
Type: text/x-patch
Size: 3367 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20170525/90a111c8/attachment.bin>


More information about the llvm-commits mailing list