[llvm] 6498b0e - Reintroduce "[ORC] Introduce EPCGenericRTDyldMemoryManager."

Lang Hames via llvm-commits llvm-commits at lists.llvm.org
Sun Sep 26 10:25:07 PDT 2021


Author: Lang Hames
Date: 2021-09-27T03:24:33+10:00
New Revision: 6498b0e991babe71e69ab02e1afa7f5535f2be0f

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

LOG: Reintroduce "[ORC] Introduce EPCGenericRTDyldMemoryManager."

This reintroduces "[ORC] Introduce EPCGenericRTDyldMemoryManager."
(bef55a2b47a938ef35cbd7b61a1e5fa74e68c9ed) and "[lli] Add ChildTarget dependence
on OrcTargetProcess library." (7a219d801bf2c3006482cf3cbd3170b3b4ea2e1b) which were
reverted in 99951a56842d8e4cd0706cd17a04f77b5d0f6dd0 due to bot failures.

The root cause of the bot failures should be fixed by "[ORC] Fix uninitialized
variable." (0371049277912afc201da721fa659ecef7ab7fba) and "[ORC] Wait for
handleDisconnect to complete in SimpleRemoteEPC::disconnect."
(320832cc9b7e7fea5fc8afbed75c34c4a43287ba).

Added: 
    llvm/include/llvm/ExecutionEngine/Orc/EPCGenericRTDyldMemoryManager.h
    llvm/lib/ExecutionEngine/Orc/EPCGenericRTDyldMemoryManager.cpp
    llvm/tools/lli/ForwardingMemoryManager.h

Modified: 
    llvm/include/llvm/ExecutionEngine/Orc/Shared/OrcRTBridge.h
    llvm/include/llvm/ExecutionEngine/Orc/TargetProcess/RegisterEHFrames.h
    llvm/lib/ExecutionEngine/Orc/CMakeLists.txt
    llvm/lib/ExecutionEngine/Orc/Shared/OrcRTBridge.cpp
    llvm/lib/ExecutionEngine/Orc/TargetProcess/OrcRTBootstrap.cpp
    llvm/lib/ExecutionEngine/Orc/TargetProcess/RegisterEHFrames.cpp
    llvm/lib/ExecutionEngine/Orc/TargetProcess/SimpleExecutorMemoryManager.cpp
    llvm/tools/lli/ChildTarget/CMakeLists.txt
    llvm/tools/lli/ChildTarget/ChildTarget.cpp
    llvm/tools/lli/lli.cpp

Removed: 
    llvm/tools/lli/RemoteJITUtils.h


################################################################################
diff  --git a/llvm/include/llvm/ExecutionEngine/Orc/EPCGenericRTDyldMemoryManager.h b/llvm/include/llvm/ExecutionEngine/Orc/EPCGenericRTDyldMemoryManager.h
new file mode 100644
index 000000000000..b6fdfb92ced3
--- /dev/null
+++ b/llvm/include/llvm/ExecutionEngine/Orc/EPCGenericRTDyldMemoryManager.h
@@ -0,0 +1,133 @@
+//===---- EPCGenericRTDyldMemoryManager.h - EPC-based MemMgr ----*- 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
+//
+//===----------------------------------------------------------------------===//
+//
+// Defines a RuntimeDyld::MemoryManager that uses EPC and the ORC runtime
+// bootstrap functions.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_EXECUTIONENGINE_ORC_EPCGENERICRTDYLDMEMORYMANAGER_H
+#define LLVM_EXECUTIONENGINE_ORC_EPCGENERICRTDYLDMEMORYMANAGER_H
+
+#include "llvm/ExecutionEngine/Orc/ExecutorProcessControl.h"
+#include "llvm/ExecutionEngine/RuntimeDyld.h"
+
+#define DEBUG_TYPE "orc"
+
+namespace llvm {
+namespace orc {
+
+/// Remote-mapped RuntimeDyld-compatible memory manager.
+class EPCGenericRTDyldMemoryManager : public RuntimeDyld::MemoryManager {
+public:
+  /// Symbol addresses for memory access.
+  struct SymbolAddrs {
+    ExecutorAddr Instance;
+    ExecutorAddr Reserve;
+    ExecutorAddr Finalize;
+    ExecutorAddr Deallocate;
+    ExecutorAddr RegisterEHFrame;
+    ExecutorAddr DeregisterEHFrame;
+  };
+
+  /// Create an EPCGenericRTDyldMemoryManager using the given EPC, looking up
+  /// the default symbol names in the bootstrap symbol set.
+  static Expected<std::unique_ptr<EPCGenericRTDyldMemoryManager>>
+  CreateWithDefaultBootstrapSymbols(ExecutorProcessControl &EPC);
+
+  /// Create an EPCGenericRTDyldMemoryManager using the given EPC and symbol
+  /// addrs.
+  EPCGenericRTDyldMemoryManager(ExecutorProcessControl &EPC, SymbolAddrs SAs);
+
+  EPCGenericRTDyldMemoryManager(const EPCGenericRTDyldMemoryManager &) = delete;
+  EPCGenericRTDyldMemoryManager &
+  operator=(const EPCGenericRTDyldMemoryManager &) = delete;
+  EPCGenericRTDyldMemoryManager(EPCGenericRTDyldMemoryManager &&) = delete;
+  EPCGenericRTDyldMemoryManager &
+  operator=(EPCGenericRTDyldMemoryManager &&) = delete;
+  ~EPCGenericRTDyldMemoryManager();
+
+  uint8_t *allocateCodeSection(uintptr_t Size, unsigned Alignment,
+                               unsigned SectionID,
+                               StringRef SectionName) override;
+
+  uint8_t *allocateDataSection(uintptr_t Size, unsigned Alignment,
+                               unsigned SectionID, StringRef SectionName,
+                               bool IsReadOnly) override;
+
+  void reserveAllocationSpace(uintptr_t CodeSize, uint32_t CodeAlign,
+                              uintptr_t RODataSize, uint32_t RODataAlign,
+                              uintptr_t RWDataSize,
+                              uint32_t RWDataAlign) override;
+
+  bool needsToReserveAllocationSpace() override;
+
+  void registerEHFrames(uint8_t *Addr, uint64_t LoadAddr, size_t Size) override;
+
+  void deregisterEHFrames() override;
+
+  void notifyObjectLoaded(RuntimeDyld &Dyld,
+                          const object::ObjectFile &Obj) override;
+
+  bool finalizeMemory(std::string *ErrMsg = nullptr) override;
+
+private:
+  struct Alloc {
+  public:
+    Alloc(uint64_t Size, unsigned Align)
+        : Size(Size), Align(Align),
+          Contents(std::make_unique<uint8_t[]>(Size + Align - 1)) {}
+
+    uint64_t Size;
+    unsigned Align;
+    std::unique_ptr<uint8_t[]> Contents;
+    ExecutorAddr RemoteAddr;
+  };
+
+  struct EHFrame {
+    ExecutorAddr Addr;
+    uint64_t Size;
+  };
+
+  // Group of section allocations to be allocated together in the executor. The
+  // RemoteCodeAddr will stand in as the id of the group for deallocation
+  // purposes.
+  struct AllocGroup {
+    AllocGroup() = default;
+    AllocGroup(const AllocGroup &) = delete;
+    AllocGroup &operator=(const AllocGroup &) = delete;
+    AllocGroup(AllocGroup &&) = default;
+    AllocGroup &operator=(AllocGroup &&) = default;
+
+    ExecutorAddrRange RemoteCode;
+    ExecutorAddrRange RemoteROData;
+    ExecutorAddrRange RemoteRWData;
+    std::vector<EHFrame> UnfinalizedEHFrames;
+    std::vector<Alloc> CodeAllocs, RODataAllocs, RWDataAllocs;
+  };
+
+  // Maps all allocations in Allocs to aligned blocks
+  void mapAllocsToRemoteAddrs(RuntimeDyld &Dyld, std::vector<Alloc> &Allocs,
+                              ExecutorAddr NextAddr);
+
+  ExecutorProcessControl &EPC;
+  SymbolAddrs SAs;
+
+  std::mutex M;
+  std::vector<AllocGroup> Unmapped;
+  std::vector<AllocGroup> Unfinalized;
+  std::vector<ExecutorAddr> FinalizedAllocs;
+  std::string ErrMsg;
+};
+
+} // end namespace orc
+} // end namespace llvm
+
+#undef DEBUG_TYPE
+
+#endif // LLVM_EXECUTIONENGINE_ORC_EPCGENERICRTDYLDMEMORYMANAGER_H

