[llvm] e05d80e - [ORC] Add Executor Resolver Utility (#143654)

via llvm-commits llvm-commits at lists.llvm.org
Mon Oct 6 23:22:57 PDT 2025


Author: SahilPatidar
Date: 2025-10-07T11:52:53+05:30
New Revision: e05d80ec7b8b7a2f7743780cb343ca55e993aed2

URL: https://github.com/llvm/llvm-project/commit/e05d80ec7b8b7a2f7743780cb343ca55e993aed2
DIFF: https://github.com/llvm/llvm-project/commit/e05d80ec7b8b7a2f7743780cb343ca55e993aed2.diff

LOG: [ORC] Add Executor Resolver Utility (#143654)

This patch adds the new **executor-side resolver API** as suggested by
@lhames. It introduces a `DylibSymbolResolver` that helps resolve
symbols for each loaded dylib.

Previously, we returned a `DylibHandle` to the controller. Now, we wrap
the native handle inside `DylibSymbolResolver` and return a
`ResolverHandle` instead. This makes the code cleaner and separates the
symbol resolution logic from raw handle management.

Added: 
    llvm/include/llvm/ExecutionEngine/Orc/ExecutorResolutionGenerator.h
    llvm/include/llvm/ExecutionEngine/Orc/TargetProcess/ExecutorResolver.h
    llvm/lib/ExecutionEngine/Orc/ExecutorResolutionGenerator.cpp
    llvm/lib/ExecutionEngine/Orc/TargetProcess/ExecutorResolver.cpp

Modified: 
    llvm/include/llvm/ExecutionEngine/Orc/EPCGenericDylibManager.h
    llvm/include/llvm/ExecutionEngine/Orc/Shared/OrcRTBridge.h
    llvm/include/llvm/ExecutionEngine/Orc/Shared/TargetProcessControlTypes.h
    llvm/include/llvm/ExecutionEngine/Orc/TargetProcess/SimpleExecutorDylibManager.h
    llvm/lib/ExecutionEngine/Orc/CMakeLists.txt
    llvm/lib/ExecutionEngine/Orc/EPCDebugObjectRegistrar.cpp
    llvm/lib/ExecutionEngine/Orc/EPCDynamicLibrarySearchGenerator.cpp
    llvm/lib/ExecutionEngine/Orc/EPCGenericDylibManager.cpp
    llvm/lib/ExecutionEngine/Orc/LookupAndRecordAddrs.cpp
    llvm/lib/ExecutionEngine/Orc/SelfExecutorProcessControl.cpp
    llvm/lib/ExecutionEngine/Orc/Shared/OrcRTBridge.cpp
    llvm/lib/ExecutionEngine/Orc/TargetProcess/CMakeLists.txt
    llvm/lib/ExecutionEngine/Orc/TargetProcess/SimpleExecutorDylibManager.cpp
    llvm/tools/lli/ForwardingMemoryManager.h
    llvm/unittests/ExecutionEngine/Orc/ObjectLinkingLayerTest.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/include/llvm/ExecutionEngine/Orc/EPCGenericDylibManager.h b/llvm/include/llvm/ExecutionEngine/Orc/EPCGenericDylibManager.h
index 68bc54b89fe56..7c995a727e348 100644
--- a/llvm/include/llvm/ExecutionEngine/Orc/EPCGenericDylibManager.h
+++ b/llvm/include/llvm/ExecutionEngine/Orc/EPCGenericDylibManager.h
@@ -34,7 +34,7 @@ class EPCGenericDylibManager {
   struct SymbolAddrs {
     ExecutorAddr Instance;
     ExecutorAddr Open;
-    ExecutorAddr Lookup;
+    ExecutorAddr Resolve;
   };
 
   /// Create an EPCGenericMemoryAccess instance from a given set of
@@ -51,25 +51,25 @@ class EPCGenericDylibManager {
   LLVM_ABI Expected<tpctypes::DylibHandle> open(StringRef Path, uint64_t Mode);
 
   /// Looks up symbols within the given dylib.
-  Expected<std::vector<ExecutorSymbolDef>>
-  lookup(tpctypes::DylibHandle H, const SymbolLookupSet &Lookup) {
-    std::promise<MSVCPExpected<std::vector<ExecutorSymbolDef>>> RP;
+  Expected<tpctypes::LookupResult> lookup(tpctypes::DylibHandle H,
+                                          const SymbolLookupSet &Lookup) {
+    std::promise<MSVCPExpected<tpctypes::LookupResult>> RP;
     auto RF = RP.get_future();
     lookupAsync(H, Lookup, [&RP](auto R) { RP.set_value(std::move(R)); });
     return RF.get();
   }
 
   /// Looks up symbols within the given dylib.
-  Expected<std::vector<ExecutorSymbolDef>>
-  lookup(tpctypes::DylibHandle H, const RemoteSymbolLookupSet &Lookup) {
-    std::promise<MSVCPExpected<std::vector<ExecutorSymbolDef>>> RP;
+  Expected<tpctypes::LookupResult> lookup(tpctypes::DylibHandle H,
+                                          const RemoteSymbolLookupSet &Lookup) {
+    std::promise<MSVCPExpected<tpctypes::LookupResult>> RP;
     auto RF = RP.get_future();
     lookupAsync(H, Lookup, [&RP](auto R) { RP.set_value(std::move(R)); });
     return RF.get();
   }
 
   using SymbolLookupCompleteFn =
-      unique_function<void(Expected<std::vector<ExecutorSymbolDef>>)>;
+      unique_function<void(Expected<tpctypes::LookupResult>)>;
 
   /// Looks up symbols within the given dylib.
   LLVM_ABI void lookupAsync(tpctypes::DylibHandle H,

diff  --git a/llvm/include/llvm/ExecutionEngine/Orc/ExecutorResolutionGenerator.h b/llvm/include/llvm/ExecutionEngine/Orc/ExecutorResolutionGenerator.h
new file mode 100644
index 0000000000000..9b972edf3e18c
--- /dev/null
+++ b/llvm/include/llvm/ExecutionEngine/Orc/ExecutorResolutionGenerator.h
@@ -0,0 +1,74 @@
+//===----- ExecutorResolver.h - Resolve symbols in executor -----*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// Declares ExecutorResolutionGenerator for symbol resolution,
+// dynamic library loading, and lookup in an executor process via
+// ExecutorResolver.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_EXECUTIONENGINE_ORC_EXECUTORRESOLUTIONGENERATOR_H
+#define LLVM_EXECUTIONENGINE_ORC_EXECUTORRESOLUTIONGENERATOR_H
+
+#include "llvm/ADT/FunctionExtras.h"
+#include "llvm/ExecutionEngine/Orc/AbsoluteSymbols.h"
+#include "llvm/ExecutionEngine/Orc/Core.h"
+
+namespace llvm::orc {
+
+class ExecutorResolutionGenerator : public DefinitionGenerator {
+public:
+  using SymbolPredicate = unique_function<bool(const SymbolStringPtr &)>;
+  using AbsoluteSymbolsFn =
+      unique_function<std::unique_ptr<MaterializationUnit>(SymbolMap)>;
+
+  ExecutorResolutionGenerator(
+      ExecutionSession &ES, tpctypes::ResolverHandle H,
+      SymbolPredicate Allow = SymbolPredicate(),
+      AbsoluteSymbolsFn AbsoluteSymbols = absoluteSymbols)
+      : EPC(ES.getExecutorProcessControl()), H(H), Allow(std::move(Allow)),
+        AbsoluteSymbols(std::move(AbsoluteSymbols)) {}
+
+  ExecutorResolutionGenerator(
+      ExecutionSession &ES, SymbolPredicate Allow = SymbolPredicate(),
+      AbsoluteSymbolsFn AbsoluteSymbols = absoluteSymbols)
+      : EPC(ES.getExecutorProcessControl()), Allow(std::move(Allow)),
+        AbsoluteSymbols(std::move(AbsoluteSymbols)) {}
+
+  /// Permanently loads the library at the given path and, on success, returns
+  /// an ExecutorResolutionGenerator that will search it for symbol
+  /// definitions in the library. On failure returns the reason the library
+  /// failed to load.
+  static Expected<std::unique_ptr<ExecutorResolutionGenerator>>
+  Load(ExecutionSession &ES, const char *LibraryPath,
+       SymbolPredicate Allow = SymbolPredicate(),
+       AbsoluteSymbolsFn AbsoluteSymbols = absoluteSymbols);
+
+  /// Creates a ExecutorResolutionGenerator that searches for symbols in
+  /// the target process.
+  static Expected<std::unique_ptr<ExecutorResolutionGenerator>>
+  GetForTargetProcess(ExecutionSession &ES,
+                      SymbolPredicate Allow = SymbolPredicate(),
+                      AbsoluteSymbolsFn AbsoluteSymbols = absoluteSymbols) {
+    return Load(ES, nullptr, std::move(Allow), std::move(AbsoluteSymbols));
+  }
+
+  Error tryToGenerate(LookupState &LS, LookupKind K, JITDylib &JD,
+                      JITDylibLookupFlags JDLookupFlags,
+                      const SymbolLookupSet &LookupSet) override;
+
+private:
+  ExecutorProcessControl &EPC;
+  tpctypes::ResolverHandle H;
+  SymbolPredicate Allow;
+  AbsoluteSymbolsFn AbsoluteSymbols;
+};
+
+} // namespace llvm::orc
+
+#endif // LLVM_EXECUTIONENGINE_ORC_EXECUTORRESOLUTIONGENERATOR_H

diff  --git a/llvm/include/llvm/ExecutionEngine/Orc/Shared/OrcRTBridge.h b/llvm/include/llvm/ExecutionEngine/Orc/Shared/OrcRTBridge.h
index 2bc6c1218ae72..99ba456e66c85 100644
--- a/llvm/include/llvm/ExecutionEngine/Orc/Shared/OrcRTBridge.h
+++ b/llvm/include/llvm/ExecutionEngine/Orc/Shared/OrcRTBridge.h
@@ -25,7 +25,7 @@ namespace rt {
 
 LLVM_ABI extern const char *SimpleExecutorDylibManagerInstanceName;
 LLVM_ABI extern const char *SimpleExecutorDylibManagerOpenWrapperName;
-LLVM_ABI extern const char *SimpleExecutorDylibManagerLookupWrapperName;
+LLVM_ABI extern const char *SimpleExecutorDylibManagerResolveWrapperName;
 
 LLVM_ABI extern const char *SimpleExecutorMemoryManagerInstanceName;
 LLVM_ABI extern const char *SimpleExecutorMemoryManagerReserveWrapperName;
@@ -66,10 +66,9 @@ using SPSSimpleExecutorDylibManagerOpenSignature =
     shared::SPSExpected<shared::SPSExecutorAddr>(shared::SPSExecutorAddr,
                                                  shared::SPSString, uint64_t);
 
-using SPSSimpleExecutorDylibManagerLookupSignature =
-    shared::SPSExpected<shared::SPSSequence<shared::SPSExecutorSymbolDef>>(
-        shared::SPSExecutorAddr, shared::SPSExecutorAddr,
-        shared::SPSRemoteSymbolLookupSet);
+using SPSSimpleExecutorDylibManagerResolveSignature = shared::SPSExpected<
+    shared::SPSSequence<shared::SPSOptional<shared::SPSExecutorSymbolDef>>>(
+    shared::SPSExecutorAddr, shared::SPSRemoteSymbolLookupSet);
 
 using SPSSimpleExecutorMemoryManagerReserveSignature =
     shared::SPSExpected<shared::SPSExecutorAddr>(shared::SPSExecutorAddr,

diff  --git a/llvm/include/llvm/ExecutionEngine/Orc/Shared/TargetProcessControlTypes.h b/llvm/include/llvm/ExecutionEngine/Orc/Shared/TargetProcessControlTypes.h
index adb07ba29b92a..28ff322556cd7 100644
--- a/llvm/include/llvm/ExecutionEngine/Orc/Shared/TargetProcessControlTypes.h
+++ b/llvm/include/llvm/ExecutionEngine/Orc/Shared/TargetProcessControlTypes.h
@@ -114,7 +114,11 @@ struct PointerWrite {
 /// A handle used to represent a loaded dylib in the target process.
 using DylibHandle = ExecutorAddr;
 
-using LookupResult = std::vector<ExecutorSymbolDef>;
+/// A handle used to reference the resolver associated with a loaded
+///  dylib in the target process.
+using ResolverHandle = ExecutorAddr;
+
+using LookupResult = std::vector<std::optional<ExecutorSymbolDef>>;
 
 } // end namespace tpctypes
 

diff  --git a/llvm/include/llvm/ExecutionEngine/Orc/TargetProcess/ExecutorResolver.h b/llvm/include/llvm/ExecutionEngine/Orc/TargetProcess/ExecutorResolver.h
new file mode 100644
index 0000000000000..2c5e98c7312b9
--- /dev/null
+++ b/llvm/include/llvm/ExecutionEngine/Orc/TargetProcess/ExecutorResolver.h
@@ -0,0 +1,48 @@
+//===----- ExecutorResolver.h - Symbol resolver -----*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// Executor Symbol resolver.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_EXECUTIONENGINE_ORC_TARGETPROCESS_EXECUTORRESOLVER_H
+#define LLVM_EXECUTIONENGINE_ORC_TARGETPROCESS_EXECUTORRESOLVER_H
+
+#include "llvm/ADT/FunctionExtras.h"
+
+#include "llvm/ExecutionEngine/Orc/Shared/ExecutorSymbolDef.h"
+#include "llvm/ExecutionEngine/Orc/Shared/SimpleRemoteEPCUtils.h"
+#include "llvm/ExecutionEngine/Orc/Shared/TargetProcessControlTypes.h"
+
+namespace llvm::orc {
+
+class ExecutorResolver {
+public:
+  using ResolveResult = Expected<std::vector<std::optional<ExecutorSymbolDef>>>;
+  using YieldResolveResultFn = unique_function<void(ResolveResult)>;
+
+  virtual ~ExecutorResolver() = default;
+
+  virtual void resolveAsync(const RemoteSymbolLookupSet &L,
+                            YieldResolveResultFn &&OnResolve) = 0;
+};
+
+class DylibSymbolResolver : public ExecutorResolver {
+public:
+  DylibSymbolResolver(tpctypes::DylibHandle H) : Handle(H) {}
+
+  void
+  resolveAsync(const RemoteSymbolLookupSet &L,
+               ExecutorResolver::YieldResolveResultFn &&OnResolve) override;
+
+private:
+  tpctypes::DylibHandle Handle;
+};
+
+} // end namespace llvm::orc
+#endif // LLVM_EXECUTIONENGINE_ORC_TARGETPROCESS_EXECUTORRESOLVER_H

diff  --git a/llvm/include/llvm/ExecutionEngine/Orc/TargetProcess/SimpleExecutorDylibManager.h b/llvm/include/llvm/ExecutionEngine/Orc/TargetProcess/SimpleExecutorDylibManager.h
index 36a6f4bf6e193..7526a29dc1066 100644
--- a/llvm/include/llvm/ExecutionEngine/Orc/TargetProcess/SimpleExecutorDylibManager.h
+++ b/llvm/include/llvm/ExecutionEngine/Orc/TargetProcess/SimpleExecutorDylibManager.h
@@ -23,6 +23,7 @@
 #include "llvm/ExecutionEngine/Orc/Shared/TargetProcessControlTypes.h"
 #include "llvm/ExecutionEngine/Orc/Shared/WrapperFunctionUtils.h"
 #include "llvm/ExecutionEngine/Orc/TargetProcess/ExecutorBootstrapService.h"
+#include "llvm/ExecutionEngine/Orc/TargetProcess/ExecutorResolver.h"
 #include "llvm/Support/Compiler.h"
 #include "llvm/Support/DynamicLibrary.h"
 #include "llvm/Support/Error.h"
@@ -39,8 +40,6 @@ class LLVM_ABI SimpleExecutorDylibManager : public ExecutorBootstrapService {
   virtual ~SimpleExecutorDylibManager();
 
   Expected<tpctypes::DylibHandle> open(const std::string &Path, uint64_t Mode);
-  Expected<std::vector<ExecutorSymbolDef>>
-  lookup(tpctypes::DylibHandle H, const RemoteSymbolLookupSet &L);
 
   Error shutdown() override;
   void addBootstrapSymbols(StringMap<ExecutorAddr> &M) override;
@@ -52,10 +51,11 @@ class LLVM_ABI SimpleExecutorDylibManager : public ExecutorBootstrapService {
   openWrapper(const char *ArgData, size_t ArgSize);
 
   static llvm::orc::shared::CWrapperFunctionResult
-  lookupWrapper(const char *ArgData, size_t ArgSize);
+  resolveWrapper(const char *ArgData, size_t ArgSize);
 
   std::mutex M;
   DylibSet Dylibs;
+  std::vector<std::unique_ptr<ExecutorResolver>> Resolvers;
 };
 
 } // end namespace rt_bootstrap

diff  --git a/llvm/lib/ExecutionEngine/Orc/CMakeLists.txt b/llvm/lib/ExecutionEngine/Orc/CMakeLists.txt
index f159d59fa3ace..0ffe3ae37da28 100644
--- a/llvm/lib/ExecutionEngine/Orc/CMakeLists.txt
+++ b/llvm/lib/ExecutionEngine/Orc/CMakeLists.txt
@@ -24,6 +24,7 @@ add_llvm_component_library(LLVMOrcJIT
   EPCGenericRTDyldMemoryManager.cpp
   EPCIndirectionUtils.cpp
   ExecutionUtils.cpp
+  ExecutorResolutionGenerator.cpp
   ObjectFileInterface.cpp
   GetDylibInterface.cpp
   IndirectionUtils.cpp

diff  --git a/llvm/lib/ExecutionEngine/Orc/EPCDebugObjectRegistrar.cpp b/llvm/lib/ExecutionEngine/Orc/EPCDebugObjectRegistrar.cpp
index 9f7d517d481d4..08bef37b06c82 100644
--- a/llvm/lib/ExecutionEngine/Orc/EPCDebugObjectRegistrar.cpp
+++ b/llvm/lib/ExecutionEngine/Orc/EPCDebugObjectRegistrar.cpp
@@ -42,7 +42,12 @@ Expected<std::unique_ptr<EPCDebugObjectRegistrar>> createJITLoaderGDBRegistrar(
   assert((*Result)[0].size() == 1 &&
          "Unexpected number of addresses in result");
 
-  ExecutorAddr RegisterAddr = (*Result)[0][0].getAddress();
+  if (!(*Result)[0][0].has_value())
+    return make_error<StringError>(
+        "Expected a valid address in the lookup result",
+        inconvertibleErrorCode());
+
+  ExecutorAddr RegisterAddr = (*Result)[0][0]->getAddress();
   return std::make_unique<EPCDebugObjectRegistrar>(ES, RegisterAddr);
 }
 

diff  --git a/llvm/lib/ExecutionEngine/Orc/EPCDynamicLibrarySearchGenerator.cpp b/llvm/lib/ExecutionEngine/Orc/EPCDynamicLibrarySearchGenerator.cpp
index 59d66b271bb09..1e83c07f4bdb1 100644
--- a/llvm/lib/ExecutionEngine/Orc/EPCDynamicLibrarySearchGenerator.cpp
+++ b/llvm/lib/ExecutionEngine/Orc/EPCDynamicLibrarySearchGenerator.cpp
@@ -79,12 +79,16 @@ Error EPCDynamicLibrarySearchGenerator::tryToGenerate(
     assert(Result->front().size() == LookupSymbols.size() &&
            "Result has incorrect number of elements");
 
+    auto SymsIt = Result->front().begin();
+    SymbolNameSet MissingSymbols;
     SymbolMap NewSymbols;
-    auto ResultI = Result->front().begin();
-    for (auto &KV : LookupSymbols) {
-      if (ResultI->getAddress())
-        NewSymbols[KV.first] = *ResultI;
-      ++ResultI;
+    for (auto &[Name, Flags] : LookupSymbols) {
+      const auto &Sym = *SymsIt++;
+      if (Sym && Sym->getAddress())
+        NewSymbols[Name] = *Sym;
+      else if (LLVM_UNLIKELY(!Sym &&
+                             Flags == SymbolLookupFlags::RequiredSymbol))
+        MissingSymbols.insert(Name);
     }
 
     LLVM_DEBUG({
@@ -96,6 +100,10 @@ Error EPCDynamicLibrarySearchGenerator::tryToGenerate(
     if (NewSymbols.empty())
       return LS.continueLookup(Error::success());
 
+    if (LLVM_UNLIKELY(!MissingSymbols.empty()))
+      return LS.continueLookup(make_error<SymbolsNotFound>(
+          this->EPC.getSymbolStringPool(), std::move(MissingSymbols)));
+
     // Define resolved symbols.
     Error Err = addAbsolutes(JD, std::move(NewSymbols));
 

diff  --git a/llvm/lib/ExecutionEngine/Orc/EPCGenericDylibManager.cpp b/llvm/lib/ExecutionEngine/Orc/EPCGenericDylibManager.cpp
index f98b18ccd0dc7..1f19d178039e5 100644
--- a/llvm/lib/ExecutionEngine/Orc/EPCGenericDylibManager.cpp
+++ b/llvm/lib/ExecutionEngine/Orc/EPCGenericDylibManager.cpp
@@ -66,7 +66,7 @@ EPCGenericDylibManager::CreateWithDefaultBootstrapSymbols(
   if (auto Err = EPC.getBootstrapSymbols(
           {{SAs.Instance, rt::SimpleExecutorDylibManagerInstanceName},
            {SAs.Open, rt::SimpleExecutorDylibManagerOpenWrapperName},
-           {SAs.Lookup, rt::SimpleExecutorDylibManagerLookupWrapperName}}))
+           {SAs.Resolve, rt::SimpleExecutorDylibManagerResolveWrapperName}}))
     return std::move(Err);
   return EPCGenericDylibManager(EPC, std::move(SAs));
 }
@@ -84,11 +84,12 @@ Expected<tpctypes::DylibHandle> EPCGenericDylibManager::open(StringRef Path,
 void EPCGenericDylibManager::lookupAsync(tpctypes::DylibHandle H,
                                          const SymbolLookupSet &Lookup,
                                          SymbolLookupCompleteFn Complete) {
-  EPC.callSPSWrapperAsync<rt::SPSSimpleExecutorDylibManagerLookupSignature>(
-      SAs.Lookup,
+  EPC.callSPSWrapperAsync<rt::SPSSimpleExecutorDylibManagerResolveSignature>(
+      SAs.Resolve,
       [Complete = std::move(Complete)](
           Error SerializationErr,
-          Expected<std::vector<ExecutorSymbolDef>> Result) mutable {
+          Expected<std::vector<std::optional<ExecutorSymbolDef>>>
+              Result) mutable {
         if (SerializationErr) {
           cantFail(Result.takeError());
           Complete(std::move(SerializationErr));
@@ -96,17 +97,18 @@ void EPCGenericDylibManager::lookupAsync(tpctypes::DylibHandle H,
         }
         Complete(std::move(Result));
       },
-      SAs.Instance, H, Lookup);
+      H, Lookup);
 }
 
 void EPCGenericDylibManager::lookupAsync(tpctypes::DylibHandle H,
                                          const RemoteSymbolLookupSet &Lookup,
                                          SymbolLookupCompleteFn Complete) {
-  EPC.callSPSWrapperAsync<rt::SPSSimpleExecutorDylibManagerLookupSignature>(
-      SAs.Lookup,
+  EPC.callSPSWrapperAsync<rt::SPSSimpleExecutorDylibManagerResolveSignature>(
+      SAs.Resolve,
       [Complete = std::move(Complete)](
           Error SerializationErr,
-          Expected<std::vector<ExecutorSymbolDef>> Result) mutable {
+          Expected<std::vector<std::optional<ExecutorSymbolDef>>>
+              Result) mutable {
         if (SerializationErr) {
           cantFail(Result.takeError());
           Complete(std::move(SerializationErr));
@@ -114,7 +116,7 @@ void EPCGenericDylibManager::lookupAsync(tpctypes::DylibHandle H,
         }
         Complete(std::move(Result));
       },
-      SAs.Instance, H, Lookup);
+      H, Lookup);
 }
 
 } // end namespace orc

diff  --git a/llvm/lib/ExecutionEngine/Orc/ExecutorResolutionGenerator.cpp b/llvm/lib/ExecutionEngine/Orc/ExecutorResolutionGenerator.cpp
new file mode 100644
index 0000000000000..e5b0bd3dbc5c3
--- /dev/null
+++ b/llvm/lib/ExecutionEngine/Orc/ExecutorResolutionGenerator.cpp
@@ -0,0 +1,98 @@
+//===---- ExecutorProcessControl.cpp -- Executor process control APIs -----===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/ExecutionEngine/Orc/ExecutorResolutionGenerator.h"
+
+#include "llvm/ExecutionEngine/Orc/DebugUtils.h"
+#include "llvm/ExecutionEngine/Orc/Shared/ExecutorSymbolDef.h"
+#include "llvm/Support/Error.h"
+
+#define DEBUG_TYPE "orc"
+
+namespace llvm {
+namespace orc {
+
+Expected<std::unique_ptr<ExecutorResolutionGenerator>>
+ExecutorResolutionGenerator::Load(ExecutionSession &ES, const char *LibraryPath,
+                                  SymbolPredicate Allow,
+                                  AbsoluteSymbolsFn AbsoluteSymbols) {
+  auto H = ES.getExecutorProcessControl().getDylibMgr().loadDylib(LibraryPath);
+  if (H)
+    return H.takeError();
+  return std::make_unique<ExecutorResolutionGenerator>(
+      ES, *H, std::move(Allow), std::move(AbsoluteSymbols));
+}
+
+Error ExecutorResolutionGenerator::tryToGenerate(
+    LookupState &LS, LookupKind K, JITDylib &JD,
+    JITDylibLookupFlags JDLookupFlags, const SymbolLookupSet &LookupSet) {
+
+  if (LookupSet.empty())
+    return Error::success();
+
+  LLVM_DEBUG({
+    dbgs() << "ExecutorResolutionGenerator trying to generate " << LookupSet
+           << "\n";
+  });
+
+  SymbolLookupSet LookupSymbols;
+  for (auto &[Name, LookupFlag] : LookupSet) {
+    if (Allow && !Allow(Name))
+      continue;
+    LookupSymbols.add(Name, LookupFlag);
+  }
+
+  DylibManager::LookupRequest LR(H, LookupSymbols);
+  EPC.getDylibMgr().lookupSymbolsAsync(
+      LR, [this, LS = std::move(LS), JD = JITDylibSP(&JD),
+           LookupSymbols](auto Result) mutable {
+        if (Result) {
+          LLVM_DEBUG({
+            dbgs() << "ExecutorResolutionGenerator lookup failed due to error";
+          });
+          return LS.continueLookup(Result.takeError());
+        }
+        assert(Result->size() == 1 &&
+               "Results for more than one library returned");
+        assert(Result->front().size() == LookupSymbols.size() &&
+               "Result has incorrect number of elements");
+
+        // const tpctypes::LookupResult &Syms = Result->front();
+        // size_t SymIdx = 0;
+        auto Syms = Result->front().begin();
+        SymbolNameSet MissingSymbols;
+        SymbolMap NewSyms;
+        for (auto &[Name, Flags] : LookupSymbols) {
+          const auto &Sym = *Syms++;
+          if (Sym && Sym->getAddress())
+            NewSyms[Name] = *Sym;
+          else if (LLVM_UNLIKELY(!Sym &&
+                                 Flags == SymbolLookupFlags::RequiredSymbol))
+            MissingSymbols.insert(Name);
+        }
+
+        LLVM_DEBUG({
+          dbgs() << "ExecutorResolutionGenerator lookup returned " << NewSyms
+                 << "\n";
+        });
+
+        if (NewSyms.empty())
+          return LS.continueLookup(Error::success());
+
+        if (LLVM_UNLIKELY(!MissingSymbols.empty()))
+          return LS.continueLookup(make_error<SymbolsNotFound>(
+              this->EPC.getSymbolStringPool(), std::move(MissingSymbols)));
+
+        LS.continueLookup(JD->define(AbsoluteSymbols(std::move(NewSyms))));
+      });
+
+  return Error::success();
+}
+
+} // end namespace orc
+} // end namespace llvm

diff  --git a/llvm/lib/ExecutionEngine/Orc/LookupAndRecordAddrs.cpp b/llvm/lib/ExecutionEngine/Orc/LookupAndRecordAddrs.cpp
index 78169a28ed63b..42d630d690864 100644
--- a/llvm/lib/ExecutionEngine/Orc/LookupAndRecordAddrs.cpp
+++ b/llvm/lib/ExecutionEngine/Orc/LookupAndRecordAddrs.cpp
@@ -72,9 +72,10 @@ Error lookupAndRecordAddrs(
     return make_error<StringError>("Error in lookup result elements",
                                    inconvertibleErrorCode());
 
-  for (unsigned I = 0; I != Pairs.size(); ++I)
-    *Pairs[I].second = Result->front()[I].getAddress();
-
+  for (unsigned I = 0; I != Pairs.size(); ++I) {
+    if (Result->front()[I])
+      *Pairs[I].second = Result->front()[I]->getAddress();
+  }
   return Error::success();
 }
 

diff  --git a/llvm/lib/ExecutionEngine/Orc/SelfExecutorProcessControl.cpp b/llvm/lib/ExecutionEngine/Orc/SelfExecutorProcessControl.cpp
index 78045f1491f04..f8a2bd36dc10d 100644
--- a/llvm/lib/ExecutionEngine/Orc/SelfExecutorProcessControl.cpp
+++ b/llvm/lib/ExecutionEngine/Orc/SelfExecutorProcessControl.cpp
@@ -91,22 +91,18 @@ void SelfExecutorProcessControl::lookupSymbolsAsync(
 
   for (auto &Elem : Request) {
     sys::DynamicLibrary Dylib(Elem.Handle.toPtr<void *>());
-    R.push_back(std::vector<ExecutorSymbolDef>());
+    R.push_back(tpctypes::LookupResult());
     for (auto &KV : Elem.Symbols) {
       auto &Sym = KV.first;
       std::string Tmp((*Sym).data() + !!GlobalManglingPrefix,
                       (*Sym).size() - !!GlobalManglingPrefix);
       void *Addr = Dylib.getAddressOfSymbol(Tmp.c_str());
-      if (!Addr && KV.second == SymbolLookupFlags::RequiredSymbol) {
-        // FIXME: Collect all failing symbols before erroring out.
-        SymbolNameVector MissingSymbols;
-        MissingSymbols.push_back(Sym);
-        return Complete(
-            make_error<SymbolsNotFound>(SSP, std::move(MissingSymbols)));
-      }
-      // FIXME: determine accurate JITSymbolFlags.
-      R.back().push_back(
-          {ExecutorAddr::fromPtr(Addr), JITSymbolFlags::Exported});
+      if (!Addr && KV.second == SymbolLookupFlags::RequiredSymbol)
+        R.back().emplace_back();
+      else
+        // FIXME: determine accurate JITSymbolFlags.
+        R.back().emplace_back(ExecutorSymbolDef(ExecutorAddr::fromPtr(Addr),
+                                                JITSymbolFlags::Exported));
     }
   }
 

diff  --git a/llvm/lib/ExecutionEngine/Orc/Shared/OrcRTBridge.cpp b/llvm/lib/ExecutionEngine/Orc/Shared/OrcRTBridge.cpp
index 123651fc623e2..26e8f5382da0e 100644
--- a/llvm/lib/ExecutionEngine/Orc/Shared/OrcRTBridge.cpp
+++ b/llvm/lib/ExecutionEngine/Orc/Shared/OrcRTBridge.cpp
@@ -16,8 +16,8 @@ const char *SimpleExecutorDylibManagerInstanceName =
     "__llvm_orc_SimpleExecutorDylibManager_Instance";
 const char *SimpleExecutorDylibManagerOpenWrapperName =
     "__llvm_orc_SimpleExecutorDylibManager_open_wrapper";
-const char *SimpleExecutorDylibManagerLookupWrapperName =
-    "__llvm_orc_SimpleExecutorDylibManager_lookup_wrapper";
+const char *SimpleExecutorDylibManagerResolveWrapperName =
+    "__llvm_orc_SimpleExecutorDylibManager_resolve_wrapper";
 
 const char *SimpleExecutorMemoryManagerInstanceName =
     "__llvm_orc_SimpleExecutorMemoryManager_Instance";

diff  --git a/llvm/lib/ExecutionEngine/Orc/TargetProcess/CMakeLists.txt b/llvm/lib/ExecutionEngine/Orc/TargetProcess/CMakeLists.txt
index 9f3abac156adb..927558649eb4d 100644
--- a/llvm/lib/ExecutionEngine/Orc/TargetProcess/CMakeLists.txt
+++ b/llvm/lib/ExecutionEngine/Orc/TargetProcess/CMakeLists.txt
@@ -15,6 +15,7 @@ endif()
 add_llvm_component_library(LLVMOrcTargetProcess
   ExecutorSharedMemoryMapperService.cpp
   DefaultHostBootstrapValues.cpp
+  ExecutorResolver.cpp
   JITLoaderGDB.cpp
   JITLoaderPerf.cpp
   JITLoaderVTune.cpp

diff  --git a/llvm/lib/ExecutionEngine/Orc/TargetProcess/ExecutorResolver.cpp b/llvm/lib/ExecutionEngine/Orc/TargetProcess/ExecutorResolver.cpp
new file mode 100644
index 0000000000000..6054d8673036a
--- /dev/null
+++ b/llvm/lib/ExecutionEngine/Orc/TargetProcess/ExecutorResolver.cpp
@@ -0,0 +1,47 @@
+
+#include "llvm/ExecutionEngine/Orc/TargetProcess/ExecutorResolver.h"
+
+#include "llvm/Support/DynamicLibrary.h"
+#include "llvm/Support/Error.h"
+
+namespace llvm::orc {
+
+void DylibSymbolResolver::resolveAsync(
+    const RemoteSymbolLookupSet &L,
+    ExecutorResolver::YieldResolveResultFn &&OnResolve) {
+  std::vector<std::optional<ExecutorSymbolDef>> Result;
+  auto DL = sys::DynamicLibrary(Handle.toPtr<void *>());
+
+  for (const auto &E : L) {
+    if (E.Name.empty()) {
+      if (E.Required)
+        OnResolve(
+            make_error<StringError>("Required address for empty symbol \"\"",
+                                    inconvertibleErrorCode()));
+      else
+        Result.emplace_back();
+    } else {
+
+      const char *DemangledSymName = E.Name.c_str();
+#ifdef __APPLE__
+      if (E.Name.front() != '_')
+        OnResolve(make_error<StringError>(Twine("MachO symbol \"") + E.Name +
+                                              "\" missing leading '_'",
+                                          inconvertibleErrorCode()));
+      ++DemangledSymName;
+#endif
+
+      void *Addr = DL.getAddressOfSymbol(DemangledSymName);
+      if (!Addr && E.Required)
+        Result.emplace_back();
+      else
+        // FIXME: determine accurate JITSymbolFlags.
+        Result.emplace_back(ExecutorSymbolDef(ExecutorAddr::fromPtr(Addr),
+                                              JITSymbolFlags::Exported));
+    }
+  }
+
+  OnResolve(std::move(Result));
+}
+
+} // end namespace llvm::orc
\ No newline at end of file

diff  --git a/llvm/lib/ExecutionEngine/Orc/TargetProcess/SimpleExecutorDylibManager.cpp b/llvm/lib/ExecutionEngine/Orc/TargetProcess/SimpleExecutorDylibManager.cpp
index db6f20130db9e..52bb55d209e56 100644
--- a/llvm/lib/ExecutionEngine/Orc/TargetProcess/SimpleExecutorDylibManager.cpp
+++ b/llvm/lib/ExecutionEngine/Orc/TargetProcess/SimpleExecutorDylibManager.cpp
@@ -10,6 +10,10 @@
 
 #include "llvm/ExecutionEngine/Orc/Shared/OrcRTBridge.h"
 
+#include "llvm/Support/MSVCErrorWorkarounds.h"
+
+#include <future>
+
 #define DEBUG_TYPE "orc"
 
 namespace llvm {
@@ -35,46 +39,9 @@ SimpleExecutorDylibManager::open(const std::string &Path, uint64_t Mode) {
 
   std::lock_guard<std::mutex> Lock(M);
   auto H = ExecutorAddr::fromPtr(DL.getOSSpecificHandle());
+  Resolvers.push_back(std::make_unique<DylibSymbolResolver>(H));
   Dylibs.insert(DL.getOSSpecificHandle());
-  return H;
-}
-
-Expected<std::vector<ExecutorSymbolDef>>
-SimpleExecutorDylibManager::lookup(tpctypes::DylibHandle H,
-                                   const RemoteSymbolLookupSet &L) {
-  std::vector<ExecutorSymbolDef> Result;
-  auto DL = sys::DynamicLibrary(H.toPtr<void *>());
-
-  for (const auto &E : L) {
-    if (E.Name.empty()) {
-      if (E.Required)
-        return make_error<StringError>("Required address for empty symbol \"\"",
-                                       inconvertibleErrorCode());
-      else
-        Result.push_back(ExecutorSymbolDef());
-    } else {
-
-      const char *DemangledSymName = E.Name.c_str();
-#ifdef __APPLE__
-      if (E.Name.front() != '_')
-        return make_error<StringError>(Twine("MachO symbol \"") + E.Name +
-                                           "\" missing leading '_'",
-                                       inconvertibleErrorCode());
-      ++DemangledSymName;
-#endif
-
-      void *Addr = DL.getAddressOfSymbol(DemangledSymName);
-      if (!Addr && E.Required)
-        return make_error<StringError>(Twine("Missing definition for ") +
-                                           DemangledSymName,
-                                       inconvertibleErrorCode());
-
-      // FIXME: determine accurate JITSymbolFlags.
-      Result.push_back({ExecutorAddr::fromPtr(Addr), JITSymbolFlags::Exported});
-    }
-  }
-
-  return Result;
+  return ExecutorAddr::fromPtr(Resolvers.back().get());
 }
 
 Error SimpleExecutorDylibManager::shutdown() {
@@ -94,8 +61,8 @@ void SimpleExecutorDylibManager::addBootstrapSymbols(
   M[rt::SimpleExecutorDylibManagerInstanceName] = ExecutorAddr::fromPtr(this);
   M[rt::SimpleExecutorDylibManagerOpenWrapperName] =
       ExecutorAddr::fromPtr(&openWrapper);
-  M[rt::SimpleExecutorDylibManagerLookupWrapperName] =
-      ExecutorAddr::fromPtr(&lookupWrapper);
+  M[rt::SimpleExecutorDylibManagerResolveWrapperName] =
+      ExecutorAddr::fromPtr(&resolveWrapper);
 }
 
 llvm::orc::shared::CWrapperFunctionResult
@@ -109,12 +76,22 @@ SimpleExecutorDylibManager::openWrapper(const char *ArgData, size_t ArgSize) {
 }
 
 llvm::orc::shared::CWrapperFunctionResult
-SimpleExecutorDylibManager::lookupWrapper(const char *ArgData, size_t ArgSize) {
-  return shared::
-      WrapperFunction<rt::SPSSimpleExecutorDylibManagerLookupSignature>::handle(
-             ArgData, ArgSize,
-             shared::makeMethodWrapperHandler(
-                 &SimpleExecutorDylibManager::lookup))
+SimpleExecutorDylibManager::resolveWrapper(const char *ArgData,
+                                           size_t ArgSize) {
+  using ResolveResult = ExecutorResolver::ResolveResult;
+  return shared::WrapperFunction<
+             rt::SPSSimpleExecutorDylibManagerResolveSignature>::
+      handle(ArgData, ArgSize,
+             [](ExecutorAddr Obj, RemoteSymbolLookupSet L) -> ResolveResult {
+               using TmpResult =
+                   MSVCPExpected<std::vector<std::optional<ExecutorSymbolDef>>>;
+               std::promise<TmpResult> P;
+               auto F = P.get_future();
+               Obj.toPtr<ExecutorResolver *>()->resolveAsync(
+                   std::move(L),
+                   [&](TmpResult R) { P.set_value(std::move(R)); });
+               return F.get();
+             })
           .release();
 }
 

diff  --git a/llvm/tools/lli/ForwardingMemoryManager.h b/llvm/tools/lli/ForwardingMemoryManager.h
index e5c10d672ccfb..d193befc0682d 100644
--- a/llvm/tools/lli/ForwardingMemoryManager.h
+++ b/llvm/tools/lli/ForwardingMemoryManager.h
@@ -109,8 +109,11 @@ class RemoteResolver : public LegacyJITSymbolResolver {
       if (Syms->size() != 1)
         return make_error<StringError>("Unexpected remote lookup result",
                                        inconvertibleErrorCode());
-      return JITSymbol(Syms->front().getAddress().getValue(),
-                       Syms->front().getFlags());
+      if (!Syms->front())
+        return make_error<StringError>("Expected valid address",
+                                       inconvertibleErrorCode());
+      return JITSymbol(Syms->front()->getAddress().getValue(),
+                       Syms->front()->getFlags());
     } else
       return Syms.takeError();
   }

diff  --git a/llvm/unittests/ExecutionEngine/Orc/ObjectLinkingLayerTest.cpp b/llvm/unittests/ExecutionEngine/Orc/ObjectLinkingLayerTest.cpp
index 8a6549b1b594e..5ff3e26f35296 100644
--- a/llvm/unittests/ExecutionEngine/Orc/ObjectLinkingLayerTest.cpp
+++ b/llvm/unittests/ExecutionEngine/Orc/ObjectLinkingLayerTest.cpp
@@ -301,7 +301,7 @@ TEST(ObjectLinkingLayerSearchGeneratorTest, AbsoluteSymbolsObjectLayer) {
 
     void lookupSymbolsAsync(ArrayRef<LookupRequest> Request,
                             SymbolLookupCompleteFn Complete) override {
-      std::vector<ExecutorSymbolDef> Result;
+      std::vector<std::optional<ExecutorSymbolDef>> Result;
       EXPECT_EQ(Request.size(), 1u);
       for (auto &LR : Request) {
         EXPECT_EQ(LR.Symbols.size(), 1u);
@@ -309,7 +309,7 @@ TEST(ObjectLinkingLayerSearchGeneratorTest, AbsoluteSymbolsObjectLayer) {
           if (*Sym.first == "_testFunc") {
             ExecutorSymbolDef Def{ExecutorAddr::fromPtr((void *)0x1000),
                                   JITSymbolFlags::Exported};
-            Result.push_back(Def);
+            Result.emplace_back(Def);
           } else {
             ADD_FAILURE() << "unexpected symbol request " << *Sym.first;
           }


        


More information about the llvm-commits mailing list