[ORC] Introduce EPCGenericDylibManager / SimpleExecutorDylibManager.
authorLang Hames <lhames@gmail.com>
Wed, 22 Sep 2021 05:34:46 +0000 (15:34 +1000)
committerLang Hames <lhames@gmail.com>
Fri, 24 Sep 2021 02:59:35 +0000 (19:59 -0700)
EPCGenericDylibManager provides an interface for loading dylibs and looking up
symbols in the executor, implemented using EPC-calls to functions in the
executor.

SimpleExecutorDylibManager is an executor-side service that provides the
functions used by EPCGenericDylibManager.

SimpleRemoteEPC is updated to use an EPCGenericDylibManager instance to
implement the ExecutorProcessControl loadDylib and lookup methods. In a future
commit these methods will be removed, and clients updated to use
EPCGenericDylibManagers directly.

12 files changed:
llvm/include/llvm/ExecutionEngine/Orc/EPCGenericDylibManager.h [new file with mode: 0644]
llvm/include/llvm/ExecutionEngine/Orc/Shared/OrcRTBridge.h
llvm/include/llvm/ExecutionEngine/Orc/SimpleRemoteEPC.h
llvm/include/llvm/ExecutionEngine/Orc/TargetProcess/SimpleExecutorDylibManager.h [new file with mode: 0644]
llvm/include/llvm/ExecutionEngine/Orc/TargetProcess/SimpleRemoteEPCServer.h
llvm/lib/ExecutionEngine/Orc/CMakeLists.txt
llvm/lib/ExecutionEngine/Orc/EPCGenericDylibManager.cpp [new file with mode: 0644]
llvm/lib/ExecutionEngine/Orc/Shared/OrcRTBridge.cpp
llvm/lib/ExecutionEngine/Orc/SimpleRemoteEPC.cpp
llvm/lib/ExecutionEngine/Orc/TargetProcess/CMakeLists.txt
llvm/lib/ExecutionEngine/Orc/TargetProcess/SimpleExecutorDylibManager.cpp [new file with mode: 0644]
llvm/lib/ExecutionEngine/Orc/TargetProcess/SimpleRemoteEPCServer.cpp

diff --git a/llvm/include/llvm/ExecutionEngine/Orc/EPCGenericDylibManager.h b/llvm/include/llvm/ExecutionEngine/Orc/EPCGenericDylibManager.h
new file mode 100644 (file)
index 0000000..89431a6
--- /dev/null
@@ -0,0 +1,67 @@
+//===- EPCGenericDylibManager.h -- Generic EPC Dylib management -*- 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
+//
+//===----------------------------------------------------------------------===//
+//
+// Implements dylib loading and searching by making calls to
+// ExecutorProcessControl::callWrapper.
+//
+// This simplifies the implementaton of new ExecutorProcessControl instances,
+// as this implementation will always work (at the cost of some performance
+// overhead for the calls).
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_EXECUTIONENGINE_ORC_EPCGENERICDYLIBMANAGER_H
+#define LLVM_EXECUTIONENGINE_ORC_EPCGENERICDYLIBMANAGER_H
+
+#include "llvm/ExecutionEngine/Orc/ExecutorProcessControl.h"
+#include "llvm/ExecutionEngine/Orc/Shared/SimpleRemoteEPCUtils.h"
+
+namespace llvm {
+namespace orc {
+
+class SymbolLookupSet;
+
+class EPCGenericDylibManager {
+public:
+  /// Function addresses for memory access.
+  struct SymbolAddrs {
+    ExecutorAddress Instance;
+    ExecutorAddress Open;
+    ExecutorAddress Lookup;
+  };
+
+  /// Create an EPCGenericMemoryAccess instance from a given set of
+  /// function addrs.
+  static Expected<EPCGenericDylibManager>
+  CreateWithDefaultBootstrapSymbols(ExecutorProcessControl &EPC);
+
+  /// Create an EPCGenericMemoryAccess instance from a given set of
+  /// function addrs.
+  EPCGenericDylibManager(ExecutorProcessControl &EPC, SymbolAddrs SAs)
+      : EPC(EPC), SAs(SAs) {}
+
+  /// Loads the dylib with the given name.
+  Expected<tpctypes::DylibHandle> open(StringRef Path, uint64_t Mode);
+
+  /// Looks up symbols within the given dylib.
+  Expected<std::vector<ExecutorAddress>> lookup(tpctypes::DylibHandle H,
+                                                const SymbolLookupSet &Lookup);
+
+  /// Looks up symbols within the given dylib.
+  Expected<std::vector<ExecutorAddress>>
+  lookup(tpctypes::DylibHandle H, const RemoteSymbolLookupSet &Lookup);
+
+private:
+  ExecutorProcessControl &EPC;
+  SymbolAddrs SAs;
+};
+
+} // end namespace orc
+} // end namespace llvm
+
+#endif // LLVM_EXECUTIONENGINE_ORC_EPCGENERICDYLIBMANAGER_H
index 54db1f7..69a9bd8 100644 (file)
 
 #include "llvm/ADT/StringMap.h"
 #include "llvm/ExecutionEngine/Orc/Shared/ExecutorAddress.h"