diff  --git a/llvm/include/llvm/ExecutionEngine/Orc/Shared/OrcRTBridge.h b/llvm/include/llvm/ExecutionEngine/Orc/Shared/OrcRTBridge.h
index a33990464a6f..3ef43f33d84c 100644
--- a/llvm/include/llvm/ExecutionEngine/Orc/Shared/OrcRTBridge.h
+++ b/llvm/include/llvm/ExecutionEngine/Orc/Shared/OrcRTBridge.h
@@ -37,6 +37,9 @@ extern const char *MemoryWriteUInt32sWrapperName;
 extern const char *MemoryWriteUInt64sWrapperName;
 extern const char *MemoryWriteBuffersWrapperName;
 
+extern const char *RegisterEHFrameSectionCustomDirectWrapperName;
+extern const char *DeregisterEHFrameSectionCustomDirectWrapperName;
+
 extern const char *RunAsMainWrapperName;
 
 using SPSSimpleExecutorDylibManagerOpenSignature =

diff  --git a/llvm/include/llvm/ExecutionEngine/Orc/TargetProcess/RegisterEHFrames.h b/llvm/include/llvm/ExecutionEngine/Orc/TargetProcess/RegisterEHFrames.h
index 3b4aabb90371..6d12be363d34 100644
--- a/llvm/include/llvm/ExecutionEngine/Orc/TargetProcess/RegisterEHFrames.h
+++ b/llvm/include/llvm/ExecutionEngine/Orc/TargetProcess/RegisterEHFrames.h
@@ -33,6 +33,22 @@ Error deregisterEHFrameSection(const void *EHFrameSectionAddr,
 } // end namespace orc
 } // end namespace llvm
 
+/// An eh-frame registration utility suitable for use as a support function
+/// call. This function expects the direct address and size of the eh-frame
+/// section to register as its arguments (it does not treat its arguments as
+/// pointers to an SPS-serialized arg buffer).
+extern "C" llvm::orc::shared::detail::CWrapperFunctionResult
+llvm_orc_registerEHFrameSectionCustomDirectWrapper(
+    const char *EHFrameSectionAddr, uint64_t Size);
+
+/// An eh-frame deregistration utility suitable for use as a support function
+/// call. This function expects the direct address and size of the eh-frame
+/// section to register as its arguments (it does not treat its arguments as
+/// pointers to an SPS-serialized arg buffer).
+extern "C" llvm::orc::shared::detail::CWrapperFunctionResult
+llvm_orc_deregisterEHFrameSectionCustomDirectWrapper(
+    const char *EHFrameSectionAddr, uint64_t Size);
+
 extern "C" llvm::orc::shared::detail::CWrapperFunctionResult
 llvm_orc_registerEHFrameSectionWrapper(const char *Data, uint64_t Size);
 

