OSDN Git Service

[RuntimeDyld] Call the SymbolResolver::findSymbolInLogicalDylib method when
authorLang Hames <lhames@gmail.com>
Wed, 25 May 2016 16:23:59 +0000 (16:23 +0000)
committerLang Hames <lhames@gmail.com>
Wed, 25 May 2016 16:23:59 +0000 (16:23 +0000)
searching for external symbols, and fall back to the SymbolResolver::findSymbol
method if the former returns null.

This makes RuntimeDyld behave more like a static linker: Symbol definitions
from within the current module's "logical dylib" will be preferred to
external definitions. We can build on this behavior in the future to properly
support weak symbol handling.

Custom symbol resolvers that override the findSymbolInLogicalDylib method may
notice changes due to this patch. Clients who have not overridden this method
should generally be unaffected, however users of the OrcMCJITReplacement class
may notice changes.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@270716 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/ExecutionEngine/Orc/CompileOnDemandLayer.h
include/llvm/ExecutionEngine/Orc/LambdaResolver.h
include/llvm/ExecutionEngine/RuntimeDyld.h
lib/ExecutionEngine/Orc/OrcCBindingsStack.h
lib/ExecutionEngine/Orc/OrcMCJITReplacement.h
lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp
tools/lli/OrcLazyJIT.h
tools/lli/lli.cpp

index 84af472..ba932b2 100644 (file)
@@ -145,7 +145,7 @@ private:
       return *this;
     }
 
-    SymbolResolverFtor ExternalSymbolResolver;
+    std::unique_ptr<RuntimeDyld::SymbolResolver> ExternalSymbolResolver;
     std::unique_ptr<ResourceOwner<RuntimeDyld::MemoryManager>> MemMgr;
     ModuleAdderFtor ModuleAdder;
   };
@@ -188,10 +188,7 @@ public:
     LogicalDylibs.push_back(CODLogicalDylib(BaseLayer));
     auto &LDResources = LogicalDylibs.back().getDylibResources();
 
-    LDResources.ExternalSymbolResolver =
-      [Resolver](const std::string &Name) {
-        return Resolver->findSymbol(Name);
-      };
+    LDResources.ExternalSymbolResolver = std::move(Resolver);
 
     auto &MemMgrRef = *MemMgr;
     LDResources.MemMgr =
@@ -357,10 +354,12 @@ private:
           auto &LMResources = LD.getLogicalModuleResources(LMH);
           if (auto Sym = LMResources.StubsMgr->findStub(Name, false))
             return RuntimeDyld::SymbolInfo(Sym.getAddress(), Sym.getFlags());
-          return LD.getDylibResources().ExternalSymbolResolver(Name);
+          auto &LDResolver = LD.getDylibResources().ExternalSymbolResolver;
+          return LDResolver->findSymbolInLogicalDylib(Name);
         },
-        [](const std::string &Name) {
-          return RuntimeDyld::SymbolInfo(nullptr);
+        [&LD](const std::string &Name) {
+          auto &LDResolver = LD.getDylibResources().ExternalSymbolResolver;
+          return LDResolver->findSymbol(Name);
         });
 
     auto GVsH =
@@ -484,13 +483,12 @@ private:
           if (auto Symbol = LD.findSymbolInternally(LMH, Name))
             return RuntimeDyld::SymbolInfo(Symbol.getAddress(),
                                            Symbol.getFlags());
-          return LD.getDylibResources().ExternalSymbolResolver(Name);
+          auto &LDResolver = LD.getDylibResources().ExternalSymbolResolver;
+          return LDResolver->findSymbolInLogicalDylib(Name);
         },