+#include "llvm/ExecutionEngine/Orc/Shared/SimpleRemoteEPCUtils.h"
 #include "llvm/ExecutionEngine/Orc/Shared/TargetProcessControlTypes.h"
 
 namespace llvm {
 namespace orc {
 namespace rt {
 
+extern const char *SimpleExecutorDylibManagerInstanceName;
+extern const char *SimpleExecutorDylibManagerOpenWrapperName;
+extern const char *SimpleExecutorDylibManagerLookupWrapperName;
+
 extern const char *SimpleExecutorMemoryManagerInstanceName;
 extern const char *SimpleExecutorMemoryManagerReserveWrapperName;
 extern const char *SimpleExecutorMemoryManagerFinalizeWrapperName;
@@ -31,8 +36,17 @@ extern const char *MemoryWriteUInt16sWrapperName;
 extern const char *MemoryWriteUInt32sWrapperName;
 extern const char *MemoryWriteUInt64sWrapperName;
 extern const char *MemoryWriteBuffersWrapperName;
+
 extern const char *RunAsMainWrapperName;
 
+using SPSSimpleExecutorDylibManagerOpenSignature =
+    shared::SPSExpected<uint64_t>(shared::SPSExecutorAddress, shared::SPSString,
+                                  uint64_t);
+
+using SPSSimpleExecutorDylibManagerLookupSignature =
+    shared::SPSExpected<shared::SPSSequence<shared::SPSExecutorAddress>>(
+        shared::SPSExecutorAddress, uint64_t, shared::SPSRemoteSymbolLookupSet);
+
 using SPSSimpleExecutorMemoryManagerReserveSignature =
     shared::SPSExpected<shared::SPSExecutorAddress>(shared::SPSExecutorAddress,
                                                     uint64_t);
index 29d43be..91cc5d2 100644 (file)
@@ -15,6 +15,8 @@
 
 #include "llvm/ADT/DenseMap.h"
 #include "llvm/ADT/FunctionExtras.h"
+#include "llvm/ExecutionEngine/Orc/EPCGenericDylibManager.h"
+#include "llvm/ExecutionEngine/Orc/EPCGenericJITLinkMemoryManager.h"
 #include "llvm/ExecutionEngine/Orc/EPCGenericMemoryAccess.h"
 #include "llvm/ExecutionEngine/Orc/ExecutorProcessControl.h"
 #include "llvm/ExecutionEngine/Orc/Shared/SimpleRemoteEPCUtils.h"
@@ -113,8 +115,7 @@ private:
   std::unique_ptr<jitlink::JITLinkMemoryManager> OwnedMemMgr;
   std::unique_ptr<MemoryAccess> OwnedMemAccess;
 
-  ExecutorAddress LoadDylibAddr;
-  ExecutorAddress LookupSymbolsAddr;
+  std::unique_ptr<EPCGenericDylibManager> DylibMgr;
   ExecutorAddress RunAsMainAddr;
 
   uint64_t NextSeqNo = 0;
diff --git a/llvm/include/llvm/ExecutionEngine/Orc/TargetProcess/SimpleExecutorDylibManager.h b/llvm/include/llvm/ExecutionEngine/Orc/TargetProcess/SimpleExecutorDylibManager.h
new file mode 100644 (file)
index 0000000..173e2ce
--- /dev/null
@@ -0,0 +1,64 @@
+//===--------------- SimpleExecutorDylibManager.h ---------------*- 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
+//
+//===----------------------------------------------------------------------===//
+//
+// A simple dynamic library management class. Allows dynamic libraries to be
+// loaded and searched.
+//
+// FIXME: The functionality in this file should be moved to the ORC runtime.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_EXECUTIONENGINE_ORC_TARGETPROCESS_SIMPLEEXECUTORDYLIBMANAGER_H
+#define LLVM_EXECUTIONENGINE_ORC_TARGETPROCESS_SIMPLEEXECUTORDYLIBMANAGER_H
+
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ExecutionEngine/Orc/Shared/ExecutorAddress.h"
+#include "llvm/ExecutionEngine/Orc/Shared/SimpleRemoteEPCUtils.h"
+#include "llvm/ExecutionEngine/Orc/Shared/TargetProcessControlTypes.h"
+#include "llvm/ExecutionEngine/Orc/Shared/WrapperFunctionUtils.h"
+#include "llvm/ExecutionEngine/Orc/TargetProcess/ExecutorBootstrapService.h"
+#include "llvm/Support/DynamicLibrary.h"
+#include "llvm/Support/Error.h"
+
+#include <mutex>
+
+namespace llvm {
+namespace orc {
+namespace rt_bootstrap {
+
+/// Simple page-based allocator.
+class SimpleExecutorDylibManager : public ExecutorBootstrapService {
+public:
+  virtual ~SimpleExecutorDylibManager();
+
+  Expected<tpctypes::DylibHandle> open(const std::string &Path, uint64_t Mode);
+  Expected<std::vector<ExecutorAddress>> lookup(tpctypes::DylibHandle H,
+                                                const RemoteSymbolLookupSet &L);
+
+  Error shutdown() override;
+  void addBootstrapSymbols(StringMap<ExecutorAddress> &M) override;
+
+private:
+  using DylibsMap = DenseMap<uint64_t, sys::DynamicLibrary>;
+
+  static llvm::orc::shared::detail::CWrapperFunctionResult
+  openWrapper(const char *ArgData, size_t ArgSize);
+
+  static llvm::orc::shared::detail::CWrapperFunctionResult
+  lookupWrapper(const char *ArgData, size_t ArgSize);
+
+  std::mutex M;
+  uint64_t NextId = 0;
+  DylibsMap Dylibs;
+};
+
+} // end namespace rt_bootstrap
+} // end namespace orc
+} // end namespace llvm
+
+#endif // LLVM_EXECUTIONENGINE_ORC_TARGETPROCESS_SIMPLEEXECUTORDYLIBMANAGER_H
index 083ed64..d52c528 100644 (file)
@@ -20,6 +20,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/SimpleExecutorDylibManager.h"
 #include "llvm/Support/DynamicLibrary.h"
 #include "llvm/Support/Error.h"
 
@@ -106,6 +107,8 @@ public:
 
     // If transport creation succeeds then start up services.
     Server->Services = std::move(S.services());
+    Server->Services.push_back(
+        std::make_unique<rt_bootstrap::SimpleExecutorDylibManager>());
     for (auto &Service : Server->Services)
       Service->addBootstrapSymbols(S.bootstrapSymbols());
 
@@ -141,18 +144,6 @@ private:
   void handleCallWrapper(uint64_t RemoteSeqNo, ExecutorAddress TagAddr,
                          SimpleRemoteEPCArgBytesVector ArgBytes);
 
-  static shared::detail::CWrapperFunctionResult
-  loadDylibWrapper(const char *ArgData, size_t ArgSize);
-
-  static shared::detail::CWrapperFunctionResult
-  lookupSymbolsWrapper(const char *ArgData, size_t ArgSize);
-
-  Expected<tpctypes::DylibHandle> loadDylib(const std::string &Path,
-                                            uint64_t Mode);
-
-  Expected<std::vector<std::vector<ExecutorAddress>>>
-  lookupSymbols(const std::vector<RemoteSymbolLookup> &L);
-
   shared::WrapperFunctionResult
   doJITDispatch(const void *FnTag, const char *ArgData, size_t ArgSize);
 
index 8e8e0d3..cce5077 100644 (file)
@@ -7,6 +7,7 @@ add_llvm_component_library(LLVMOrcJIT
   EPCDynamicLibrarySearchGenerator.cpp
   EPCDebugObjectRegistrar.cpp
   EPCEHFrameRegistrar.cpp
+  EPCGenericDylibManager.cpp
   EPCGenericJITLinkMemoryManager.cpp
   EPCIndirectionUtils.cpp
   ExecutionUtils.cpp
diff --git a/llvm/lib/ExecutionEngine/Orc/EPCGenericDylibManager.cpp b/llvm/lib/ExecutionEngine/Orc/EPCGenericDylibManager.cpp
new file mode 100644 (file)
index 0000000..dcdc84e
--- /dev/null
@@ -0,0 +1,109 @@
+//===------- EPCGenericDylibManager.cpp -- Dylib management via EPC -------===//
+//
+// 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/EPCGenericDylibManager.h"
+
+#include "llvm/ExecutionEngine/Orc/Core.h"
+#include "llvm/ExecutionEngine/Orc/Shared/OrcRTBridge.h"
+#include "llvm/ExecutionEngine/Orc/Shared/SimpleRemoteEPCUtils.h"
+
+namespace llvm {
+namespace orc {
+namespace shared {
+
+template <>
+class SPSSerializationTraits<SPSRemoteSymbolLookupSetElement,
+                             SymbolLookupSet::value_type> {
+public:
+  static size_t size(const SymbolLookupSet::value_type &V) {
+    return SPSArgList<SPSString, bool>::size(
+        *V.first, V.second == SymbolLookupFlags::RequiredSymbol);
+  }
+
+  static bool serialize(SPSOutputBuffer &OB,
+                        const SymbolLookupSet::value_type &V) {
+    return SPSArgList<SPSString, bool>::serialize(
+        OB, *V.first, V.second == SymbolLookupFlags::RequiredSymbol);
+  }
+};
+
+template <>
+class TrivialSPSSequenceSerialization<SPSRemoteSymbolLookupSetElement,
+                                      SymbolLookupSet> {
+public:
+  static constexpr bool available = true;
+};
+
+template <>
+class SPSSerializationTraits<SPSRemoteSymbolLookup,
+                             ExecutorProcessControl::LookupRequest> {
+  using MemberSerialization =
+      SPSArgList<SPSExecutorAddress, SPSRemoteSymbolLookupSet>;
+
+public:
+  static size_t size(const ExecutorProcessControl::LookupRequest &LR) {
+    return MemberSerialization::size(ExecutorAddress(LR.Handle), LR.Symbols);
+  }
+
+  static bool serialize(SPSOutputBuffer &OB,
+                        const ExecutorProcessControl::LookupRequest &LR) {
+    return MemberSerialization::serialize(OB, ExecutorAddress(LR.Handle),
+                                          LR.Symbols);
+  }
+};
+
+} // end namespace shared
+
+Expected<EPCGenericDylibManager>
+EPCGenericDylibManager::CreateWithDefaultBootstrapSymbols(
+    ExecutorProcessControl &EPC) {
+  SymbolAddrs SAs;
+  if (auto Err = EPC.getBootstrapSymbols(
+          {{SAs.Instance, rt::SimpleExecutorDylibManagerInstanceName},
+           {SAs.Open, rt::SimpleExecutorDylibManagerOpenWrapperName},
+           {SAs.Lookup, rt::SimpleExecutorDylibManagerLookupWrapperName}}))
+    return std::move(Err);
+  return EPCGenericDylibManager(EPC, std::move(SAs));
+}
+
+Expected<tpctypes::DylibHandle> EPCGenericDylibManager::open(StringRef Path,
+                                                             uint64_t Mode) {
+  Expected<tpctypes::DylibHandle> H(0);
+  if (auto Err =
+          EPC.callSPSWrapper<rt::SPSSimpleExecutorDylibManagerOpenSignature>(
+              SAs.Open.getValue(), H, SAs.Instance, Path, Mode))
+    return std::move(Err);
+  return H;
+}
+
+Expected<std::vector<ExecutorAddress>>
+EPCGenericDylibManager::lookup(tpctypes::DylibHandle H,
+                               const SymbolLookupSet &Lookup) {
+  Expected<std::vector<ExecutorAddress>> Result(
+      (std::vector<ExecutorAddress>()));
+  if (auto Err =
+          EPC.callSPSWrapper<rt::SPSSimpleExecutorDylibManagerLookupSignature>(
+              SAs.Lookup.getValue(), Result, SAs.Instance, H, Lookup))
+    return std::move(Err);
+  return Result;
+}
+
+Expected<std::vector<ExecutorAddress>>
+EPCGenericDylibManager::lookup(tpctypes::DylibHandle H,
+                               const RemoteSymbolLookupSet &Lookup) {
+  Expected<std::vector<ExecutorAddress>> Result(
+      (std::vector<ExecutorAddress>()));
+  if (auto Err =
+          EPC.callSPSWrapper<rt::SPSSimpleExecutorDylibManagerLookupSignature>(
+              SAs.Lookup.getValue(), Result, SAs.Instance, H, Lookup))
+    return std::move(Err);
+  return Result;
+}
+
+} // end namespace orc
+} // end namespace llvm
index 0927fce..6c3032c 100644 (file)
@@ -12,6 +12,12 @@ namespace llvm {
 namespace orc {
 namespace rt {
 
+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 *SimpleExecutorMemoryManagerInstanceName =
     "__llvm_orc_SimpleExecutorMemoryManager_Instance";
 const char *SimpleExecutorMemoryManagerReserveWrapperName =
index c720f9d..e5c3391 100644 (file)
 
 namespace llvm {
 namespace orc {
-namespace shared {
-
-template <>
-class SPSSerializationTraits<SPSRemoteSymbolLookupSetElement,
-                             SymbolLookupSet::value_type> {
-public:
-  static size_t size(const SymbolLookupSet::value_type &V) {
-    return SPSArgList<SPSString, bool>::size(
-        *V.first, V.second == SymbolLookupFlags::RequiredSymbol);
-  }
-
-  static bool serialize(SPSOutputBuffer &OB,
-                        const SymbolLookupSet::value_type &V) {
-    return SPSArgList<SPSString, bool>::serialize(
-        OB, *V.first, V.second == SymbolLookupFlags::RequiredSymbol);
-  }
-};
-
-template <>
-class TrivialSPSSequenceSerialization<SPSRemoteSymbolLookupSetElement,
-                                      SymbolLookupSet> {
-public:
-  static constexpr bool available = true;
-};
-
-template <>
-class SPSSerializationTraits<SPSRemoteSymbolLookup,
-                             ExecutorProcessControl::LookupRequest> {
-  using MemberSerialization =
-      SPSArgList<SPSExecutorAddress, SPSRemoteSymbolLookupSet>;
-
-public:
-  static size_t size(const ExecutorProcessControl::LookupRequest &LR) {
-    return MemberSerialization::size(ExecutorAddress(LR.Handle), LR.Symbols);
-  }
-
-  static bool serialize(SPSOutputBuffer &OB,
-                        const ExecutorProcessControl::LookupRequest &LR) {
-    return MemberSerialization::serialize(OB, ExecutorAddress(LR.Handle),
-                                          LR.Symbols);
-  }
-};
-
-} // end namespace shared
 
 SimpleRemoteEPC::~SimpleRemoteEPC() {
   assert(Disconnected && "Destroyed without disconnection");
@@ -67,24 +23,23 @@ SimpleRemoteEPC::~SimpleRemoteEPC() {
 
 Expected<tpctypes::DylibHandle>
 SimpleRemoteEPC::loadDylib(const char *DylibPath) {
-  Expected<tpctypes::DylibHandle> H((tpctypes::DylibHandle()));
-  if (auto Err = callSPSWrapper<shared::SPSLoadDylibSignature>(
-          LoadDylibAddr.getValue(), H, JDI.JITDispatchContextAddress,
-          StringRef(DylibPath), (uint64_t)0))
-    return std::move(Err);
-  return H;
+  return DylibMgr->open(DylibPath, 0);
 }
 
 Expected<std::vector<tpctypes::LookupResult>>
 SimpleRemoteEPC::lookupSymbols(ArrayRef<LookupRequest> Request) {
-  Expected<std::vector<tpctypes::LookupResult>> R(
-      (std::vector<tpctypes::LookupResult>()));
-
-  if (auto Err = callSPSWrapper<shared::SPSLookupSymbolsSignature>(
-          LookupSymbolsAddr.getValue(), R, JDI.JITDispatchContextAddress,
-          Request))
-    return std::move(Err);
-  return R;
+  std::vector<tpctypes::LookupResult> Result;
+
+  for (auto &Element : Request) {
+    if (auto R = DylibMgr->lookup(Element.Handle, Element.Symbols)) {
+      Result.push_back({});
+      Result.back().reserve(R->size());
+      for (auto Addr : *R)
+        Result.back().push_back(Addr.getValue());
+    } else
+      return R.takeError();
+  }
+  return std::move(Result);
 }
 
 Expected<int32_t> SimpleRemoteEPC::runAsMain(JITTargetAddress MainFnAddr,
@@ -253,11 +208,15 @@ Error SimpleRemoteEPC::setup(std::unique_ptr<SimpleRemoteEPCTransport> T,
   if (auto Err = getBootstrapSymbols(
           {{JDI.JITDispatchContextAddress, ExecutorSessionObjectName},
            {JDI.JITDispatchFunctionAddress, DispatchFnName},
-           {LoadDylibAddr, "__llvm_orc_load_dylib"},
-           {LookupSymbolsAddr, "__llvm_orc_lookup_symbols"},
            {RunAsMainAddr, rt::RunAsMainWrapperName}}))
     return Err;
 
+  if (auto DM =
+          EPCGenericDylibManager::CreateWithDefaultBootstrapSymbols(*this))
+    DylibMgr = std::make_unique<EPCGenericDylibManager>(std::move(*DM));
+  else
+    return DM.takeError();
+
   if (auto MemMgr = createMemoryManager()) {
     OwnedMemMgr = std::move(*MemMgr);
     this->MemMgr = OwnedMemMgr.get();
index 6bed786..c4edece 100644 (file)
@@ -2,6 +2,7 @@ add_llvm_component_library(LLVMOrcTargetProcess
   JITLoaderGDB.cpp
   OrcRTBootstrap.cpp
   RegisterEHFrames.cpp
+  SimpleExecutorDylibManager.cpp
   SimpleExecutorMemoryManager.cpp
   SimpleRemoteEPCServer.cpp
   TargetExecutionUtils.cpp
diff --git a/llvm/lib/ExecutionEngine/Orc/TargetProcess/SimpleExecutorDylibManager.cpp b/llvm/lib/ExecutionEngine/Orc/TargetProcess/SimpleExecutorDylibManager.cpp
new file mode 100644 (file)
index 0000000..241934c
--- /dev/null
@@ -0,0 +1,130 @@
+//===--- SimpleExecutorDylibManager.cpp - Executor-side dylib management --===//
+//
+// 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/TargetProcess/SimpleExecutorDylibManager.h"
+
+#include "llvm/ExecutionEngine/Orc/Shared/OrcRTBridge.h"
+#include "llvm/Support/FormatVariadic.h"
+
+#define DEBUG_TYPE "orc"
+
+namespace llvm {
+namespace orc {
+namespace rt_bootstrap {
+
+SimpleExecutorDylibManager::~SimpleExecutorDylibManager() {
+  assert(Dylibs.empty() && "shutdown not called?");
+}
+
+Expected<tpctypes::DylibHandle>
+SimpleExecutorDylibManager::open(const std::string &Path, uint64_t Mode) {
+  if (Mode != 0)
+    return make_error<StringError>("open: non-zero mode bits not yet supported",
+                                   inconvertibleErrorCode());
+
+  const char *PathCStr = Path.empty() ? nullptr : Path.c_str();
+  std::string ErrMsg;
+
+  auto DL = sys::DynamicLibrary::getPermanentLibrary(PathCStr, &ErrMsg);
+  if (!DL.isValid())
+    return make_error<StringError>(std::move(ErrMsg), inconvertibleErrorCode());
+
+  std::lock_guard<std::mutex> Lock(M);
+  Dylibs[NextId] = std::move(DL);
+  return NextId++;
+}
+
+Expected<std::vector<ExecutorAddress>>
+SimpleExecutorDylibManager::lookup(tpctypes::DylibHandle H,
+                                   const RemoteSymbolLookupSet &L) {
+  std::vector<ExecutorAddress> Result;
+
+  std::lock_guard<std::mutex> Lock(M);
+  auto I = Dylibs.find(H);
+  if (I == Dylibs.end())
+    return make_error<StringError>("No dylib for handle " + formatv("{0:x}", H),
+                                   inconvertibleErrorCode());
+  auto &DL = I->second;
+
+  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(ExecutorAddress());
+    } 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());
+
+      Result.push_back(ExecutorAddress::fromPtr(Addr));
+    }
+  }
+
+  return Result;
+}
+
+Error SimpleExecutorDylibManager::shutdown() {
+
+  DylibsMap DM;
+  {
+    std::lock_guard<std::mutex> Lock(M);
+    std::swap(DM, Dylibs);
+  }
+
+  // There is no removal of dylibs at the moment, so nothing to do here.
+  return Error::success();
+}
+
+void SimpleExecutorDylibManager::addBootstrapSymbols(
+    StringMap<ExecutorAddress> &M) {
+  M[rt::SimpleExecutorDylibManagerInstanceName] =
+      ExecutorAddress::fromPtr(this);
+  M[rt::SimpleExecutorDylibManagerOpenWrapperName] =
+      ExecutorAddress::fromPtr(&openWrapper);
+  M[rt::SimpleExecutorDylibManagerLookupWrapperName] =
+      ExecutorAddress::fromPtr(&lookupWrapper);
+}
+
+llvm::orc::shared::detail::CWrapperFunctionResult
+SimpleExecutorDylibManager::openWrapper(const char *ArgData, size_t ArgSize) {
+  return shared::
+      WrapperFunction<rt::SPSSimpleExecutorDylibManagerOpenSignature>::handle(
+             ArgData, ArgSize,
+             shared::makeMethodWrapperHandler(
+                 &SimpleExecutorDylibManager::open))
+          .release();
+}
+
+llvm::orc::shared::detail::CWrapperFunctionResult
+SimpleExecutorDylibManager::lookupWrapper(const char *ArgData, size_t ArgSize) {
+  return shared::
+      WrapperFunction<rt::SPSSimpleExecutorDylibManagerLookupSignature>::handle(
+             ArgData, ArgSize,
+             shared::makeMethodWrapperHandler(
+                 &SimpleExecutorDylibManager::lookup))
+          .release();
+}
+
+} // namespace rt_bootstrap
+} // end namespace orc
+} // end namespace llvm
index aa35263..30c9e0f 100644 (file)
@@ -54,9 +54,6 @@ void SimpleRemoteEPCServer::ThreadDispatcher::shutdown() {
 StringMap<ExecutorAddress> SimpleRemoteEPCServer::defaultBootstrapSymbols() {
   StringMap<ExecutorAddress> DBS;
   rt_bootstrap::addTo(DBS);
-  DBS["__llvm_orc_load_dylib"] = ExecutorAddress::fromPtr(&loadDylibWrapper);
-  DBS["__llvm_orc_lookup_symbols"] =
-      ExecutorAddress::fromPtr(&lookupSymbolsWrapper);
   return DBS;
 }
 
@@ -199,76 +196,6 @@ void SimpleRemoteEPCServer::handleCallWrapper(
   });
 }
 
-shared::detail::CWrapperFunctionResult
-SimpleRemoteEPCServer::loadDylibWrapper(const char *ArgData, size_t ArgSize) {
-  return shared::WrapperFunction<shared::SPSLoadDylibSignature>::handle(
-             ArgData, ArgSize,
-             [](ExecutorAddress ExecutorSessionObj, std::string Path,
-                uint64_t Flags) -> Expected<uint64_t> {
-               return ExecutorSessionObj.toPtr<SimpleRemoteEPCServer *>()
-                   ->loadDylib(Path, Flags);
-             })
-      .release();
-}
-
-shared::detail::CWrapperFunctionResult
-SimpleRemoteEPCServer::lookupSymbolsWrapper(const char *ArgData,
-                                            size_t ArgSize) {
-  return shared::WrapperFunction<shared::SPSLookupSymbolsSignature>::handle(
-             ArgData, ArgSize,
-             [](ExecutorAddress ExecutorSessionObj,
-                std::vector<RemoteSymbolLookup> Lookup) {
-               return ExecutorSessionObj.toPtr<SimpleRemoteEPCServer *>()
-                   ->lookupSymbols(Lookup);
-             })
-      .release();
-}
-
-Expected<tpctypes::DylibHandle>
-SimpleRemoteEPCServer::loadDylib(const std::string &Path, uint64_t Mode) {
-  std::string ErrMsg;
-  const char *P = Path.empty() ? nullptr : Path.c_str();
-  auto DL = sys::DynamicLibrary::getPermanentLibrary(P, &ErrMsg);
-  if (!DL.isValid())
-    return make_error<StringError>(std::move(ErrMsg), inconvertibleErrorCode());
-  std::lock_guard<std::mutex> Lock(ServerStateMutex);
-  uint64_t Id = Dylibs.size();
-  Dylibs.push_back(std::move(DL));
-  return Id;
-}
-
-Expected<std::vector<std::vector<ExecutorAddress>>>
-SimpleRemoteEPCServer::lookupSymbols(const std::vector<RemoteSymbolLookup> &L) {
-  std::vector<std::vector<ExecutorAddress>> Result;
-
-  for (const auto &E : L) {
-    if (E.H >= Dylibs.size())
-      return make_error<StringError>("Unrecognized handle",
-                                     inconvertibleErrorCode());
-    auto &DL = Dylibs[E.H];
-    Result.push_back({});
-
-    for (const auto &Sym : E.Symbols) {
-
-      const char *DemangledSymName = Sym.Name.c_str();
-#ifdef __APPLE__
-      if (*DemangledSymName == '_')
-        ++DemangledSymName;
-#endif
-
-      void *Addr = DL.getAddressOfSymbol(DemangledSymName);
-      if (!Addr && Sym.Required)
-        return make_error<StringError>(Twine("Missing definition for ") +
-                                           DemangledSymName,
-                                       inconvertibleErrorCode());
-
-      Result.back().push_back(ExecutorAddress::fromPtr(Addr));
-    }
-  }
-
-  return std::move(Result);
-}
-
 shared::WrapperFunctionResult
 SimpleRemoteEPCServer::doJITDispatch(const void *FnTag, const char *ArgData,
                                      size_t ArgSize) {