diff  --git a/llvm/lib/ExecutionEngine/Orc/CMakeLists.txt b/llvm/lib/ExecutionEngine/Orc/CMakeLists.txt
index cce507745826..8d69cc31e4c6 100644
--- a/llvm/lib/ExecutionEngine/Orc/CMakeLists.txt
+++ b/llvm/lib/ExecutionEngine/Orc/CMakeLists.txt
@@ -9,6 +9,7 @@ add_llvm_component_library(LLVMOrcJIT
   EPCEHFrameRegistrar.cpp
   EPCGenericDylibManager.cpp
   EPCGenericJITLinkMemoryManager.cpp
+  EPCGenericRTDyldMemoryManager.cpp
   EPCIndirectionUtils.cpp
   ExecutionUtils.cpp
   IndirectionUtils.cpp

diff  --git a/llvm/lib/ExecutionEngine/Orc/EPCGenericRTDyldMemoryManager.cpp b/llvm/lib/ExecutionEngine/Orc/EPCGenericRTDyldMemoryManager.cpp
new file mode 100644
index 000000000000..cb5e72493a38
--- /dev/null
+++ b/llvm/lib/ExecutionEngine/Orc/EPCGenericRTDyldMemoryManager.cpp
@@ -0,0 +1,315 @@
+//===----- EPCGenericRTDyldMemoryManager.cpp - EPC-bbasde MemMgr -----===//
+//
+// 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/EPCGenericRTDyldMemoryManager.h"
+#include "llvm/ExecutionEngine/Orc/EPCGenericMemoryAccess.h"
+#include "llvm/ExecutionEngine/Orc/Shared/OrcRTBridge.h"
+#include "llvm/Support/Alignment.h"
+#include "llvm/Support/FormatVariadic.h"
+
+#define DEBUG_TYPE "orc"
+
+namespace llvm {
+namespace orc {
+
+Expected<std::unique_ptr<EPCGenericRTDyldMemoryManager>>
+EPCGenericRTDyldMemoryManager::CreateWithDefaultBootstrapSymbols(
+    ExecutorProcessControl &EPC) {
+  SymbolAddrs SAs;
+  if (auto Err = EPC.getBootstrapSymbols(
+          {{SAs.Instance, rt::SimpleExecutorMemoryManagerInstanceName},
+           {SAs.Reserve, rt::SimpleExecutorMemoryManagerReserveWrapperName},
+           {SAs.Finalize, rt::SimpleExecutorMemoryManagerFinalizeWrapperName},
+           {SAs.Deallocate,
+            rt::SimpleExecutorMemoryManagerDeallocateWrapperName},
+           {SAs.RegisterEHFrame,
+            rt::RegisterEHFrameSectionCustomDirectWrapperName},
+           {SAs.DeregisterEHFrame,
+            rt::DeregisterEHFrameSectionCustomDirectWrapperName}}))
+    return std::move(Err);
+  return std::make_unique<EPCGenericRTDyldMemoryManager>(EPC, std::move(SAs));
+}
+
+EPCGenericRTDyldMemoryManager::EPCGenericRTDyldMemoryManager(
+    ExecutorProcessControl &EPC, SymbolAddrs SAs)
+    : EPC(EPC), SAs(std::move(SAs)) {
+  LLVM_DEBUG(dbgs() << "Created remote allocator " << (void *)this << "\n");
+}
+
+EPCGenericRTDyldMemoryManager::~EPCGenericRTDyldMemoryManager() {
+  LLVM_DEBUG(dbgs() << "Destroyed remote allocator " << (void *)this << "\n");
+  if (!ErrMsg.empty())
+    errs() << "Destroying with existing errors:\n" << ErrMsg << "\n";
+
+  Error Err = Error::success();
+  if (auto Err2 = EPC.callSPSWrapper<
+                  rt::SPSSimpleExecutorMemoryManagerDeallocateSignature>(
+          SAs.Reserve.getValue(), Err, SAs.Instance, FinalizedAllocs)) {
+    // FIXME: Report errors through EPC once that functionality is available.
+    logAllUnhandledErrors(std::move(Err2), errs(), "");
+    return;
+  }
+
+  if (Err)
+    logAllUnhandledErrors(std::move(Err), errs(), "");
+}
+
+uint8_t *EPCGenericRTDyldMemoryManager::allocateCodeSection(
+    uintptr_t Size, unsigned Alignment, unsigned SectionID,
+    StringRef SectionName) {
+  std::lock_guard<std::mutex> Lock(M);
+  LLVM_DEBUG({
+    dbgs() << "Allocator " << (void *)this << " allocating code section "
+           << SectionName << ": size = " << formatv("{0:x}", Size)
+           << " bytes, alignment = " << Alignment << "\n";
+  });
+  auto &Seg = Unmapped.back().CodeAllocs;
+  Seg.emplace_back(Size, Alignment);
+  return reinterpret_cast<uint8_t *>(
+      alignAddr(Seg.back().Contents.get(), Align(Alignment)));
+}
+
+uint8_t *EPCGenericRTDyldMemoryManager::allocateDataSection(
+    uintptr_t Size, unsigned Alignment, unsigned SectionID,
+    StringRef SectionName, bool IsReadOnly) {
+  std::lock_guard<std::mutex> Lock(M);
+  LLVM_DEBUG({
+    dbgs() << "Allocator " << (void *)this << " allocating "
+           << (IsReadOnly ? "ro" : "rw") << "-data section " << SectionName
+           << ": size = " << formatv("{0:x}", Size) << " bytes, alignment "
+           << Alignment << ")\n";
+  });
+
+  auto &Seg =
+      IsReadOnly ? Unmapped.back().RODataAllocs : Unmapped.back().RWDataAllocs;
+
+  Seg.emplace_back(Size, Alignment);
+  return reinterpret_cast<uint8_t *>(
+      alignAddr(Seg.back().Contents.get(), Align(Alignment)));
+}
+
+void EPCGenericRTDyldMemoryManager::reserveAllocationSpace(
+    uintptr_t CodeSize, uint32_t CodeAlign, uintptr_t RODataSize,
+    uint32_t RODataAlign, uintptr_t RWDataSize, uint32_t RWDataAlign) {
+
+  {
+    std::lock_guard<std::mutex> Lock(M);
+    // If there's already an error then bail out.
+    if (!ErrMsg.empty())
+      return;
+
+    if (!isPowerOf2_32(CodeAlign) || CodeAlign > EPC.getPageSize()) {
+      ErrMsg = "Invalid code alignment in reserveAllocationSpace";
+      return;
+    }
+    if (!isPowerOf2_32(RODataAlign) || RODataAlign > EPC.getPageSize()) {
+      ErrMsg = "Invalid ro-data alignment in reserveAllocationSpace";
+      return;
+    }
+    if (!isPowerOf2_32(RWDataAlign) || RWDataAlign > EPC.getPageSize()) {
+      ErrMsg = "Invalid rw-data alignment in reserveAllocationSpace";
+      return;
+    }
+  }
+
+  uint64_t TotalSize = 0;
+  TotalSize += alignTo(CodeSize, EPC.getPageSize());
+  TotalSize += alignTo(RODataSize, EPC.getPageSize());
+  TotalSize += alignTo(RWDataSize, EPC.getPageSize());
+
+  LLVM_DEBUG({
+    dbgs() << "Allocator " << (void *)this << " reserving "
+           << formatv("{0:x}", TotalSize) << " bytes.\n";
+  });
+
+  Expected<ExecutorAddr> TargetAllocAddr((ExecutorAddr()));
+  if (auto Err = EPC.callSPSWrapper<
+                 rt::SPSSimpleExecutorMemoryManagerReserveSignature>(
+          SAs.Reserve.getValue(), TargetAllocAddr, SAs.Instance, TotalSize)) {
+    std::lock_guard<std::mutex> Lock(M);
+    ErrMsg = toString(std::move(Err));
+    return;
+  }
+  if (!TargetAllocAddr) {
+    std::lock_guard<std::mutex> Lock(M);
+    ErrMsg = toString(TargetAllocAddr.takeError());
+    return;
+  }
+
+  std::lock_guard<std::mutex> Lock(M);
+  Unmapped.push_back(AllocGroup());
+  Unmapped.back().RemoteCode = {
+      *TargetAllocAddr, ExecutorAddrDiff(alignTo(CodeSize, EPC.getPageSize()))};
+  Unmapped.back().RemoteROData = {
+      Unmapped.back().RemoteCode.End,
+      ExecutorAddrDiff(alignTo(RODataSize, EPC.getPageSize()))};
+  Unmapped.back().RemoteRWData = {
+      Unmapped.back().RemoteROData.End,
+      ExecutorAddrDiff(alignTo(RWDataSize, EPC.getPageSize()))};
+}
+
+bool EPCGenericRTDyldMemoryManager::needsToReserveAllocationSpace() {
+  return true;
+}
+
+void EPCGenericRTDyldMemoryManager::registerEHFrames(uint8_t *Addr,
+                                                     uint64_t LoadAddr,
+                                                     size_t Size) {
+  LLVM_DEBUG({
+    dbgs() << "Allocator " << (void *)this << " added unfinalized eh-frame "
+           << formatv("[ {0:x} {1:x} ]", LoadAddr, LoadAddr + Size) << "\n";
+  });
+  std::lock_guard<std::mutex> Lock(M);
+  // Bail out early if there's already an error.
+  if (!ErrMsg.empty())
+    return;
+
+  ExecutorAddr LA(LoadAddr);
+  for (auto &Alloc : llvm::reverse(Unfinalized)) {
+    if (Alloc.RemoteCode.contains(LA) || Alloc.RemoteROData.contains(LA) ||
+        Alloc.RemoteRWData.contains(LA)) {
+      Alloc.UnfinalizedEHFrames.push_back({LA, Size});
+      return;
+    }
+  }
+  ErrMsg = "eh-frame does not lie inside unfinalized alloc";
+}
+
+void EPCGenericRTDyldMemoryManager::deregisterEHFrames() {
+  // This is a no-op for us: We've registered a deallocation action for it.
+}
+
+void EPCGenericRTDyldMemoryManager::notifyObjectLoaded(
+    RuntimeDyld &Dyld, const object::ObjectFile &Obj) {
+  std::lock_guard<std::mutex> Lock(M);
+  LLVM_DEBUG(dbgs() << "Allocator " << (void *)this << " applied mappings:\n");
+  for (auto &ObjAllocs : Unmapped) {
+    mapAllocsToRemoteAddrs(Dyld, ObjAllocs.CodeAllocs,
+                           ObjAllocs.RemoteCode.Start);
+    mapAllocsToRemoteAddrs(Dyld, ObjAllocs.RODataAllocs,
+                           ObjAllocs.RemoteROData.Start);
+    mapAllocsToRemoteAddrs(Dyld, ObjAllocs.RWDataAllocs,
+                           ObjAllocs.RemoteRWData.Start);
+    Unfinalized.push_back(std::move(ObjAllocs));
+  }
+  Unmapped.clear();
+}
+
+bool EPCGenericRTDyldMemoryManager::finalizeMemory(std::string *ErrMsg) {
+  LLVM_DEBUG(dbgs() << "Allocator " << (void *)this << " finalizing:\n");
+
+  // If there's an error then bail out here.
+  std::vector<AllocGroup> Allocs;
+  {
+    std::lock_guard<std::mutex> Lock(M);
+    if (ErrMsg && !this->ErrMsg.empty()) {
+      *ErrMsg = std::move(this->ErrMsg);
+      return true;
+    }
+    std::swap(Allocs, Unfinalized);
+  }
+
+  // Loop over unfinalized objects to make finalization requests.
+  for (auto &ObjAllocs : Allocs) {
+
+    tpctypes::WireProtectionFlags SegProts[3] = {
+        tpctypes::toWireProtectionFlags(
+            static_cast<sys::Memory::ProtectionFlags>(sys::Memory::MF_READ |
+                                                      sys::Memory::MF_EXEC)),
+        tpctypes::toWireProtectionFlags(sys::Memory::MF_READ),
+        tpctypes::toWireProtectionFlags(
+            static_cast<sys::Memory::ProtectionFlags>(sys::Memory::MF_READ |
+                                                      sys::Memory::MF_WRITE))};
+
+    ExecutorAddrRange *RemoteAddrs[3] = {&ObjAllocs.RemoteCode,
+                                         &ObjAllocs.RemoteROData,
+                                         &ObjAllocs.RemoteRWData};
+
+    std::vector<Alloc> *SegSections[3] = {&ObjAllocs.CodeAllocs,
+                                          &ObjAllocs.RODataAllocs,
+                                          &ObjAllocs.RWDataAllocs};
+
+    tpctypes::FinalizeRequest FR;
+    std::unique_ptr<char[]> AggregateContents[3];
+
+    for (unsigned I = 0; I != 3; ++I) {
+      FR.Segments.push_back({});
+      auto &Seg = FR.Segments.back();
+      Seg.Prot = SegProts[I];
+      Seg.Addr = RemoteAddrs[I]->Start;
+      for (auto &SecAlloc : *SegSections[I]) {
+        Seg.Size = alignTo(Seg.Size, SecAlloc.Align);
+        Seg.Size += SecAlloc.Size;
+      }
+      AggregateContents[I] = std::make_unique<char[]>(Seg.Size);
+      size_t SecOffset = 0;
+      for (auto &SecAlloc : *SegSections[I]) {
+        SecOffset = alignTo(SecOffset, SecAlloc.Align);
+        memcpy(&AggregateContents[I][SecOffset],
+               reinterpret_cast<const char *>(
+                   alignAddr(SecAlloc.Contents.get(), Align(SecAlloc.Align))),
+               SecAlloc.Size);
+        SecOffset += SecAlloc.Size;
+        // FIXME: Can we reset SecAlloc.Content here, now that it's copied into
+        // the aggregated content?
+      }
+      Seg.Content = {AggregateContents[I].get(), SecOffset};
+    }
+
+    for (auto &Frame : ObjAllocs.UnfinalizedEHFrames)
+      FR.Actions.push_back({{SAs.RegisterEHFrame, Frame.Addr, Frame.Size},
+                            {SAs.DeregisterEHFrame, Frame.Addr, Frame.Size}});
+
+    // We'll also need to make an extra allocation for the eh-frame wrapper call
+    // arguments.
+    Error FinalizeErr = Error::success();
+    if (auto Err = EPC.callSPSWrapper<
+                   rt::SPSSimpleExecutorMemoryManagerFinalizeSignature>(
+            SAs.Finalize.getValue(), FinalizeErr, SAs.Instance,
+            std::move(FR))) {
+      std::lock_guard<std::mutex> Lock(M);
+      this->ErrMsg = toString(std::move(Err));
+      dbgs() << "Serialization error: " << this->ErrMsg << "\n";
+      if (ErrMsg)
+        *ErrMsg = this->ErrMsg;
+      return true;
+    }
+    if (FinalizeErr) {
+      std::lock_guard<std::mutex> Lock(M);
+      this->ErrMsg = toString(std::move(FinalizeErr));
+      dbgs() << "Finalization error: " << this->ErrMsg << "\n";
+      if (ErrMsg)
+        *ErrMsg = this->ErrMsg;
+      return true;
+    }
+  }
+
+  return false;
+}
+
+void EPCGenericRTDyldMemoryManager::mapAllocsToRemoteAddrs(
+    RuntimeDyld &Dyld, std::vector<Alloc> &Allocs, ExecutorAddr NextAddr) {
+  for (auto &Alloc : Allocs) {
+    NextAddr.setValue(alignTo(NextAddr.getValue(), Alloc.Align));
+    LLVM_DEBUG({
+      dbgs() << "     " << static_cast<void *>(Alloc.Contents.get()) << " -> "
+             << format("0x%016" PRIx64, NextAddr.getValue()) << "\n";
+    });
+    Dyld.mapSectionAddress(reinterpret_cast<const void *>(alignAddr(
+                               Alloc.Contents.get(), Align(Alloc.Align))),
+                           NextAddr.getValue());
+    Alloc.RemoteAddr = NextAddr;
+    // Only advance NextAddr if it was non-null to begin with,
+    // otherwise leave it as null.
+    if (NextAddr)
+      NextAddr += ExecutorAddrDiff(Alloc.Size);
+  }
+}
+
+} // end namespace orc
+} // end namespace llvm

diff  --git a/llvm/lib/ExecutionEngine/Orc/Shared/OrcRTBridge.cpp b/llvm/lib/ExecutionEngine/Orc/Shared/OrcRTBridge.cpp
index 6c3032c2428c..02044e4af29a 100644
--- a/llvm/lib/ExecutionEngine/Orc/Shared/OrcRTBridge.cpp
+++ b/llvm/lib/ExecutionEngine/Orc/Shared/OrcRTBridge.cpp
@@ -36,6 +36,10 @@ const char *MemoryWriteUInt64sWrapperName =
     "__llvm_orc_bootstrap_mem_write_uint64s_wrapper";
 const char *MemoryWriteBuffersWrapperName =
     "__llvm_orc_bootstrap_mem_write_buffers_wrapper";
+const char *RegisterEHFrameSectionCustomDirectWrapperName =
+    "__llvm_orc_bootstrap_register_ehframe_section_custom_direct_wrapper";
+const char *DeregisterEHFrameSectionCustomDirectWrapperName =
+    "__llvm_orc_bootstrap_deregister_ehframe_section_custom_direct_wrapper";
 const char *RunAsMainWrapperName = "__llvm_orc_bootstrap_run_as_main_wrapper";
 
 } // end namespace rt