-        [this, &LD, LMH](const std::string &Name) {
-          if (auto Symbol = LD.findSymbolInternally(LMH, Name))
-            return RuntimeDyld::SymbolInfo(Symbol.getAddress(),
-                                           Symbol.getFlags());
-          return RuntimeDyld::SymbolInfo(nullptr);
+        [this, &LD](const std::string &Name) {
+          auto &LDResolver = LD.getDylibResources().ExternalSymbolResolver;
+          return LDResolver->findSymbol(Name);
         });
 
     return LD.getDylibResources().ModuleAdder(BaseLayer, std::move(M),
index f59e884..a42b9d5 100644 (file)
 namespace llvm {
 namespace orc {
 
-template <typename ExternalLookupFtorT, typename DylibLookupFtorT>
+template <typename DylibLookupFtorT, typename ExternalLookupFtorT>
 class LambdaResolver : public RuntimeDyld::SymbolResolver {
 public:
 
-  LambdaResolver(ExternalLookupFtorT ExternalLookupFtor,
-                 DylibLookupFtorT DylibLookupFtor)
-      : ExternalLookupFtor(ExternalLookupFtor),
-        DylibLookupFtor(DylibLookupFtor) {}
-
-  RuntimeDyld::SymbolInfo findSymbol(const std::string &Name) final {
-    return ExternalLookupFtor(Name);
-  }
+  LambdaResolver(DylibLookupFtorT DylibLookupFtor,
+                 ExternalLookupFtorT ExternalLookupFtor)
+      : DylibLookupFtor(DylibLookupFtor),
+        ExternalLookupFtor(ExternalLookupFtor) {}
 
   RuntimeDyld::SymbolInfo
   findSymbolInLogicalDylib(const std::string &Name) final {
     return DylibLookupFtor(Name);
   }
 
+  RuntimeDyld::SymbolInfo findSymbol(const std::string &Name) final {
+    return ExternalLookupFtor(Name);
+  }
+
 private:
-  ExternalLookupFtorT ExternalLookupFtor;
   DylibLookupFtorT DylibLookupFtor;
+  ExternalLookupFtorT ExternalLookupFtor;
 };
 
-template <typename ExternalLookupFtorT,
-          typename DylibLookupFtorT>
-std::unique_ptr<LambdaResolver<ExternalLookupFtorT, DylibLookupFtorT>>
-createLambdaResolver(ExternalLookupFtorT ExternalLookupFtor,
-                     DylibLookupFtorT DylibLookupFtor) {
-  typedef LambdaResolver<ExternalLookupFtorT, DylibLookupFtorT> LR;
-  return make_unique<LR>(std::move(ExternalLookupFtor),
-                         std::move(DylibLookupFtor));
+template <typename DylibLookupFtorT,
+          typename ExternalLookupFtorT>
+std::unique_ptr<LambdaResolver<DylibLookupFtorT, ExternalLookupFtorT>>
+createLambdaResolver(DylibLookupFtorT DylibLookupFtor,
+                     ExternalLookupFtorT ExternalLookupFtor) {
+  typedef LambdaResolver<DylibLookupFtorT, ExternalLookupFtorT> LR;
+  return make_unique<LR>(std::move(DylibLookupFtor),
+                         std::move(ExternalLookupFtor));
 }
 
 } // End namespace orc.
index ad2e202..c2e9777 100644 (file)
@@ -193,17 +193,9 @@ public:
   public:
     virtual ~SymbolResolver() {}
 
-    /// This method returns the address of the specified function or variable.
-    /// It is used to resolve symbols during module linking.
-    ///
-    /// If the returned symbol's address is equal to ~0ULL then RuntimeDyld will
-    /// skip all relocations for that symbol, and the client will be responsible
-    /// for handling them manually.
-    virtual SymbolInfo findSymbol(const std::string &Name) = 0;
-
     /// This method returns the address of the specified symbol if it exists
     /// within the logical dynamic library represented by this
-    /// RTDyldMemoryManager. Unlike getSymbolAddress, queries through this
+    /// RTDyldMemoryManager. Unlike findSymbol, queries through this
     /// interface should return addresses for hidden symbols.
     ///
     /// This is of particular importance for the Orc JIT APIs, which support lazy
@@ -212,13 +204,17 @@ public:
     /// writing memory managers for MCJIT can usually ignore this method.
     ///
     /// This method will be queried by RuntimeDyld when checking for previous
-    /// definitions of common symbols. It will *not* be queried by default when
-    /// resolving external symbols (this minimises the link-time overhead for
-    /// MCJIT clients who don't care about Orc features). If you are writing a
-    /// RTDyldMemoryManager for Orc and want "external" symbol resolution to
-    /// search the logical dylib, you should override your getSymbolAddress
-    /// method call this method directly.
+    /// definitions of common symbols.
     virtual SymbolInfo findSymbolInLogicalDylib(const std::string &Name) = 0;
+
+    /// This method returns the address of the specified function or variable.
+    /// It is used to resolve symbols during module linking.
+    ///
+    /// If the returned symbol's address is equal to ~0ULL then RuntimeDyld will
+    /// skip all relocations for that symbol, and the client will be responsible
+    /// for handling them manually.
+    virtual SymbolInfo findSymbol(const std::string &Name) = 0;
+
   private:
     virtual void anchor();
   };
index 508ce62..dd14a14 100644 (file)
@@ -137,10 +137,10 @@ public:
     return mapError(IndirectStubsMgr->updatePointer(Name, Addr));
   }
 
-  std::shared_ptr<RuntimeDyld::SymbolResolver>
+  std::unique_ptr<RuntimeDyld::SymbolResolver>
   createResolver(LLVMOrcSymbolResolverFn ExternalResolver,
                  void *ExternalResolverCtx) {
-    auto Resolver = orc::createLambdaResolver(
+    return orc::createLambdaResolver(
         [this, ExternalResolver, ExternalResolverCtx](const std::string &Name) {
           // Search order:
           // 1. JIT'd symbols.
@@ -162,8 +162,6 @@ public:
         [](const std::string &Name) {
           return RuntimeDyld::SymbolInfo(nullptr);
         });
-
-    return std::shared_ptr<RuntimeDyld::SymbolResolver>(std::move(Resolver));
   }
 
   template <typename LayerT>
index db7c08f..518ba28 100644 (file)
@@ -121,7 +121,7 @@ class OrcMCJITReplacement : public ExecutionEngine {
 
     RuntimeDyld::SymbolInfo
     findSymbolInLogicalDylib(const std::string &Name) override {
-      return M.ClientResolver->findSymbolInLogicalDylib(Name);
+      return M.ClientResolver->findSymbol(Name);
     }
 
   private:
index 2df35da..4a282cb 100644 (file)
@@ -916,7 +916,11 @@ void RuntimeDyldImpl::resolveExternalSymbols() {
       if (Loc == GlobalSymbolTable.end()) {
         // This is an external symbol, try to get its address from the symbol
         // resolver.
-        Addr = Resolver.findSymbol(Name.data()).getAddress();
+        // First search for the symbol in this logical dylib.
+        Addr = Resolver.findSymbolInLogicalDylib(Name.data()).getAddress();
+        // If that fails, try searching for an external symbol.
+        if (!Addr)
+          Addr = Resolver.findSymbol(Name.data()).getAddress();
         // The call to getSymbolAddress may have caused additional modules to
         // be loaded, which may have added new entries to the
         // ExternalSymbolRelocations map.  Consquently, we need to update our
index 2a5b31d..6409ebf 100644 (file)
@@ -82,7 +82,7 @@ public:
     //   1) Search the JIT symbols.
     //   2) Check for C++ runtime overrides.
     //   3) Search the host process (LLI)'s symbol table.
-    std::shared_ptr<RuntimeDyld::SymbolResolver> Resolver =
+    auto Resolver =
       orc::createLambdaResolver(
         [this](const std::string &Name) {
           if (auto Sym = CODLayer.findSymbol(Name, true))
index e691b5a..2823247 100644 (file)
@@ -662,12 +662,12 @@ int main(int argc, char **argv, char * const *envp) {
     // Forward MCJIT's symbol resolution calls to the remote.
     static_cast<ForwardingMemoryManager*>(RTDyldMM)->setResolver(
       orc::createLambdaResolver(
+        [](const std::string &Name) { return nullptr; },
         [&](const std::string &Name) {
           if (auto Addr = ExitOnErr(R.getSymbolAddress(Name)))
            return RuntimeDyld::SymbolInfo(Addr, JITSymbolFlags::Exported);
           return RuntimeDyld::SymbolInfo(nullptr);
-        },
-        [](const std::string &Name) { return nullptr; }
+        }
       ));
 
     // Grab the target address of the JIT'd main function on the remote and call