diff  --git a/llvm/lib/ExecutionEngine/Orc/TargetProcess/OrcRTBootstrap.cpp b/llvm/lib/ExecutionEngine/Orc/TargetProcess/OrcRTBootstrap.cpp
index f61bb6e87177..356bb0be33f0 100644
--- a/llvm/lib/ExecutionEngine/Orc/TargetProcess/OrcRTBootstrap.cpp
+++ b/llvm/lib/ExecutionEngine/Orc/TargetProcess/OrcRTBootstrap.cpp
@@ -10,6 +10,7 @@
 
 #include "llvm/ExecutionEngine/Orc/Shared/OrcRTBridge.h"
 #include "llvm/ExecutionEngine/Orc/Shared/WrapperFunctionUtils.h"
+#include "llvm/ExecutionEngine/Orc/TargetProcess/RegisterEHFrames.h"
 #include "llvm/ExecutionEngine/Orc/TargetProcess/TargetExecutionUtils.h"
 
 #define DEBUG_TYPE "orc"
@@ -71,6 +72,11 @@ void addTo(StringMap<ExecutorAddr> &M) {
                          shared::SPSMemoryAccessUInt64Write>);
   M[rt::MemoryWriteBuffersWrapperName] =
       ExecutorAddr::fromPtr(&writeBuffersWrapper);
+  M[rt::RegisterEHFrameSectionCustomDirectWrapperName] = ExecutorAddr::fromPtr(
+      &llvm_orc_registerEHFrameSectionCustomDirectWrapper);
+  M[rt::DeregisterEHFrameSectionCustomDirectWrapperName] =
+      ExecutorAddr::fromPtr(
+          &llvm_orc_deregisterEHFrameSectionCustomDirectWrapper);
   M[rt::RunAsMainWrapperName] = ExecutorAddr::fromPtr(&runAsMainWrapper);
 }
 

diff  --git a/llvm/lib/ExecutionEngine/Orc/TargetProcess/RegisterEHFrames.cpp b/llvm/lib/ExecutionEngine/Orc/TargetProcess/RegisterEHFrames.cpp
index 3e4c61fc09e2..ee67e61358b2 100644
--- a/llvm/lib/ExecutionEngine/Orc/TargetProcess/RegisterEHFrames.cpp
+++ b/llvm/lib/ExecutionEngine/Orc/TargetProcess/RegisterEHFrames.cpp
@@ -158,6 +158,24 @@ Error deregisterEHFrameSection(const void *EHFrameSectionAddr,
 } // end namespace orc
 } // end namespace llvm
 
+extern "C" llvm::orc::shared::detail::CWrapperFunctionResult
+llvm_orc_registerEHFrameSectionCustomDirectWrapper(
+    const char *EHFrameSectionAddr, uint64_t Size) {
+  if (auto Err = registerEHFrameSection(EHFrameSectionAddr, Size))
+    return WrapperFunctionResult::createOutOfBandError(toString(std::move(Err)))
+        .release();
+  return llvm::orc::shared::detail::CWrapperFunctionResult();
+}
+
+extern "C" llvm::orc::shared::detail::CWrapperFunctionResult
+llvm_orc_deregisterEHFrameSectionCustomDirectWrapper(
+    const char *EHFrameSectionAddr, uint64_t Size) {
+  if (auto Err = deregisterEHFrameSection(EHFrameSectionAddr, Size))
+    return WrapperFunctionResult::createOutOfBandError(toString(std::move(Err)))
+        .release();
+  return llvm::orc::shared::detail::CWrapperFunctionResult();
+}
+
 static Error registerEHFrameWrapper(JITTargetAddress Addr, uint64_t Size) {
   return llvm::orc::registerEHFrameSection(
       jitTargetAddressToPointer<const void *>(Addr), Size);

diff  --git a/llvm/lib/ExecutionEngine/Orc/TargetProcess/SimpleExecutorMemoryManager.cpp b/llvm/lib/ExecutionEngine/Orc/TargetProcess/SimpleExecutorMemoryManager.cpp
index 83b39b8f9720..c25d188e0054 100644
--- a/llvm/lib/ExecutionEngine/Orc/TargetProcess/SimpleExecutorMemoryManager.cpp
+++ b/llvm/lib/ExecutionEngine/Orc/TargetProcess/SimpleExecutorMemoryManager.cpp
@@ -38,6 +38,16 @@ Error SimpleExecutorMemoryManager::finalize(tpctypes::FinalizeRequest &FR) {
   std::vector<tpctypes::SupportFunctionCall> DeallocationActions;
   size_t SuccessfulFinalizationActions = 0;
 
+  if (FR.Segments.empty()) {
+    // NOTE: Finalizing nothing is currently a no-op. Should it be an error?
+    if (FR.Actions.empty())
+      return Error::success();
+    else
+      return make_error<StringError>("Finalization actions attached to empty "
+                                     "finalization request",
+                                     inconvertibleErrorCode());
+  }
+
   for (auto &Seg : FR.Segments)
     Base = std::min(Base, Seg.Addr);
 

diff  --git a/llvm/tools/lli/ChildTarget/CMakeLists.txt b/llvm/tools/lli/ChildTarget/CMakeLists.txt
index c5795eebd71a..ea28756e8932 100644
--- a/llvm/tools/lli/ChildTarget/CMakeLists.txt
+++ b/llvm/tools/lli/ChildTarget/CMakeLists.txt
@@ -1,7 +1,7 @@
 set(LLVM_LINK_COMPONENTS
-  OrcShared
   OrcJIT
-  RuntimeDyld
+  OrcShared
+  OrcTargetProcess
   Support
   )
 
@@ -11,4 +11,3 @@ add_llvm_utility(lli-child-target
   DEPENDS
   intrinsics_gen
 )
-

diff  --git a/llvm/tools/lli/ChildTarget/ChildTarget.cpp b/llvm/tools/lli/ChildTarget/ChildTarget.cpp
index 5772baca1d09..dd57c657509f 100644
--- a/llvm/tools/lli/ChildTarget/ChildTarget.cpp
+++ b/llvm/tools/lli/ChildTarget/ChildTarget.cpp
@@ -1,69 +1,80 @@
-#include "llvm/ExecutionEngine/Orc/OrcABISupport.h"
-#include "llvm/ExecutionEngine/Orc/OrcRemoteTargetServer.h"
+//===----------- ChildTarget.cpp - Out-of-proc executor for lli -----------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+//
+// Simple out-of-process executor for lli.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/ADT/StringRef.h"
 #include "llvm/ExecutionEngine/Orc/Shared/FDRawByteChannel.h"
-#include "llvm/Support/Debug.h"
+#include "llvm/ExecutionEngine/Orc/TargetProcess/JITLoaderGDB.h"
+#include "llvm/ExecutionEngine/Orc/TargetProcess/RegisterEHFrames.h"
+#include "llvm/ExecutionEngine/Orc/TargetProcess/SimpleExecutorMemoryManager.h"
+#include "llvm/ExecutionEngine/Orc/TargetProcess/SimpleRemoteEPCServer.h"
 #include "llvm/Support/DynamicLibrary.h"
-#include "llvm/Support/Process.h"
+#include "llvm/Support/Error.h"
+#include "llvm/Support/MathExtras.h"
+#include "llvm/Support/raw_ostream.h"
+#include <cstring>
 #include <sstream>
 
-#include "../RemoteJITUtils.h"
-
 using namespace llvm;
 using namespace llvm::orc;
-using namespace llvm::sys;
-
-#ifdef __x86_64__
-typedef OrcX86_64_SysV HostOrcArch;
-#else
-typedef OrcGenericABI HostOrcArch;
-#endif
 
 ExitOnError ExitOnErr;
 
 int main(int argc, char *argv[]) {
+#if LLVM_ENABLE_THREADS
 
   if (argc != 3) {
     errs() << "Usage: " << argv[0] << " <input fd> <output fd>\n";
     return 1;
   }
 
-  ExitOnErr.setBanner(std::string(argv[0]) + ":");
-
-  int InFD;
-  int OutFD;
-  {
-    std::istringstream InFDStream(argv[1]), OutFDStream(argv[2]);
-    InFDStream >> InFD;
-    OutFDStream >> OutFD;
-  }
-
   if (sys::DynamicLibrary::LoadLibraryPermanently(nullptr)) {
     errs() << "Error loading program symbols.\n";
     return 1;
   }
 
-  auto SymbolLookup = [](const std::string &Name) {
-    return RTDyldMemoryManager::getSymbolAddressInProcess(Name);
-  };
+  ExitOnErr.setBanner(std::string(argv[0]) + ": ");
 
-  auto RegisterEHFrames = [](uint8_t *Addr, uint32_t Size) {
-    RTDyldMemoryManager::registerEHFramesInProcess(Addr, Size);
-  };
-
-  auto DeregisterEHFrames = [](uint8_t *Addr, uint32_t Size) {
-    RTDyldMemoryManager::deregisterEHFramesInProcess(Addr, Size);
-  };
-
-  shared::FDRawByteChannel Channel(InFD, OutFD);
-  typedef remote::OrcRemoteTargetServer<shared::FDRawByteChannel, HostOrcArch>
-      JITServer;
-  JITServer Server(Channel, SymbolLookup, RegisterEHFrames, DeregisterEHFrames);
+  int InFD = 0;
+  int OutFD = 0;
+  {
+    std::istringstream InFDStream(argv[1]), OutFDStream(argv[2]);
+    InFDStream >> InFD;
+    OutFDStream >> OutFD;
+  }
 
-  while (!Server.receivedTerminate())
-    ExitOnErr(Server.handleOne());
+  auto Server =
+      ExitOnErr(SimpleRemoteEPCServer::Create<FDSimpleRemoteEPCTransport>(
+          [](SimpleRemoteEPCServer::Setup &S) -> Error {
+            S.setDispatcher(
+                std::make_unique<SimpleRemoteEPCServer::ThreadDispatcher>());
+            S.bootstrapSymbols() =
+                SimpleRemoteEPCServer::defaultBootstrapSymbols();
+            S.services().push_back(
+                std::make_unique<rt_bootstrap::SimpleExecutorMemoryManager>());
+            return Error::success();
+          },
+          InFD, OutFD));
+
+  ExitOnErr(Server->waitForDisconnect());
 
   close(InFD);
   close(OutFD);
 
   return 0;
+
+#else
+  errs() << argv[0]
+         << " error: this tool requires threads, but LLVM was "
+            "built with LLVM_ENABLE_THREADS=Off\n";
+  return 1;
+#endif
 }

diff  --git a/llvm/tools/lli/RemoteJITUtils.h b/llvm/tools/lli/ForwardingMemoryManager.h
similarity index 68%
rename from llvm/tools/lli/RemoteJITUtils.h
rename to llvm/tools/lli/ForwardingMemoryManager.h
index cc8d034f62a5..99a545e60de4 100644
--- a/llvm/tools/lli/RemoteJITUtils.h
+++ b/llvm/tools/lli/ForwardingMemoryManager.h
@@ -10,21 +10,11 @@
 //
 //===----------------------------------------------------------------------===//
 
-#ifndef LLVM_TOOLS_LLI_REMOTEJITUTILS_H
-#define LLVM_TOOLS_LLI_REMOTEJITUTILS_H
+#ifndef LLVM_TOOLS_LLI_FORWARDINGMEMORYMANAGER_H
+#define LLVM_TOOLS_LLI_FORWARDINGMEMORYMANAGER_H
 
-#include "llvm/ExecutionEngine/Orc/Shared/FDRawByteChannel.h"
+#include "llvm/ExecutionEngine/Orc/EPCGenericDylibManager.h"
 #include "llvm/ExecutionEngine/RTDyldMemoryManager.h"
-#include <mutex>
-
-#if !defined(_MSC_VER) && !defined(__MINGW32__)
-#include <unistd.h>
-#else
-#include <io.h>
-#endif
-
-// launch the remote process (see lli.cpp) and return a channel to it.
-std::unique_ptr<llvm::orc::shared::FDRawByteChannel> launchRemote();
 
 namespace llvm {
 
@@ -70,9 +60,7 @@ class ForwardingMemoryManager : public llvm::RTDyldMemoryManager {
     MemMgr->registerEHFrames(Addr, LoadAddr, Size);
   }
 
-  void deregisterEHFrames() override {
-    MemMgr->deregisterEHFrames();
-  }
+  void deregisterEHFrames() override { MemMgr->deregisterEHFrames(); }
 
   bool finalizeMemory(std::string *ErrMsg = nullptr) override {
     return MemMgr->finalizeMemory(ErrMsg);
@@ -90,8 +78,7 @@ class ForwardingMemoryManager : public llvm::RTDyldMemoryManager {
     return Resolver->findSymbol(Name);
   }
 
-  JITSymbol
-  findSymbolInLogicalDylib(const std::string &Name) override {
+  JITSymbol findSymbolInLogicalDylib(const std::string &Name) override {
     return Resolver->findSymbolInLogicalDylib(Name);
   }
 
@@ -100,17 +87,31 @@ class ForwardingMemoryManager : public llvm::RTDyldMemoryManager {
   std::shared_ptr<LegacyJITSymbolResolver> Resolver;
 };
 
-template <typename RemoteT>
 class RemoteResolver : public LegacyJITSymbolResolver {
 public:
-
-  RemoteResolver(RemoteT &R) : R(R) {}
+  static Expected<std::unique_ptr<RemoteResolver>>
+  Create(orc::ExecutorProcessControl &EPC) {
+    auto DylibMgr =
+        orc::EPCGenericDylibManager::CreateWithDefaultBootstrapSymbols(EPC);
+    if (!DylibMgr)
+      return DylibMgr.takeError();
+    auto H = DylibMgr->open("", 0);
+    if (!H)
+      return H.takeError();
+    return std::unique_ptr<RemoteResolver>(
+        new RemoteResolver(std::move(*DylibMgr), std::move(*H)));
+  }
 
   JITSymbol findSymbol(const std::string &Name) override {
-    if (auto Addr = R.getSymbolAddress(Name))
-      return JITSymbol(*Addr, JITSymbolFlags::Exported);
-    else
-      return Addr.takeError();
+    orc::RemoteSymbolLookupSet R;
+    R.push_back({std::move(Name), false});
+    if (auto Addrs = DylibMgr.lookup(H, R)) {
+      if (Addrs->size() != 1)
+        return make_error<StringError>("Unexpected remote lookup result",
+                                       inconvertibleErrorCode());
+      return JITSymbol(Addrs->front().getValue(), JITSymbolFlags::Exported);
+    } else
+      return Addrs.takeError();
   }
 
   JITSymbol findSymbolInLogicalDylib(const std::string &Name) override {
@@ -118,8 +119,13 @@ class RemoteResolver : public LegacyJITSymbolResolver {
   }
 
 public:
-  RemoteT &R;
+  RemoteResolver(orc::EPCGenericDylibManager DylibMgr,
+                 orc::tpctypes::DylibHandle H)
+      : DylibMgr(std::move(DylibMgr)), H(std::move(H)) {}
+
+  orc::EPCGenericDylibManager DylibMgr;
+  orc::tpctypes::DylibHandle H;
 };
-}
+} // namespace llvm
 
-#endif
+#endif // LLVM_TOOLS_LLI_FORWARDINGMEMORYMANAGER_H

diff  --git a/llvm/tools/lli/lli.cpp b/llvm/tools/lli/lli.cpp
index 170cc3b42193..6f75c75a47dc 100644
--- a/llvm/tools/lli/lli.cpp
+++ b/llvm/tools/lli/lli.cpp
@@ -13,7 +13,7 @@
 //===----------------------------------------------------------------------===//
 
 #include "ExecutionUtils.h"
-#include "RemoteJITUtils.h"
+#include "ForwardingMemoryManager.h"
 #include "llvm/ADT/StringExtras.h"
 #include "llvm/ADT/Triple.h"
 #include "llvm/Bitcode/BitcodeReader.h"
@@ -30,11 +30,12 @@
 #include "llvm/ExecutionEngine/Orc/DebugUtils.h"
 #include "llvm/ExecutionEngine/Orc/EPCDebugObjectRegistrar.h"
 #include "llvm/ExecutionEngine/Orc/EPCEHFrameRegistrar.h"
+#include "llvm/ExecutionEngine/Orc/EPCGenericRTDyldMemoryManager.h"
 #include "llvm/ExecutionEngine/Orc/ExecutionUtils.h"
 #include "llvm/ExecutionEngine/Orc/JITTargetMachineBuilder.h"
 #include "llvm/ExecutionEngine/Orc/LLJIT.h"
-#include "llvm/ExecutionEngine/Orc/OrcRemoteTargetClient.h"
 #include "llvm/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.h"
+#include "llvm/ExecutionEngine/Orc/SimpleRemoteEPC.h"
 #include "llvm/ExecutionEngine/Orc/SymbolStringPool.h"
 #include "llvm/ExecutionEngine/Orc/TargetProcess/JITLoaderGDB.h"
 #include "llvm/ExecutionEngine/Orc/TargetProcess/RegisterEHFrames.h"
@@ -68,6 +69,12 @@
 #include "llvm/Transforms/Instrumentation.h"
 #include <cerrno>
 
+#if !defined(_MSC_VER) && !defined(__MINGW32__)
+#include <unistd.h>
+#else
+#include <io.h>
+#endif
+
 #ifdef __CYGWIN__
 #include <cygwin/version.h>
 #if defined(CYGWIN_VERSION_DLL_MAJOR) && CYGWIN_VERSION_DLL_MAJOR<1007
@@ -418,6 +425,7 @@ CodeGenOpt::Level getOptLevel() {
 Error loadDylibs();
 int runOrcJIT(const char *ProgName);
 void disallowOrcOptions();
+Expected<std::unique_ptr<orc::ExecutorProcessControl>> launchRemote();
 
 //===----------------------------------------------------------------------===//
 // main Driver function
@@ -658,6 +666,10 @@ int main(int argc, char **argv, char * const *envp) {
 #endif
   }
 
+  std::unique_ptr<orc::ExecutorProcessControl> EPC =
+      RemoteMCJIT ? ExitOnErr(launchRemote())
+                  : ExitOnErr(orc::SelfExecutorProcessControl::Create());
+
   if (!RemoteMCJIT) {
     // If the program doesn't explicitly call exit, we will need the Exit
     // function later on to make an explicit call, so get the function now.
@@ -708,22 +720,10 @@ int main(int argc, char **argv, char * const *envp) {
     // it couldn't. This is a limitation of the LLI implementation, not the
     // MCJIT itself. FIXME.
 
-    // Lanch the remote process and get a channel to it.
-    std::unique_ptr<orc::shared::FDRawByteChannel> C = launchRemote();
-    if (!C) {
-      WithColor::error(errs(), argv[0]) << "failed to launch remote JIT.\n";
-      exit(1);
-    }
-
-    // Create a remote target client running over the channel.
-    llvm::orc::ExecutionSession ES(
-        std::make_unique<orc::UnsupportedExecutorProcessControl>());
-    ES.setErrorReporter([&](Error Err) { ExitOnErr(std::move(Err)); });
-    typedef orc::remote::OrcRemoteTargetClient MyRemote;
-    auto R = ExitOnErr(MyRemote::Create(*C, ES));
-
     // Create a remote memory manager.
-    auto RemoteMM = ExitOnErr(R->createRemoteMemoryManager());
+    auto RemoteMM = ExitOnErr(
+        orc::EPCGenericRTDyldMemoryManager::CreateWithDefaultBootstrapSymbols(
+            *EPC));
 
     // Forward MCJIT's memory manager calls to the remote memory manager.
     static_cast<ForwardingMemoryManager*>(RTDyldMM)->setMemMgr(
@@ -731,8 +731,7 @@ int main(int argc, char **argv, char * const *envp) {
 
     // Forward MCJIT's symbol resolution calls to the remote.
     static_cast<ForwardingMemoryManager *>(RTDyldMM)->setResolver(
-        std::make_unique<RemoteResolver<MyRemote>>(*R));
-
+        ExitOnErr(RemoteResolver::Create(*EPC)));
     // Grab the target address of the JIT'd main function on the remote and call
     // it.
     // FIXME: argv and envp handling.
@@ -740,7 +739,7 @@ int main(int argc, char **argv, char * const *envp) {
     EE->finalizeObject();
     LLVM_DEBUG(dbgs() << "Executing '" << EntryFn->getName() << "' at 0x"
                       << format("%llx", Entry) << "\n");
-    Result = ExitOnErr(R->callIntVoid(Entry));
+    Result = ExitOnErr(EPC->runAsMain(Entry, {}));
 
     // Like static constructors, the remote target MCJIT support doesn't handle
     // this yet. It could. FIXME.
@@ -751,7 +750,7 @@ int main(int argc, char **argv, char * const *envp) {
     EE.reset();
 
     // Signal the remote target that we're done JITing.
-    ExitOnErr(R->terminateSession());
+    ExitOnErr(EPC->disconnect());
   }
 
   return Result;
@@ -1098,7 +1097,7 @@ void disallowOrcOptions() {
   }
 }
 
-std::unique_ptr<orc::shared::FDRawByteChannel> launchRemote() {
+Expected<std::unique_ptr<orc::ExecutorProcessControl>> launchRemote() {
 #ifndef LLVM_ON_UNIX
   llvm_unreachable("launchRemote not supported on non-Unix platforms");
 #else
@@ -1147,8 +1146,8 @@ std::unique_ptr<orc::shared::FDRawByteChannel> launchRemote() {
   close(PipeFD[0][0]);
   close(PipeFD[1][1]);
 
-  // Return an RPC channel connected to our end of the pipes.
-  return std::make_unique<orc::shared::FDRawByteChannel>(PipeFD[1][0],
-                                                         PipeFD[0][1]);
+  // Return a SimpleRemoteEPC instance connected to our end of the pipes.
+  return orc::SimpleRemoteEPC::Create<orc::FDSimpleRemoteEPCTransport>(
+      PipeFD[1][0], PipeFD[0][1]);
 #endif
 }


        


More information about the llvm-commits mailing list