Update prebuilt Clang to r416183b from Android.

https://android.googlesource.com/platform/prebuilts/clang/host/
linux-x86/+/06a71ddac05c22edb2d10b590e1769b3f8619bef

clang 12.0.5 (based on r416183b) from build 7284624.

Change-Id: I277a316abcf47307562d8b748b84870f31a72866
Signed-off-by: Olivier Deprez <olivier.deprez@arm.com>
diff --git a/linux-x64/clang/include/llvm/ExecutionEngine/Orc/CompileOnDemandLayer.h b/linux-x64/clang/include/llvm/ExecutionEngine/Orc/CompileOnDemandLayer.h
index ca1ce40..67aa09b 100644
--- a/linux-x64/clang/include/llvm/ExecutionEngine/Orc/CompileOnDemandLayer.h
+++ b/linux-x64/clang/include/llvm/ExecutionEngine/Orc/CompileOnDemandLayer.h
@@ -18,14 +18,12 @@
 #include "llvm/ADT/Optional.h"
 #include "llvm/ADT/STLExtras.h"
 #include "llvm/ADT/StringRef.h"
-#include "llvm/ADT/Twine.h"
 #include "llvm/ExecutionEngine/JITSymbol.h"
 #include "llvm/ExecutionEngine/Orc/IndirectionUtils.h"
-#include "llvm/ExecutionEngine/Orc/LambdaResolver.h"
 #include "llvm/ExecutionEngine/Orc/Layer.h"
 #include "llvm/ExecutionEngine/Orc/LazyReexports.h"
-#include "llvm/ExecutionEngine/Orc/Legacy.h"
 #include "llvm/ExecutionEngine/Orc/OrcError.h"
+#include "llvm/ExecutionEngine/Orc/Speculation.h"
 #include "llvm/ExecutionEngine/RuntimeDyld.h"
 #include "llvm/IR/Attributes.h"
 #include "llvm/IR/Constant.h"
@@ -91,9 +89,13 @@
   /// Sets the partition function.
   void setPartitionFunction(PartitionFunction Partition);
 
+  /// Sets the ImplSymbolMap
+  void setImplMap(ImplSymbolMap *Imp);
+
   /// Emits the given module. This should not be called by clients: it will be
   /// called by the JIT when a definition added via the add method is requested.
-  void emit(MaterializationResponsibility R, ThreadSafeModule TSM) override;
+  void emit(std::unique_ptr<MaterializationResponsibility> R,
+            ThreadSafeModule TSM) override;
 
 private:
   struct PerDylibResources {
@@ -117,7 +119,8 @@
 
   void expandPartition(GlobalValueSet &Partition);
 
-  void emitPartition(MaterializationResponsibility R, ThreadSafeModule TSM,
+  void emitPartition(std::unique_ptr<MaterializationResponsibility> R,
+                     ThreadSafeModule TSM,
                      IRMaterializationUnit::SymbolNameToDefinitionMap Defs);
 
   mutable std::mutex CODLayerMutex;
@@ -128,609 +131,10 @@
   PerDylibResourcesMap DylibResources;
   PartitionFunction Partition = compileRequested;
   SymbolLinkagePromoter PromoteSymbols;
-};
-
-/// Compile-on-demand layer.
-///
-///   When a module is added to this layer a stub is created for each of its
-/// function definitions. The stubs and other global values are immediately
-/// added to the layer below. When a stub is called it triggers the extraction
-/// of the function body from the original module. The extracted body is then
-/// compiled and executed.
-template <typename BaseLayerT,
-          typename CompileCallbackMgrT = JITCompileCallbackManager,
-          typename IndirectStubsMgrT = IndirectStubsManager>
-class LegacyCompileOnDemandLayer {
-private:
-  template <typename MaterializerFtor>
-  class LambdaMaterializer final : public ValueMaterializer {
-  public:
-    LambdaMaterializer(MaterializerFtor M) : M(std::move(M)) {}
-
-    Value *materialize(Value *V) final { return M(V); }
-
-  private:
-    MaterializerFtor M;
-  };
-
-  template <typename MaterializerFtor>
-  LambdaMaterializer<MaterializerFtor>
-  createLambdaMaterializer(MaterializerFtor M) {
-    return LambdaMaterializer<MaterializerFtor>(std::move(M));
-  }
-
-  // Provide type-erasure for the Modules and MemoryManagers.
-  template <typename ResourceT>
-  class ResourceOwner {
-  public:
-    ResourceOwner() = default;
-    ResourceOwner(const ResourceOwner &) = delete;
-    ResourceOwner &operator=(const ResourceOwner &) = delete;
-    virtual ~ResourceOwner() = default;
-
-    virtual ResourceT& getResource() const = 0;
-  };
-
-  template <typename ResourceT, typename ResourcePtrT>
-  class ResourceOwnerImpl : public ResourceOwner<ResourceT> {
-  public:
-    ResourceOwnerImpl(ResourcePtrT ResourcePtr)
-      : ResourcePtr(std::move(ResourcePtr)) {}
-
-    ResourceT& getResource() const override { return *ResourcePtr; }
-
-  private:
-    ResourcePtrT ResourcePtr;
-  };
-
-  template <typename ResourceT, typename ResourcePtrT>
-  std::unique_ptr<ResourceOwner<ResourceT>>
-  wrapOwnership(ResourcePtrT ResourcePtr) {
-    using RO = ResourceOwnerImpl<ResourceT, ResourcePtrT>;
-    return llvm::make_unique<RO>(std::move(ResourcePtr));
-  }
-
-  struct LogicalDylib {
-    struct SourceModuleEntry {
-      std::unique_ptr<Module> SourceMod;
-      std::set<Function*> StubsToClone;
-    };
-
-    using SourceModulesList = std::vector<SourceModuleEntry>;
-    using SourceModuleHandle = typename SourceModulesList::size_type;
-
-    LogicalDylib() = default;
-
-    LogicalDylib(VModuleKey K, std::shared_ptr<SymbolResolver> BackingResolver,
-                 std::unique_ptr<IndirectStubsMgrT> StubsMgr)
-        : K(std::move(K)), BackingResolver(std::move(BackingResolver)),
-          StubsMgr(std::move(StubsMgr)) {}
-
-    SourceModuleHandle addSourceModule(std::unique_ptr<Module> M) {
-      SourceModuleHandle H = SourceModules.size();
-      SourceModules.push_back(SourceModuleEntry());
-      SourceModules.back().SourceMod = std::move(M);
-      return H;
-    }
-
-    Module& getSourceModule(SourceModuleHandle H) {
-      return *SourceModules[H].SourceMod;
-    }
-
-    std::set<Function*>& getStubsToClone(SourceModuleHandle H) {
-      return SourceModules[H].StubsToClone;
-    }
-
-    JITSymbol findSymbol(BaseLayerT &BaseLayer, const std::string &Name,
-                         bool ExportedSymbolsOnly) {
-      if (auto Sym = StubsMgr->findStub(Name, ExportedSymbolsOnly))
-        return Sym;
-      for (auto BLK : BaseLayerVModuleKeys)
-        if (auto Sym = BaseLayer.findSymbolIn(BLK, Name, ExportedSymbolsOnly))
-          return Sym;
-        else if (auto Err = Sym.takeError())
-          return std::move(Err);
-      return nullptr;
-    }
-
-    Error removeModulesFromBaseLayer(BaseLayerT &BaseLayer) {
-      for (auto &BLK : BaseLayerVModuleKeys)
-        if (auto Err = BaseLayer.removeModule(BLK))
-          return Err;
-      return Error::success();
-    }
-
-    VModuleKey K;
-    std::shared_ptr<SymbolResolver> BackingResolver;
-    std::unique_ptr<IndirectStubsMgrT> StubsMgr;
-    SymbolLinkagePromoter PromoteSymbols;
-    SourceModulesList SourceModules;
-    std::vector<VModuleKey> BaseLayerVModuleKeys;
-  };
-
-public:
-
-  /// Module partitioning functor.
-  using PartitioningFtor = std::function<std::set<Function*>(Function&)>;
-
-  /// Builder for IndirectStubsManagers.
-  using IndirectStubsManagerBuilderT =
-      std::function<std::unique_ptr<IndirectStubsMgrT>()>;
-
-  using SymbolResolverGetter =
-      std::function<std::shared_ptr<SymbolResolver>(VModuleKey K)>;
-
-  using SymbolResolverSetter =
-      std::function<void(VModuleKey K, std::shared_ptr<SymbolResolver> R)>;
-
-  /// Construct a compile-on-demand layer instance.
-  LegacyCompileOnDemandLayer(ExecutionSession &ES, BaseLayerT &BaseLayer,
-                             SymbolResolverGetter GetSymbolResolver,
-                             SymbolResolverSetter SetSymbolResolver,
-                             PartitioningFtor Partition,
-                             CompileCallbackMgrT &CallbackMgr,
-                             IndirectStubsManagerBuilderT CreateIndirectStubsManager,
-                             bool CloneStubsIntoPartitions = true)
-      : ES(ES), BaseLayer(BaseLayer),
-        GetSymbolResolver(std::move(GetSymbolResolver)),
-        SetSymbolResolver(std::move(SetSymbolResolver)),
-        Partition(std::move(Partition)), CompileCallbackMgr(CallbackMgr),
-        CreateIndirectStubsManager(std::move(CreateIndirectStubsManager)),
-        CloneStubsIntoPartitions(CloneStubsIntoPartitions) {}
-
-  ~LegacyCompileOnDemandLayer() {
-    // FIXME: Report error on log.
-    while (!LogicalDylibs.empty())
-      consumeError(removeModule(LogicalDylibs.begin()->first));
-  }
-
-  /// Add a module to the compile-on-demand layer.
-  Error addModule(VModuleKey K, std::unique_ptr<Module> M) {
-
-    assert(!LogicalDylibs.count(K) && "VModuleKey K already in use");
-    auto I = LogicalDylibs.insert(
-        LogicalDylibs.end(),
-        std::make_pair(K, LogicalDylib(K, GetSymbolResolver(K),
-                                       CreateIndirectStubsManager())));
-
-    return addLogicalModule(I->second, std::move(M));
-  }
-
-  /// Add extra modules to an existing logical module.
-  Error addExtraModule(VModuleKey K, std::unique_ptr<Module> M) {
-    return addLogicalModule(LogicalDylibs[K], std::move(M));
-  }
-
-  /// Remove the module represented by the given key.
-  ///
-  ///   This will remove all modules in the layers below that were derived from
-  /// the module represented by K.
-  Error removeModule(VModuleKey K) {
-    auto I = LogicalDylibs.find(K);
-    assert(I != LogicalDylibs.end() && "VModuleKey K not valid here");
-    auto Err = I->second.removeModulesFromBaseLayer(BaseLayer);
-    LogicalDylibs.erase(I);
-    return Err;
-  }
-
-  /// Search for the given named symbol.
-  /// @param Name The name of the symbol to search for.
-  /// @param ExportedSymbolsOnly If true, search only for exported symbols.
-  /// @return A handle for the given named symbol, if it exists.
-  JITSymbol findSymbol(StringRef Name, bool ExportedSymbolsOnly) {
-    for (auto &KV : LogicalDylibs) {
-      if (auto Sym = KV.second.StubsMgr->findStub(Name, ExportedSymbolsOnly))
-        return Sym;
-      if (auto Sym = findSymbolIn(KV.first, Name, ExportedSymbolsOnly))
-        return Sym;
-      else if (auto Err = Sym.takeError())
-        return std::move(Err);
-    }
-    return BaseLayer.findSymbol(Name, ExportedSymbolsOnly);
-  }
-
-  /// Get the address of a symbol provided by this layer, or some layer
-  ///        below this one.
-  JITSymbol findSymbolIn(VModuleKey K, const std::string &Name,
-                         bool ExportedSymbolsOnly) {
-    assert(LogicalDylibs.count(K) && "VModuleKey K is not valid here");
-    return LogicalDylibs[K].findSymbol(BaseLayer, Name, ExportedSymbolsOnly);
-  }
-
-  /// Update the stub for the given function to point at FnBodyAddr.
-  /// This can be used to support re-optimization.
-  /// @return true if the function exists and the stub is updated, false
-  ///         otherwise.
-  //
-  // FIXME: We should track and free associated resources (unused compile
-  //        callbacks, uncompiled IR, and no-longer-needed/reachable function
-  //        implementations).
-  Error updatePointer(std::string FuncName, JITTargetAddress FnBodyAddr) {
-    //Find out which logical dylib contains our symbol
-    auto LDI = LogicalDylibs.begin();
-    for (auto LDE = LogicalDylibs.end(); LDI != LDE; ++LDI) {
-      if (auto LMResources =
-            LDI->getLogicalModuleResourcesForSymbol(FuncName, false)) {
-        Module &SrcM = LMResources->SourceModule->getResource();
-        std::string CalledFnName = mangle(FuncName, SrcM.getDataLayout());
-        if (auto Err = LMResources->StubsMgr->updatePointer(CalledFnName,
-                                                            FnBodyAddr))
-          return Err;
-        return Error::success();
-      }
-    }
-    return make_error<JITSymbolNotFound>(FuncName);
-  }
-
-private:
-  Error addLogicalModule(LogicalDylib &LD, std::unique_ptr<Module> SrcMPtr) {
-
-    // Rename anonymous globals and promote linkage to ensure that everything
-    // will resolve properly after we partition SrcM.
-    LD.PromoteSymbols(*SrcMPtr);
-
-    // Create a logical module handle for SrcM within the logical dylib.
-    Module &SrcM = *SrcMPtr;
-    auto LMId = LD.addSourceModule(std::move(SrcMPtr));
-
-    // Create stub functions.
-    const DataLayout &DL = SrcM.getDataLayout();
-    {
-      typename IndirectStubsMgrT::StubInitsMap StubInits;
-      for (auto &F : SrcM) {
-        // Skip declarations.
-        if (F.isDeclaration())
-          continue;
-
-        // Skip weak functions for which we already have definitions.
-        auto MangledName = mangle(F.getName(), DL);
-        if (F.hasWeakLinkage() || F.hasLinkOnceLinkage()) {
-          if (auto Sym = LD.findSymbol(BaseLayer, MangledName, false))
-            continue;
-          else if (auto Err = Sym.takeError())
-            return std::move(Err);
-        }
-
-        // Record all functions defined by this module.
-        if (CloneStubsIntoPartitions)
-          LD.getStubsToClone(LMId).insert(&F);
-
-        // Create a callback, associate it with the stub for the function,
-        // and set the compile action to compile the partition containing the
-        // function.
-        auto CompileAction = [this, &LD, LMId, &F]() -> JITTargetAddress {
-          if (auto FnImplAddrOrErr = this->extractAndCompile(LD, LMId, F))
-            return *FnImplAddrOrErr;
-          else {
-            // FIXME: Report error, return to 'abort' or something similar.
-            consumeError(FnImplAddrOrErr.takeError());
-            return 0;
-          }
-        };
-        if (auto CCAddr =
-                CompileCallbackMgr.getCompileCallback(std::move(CompileAction)))
-          StubInits[MangledName] =
-              std::make_pair(*CCAddr, JITSymbolFlags::fromGlobalValue(F));
-        else
-          return CCAddr.takeError();
-      }
-
-      if (auto Err = LD.StubsMgr->createStubs(StubInits))
-        return Err;
-    }
-
-    // If this module doesn't contain any globals, aliases, or module flags then
-    // we can bail out early and avoid the overhead of creating and managing an
-    // empty globals module.
-    if (SrcM.global_empty() && SrcM.alias_empty() &&
-        !SrcM.getModuleFlagsMetadata())
-      return Error::success();
-
-    // Create the GlobalValues module.
-    auto GVsM = llvm::make_unique<Module>((SrcM.getName() + ".globals").str(),
-                                          SrcM.getContext());
-    GVsM->setDataLayout(DL);
-
-    ValueToValueMapTy VMap;
-
-    // Clone global variable decls.
-    for (auto &GV : SrcM.globals())
-      if (!GV.isDeclaration() && !VMap.count(&GV))
-        cloneGlobalVariableDecl(*GVsM, GV, &VMap);
-
-    // And the aliases.
-    for (auto &A : SrcM.aliases())
-      if (!VMap.count(&A))
-        cloneGlobalAliasDecl(*GVsM, A, VMap);
-
-    // Clone the module flags.
-    cloneModuleFlagsMetadata(*GVsM, SrcM, VMap);
-
-    // Now we need to clone the GV and alias initializers.
-
-    // Initializers may refer to functions declared (but not defined) in this
-    // module. Build a materializer to clone decls on demand.
-    auto Materializer = createLambdaMaterializer(
-      [&LD, &GVsM](Value *V) -> Value* {
-        if (auto *F = dyn_cast<Function>(V)) {
-          // Decls in the original module just get cloned.
-          if (F->isDeclaration())
-            return cloneFunctionDecl(*GVsM, *F);
-
-          // Definitions in the original module (which we have emitted stubs
-          // for at this point) get turned into a constant alias to the stub
-          // instead.
-          const DataLayout &DL = GVsM->getDataLayout();
-          std::string FName = mangle(F->getName(), DL);
-          unsigned PtrBitWidth = DL.getPointerTypeSizeInBits(F->getType());
-          JITTargetAddress StubAddr =
-            LD.StubsMgr->findStub(FName, false).getAddress();
-
-          ConstantInt *StubAddrCI =
-            ConstantInt::get(GVsM->getContext(), APInt(PtrBitWidth, StubAddr));
-          Constant *Init = ConstantExpr::getCast(Instruction::IntToPtr,
-                                                 StubAddrCI, F->getType());
-          return GlobalAlias::create(F->getFunctionType(),
-                                     F->getType()->getAddressSpace(),
-                                     F->getLinkage(), F->getName(),
-                                     Init, GVsM.get());
-        }
-        // else....
-        return nullptr;
-      });
-
-    // Clone the global variable initializers.
-    for (auto &GV : SrcM.globals())
-      if (!GV.isDeclaration())
-        moveGlobalVariableInitializer(GV, VMap, &Materializer);
-
-    // Clone the global alias initializers.
-    for (auto &A : SrcM.aliases()) {
-      auto *NewA = cast<GlobalAlias>(VMap[&A]);
-      assert(NewA && "Alias not cloned?");
-      Value *Init = MapValue(A.getAliasee(), VMap, RF_None, nullptr,
-                             &Materializer);
-      NewA->setAliasee(cast<Constant>(Init));
-    }
-
-    // Build a resolver for the globals module and add it to the base layer.
-    auto LegacyLookup = [this, &LD](const std::string &Name) -> JITSymbol {
-      if (auto Sym = LD.StubsMgr->findStub(Name, false))
-        return Sym;
-
-      if (auto Sym = LD.findSymbol(BaseLayer, Name, false))
-        return Sym;
-      else if (auto Err = Sym.takeError())
-        return std::move(Err);
-
-      return nullptr;
-    };
-
-    auto GVsResolver = createSymbolResolver(
-        [&LD, LegacyLookup](const SymbolNameSet &Symbols) {
-          auto RS = getResponsibilitySetWithLegacyFn(Symbols, LegacyLookup);
-
-          if (!RS) {
-            logAllUnhandledErrors(
-                RS.takeError(), errs(),
-                "CODLayer/GVsResolver responsibility set lookup failed: ");
-            return SymbolNameSet();
-          }
-
-          if (RS->size() == Symbols.size())
-            return *RS;
-
-          SymbolNameSet NotFoundViaLegacyLookup;
-          for (auto &S : Symbols)
-            if (!RS->count(S))
-              NotFoundViaLegacyLookup.insert(S);
-          auto RS2 =
-              LD.BackingResolver->getResponsibilitySet(NotFoundViaLegacyLookup);
-
-          for (auto &S : RS2)
-            (*RS).insert(S);
-
-          return *RS;
-        },
-        [this, &LD,
-         LegacyLookup](std::shared_ptr<AsynchronousSymbolQuery> Query,
-                       SymbolNameSet Symbols) {
-          auto NotFoundViaLegacyLookup =
-              lookupWithLegacyFn(ES, *Query, Symbols, LegacyLookup);
-          return LD.BackingResolver->lookup(Query, NotFoundViaLegacyLookup);
-        });
-
-    SetSymbolResolver(LD.K, std::move(GVsResolver));
-
-    if (auto Err = BaseLayer.addModule(LD.K, std::move(GVsM)))
-      return Err;
-
-    LD.BaseLayerVModuleKeys.push_back(LD.K);
-
-    return Error::success();
-  }
-
-  static std::string mangle(StringRef Name, const DataLayout &DL) {
-    std::string MangledName;
-    {
-      raw_string_ostream MangledNameStream(MangledName);
-      Mangler::getNameWithPrefix(MangledNameStream, Name, DL);
-    }
-    return MangledName;
-  }
-
-  Expected<JITTargetAddress>
-  extractAndCompile(LogicalDylib &LD,
-                    typename LogicalDylib::SourceModuleHandle LMId,
-                    Function &F) {
-    Module &SrcM = LD.getSourceModule(LMId);
-
-    // If F is a declaration we must already have compiled it.
-    if (F.isDeclaration())
-      return 0;
-
-    // Grab the name of the function being called here.
-    std::string CalledFnName = mangle(F.getName(), SrcM.getDataLayout());
-
-    JITTargetAddress CalledAddr = 0;
-    auto Part = Partition(F);
-    if (auto PartKeyOrErr = emitPartition(LD, LMId, Part)) {
-      auto &PartKey = *PartKeyOrErr;
-      for (auto *SubF : Part) {
-        std::string FnName = mangle(SubF->getName(), SrcM.getDataLayout());
-        if (auto FnBodySym = BaseLayer.findSymbolIn(PartKey, FnName, false)) {
-          if (auto FnBodyAddrOrErr = FnBodySym.getAddress()) {
-            JITTargetAddress FnBodyAddr = *FnBodyAddrOrErr;
-
-            // If this is the function we're calling record the address so we can
-            // return it from this function.
-            if (SubF == &F)
-              CalledAddr = FnBodyAddr;
-
-            // Update the function body pointer for the stub.
-            if (auto EC = LD.StubsMgr->updatePointer(FnName, FnBodyAddr))
-              return 0;
-
-          } else
-            return FnBodyAddrOrErr.takeError();
-        } else if (auto Err = FnBodySym.takeError())
-          return std::move(Err);
-        else
-          llvm_unreachable("Function not emitted for partition");
-      }
-
-      LD.BaseLayerVModuleKeys.push_back(PartKey);
-    } else
-      return PartKeyOrErr.takeError();
-
-    return CalledAddr;
-  }
-
-  template <typename PartitionT>
-  Expected<VModuleKey>
-  emitPartition(LogicalDylib &LD,
-                typename LogicalDylib::SourceModuleHandle LMId,
-                const PartitionT &Part) {
-    Module &SrcM = LD.getSourceModule(LMId);
-
-    // Create the module.
-    std::string NewName = SrcM.getName();
-    for (auto *F : Part) {
-      NewName += ".";
-      NewName += F->getName();
-    }
-
-    auto M = llvm::make_unique<Module>(NewName, SrcM.getContext());
-    M->setDataLayout(SrcM.getDataLayout());
-    ValueToValueMapTy VMap;
-
-    auto Materializer = createLambdaMaterializer([&LD, &LMId,
-                                                  &M](Value *V) -> Value * {
-      if (auto *GV = dyn_cast<GlobalVariable>(V))
-        return cloneGlobalVariableDecl(*M, *GV);
-
-      if (auto *F = dyn_cast<Function>(V)) {
-        // Check whether we want to clone an available_externally definition.
-        if (!LD.getStubsToClone(LMId).count(F))
-          return cloneFunctionDecl(*M, *F);
-
-        // Ok - we want an inlinable stub. For that to work we need a decl
-        // for the stub pointer.
-        auto *StubPtr = createImplPointer(*F->getType(), *M,
-                                          F->getName() + "$stub_ptr", nullptr);
-        auto *ClonedF = cloneFunctionDecl(*M, *F);
-        makeStub(*ClonedF, *StubPtr);
-        ClonedF->setLinkage(GlobalValue::AvailableExternallyLinkage);
-        ClonedF->addFnAttr(Attribute::AlwaysInline);
-        return ClonedF;
-      }
-
-      if (auto *A = dyn_cast<GlobalAlias>(V)) {
-        auto *Ty = A->getValueType();
-        if (Ty->isFunctionTy())
-          return Function::Create(cast<FunctionType>(Ty),
-                                  GlobalValue::ExternalLinkage, A->getName(),
-                                  M.get());
-
-        return new GlobalVariable(*M, Ty, false, GlobalValue::ExternalLinkage,
-                                  nullptr, A->getName(), nullptr,
-                                  GlobalValue::NotThreadLocal,
-                                  A->getType()->getAddressSpace());
-      }
-
-      return nullptr;
-    });
-
-    // Create decls in the new module.
-    for (auto *F : Part)
-      cloneFunctionDecl(*M, *F, &VMap);
-
-    // Move the function bodies.
-    for (auto *F : Part)
-      moveFunctionBody(*F, VMap, &Materializer);
-
-    auto K = ES.allocateVModule();
-
-    auto LegacyLookup = [this, &LD](const std::string &Name) -> JITSymbol {
-      return LD.findSymbol(BaseLayer, Name, false);
-    };
-
-    // Create memory manager and symbol resolver.
-    auto Resolver = createSymbolResolver(
-        [&LD, LegacyLookup](const SymbolNameSet &Symbols) {
-          auto RS = getResponsibilitySetWithLegacyFn(Symbols, LegacyLookup);
-          if (!RS) {
-            logAllUnhandledErrors(
-                RS.takeError(), errs(),
-                "CODLayer/SubResolver responsibility set lookup failed: ");
-            return SymbolNameSet();
-          }
-
-          if (RS->size() == Symbols.size())
-            return *RS;
-
-          SymbolNameSet NotFoundViaLegacyLookup;
-          for (auto &S : Symbols)
-            if (!RS->count(S))
-              NotFoundViaLegacyLookup.insert(S);
-
-          auto RS2 =
-              LD.BackingResolver->getResponsibilitySet(NotFoundViaLegacyLookup);
-
-          for (auto &S : RS2)
-            (*RS).insert(S);
-
-          return *RS;
-        },
-        [this, &LD, LegacyLookup](std::shared_ptr<AsynchronousSymbolQuery> Q,
-                                  SymbolNameSet Symbols) {
-          auto NotFoundViaLegacyLookup =
-              lookupWithLegacyFn(ES, *Q, Symbols, LegacyLookup);
-          return LD.BackingResolver->lookup(Q,
-                                            std::move(NotFoundViaLegacyLookup));
-        });
-    SetSymbolResolver(K, std::move(Resolver));
-
-    if (auto Err = BaseLayer.addModule(std::move(K), std::move(M)))
-      return std::move(Err);
-
-    return K;
-  }
-
-  ExecutionSession &ES;
-  BaseLayerT &BaseLayer;
-  SymbolResolverGetter GetSymbolResolver;
-  SymbolResolverSetter SetSymbolResolver;
-  PartitioningFtor Partition;
-  CompileCallbackMgrT &CompileCallbackMgr;
-  IndirectStubsManagerBuilderT CreateIndirectStubsManager;
-
-  std::map<VModuleKey, LogicalDylib> LogicalDylibs;
-  bool CloneStubsIntoPartitions;
+  ImplSymbolMap *AliaseeImpls = nullptr;
 };
 
 } // end namespace orc
-
 } // end namespace llvm
 
 #endif // LLVM_EXECUTIONENGINE_ORC_COMPILEONDEMANDLAYER_H
diff --git a/linux-x64/clang/include/llvm/ExecutionEngine/Orc/CompileUtils.h b/linux-x64/clang/include/llvm/ExecutionEngine/Orc/CompileUtils.h
index 1585925..c7ba572 100644
--- a/linux-x64/clang/include/llvm/ExecutionEngine/Orc/CompileUtils.h
+++ b/linux-x64/clang/include/llvm/ExecutionEngine/Orc/CompileUtils.h
@@ -13,12 +13,13 @@
 #ifndef LLVM_EXECUTIONENGINE_ORC_COMPILEUTILS_H
 #define LLVM_EXECUTIONENGINE_ORC_COMPILEUTILS_H
 
+#include "llvm/ExecutionEngine/Orc/IRCompileLayer.h"
 #include "llvm/ExecutionEngine/Orc/JITTargetMachineBuilder.h"
+#include "llvm/ExecutionEngine/Orc/Layer.h"
 #include <memory>
 
 namespace llvm {
 
-class JITTargetMachineBuilder;
 class MCContext;
 class MemoryBuffer;
 class Module;
@@ -27,24 +28,31 @@
 
 namespace orc {
 
+IRSymbolMapper::ManglingOptions
+irManglingOptionsFromTargetOptions(const TargetOptions &Opts);
+
 /// Simple compile functor: Takes a single IR module and returns an ObjectFile.
 /// This compiler supports a single compilation thread and LLVMContext only.
 /// For multithreaded compilation, use ConcurrentIRCompiler below.
-class SimpleCompiler {
+class SimpleCompiler : public IRCompileLayer::IRCompiler {
 public:
   using CompileResult = std::unique_ptr<MemoryBuffer>;
 
   /// Construct a simple compile functor with the given target.
   SimpleCompiler(TargetMachine &TM, ObjectCache *ObjCache = nullptr)
-    : TM(TM), ObjCache(ObjCache) {}
+      : IRCompiler(irManglingOptionsFromTargetOptions(TM.Options)), TM(TM),
+        ObjCache(ObjCache) {}
 
   /// Set an ObjectCache to query before compiling.
   void setObjectCache(ObjectCache *NewCache) { ObjCache = NewCache; }
 
   /// Compile a Module to an ObjectFile.
-  CompileResult operator()(Module &M);
+  Expected<CompileResult> operator()(Module &M) override;
 
 private:
+  IRSymbolMapper::ManglingOptions
+  manglingOptionsForTargetMachine(const TargetMachine &TM);
+
   CompileResult tryToLoadFromObjectCache(const Module &M);
   void notifyObjectCompiled(const Module &M, const MemoryBuffer &ObjBuffer);
 
@@ -52,18 +60,34 @@
   ObjectCache *ObjCache = nullptr;
 };
 
+/// A SimpleCompiler that owns its TargetMachine.
+///
+/// This convenient for clients who don't want to own their TargetMachines,
+/// e.g. LLJIT.
+class TMOwningSimpleCompiler : public SimpleCompiler {
+public:
+  TMOwningSimpleCompiler(std::unique_ptr<TargetMachine> TM,
+                         ObjectCache *ObjCache = nullptr)
+      : SimpleCompiler(*TM, ObjCache), TM(std::move(TM)) {}
+
+private:
+  // FIXME: shared because std::functions (and consequently
+  // IRCompileLayer::CompileFunction) are not moveable.
+  std::shared_ptr<llvm::TargetMachine> TM;
+};
+
 /// A thread-safe version of SimpleCompiler.
 ///
 /// This class creates a new TargetMachine and SimpleCompiler instance for each
 /// compile.
-class ConcurrentIRCompiler {
+class ConcurrentIRCompiler : public IRCompileLayer::IRCompiler {
 public:
   ConcurrentIRCompiler(JITTargetMachineBuilder JTMB,
                        ObjectCache *ObjCache = nullptr);
 
   void setObjectCache(ObjectCache *ObjCache) { this->ObjCache = ObjCache; }
 
-  std::unique_ptr<MemoryBuffer> operator()(Module &M);
+  Expected<std::unique_ptr<MemoryBuffer>> operator()(Module &M) override;
 
 private:
   JITTargetMachineBuilder JTMB;
diff --git a/linux-x64/clang/include/llvm/ExecutionEngine/Orc/Core.h b/linux-x64/clang/include/llvm/ExecutionEngine/Orc/Core.h
index 016fd82..4a4b58e 100644
--- a/linux-x64/clang/include/llvm/ExecutionEngine/Orc/Core.h
+++ b/linux-x64/clang/include/llvm/ExecutionEngine/Orc/Core.h
@@ -14,16 +14,19 @@
 #define LLVM_EXECUTIONENGINE_ORC_CORE_H
 
 #include "llvm/ADT/BitmaskEnum.h"
+#include "llvm/ADT/DenseSet.h"
+#include "llvm/ADT/FunctionExtras.h"
+#include "llvm/ADT/IntrusiveRefCntPtr.h"
+#include "llvm/ExecutionEngine/JITLink/JITLinkDylib.h"
 #include "llvm/ExecutionEngine/JITSymbol.h"
 #include "llvm/ExecutionEngine/Orc/SymbolStringPool.h"
-#include "llvm/IR/Module.h"
+#include "llvm/ExecutionEngine/OrcV1Deprecation.h"
 #include "llvm/Support/Debug.h"
 
+#include <atomic>
 #include <memory>
 #include <vector>
 
-#define DEBUG_TYPE "orc"
-
 namespace llvm {
 namespace orc {
 
@@ -33,29 +36,333 @@
 class MaterializationUnit;
 class MaterializationResponsibility;
 class JITDylib;
+class ResourceTracker;
+class InProgressLookupState;
+
 enum class SymbolState : uint8_t;
 
-/// VModuleKey provides a unique identifier (allocated and managed by
-/// ExecutionSessions) for a module added to the JIT.
-using VModuleKey = uint64_t;
+using ResourceTrackerSP = IntrusiveRefCntPtr<ResourceTracker>;
+using JITDylibSP = IntrusiveRefCntPtr<JITDylib>;
+
+using ResourceKey = uintptr_t;
+
+/// API to remove / transfer ownership of JIT resources.
+class ResourceTracker : public ThreadSafeRefCountedBase<ResourceTracker> {
+private:
+  friend class ExecutionSession;
+  friend class JITDylib;
+  friend class MaterializationResponsibility;
+
+public:
+  ResourceTracker(const ResourceTracker &) = delete;
+  ResourceTracker &operator=(const ResourceTracker &) = delete;
+  ResourceTracker(ResourceTracker &&) = delete;
+  ResourceTracker &operator=(ResourceTracker &&) = delete;
+
+  ~ResourceTracker();
+
+  /// Return the JITDylib targeted by this tracker.
+  JITDylib &getJITDylib() const {
+    return *reinterpret_cast<JITDylib *>(JDAndFlag.load() &
+                                         ~static_cast<uintptr_t>(1));
+  }
+
+  /// Remove all resources associated with this key.
+  Error remove();
+
+  /// Transfer all resources associated with this key to the given
+  /// tracker, which must target the same JITDylib as this one.
+  void transferTo(ResourceTracker &DstRT);
+
+  /// Return true if this tracker has become defunct.
+  bool isDefunct() const { return JDAndFlag.load() & 0x1; }
+
+  /// Returns the key associated with this tracker.
+  /// This method should not be used except for debug logging: there is no
+  /// guarantee that the returned value will remain valid.
+  ResourceKey getKeyUnsafe() const { return reinterpret_cast<uintptr_t>(this); }
+
+private:
+  ResourceTracker(JITDylibSP JD);
+
+  void makeDefunct();
+
+  std::atomic_uintptr_t JDAndFlag;
+};
+
+/// Listens for ResourceTracker operations.
+class ResourceManager {
+public:
+  virtual ~ResourceManager();
+  virtual Error handleRemoveResources(ResourceKey K) = 0;
+  virtual void handleTransferResources(ResourceKey DstK, ResourceKey SrcK) = 0;
+};
 
 /// A set of symbol names (represented by SymbolStringPtrs for
 //         efficiency).
 using SymbolNameSet = DenseSet<SymbolStringPtr>;
 
+/// A vector of symbol names.
+using SymbolNameVector = std::vector<SymbolStringPtr>;
+
 /// A map from symbol names (as SymbolStringPtrs) to JITSymbols
-///        (address/flags pairs).
+/// (address/flags pairs).
 using SymbolMap = DenseMap<SymbolStringPtr, JITEvaluatedSymbol>;
 
 /// A map from symbol names (as SymbolStringPtrs) to JITSymbolFlags.
 using SymbolFlagsMap = DenseMap<SymbolStringPtr, JITSymbolFlags>;
 
-/// A base class for materialization failures that allows the failing
-///        symbols to be obtained for logging.
+/// A map from JITDylibs to sets of symbols.
 using SymbolDependenceMap = DenseMap<JITDylib *, SymbolNameSet>;
 
-/// A list of (JITDylib*, bool) pairs.
-using JITDylibSearchList = std::vector<std::pair<JITDylib *, bool>>;
+/// Lookup flags that apply to each dylib in the search order for a lookup.
+///
+/// If MatchHiddenSymbolsOnly is used (the default) for a given dylib, then
+/// only symbols in that Dylib's interface will be searched. If
+/// MatchHiddenSymbols is used then symbols with hidden visibility will match
+/// as well.
+enum class JITDylibLookupFlags { MatchExportedSymbolsOnly, MatchAllSymbols };
+
+/// Lookup flags that apply to each symbol in a lookup.
+///
+/// If RequiredSymbol is used (the default) for a given symbol then that symbol
+/// must be found during the lookup or the lookup will fail returning a
+/// SymbolNotFound error. If WeaklyReferencedSymbol is used and the given
+/// symbol is not found then the query will continue, and no result for the
+/// missing symbol will be present in the result (assuming the rest of the
+/// lookup succeeds).
+enum class SymbolLookupFlags { RequiredSymbol, WeaklyReferencedSymbol };
+
+/// Describes the kind of lookup being performed. The lookup kind is passed to
+/// symbol generators (if they're invoked) to help them determine what
+/// definitions to generate.
+///
+/// Static -- Lookup is being performed as-if at static link time (e.g.
+///           generators representing static archives should pull in new
+///           definitions).
+///
+/// DLSym -- Lookup is being performed as-if at runtime (e.g. generators
+///          representing static archives should not pull in new definitions).
+enum class LookupKind { Static, DLSym };
+
+/// A list of (JITDylib*, JITDylibLookupFlags) pairs to be used as a search
+/// order during symbol lookup.
+using JITDylibSearchOrder =
+    std::vector<std::pair<JITDylib *, JITDylibLookupFlags>>;
+
+/// Convenience function for creating a search order from an ArrayRef of
+/// JITDylib*, all with the same flags.
+inline JITDylibSearchOrder makeJITDylibSearchOrder(
+    ArrayRef<JITDylib *> JDs,
+    JITDylibLookupFlags Flags = JITDylibLookupFlags::MatchExportedSymbolsOnly) {
+  JITDylibSearchOrder O;
+  O.reserve(JDs.size());
+  for (auto *JD : JDs)
+    O.push_back(std::make_pair(JD, Flags));
+  return O;
+}
+
+/// A set of symbols to look up, each associated with a SymbolLookupFlags
+/// value.
+///
+/// This class is backed by a vector and optimized for fast insertion,
+/// deletion and iteration. It does not guarantee a stable order between
+/// operations, and will not automatically detect duplicate elements (they
+/// can be manually checked by calling the validate method).
+class SymbolLookupSet {
+public:
+  using value_type = std::pair<SymbolStringPtr, SymbolLookupFlags>;
+  using UnderlyingVector = std::vector<value_type>;
+  using iterator = UnderlyingVector::iterator;
+  using const_iterator = UnderlyingVector::const_iterator;
+
+  SymbolLookupSet() = default;
+
+  explicit SymbolLookupSet(
+      SymbolStringPtr Name,
+      SymbolLookupFlags Flags = SymbolLookupFlags::RequiredSymbol) {
+    add(std::move(Name), Flags);
+  }
+
+  /// Construct a SymbolLookupSet from an initializer list of SymbolStringPtrs.
+  explicit SymbolLookupSet(
+      std::initializer_list<SymbolStringPtr> Names,
+      SymbolLookupFlags Flags = SymbolLookupFlags::RequiredSymbol) {
+    Symbols.reserve(Names.size());
+    for (auto &Name : Names)
+      add(std::move(Name), Flags);
+  }
+
+  /// Construct a SymbolLookupSet from a SymbolNameSet with the given
+  /// Flags used for each value.
+  explicit SymbolLookupSet(
+      const SymbolNameSet &Names,
+      SymbolLookupFlags Flags = SymbolLookupFlags::RequiredSymbol) {
+    Symbols.reserve(Names.size());
+    for (const auto &Name : Names)
+      add(Name, Flags);
+  }
+
+  /// Construct a SymbolLookupSet from a vector of symbols with the given Flags
+  /// used for each value.
+  /// If the ArrayRef contains duplicates it is up to the client to remove these
+  /// before using this instance for lookup.
+  explicit SymbolLookupSet(
+      ArrayRef<SymbolStringPtr> Names,
+      SymbolLookupFlags Flags = SymbolLookupFlags::RequiredSymbol) {
+    Symbols.reserve(Names.size());
+    for (const auto &Name : Names)
+      add(Name, Flags);
+  }
+
+  /// Add an element to the set. The client is responsible for checking that
+  /// duplicates are not added.
+  SymbolLookupSet &
+  add(SymbolStringPtr Name,
+      SymbolLookupFlags Flags = SymbolLookupFlags::RequiredSymbol) {
+    Symbols.push_back(std::make_pair(std::move(Name), Flags));
+    return *this;
+  }
+
+  /// Quickly append one lookup set to another.
+  SymbolLookupSet &append(SymbolLookupSet Other) {
+    Symbols.reserve(Symbols.size() + Other.size());
+    for (auto &KV : Other)
+      Symbols.push_back(std::move(KV));
+    return *this;
+  }
+
+  bool empty() const { return Symbols.empty(); }
+  UnderlyingVector::size_type size() const { return Symbols.size(); }
+  iterator begin() { return Symbols.begin(); }
+  iterator end() { return Symbols.end(); }
+  const_iterator begin() const { return Symbols.begin(); }
+  const_iterator end() const { return Symbols.end(); }
+
+  /// Removes the Ith element of the vector, replacing it with the last element.
+  void remove(UnderlyingVector::size_type I) {
+    std::swap(Symbols[I], Symbols.back());
+    Symbols.pop_back();
+  }
+
+  /// Removes the element pointed to by the given iterator. This iterator and
+  /// all subsequent ones (including end()) are invalidated.
+  void remove(iterator I) { remove(I - begin()); }
+
+  /// Removes all elements matching the given predicate, which must be callable
+  /// as bool(const SymbolStringPtr &, SymbolLookupFlags Flags).
+  template <typename PredFn> void remove_if(PredFn &&Pred) {
+    UnderlyingVector::size_type I = 0;
+    while (I != Symbols.size()) {
+      const auto &Name = Symbols[I].first;
+      auto Flags = Symbols[I].second;
+      if (Pred(Name, Flags))
+        remove(I);
+      else
+        ++I;
+    }
+  }
+
+  /// Loop over the elements of this SymbolLookupSet, applying the Body function
+  /// to each one. Body must be callable as
+  /// bool(const SymbolStringPtr &, SymbolLookupFlags).
+  /// If Body returns true then the element just passed in is removed from the
+  /// set. If Body returns false then the element is retained.
+  template <typename BodyFn>
+  auto forEachWithRemoval(BodyFn &&Body) -> std::enable_if_t<
+      std::is_same<decltype(Body(std::declval<const SymbolStringPtr &>(),
+                                 std::declval<SymbolLookupFlags>())),
+                   bool>::value> {
+    UnderlyingVector::size_type I = 0;
+    while (I != Symbols.size()) {
+      const auto &Name = Symbols[I].first;
+      auto Flags = Symbols[I].second;
+      if (Body(Name, Flags))
+        remove(I);
+      else
+        ++I;
+    }
+  }
+
+  /// Loop over the elements of this SymbolLookupSet, applying the Body function
+  /// to each one. Body must be callable as
+  /// Expected<bool>(const SymbolStringPtr &, SymbolLookupFlags).
+  /// If Body returns a failure value, the loop exits immediately. If Body
+  /// returns true then the element just passed in is removed from the set. If
+  /// Body returns false then the element is retained.
+  template <typename BodyFn>
+  auto forEachWithRemoval(BodyFn &&Body) -> std::enable_if_t<
+      std::is_same<decltype(Body(std::declval<const SymbolStringPtr &>(),
+                                 std::declval<SymbolLookupFlags>())),
+                   Expected<bool>>::value,
+      Error> {
+    UnderlyingVector::size_type I = 0;
+    while (I != Symbols.size()) {
+      const auto &Name = Symbols[I].first;
+      auto Flags = Symbols[I].second;
+      auto Remove = Body(Name, Flags);
+      if (!Remove)
+        return Remove.takeError();
+      if (*Remove)
+        remove(I);
+      else
+        ++I;
+    }
+    return Error::success();
+  }
+
+  /// Construct a SymbolNameVector from this instance by dropping the Flags
+  /// values.
+  SymbolNameVector getSymbolNames() const {
+    SymbolNameVector Names;
+    Names.reserve(Symbols.size());
+    for (auto &KV : Symbols)
+      Names.push_back(KV.first);
+    return Names;
+  }
+
+  /// Sort the lookup set by pointer value. This sort is fast but sensitive to
+  /// allocation order and so should not be used where a consistent order is
+  /// required.
+  void sortByAddress() {
+    llvm::sort(Symbols, [](const value_type &LHS, const value_type &RHS) {
+      return LHS.first < RHS.first;
+    });
+  }
+
+  /// Sort the lookup set lexicographically. This sort is slow but the order
+  /// is unaffected by allocation order.
+  void sortByName() {
+    llvm::sort(Symbols, [](const value_type &LHS, const value_type &RHS) {
+      return *LHS.first < *RHS.first;
+    });
+  }
+
+  /// Remove any duplicate elements. If a SymbolLookupSet is not duplicate-free
+  /// by construction, this method can be used to turn it into a proper set.
+  void removeDuplicates() {
+    sortByAddress();
+    auto LastI = std::unique(Symbols.begin(), Symbols.end());
+    Symbols.erase(LastI, Symbols.end());
+  }
+
+#ifndef NDEBUG
+  /// Returns true if this set contains any duplicates. This should only be used
+  /// in assertions.
+  bool containsDuplicates() {
+    if (Symbols.size() < 2)
+      return false;
+    sortByAddress();
+    for (UnderlyingVector::size_type I = 1; I != Symbols.size(); ++I)
+      if (Symbols[I].first == Symbols[I - 1].first)
+        return true;
+    return false;
+  }
+#endif
+
+private:
+  UnderlyingVector Symbols;
+};
 
 struct SymbolAliasMapEntry {
   SymbolAliasMapEntry() = default;
@@ -69,45 +376,8 @@
 /// A map of Symbols to (Symbol, Flags) pairs.
 using SymbolAliasMap = DenseMap<SymbolStringPtr, SymbolAliasMapEntry>;
 
-/// Render a SymbolStringPtr.
-raw_ostream &operator<<(raw_ostream &OS, const SymbolStringPtr &Sym);
-
-/// Render a SymbolNameSet.
-raw_ostream &operator<<(raw_ostream &OS, const SymbolNameSet &Symbols);
-
-/// Render a SymbolFlagsMap entry.
-raw_ostream &operator<<(raw_ostream &OS, const SymbolFlagsMap::value_type &KV);
-
-/// Render a SymbolMap entry.
-raw_ostream &operator<<(raw_ostream &OS, const SymbolMap::value_type &KV);
-
-/// Render a SymbolFlagsMap.
-raw_ostream &operator<<(raw_ostream &OS, const SymbolFlagsMap &SymbolFlags);
-
-/// Render a SymbolMap.
-raw_ostream &operator<<(raw_ostream &OS, const SymbolMap &Symbols);
-
-/// Render a SymbolDependenceMap entry.
-raw_ostream &operator<<(raw_ostream &OS,
-                        const SymbolDependenceMap::value_type &KV);
-
-/// Render a SymbolDependendeMap.
-raw_ostream &operator<<(raw_ostream &OS, const SymbolDependenceMap &Deps);
-
-/// Render a MaterializationUnit.
-raw_ostream &operator<<(raw_ostream &OS, const MaterializationUnit &MU);
-
-/// Render a JITDylibSearchList.
-raw_ostream &operator<<(raw_ostream &OS, const JITDylibSearchList &JDs);
-
-/// Render a SymbolAliasMap.
-raw_ostream &operator<<(raw_ostream &OS, const SymbolAliasMap &Aliases);
-
-/// Render a SymbolState.
-raw_ostream &operator<<(raw_ostream &OS, const SymbolState &S);
-
 /// Callback to notify client that symbols have been resolved.
-using SymbolsResolvedCallback = std::function<void(Expected<SymbolMap>)>;
+using SymbolsResolvedCallback = unique_function<void(Expected<SymbolMap>)>;
 
 /// Callback to register the dependencies for a given query.
 using RegisterDependenciesFunction =
@@ -117,19 +387,31 @@
 /// are no dependants to register with.
 extern RegisterDependenciesFunction NoDependenciesToRegister;
 
+class ResourceTrackerDefunct : public ErrorInfo<ResourceTrackerDefunct> {
+public:
+  static char ID;
+
+  ResourceTrackerDefunct(ResourceTrackerSP RT);
+  std::error_code convertToErrorCode() const override;
+  void log(raw_ostream &OS) const override;
+
+private:
+  ResourceTrackerSP RT;
+};
+
 /// Used to notify a JITDylib that the given set of symbols failed to
 /// materialize.
 class FailedToMaterialize : public ErrorInfo<FailedToMaterialize> {
 public:
   static char ID;
 
-  FailedToMaterialize(SymbolNameSet Symbols);
+  FailedToMaterialize(std::shared_ptr<SymbolDependenceMap> Symbols);
   std::error_code convertToErrorCode() const override;
   void log(raw_ostream &OS) const override;
-  const SymbolNameSet &getSymbols() const { return Symbols; }
+  const SymbolDependenceMap &getSymbols() const { return *Symbols; }
 
 private:
-  SymbolNameSet Symbols;
+  std::shared_ptr<SymbolDependenceMap> Symbols;
 };
 
 /// Used to notify clients when symbols can not be found during a lookup.
@@ -138,12 +420,13 @@
   static char ID;
 
   SymbolsNotFound(SymbolNameSet Symbols);
+  SymbolsNotFound(SymbolNameVector Symbols);
   std::error_code convertToErrorCode() const override;
   void log(raw_ostream &OS) const override;
-  const SymbolNameSet &getSymbols() const { return Symbols; }
+  const SymbolNameVector &getSymbols() const { return Symbols; }
 
 private:
-  SymbolNameSet Symbols;
+  SymbolNameVector Symbols;
 };
 
 /// Used to notify clients that a set of symbols could not be removed.
@@ -160,6 +443,44 @@
   SymbolNameSet Symbols;
 };
 
+/// Errors of this type should be returned if a module fails to include
+/// definitions that are claimed by the module's associated
+/// MaterializationResponsibility. If this error is returned it is indicative of
+/// a broken transformation / compiler / object cache.
+class MissingSymbolDefinitions : public ErrorInfo<MissingSymbolDefinitions> {
+public:
+  static char ID;
+
+  MissingSymbolDefinitions(std::string ModuleName, SymbolNameVector Symbols)
+    : ModuleName(std::move(ModuleName)), Symbols(std::move(Symbols)) {}
+  std::error_code convertToErrorCode() const override;
+  void log(raw_ostream &OS) const override;
+  const std::string &getModuleName() const { return ModuleName; }
+  const SymbolNameVector &getSymbols() const { return Symbols; }
+private:
+  std::string ModuleName;
+  SymbolNameVector Symbols;
+};
+
+/// Errors of this type should be returned if a module contains definitions for
+/// symbols that are not claimed by the module's associated
+/// MaterializationResponsibility. If this error is returned it is indicative of
+/// a broken transformation / compiler / object cache.
+class UnexpectedSymbolDefinitions : public ErrorInfo<UnexpectedSymbolDefinitions> {
+public:
+  static char ID;
+
+  UnexpectedSymbolDefinitions(std::string ModuleName, SymbolNameVector Symbols)
+    : ModuleName(std::move(ModuleName)), Symbols(std::move(Symbols)) {}
+  std::error_code convertToErrorCode() const override;
+  void log(raw_ostream &OS) const override;
+  const std::string &getModuleName() const { return ModuleName; }
+  const SymbolNameVector &getSymbols() const { return Symbols; }
+private:
+  std::string ModuleName;
+  SymbolNameVector Symbols;
+};
+
 /// Tracks responsibility for materialization, and mediates interactions between
 /// MaterializationUnits and JDs.
 ///
@@ -168,9 +489,10 @@
 /// emit symbols, or abandon materialization by notifying any unmaterialized
 /// symbols of an error.
 class MaterializationResponsibility {
-  friend class MaterializationUnit;
+  friend class ExecutionSession;
+
 public:
-  MaterializationResponsibility(MaterializationResponsibility &&) = default;
+  MaterializationResponsibility(MaterializationResponsibility &&) = delete;
   MaterializationResponsibility &
   operator=(MaterializationResponsibility &&) = delete;
 
@@ -179,12 +501,15 @@
   ///        emitted or notified of an error.
   ~MaterializationResponsibility();
 
+  /// Returns the ResourceTracker for this instance.
+  template <typename Func> Error withResourceKeyDo(Func &&F) const;
+
   /// Returns the target JITDylib that these symbols are being materialized
   ///        into.
-  JITDylib &getTargetJITDylib() const { return JD; }
+  JITDylib &getTargetJITDylib() const { return *JD; }
 
-  /// Returns the VModuleKey for this instance.
-  VModuleKey getVModuleKey() const { return K; }
+  /// Returns the ExecutionSession for this instance.
+  ExecutionSession &getExecutionSession();
 
   /// Returns the symbol flags map for this responsibility instance.
   /// Note: The returned flags may have transient flags (Lazy, Materializing)
@@ -192,6 +517,11 @@
   /// before using.
   const SymbolFlagsMap &getSymbols() const { return SymbolFlags; }
 
+  /// Returns the initialization pseudo-symbol, if any. This symbol will also
+  /// be present in the SymbolFlagsMap for this MaterializationResponsibility
+  /// object.
+  const SymbolStringPtr &getInitializerSymbol() const { return InitSymbol; }
+
   /// Returns the names of any symbols covered by this
   /// MaterializationResponsibility object that have queries pending. This
   /// information can be used to return responsibility for unrequested symbols
@@ -204,20 +534,53 @@
   /// symbols must be ones covered by this MaterializationResponsibility
   /// instance. Individual calls to this method may resolve a subset of the
   /// symbols, but all symbols must have been resolved prior to calling emit.
-  void notifyResolved(const SymbolMap &Symbols);
+  ///
+  /// This method will return an error if any symbols being resolved have been
+  /// moved to the error state due to the failure of a dependency. If this
+  /// method returns an error then clients should log it and call
+  /// failMaterialize. If no dependencies have been registered for the
+  /// symbols covered by this MaterializationResponsibiility then this method
+  /// is guaranteed to return Error::success() and can be wrapped with cantFail.
+  Error notifyResolved(const SymbolMap &Symbols);
 
   /// Notifies the target JITDylib (and any pending queries on that JITDylib)
   /// that all symbols covered by this MaterializationResponsibility instance
   /// have been emitted.
-  void notifyEmitted();
+  ///
+  /// This method will return an error if any symbols being resolved have been
+  /// moved to the error state due to the failure of a dependency. If this
+  /// method returns an error then clients should log it and call
+  /// failMaterialize. If no dependencies have been registered for the
+  /// symbols covered by this MaterializationResponsibiility then this method
+  /// is guaranteed to return Error::success() and can be wrapped with cantFail.
+  Error notifyEmitted();
 
-  /// Adds new symbols to the JITDylib and this responsibility instance.
-  ///        JITDylib entries start out in the materializing state.
+  /// Attempt to claim responsibility for new definitions. This method can be
+  /// used to claim responsibility for symbols that are added to a
+  /// materialization unit during the compilation process (e.g. literal pool
+  /// symbols). Symbol linkage rules are the same as for symbols that are
+  /// defined up front: duplicate strong definitions will result in errors.
+  /// Duplicate weak definitions will be discarded (in which case they will
+  /// not be added to this responsibility instance).
   ///
   ///   This method can be used by materialization units that want to add
   /// additional symbols at materialization time (e.g. stubs, compile
   /// callbacks, metadata).
-  Error defineMaterializing(const SymbolFlagsMap &SymbolFlags);
+  Error defineMaterializing(SymbolFlagsMap SymbolFlags);
+
+  /// Define the given symbols as non-existent, removing it from the symbol
+  /// table and notifying any pending queries. Queries that lookup up the
+  /// symbol using the SymbolLookupFlags::WeaklyReferencedSymbol flag will
+  /// behave as if the symbol had not been matched in the first place. Queries
+  /// that required this symbol will fail with a missing symbol definition
+  /// error.
+  ///
+  /// This method is intended to support cleanup of special symbols like
+  /// initializer symbols: Queries using
+  /// SymbolLookupFlags::WeaklyReferencedSymbol can be used to trigger their
+  /// emission, and this method can be used to remove them from the JITDylib
+  /// once materialization is complete.
+  void defineNonExistent(ArrayRef<SymbolStringPtr> Symbols);
 
   /// Notify all not-yet-emitted covered by this MaterializationResponsibility
   /// instance that an error has occurred.
@@ -231,13 +594,13 @@
   /// materializers to break up work based on run-time information (e.g.
   /// by introspecting which symbols have actually been looked up and
   /// materializing only those).
-  void replace(std::unique_ptr<MaterializationUnit> MU);
+  Error replace(std::unique_ptr<MaterializationUnit> MU);
 
   /// Delegates responsibility for the given symbols to the returned
   /// materialization responsibility. Useful for breaking up work between
   /// threads, or different kinds of materialization processes.
-  MaterializationResponsibility delegate(const SymbolNameSet &Symbols,
-                                         VModuleKey NewKey = VModuleKey());
+  Expected<std::unique_ptr<MaterializationResponsibility>>
+  delegate(const SymbolNameSet &Symbols);
 
   void addDependencies(const SymbolStringPtr &Name,
                        const SymbolDependenceMap &Dependencies);
@@ -248,12 +611,17 @@
 private:
   /// Create a MaterializationResponsibility for the given JITDylib and
   ///        initial symbols.
-  MaterializationResponsibility(JITDylib &JD, SymbolFlagsMap SymbolFlags,
-                                VModuleKey K);
+  MaterializationResponsibility(JITDylibSP JD, SymbolFlagsMap SymbolFlags,
+                                SymbolStringPtr InitSymbol)
+      : JD(std::move(JD)), SymbolFlags(std::move(SymbolFlags)),
+        InitSymbol(std::move(InitSymbol)) {
+    assert(this->JD && "Cannot initialize with null JITDylib");
+    assert(!this->SymbolFlags.empty() && "Materializing nothing?");
+  }
 
-  JITDylib &JD;
+  JITDylibSP JD;
   SymbolFlagsMap SymbolFlags;
-  VModuleKey K;
+  SymbolStringPtr InitSymbol;
 };
 
 /// A MaterializationUnit represents a set of symbol definitions that can
@@ -265,9 +633,17 @@
 /// is requested via the lookup method. The JITDylib will call discard if a
 /// stronger definition is added or already present.
 class MaterializationUnit {
+  friend class ExecutionSession;
+  friend class JITDylib;
+
 public:
-  MaterializationUnit(SymbolFlagsMap InitalSymbolFlags, VModuleKey K)
-      : SymbolFlags(std::move(InitalSymbolFlags)), K(std::move(K)) {}
+  MaterializationUnit(SymbolFlagsMap InitalSymbolFlags,
+                      SymbolStringPtr InitSymbol)
+      : SymbolFlags(std::move(InitalSymbolFlags)),
+        InitSymbol(std::move(InitSymbol)) {
+    assert((!this->InitSymbol || this->SymbolFlags.count(this->InitSymbol)) &&
+           "If set, InitSymbol should appear in InitialSymbolFlags map");
+  }
 
   virtual ~MaterializationUnit() {}
 
@@ -278,13 +654,14 @@
   /// Return the set of symbols that this source provides.
   const SymbolFlagsMap &getSymbols() const { return SymbolFlags; }
 
-  /// Called by materialization dispatchers (see
-  /// ExecutionSession::DispatchMaterializationFunction) to trigger
-  /// materialization of this MaterializationUnit.
-  void doMaterialize(JITDylib &JD) {
-    materialize(MaterializationResponsibility(JD, std::move(SymbolFlags),
-                                              std::move(K)));
-  }
+  /// Returns the initialization symbol for this MaterializationUnit (if any).
+  const SymbolStringPtr &getInitializerSymbol() const { return InitSymbol; }
+
+  /// Implementations of this method should materialize all symbols
+  ///        in the materialzation unit, except for those that have been
+  ///        previously discarded.
+  virtual void
+  materialize(std::unique_ptr<MaterializationResponsibility> R) = 0;
 
   /// Called by JITDylibs to notify MaterializationUnits that the given symbol
   /// has been overridden.
@@ -295,16 +672,11 @@
 
 protected:
   SymbolFlagsMap SymbolFlags;
-  VModuleKey K;
+  SymbolStringPtr InitSymbol;
 
 private:
   virtual void anchor();
 
-  /// Implementations of this method should materialize all symbols
-  ///        in the materialzation unit, except for those that have been
-  ///        previously discarded.
-  virtual void materialize(MaterializationResponsibility R) = 0;
-
   /// Implementations of this method should discard the given symbol
   ///        from the source (e.g. if the source is an LLVM IR Module and the
   ///        symbol is a function, delete the function body or mark it available
@@ -312,21 +684,18 @@
   virtual void discard(const JITDylib &JD, const SymbolStringPtr &Name) = 0;
 };
 
-using MaterializationUnitList =
-    std::vector<std::unique_ptr<MaterializationUnit>>;
-
 /// A MaterializationUnit implementation for pre-existing absolute symbols.
 ///
 /// All symbols will be resolved and marked ready as soon as the unit is
 /// materialized.
 class AbsoluteSymbolsMaterializationUnit : public MaterializationUnit {
 public:
-  AbsoluteSymbolsMaterializationUnit(SymbolMap Symbols, VModuleKey K);
+  AbsoluteSymbolsMaterializationUnit(SymbolMap Symbols);
 
   StringRef getName() const override;
 
 private:
-  void materialize(MaterializationResponsibility R) override;
+  void materialize(std::unique_ptr<MaterializationResponsibility> R) override;
   void discard(const JITDylib &JD, const SymbolStringPtr &Name) override;
   static SymbolFlagsMap extractFlags(const SymbolMap &Symbols);
 
@@ -344,9 +713,9 @@
 /// \endcode
 ///
 inline std::unique_ptr<AbsoluteSymbolsMaterializationUnit>
-absoluteSymbols(SymbolMap Symbols, VModuleKey K = VModuleKey()) {
-  return llvm::make_unique<AbsoluteSymbolsMaterializationUnit>(
-      std::move(Symbols), std::move(K));
+absoluteSymbols(SymbolMap Symbols) {
+  return std::make_unique<AbsoluteSymbolsMaterializationUnit>(
+      std::move(Symbols));
 }
 
 /// A materialization unit for symbol aliases. Allows existing symbols to be
@@ -361,18 +730,19 @@
   /// Note: Care must be taken that no sets of aliases form a cycle, as such
   ///       a cycle will result in a deadlock when any symbol in the cycle is
   ///       resolved.
-  ReExportsMaterializationUnit(JITDylib *SourceJD, bool MatchNonExported,
-                               SymbolAliasMap Aliases, VModuleKey K);
+  ReExportsMaterializationUnit(JITDylib *SourceJD,
+                               JITDylibLookupFlags SourceJDLookupFlags,
+                               SymbolAliasMap Aliases);
 
   StringRef getName() const override;
 
 private:
-  void materialize(MaterializationResponsibility R) override;
+  void materialize(std::unique_ptr<MaterializationResponsibility> R) override;
   void discard(const JITDylib &JD, const SymbolStringPtr &Name) override;
   static SymbolFlagsMap extractFlags(const SymbolAliasMap &Aliases);
 
   JITDylib *SourceJD = nullptr;
-  bool MatchNonExported = false;
+  JITDylibLookupFlags SourceJDLookupFlags;
   SymbolAliasMap Aliases;
 };
 
@@ -388,47 +758,26 @@
 ///     return Err;
 /// \endcode
 inline std::unique_ptr<ReExportsMaterializationUnit>
-symbolAliases(SymbolAliasMap Aliases, VModuleKey K = VModuleKey()) {
-  return llvm::make_unique<ReExportsMaterializationUnit>(
-      nullptr, true, std::move(Aliases), std::move(K));
+symbolAliases(SymbolAliasMap Aliases) {
+  return std::make_unique<ReExportsMaterializationUnit>(
+      nullptr, JITDylibLookupFlags::MatchAllSymbols, std::move(Aliases));
 }
 
 /// Create a materialization unit for re-exporting symbols from another JITDylib
 /// with alternative names/flags.
-/// If MatchNonExported is true then non-exported symbols from SourceJD can be
-/// re-exported. If it is false, attempts to re-export a non-exported symbol
-/// will result in a "symbol not found" error.
+/// SourceJD will be searched using the given JITDylibLookupFlags.
 inline std::unique_ptr<ReExportsMaterializationUnit>
 reexports(JITDylib &SourceJD, SymbolAliasMap Aliases,
-          bool MatchNonExported = false, VModuleKey K = VModuleKey()) {
-  return llvm::make_unique<ReExportsMaterializationUnit>(
-      &SourceJD, MatchNonExported, std::move(Aliases), std::move(K));
+          JITDylibLookupFlags SourceJDLookupFlags =
+              JITDylibLookupFlags::MatchExportedSymbolsOnly) {
+  return std::make_unique<ReExportsMaterializationUnit>(
+      &SourceJD, SourceJDLookupFlags, std::move(Aliases));
 }
 
 /// Build a SymbolAliasMap for the common case where you want to re-export
 /// symbols from another JITDylib with the same linkage/flags.
 Expected<SymbolAliasMap>
-buildSimpleReexportsAliasMap(JITDylib &SourceJD, const SymbolNameSet &Symbols);
-
-/// ReexportsGenerator can be used with JITDylib::setGenerator to automatically
-/// re-export a subset of the source JITDylib's symbols in the target.
-class ReexportsGenerator {
-public:
-  using SymbolPredicate = std::function<bool(SymbolStringPtr)>;
-
-  /// Create a reexports generator. If an Allow predicate is passed, only
-  /// symbols for which the predicate returns true will be reexported. If no
-  /// Allow predicate is passed, all symbols will be exported.
-  ReexportsGenerator(JITDylib &SourceJD, bool MatchNonExported = false,
-                     SymbolPredicate Allow = SymbolPredicate());
-
-  Expected<SymbolNameSet> operator()(JITDylib &JD, const SymbolNameSet &Names);
-
-private:
-  JITDylib &SourceJD;
-  bool MatchNonExported = false;
-  SymbolPredicate Allow;
-};
+buildSimpleReexportsAAliasMap(JITDylib &SourceJD, const SymbolNameSet &Symbols);
 
 /// Represents the state that a symbol has reached during materialization.
 enum class SymbolState : uint8_t {
@@ -436,6 +785,7 @@
   NeverSearched, /// Added to the symbol table, never queried.
   Materializing, /// Queried, materialization begun.
   Resolved,      /// Assigned address, still materializing.
+  Emitted,       /// Emitted to memory, but waiting on transitive dependencies.
   Ready = 0x3f   /// Ready and safe for clients to access.
 };
 
@@ -445,14 +795,16 @@
 /// makes a callback when all symbols are available.
 class AsynchronousSymbolQuery {
   friend class ExecutionSession;
+  friend class InProgressFullLookupState;
   friend class JITDylib;
   friend class JITSymbolResolverAdapter;
+  friend class MaterializationResponsibility;
 
 public:
   /// Create a query for the given symbols. The NotifyComplete
   /// callback will be called once all queried symbols reach the given
   /// minimum state.
-  AsynchronousSymbolQuery(const SymbolNameSet &Symbols,
+  AsynchronousSymbolQuery(const SymbolLookupSet &Symbols,
                           SymbolState RequiredState,
                           SymbolsResolvedCallback NotifyComplete);
 
@@ -477,7 +829,7 @@
 
   void removeQueryDependence(JITDylib &JD, const SymbolStringPtr &Name);
 
-  bool canStillFail();
+  void dropSymbol(const SymbolStringPtr &Name);
 
   void handleFailed(Error Err);
 
@@ -490,19 +842,62 @@
   SymbolState RequiredState;
 };
 
+/// Wraps state for a lookup-in-progress.
+/// DefinitionGenerators can optionally take ownership of a LookupState object
+/// to suspend a lookup-in-progress while they search for definitions.
+class LookupState {
+  friend class OrcV2CAPIHelper;
+  friend class ExecutionSession;
+
+public:
+  LookupState();
+  LookupState(LookupState &&);
+  LookupState &operator=(LookupState &&);
+  ~LookupState();
+
+  /// Continue the lookup. This can be called by DefinitionGenerators
+  /// to re-start a captured query-application operation.
+  void continueLookup(Error Err);
+
+private:
+  LookupState(std::unique_ptr<InProgressLookupState> IPLS);
+
+  // For C API.
+  void reset(InProgressLookupState *IPLS);
+
+  std::unique_ptr<InProgressLookupState> IPLS;
+};
+
+/// Definition generators can be attached to JITDylibs to generate new
+/// definitions for otherwise unresolved symbols during lookup.
+class DefinitionGenerator {
+public:
+  virtual ~DefinitionGenerator();
+
+  /// DefinitionGenerators should override this method to insert new
+  /// definitions into the parent JITDylib. K specifies the kind of this
+  /// lookup. JD specifies the target JITDylib being searched, and
+  /// JDLookupFlags specifies whether the search should match against
+  /// hidden symbols. Finally, Symbols describes the set of unresolved
+  /// symbols and their associated lookup flags.
+  virtual Error tryToGenerate(LookupState &LS, LookupKind K, JITDylib &JD,
+                              JITDylibLookupFlags JDLookupFlags,
+                              const SymbolLookupSet &LookupSet) = 0;
+};
+
 /// A symbol table that supports asynchoronous symbol queries.
 ///
 /// Represents a virtual shared object. Instances can not be copied or moved, so
 /// their addresses may be used as keys for resource management.
 /// JITDylib state changes must be made via an ExecutionSession to guarantee
 /// that they are synchronized with respect to other JITDylib operations.
-class JITDylib {
+class JITDylib : public ThreadSafeRefCountedBase<JITDylib>,
+                 public jitlink::JITLinkDylib {
   friend class AsynchronousSymbolQuery;
   friend class ExecutionSession;
+  friend class Platform;
   friend class MaterializationResponsibility;
 public:
-  using GeneratorFunction = std::function<Expected<SymbolNameSet>(
-      JITDylib &Parent, const SymbolNameSet &Names)>;
 
   using AsynchronousSymbolQuerySet =
     std::set<std::shared_ptr<AsynchronousSymbolQuery>>;
@@ -518,62 +913,88 @@
   /// Get a reference to the ExecutionSession for this JITDylib.
   ExecutionSession &getExecutionSession() const { return ES; }
 
-  /// Set a definition generator. If set, whenever a symbol fails to resolve
-  /// within this JITDylib, lookup and lookupFlags will pass the unresolved
-  /// symbols set to the definition generator. The generator can optionally
-  /// add a definition for the unresolved symbols to the dylib.
-  void setGenerator(GeneratorFunction DefGenerator) {
-    this->DefGenerator = std::move(DefGenerator);
-  }
+  /// Calls remove on all trackers currently associated with this JITDylib.
+  /// Does not run static deinits.
+  ///
+  /// Note that removal happens outside the session lock, so new code may be
+  /// added concurrently while the clear is underway, and the newly added
+  /// code will *not* be cleared. Adding new code concurrently with a clear
+  /// is usually a bug and should be avoided.
+  Error clear();
 
-  /// Set the search order to be used when fixing up definitions in JITDylib.
-  /// This will replace the previous search order, and apply to any symbol
+  /// Get the default resource tracker for this JITDylib.
+  ResourceTrackerSP getDefaultResourceTracker();
+
+  /// Create a resource tracker for this JITDylib.
+  ResourceTrackerSP createResourceTracker();
+
+  /// Adds a definition generator to this JITDylib and returns a referenece to
+  /// it.
+  ///
+  /// When JITDylibs are searched during lookup, if no existing definition of
+  /// a symbol is found, then any generators that have been added are run (in
+  /// the order that they were added) to potentially generate a definition.
+  template <typename GeneratorT>
+  GeneratorT &addGenerator(std::unique_ptr<GeneratorT> DefGenerator);
+
+  /// Remove a definition generator from this JITDylib.
+  ///
+  /// The given generator must exist in this JITDylib's generators list (i.e.
+  /// have been added and not yet removed).
+  void removeGenerator(DefinitionGenerator &G);
+
+  /// Set the link order to be used when fixing up definitions in JITDylib.
+  /// This will replace the previous link order, and apply to any symbol
   /// resolutions made for definitions in this JITDylib after the call to
-  /// setSearchOrder (even if the definition itself was added before the
+  /// setLinkOrder (even if the definition itself was added before the
   /// call).
   ///
-  /// If SearchThisJITDylibFirst is set, which by default it is, then this
-  /// JITDylib will add itself to the beginning of the SearchOrder (Clients
-  /// should *not* put this JITDylib in the list in this case, to avoid
-  /// redundant lookups).
+  /// If LinkAgainstThisJITDylibFirst is true (the default) then this JITDylib
+  /// will add itself to the beginning of the LinkOrder (Clients should not
+  /// put this JITDylib in the list in this case, to avoid redundant lookups).
   ///
-  /// If SearchThisJITDylibFirst is false then the search order will be used as
-  /// given. The main motivation for this feature is to support deliberate
+  /// If LinkAgainstThisJITDylibFirst is false then the link order will be used
+  /// as-is. The primary motivation for this feature is to support deliberate
   /// shadowing of symbols in this JITDylib by a facade JITDylib. For example,
   /// the facade may resolve function names to stubs, and the stubs may compile
   /// lazily by looking up symbols in this dylib. Adding the facade dylib
-  /// as the first in the search order (instead of this dylib) ensures that
+  /// as the first in the link order (instead of this dylib) ensures that
   /// definitions within this dylib resolve to the lazy-compiling stubs,
   /// rather than immediately materializing the definitions in this dylib.
-  void setSearchOrder(JITDylibSearchList NewSearchOrder,
-                      bool SearchThisJITDylibFirst = true,
-                      bool MatchNonExportedInThisDylib = true);
+  void setLinkOrder(JITDylibSearchOrder NewSearchOrder,
+                    bool LinkAgainstThisJITDylibFirst = true);
 
-  /// Add the given JITDylib to the search order for definitions in this
+  /// Add the given JITDylib to the link order for definitions in this
   /// JITDylib.
-  void addToSearchOrder(JITDylib &JD, bool MatcNonExported = false);
+  void addToLinkOrder(JITDylib &JD,
+                      JITDylibLookupFlags JDLookupFlags =
+                          JITDylibLookupFlags::MatchExportedSymbolsOnly);
 
-  /// Replace OldJD with NewJD in the search order if OldJD is present.
+  /// Replace OldJD with NewJD in the link order if OldJD is present.
   /// Otherwise this operation is a no-op.
-  void replaceInSearchOrder(JITDylib &OldJD, JITDylib &NewJD,
-                            bool MatchNonExported = false);
+  void replaceInLinkOrder(JITDylib &OldJD, JITDylib &NewJD,
+                          JITDylibLookupFlags JDLookupFlags =
+                              JITDylibLookupFlags::MatchExportedSymbolsOnly);
 
-  /// Remove the given JITDylib from the search order for this JITDylib if it is
+  /// Remove the given JITDylib from the link order for this JITDylib if it is
   /// present. Otherwise this operation is a no-op.
-  void removeFromSearchOrder(JITDylib &JD);
+  void removeFromLinkOrder(JITDylib &JD);
 
-  /// Do something with the search order (run under the session lock).
+  /// Do something with the link order (run under the session lock).
   template <typename Func>
-  auto withSearchOrderDo(Func &&F)
-      -> decltype(F(std::declval<const JITDylibSearchList &>()));
+  auto withLinkOrderDo(Func &&F)
+      -> decltype(F(std::declval<const JITDylibSearchOrder &>()));
 
   /// Define all symbols provided by the materialization unit to be part of this
   /// JITDylib.
   ///
+  /// If RT is not specified then the default resource tracker will be used.
+  ///
   /// This overload always takes ownership of the MaterializationUnit. If any
   /// errors occur, the MaterializationUnit consumed.
   template <typename MaterializationUnitType>
-  Error define(std::unique_ptr<MaterializationUnitType> &&MU);
+  Error define(std::unique_ptr<MaterializationUnitType> &&MU,
+               ResourceTrackerSP RT = nullptr);
 
   /// Define all symbols provided by the materialization unit to be part of this
   /// JITDylib.
@@ -583,7 +1004,8 @@
   /// may allow the caller to modify the MaterializationUnit to correct the
   /// issue, then re-call define.
   template <typename MaterializationUnitType>
-  Error define(std::unique_ptr<MaterializationUnitType> &MU);
+  Error define(std::unique_ptr<MaterializationUnitType> &MU,
+               ResourceTrackerSP RT = nullptr);
 
   /// Tries to remove the given symbols.
   ///
@@ -597,52 +1019,61 @@
   /// left unmodified (no symbols are removed).
   Error remove(const SymbolNameSet &Names);
 
-  /// Search the given JITDylib for the symbols in Symbols. If found, store
-  ///        the flags for each symbol in Flags. Returns any unresolved symbols.
-  Expected<SymbolFlagsMap> lookupFlags(const SymbolNameSet &Names);
-
   /// Dump current JITDylib state to OS.
   void dump(raw_ostream &OS);
 
-  /// FIXME: Remove this when we remove the old ORC layers.
-  /// Search the given JITDylibs in order for the symbols in Symbols. Results
-  ///        (once they become available) will be returned via the given Query.
-  ///
-  /// If any symbol is not found then the unresolved symbols will be returned,
-  /// and the query will not be applied. The Query is not failed and can be
-  /// re-used in a subsequent lookup once the symbols have been added, or
-  /// manually failed.
-  Expected<SymbolNameSet>
-  legacyLookup(std::shared_ptr<AsynchronousSymbolQuery> Q, SymbolNameSet Names);
+  /// Returns the given JITDylibs and all of their transitive dependencies in
+  /// DFS order (based on linkage relationships). Each JITDylib will appear
+  /// only once.
+  static std::vector<JITDylibSP> getDFSLinkOrder(ArrayRef<JITDylibSP> JDs);
+
+  /// Returns the given JITDylibs and all of their transitive dependensies in
+  /// reverse DFS order (based on linkage relationships). Each JITDylib will
+  /// appear only once.
+  static std::vector<JITDylibSP>
+  getReverseDFSLinkOrder(ArrayRef<JITDylibSP> JDs);
+
+  /// Return this JITDylib and its transitive dependencies in DFS order
+  /// based on linkage relationships.
+  std::vector<JITDylibSP> getDFSLinkOrder();
+
+  /// Rteurn this JITDylib and its transitive dependencies in reverse DFS order
+  /// based on linkage relationships.
+  std::vector<JITDylibSP> getReverseDFSLinkOrder();
 
 private:
   using AsynchronousSymbolQueryList =
       std::vector<std::shared_ptr<AsynchronousSymbolQuery>>;
 
   struct UnmaterializedInfo {
-    UnmaterializedInfo(std::unique_ptr<MaterializationUnit> MU)
-        : MU(std::move(MU)) {}
+    UnmaterializedInfo(std::unique_ptr<MaterializationUnit> MU,
+                       ResourceTracker *RT)
+        : MU(std::move(MU)), RT(RT) {}
 
     std::unique_ptr<MaterializationUnit> MU;
+    ResourceTracker *RT;
   };
 
   using UnmaterializedInfosMap =
       DenseMap<SymbolStringPtr, std::shared_ptr<UnmaterializedInfo>>;
 
+  using UnmaterializedInfosList =
+      std::vector<std::shared_ptr<UnmaterializedInfo>>;
+
   struct MaterializingInfo {
     SymbolDependenceMap Dependants;
     SymbolDependenceMap UnemittedDependencies;
-    bool IsEmitted = false;
 
     void addQuery(std::shared_ptr<AsynchronousSymbolQuery> Q);
     void removeQuery(const AsynchronousSymbolQuery &Q);
     AsynchronousSymbolQueryList takeQueriesMeeting(SymbolState RequiredState);
-    AsynchronousSymbolQueryList takeAllQueries();
+    AsynchronousSymbolQueryList takeAllPendingQueries() {
+      return std::move(PendingQueries);
+    }
     bool hasQueriesPending() const { return !PendingQueries.empty(); }
     const AsynchronousSymbolQueryList &pendingQueries() const {
       return PendingQueries;
     }
-
   private:
     AsynchronousSymbolQueryList PendingQueries;
   };
@@ -660,11 +1091,6 @@
     JITSymbolFlags getFlags() const { return Flags; }
     SymbolState getState() const { return static_cast<SymbolState>(State); }
 
-    bool isInMaterializationPhase() const {
-      return getState() == SymbolState::Materializing ||
-             getState() == SymbolState::Resolved;
-    }
-
     bool hasMaterializerAttached() const { return MaterializerAttached; }
     bool isPendingRemoval() const { return PendingRemoval; }
 
@@ -700,22 +1126,16 @@
 
   JITDylib(ExecutionSession &ES, std::string Name);
 
+  ResourceTrackerSP getTracker(MaterializationResponsibility &MR);
+  std::pair<AsynchronousSymbolQuerySet, std::shared_ptr<SymbolDependenceMap>>
+  removeTracker(ResourceTracker &RT);
+
+  void transferTracker(ResourceTracker &DstRT, ResourceTracker &SrcRT);
+
   Error defineImpl(MaterializationUnit &MU);
 
-  Expected<SymbolNameSet> lookupFlagsImpl(SymbolFlagsMap &Flags,
-                                          const SymbolNameSet &Names);
-
-  Error lodgeQuery(std::shared_ptr<AsynchronousSymbolQuery> &Q,
-                   SymbolNameSet &Unresolved, bool MatchNonExported,
-                   MaterializationUnitList &MUs);
-
-  void lodgeQueryImpl(std::shared_ptr<AsynchronousSymbolQuery> &Q,
-                      SymbolNameSet &Unresolved, bool MatchNonExported,
-                      MaterializationUnitList &MUs);
-
-  bool lookupImpl(std::shared_ptr<AsynchronousSymbolQuery> &Q,
-                  std::vector<std::unique_ptr<MaterializationUnit>> &MUs,
-                  SymbolNameSet &Unresolved);
+  void installMaterializationUnit(std::unique_ptr<MaterializationUnit> MU,
+                                  ResourceTracker &RT);
 
   void detachQueryHelper(AsynchronousSymbolQuery &Q,
                          const SymbolNameSet &QuerySymbols);
@@ -724,86 +1144,156 @@
                                        const SymbolStringPtr &DependantName,
                                        MaterializingInfo &EmittedMI);
 
-  Error defineMaterializing(const SymbolFlagsMap &SymbolFlags);
+  Expected<SymbolFlagsMap> defineMaterializing(SymbolFlagsMap SymbolFlags);
 
-  void replace(std::unique_ptr<MaterializationUnit> MU);
+  Error replace(MaterializationResponsibility &FromMR,
+                std::unique_ptr<MaterializationUnit> MU);
+
+  Expected<std::unique_ptr<MaterializationResponsibility>>
+  delegate(MaterializationResponsibility &FromMR, SymbolFlagsMap SymbolFlags,
+           SymbolStringPtr InitSymbol);
 
   SymbolNameSet getRequestedSymbols(const SymbolFlagsMap &SymbolFlags) const;
 
   void addDependencies(const SymbolStringPtr &Name,
                        const SymbolDependenceMap &Dependants);
 
-  void resolve(const SymbolMap &Resolved);
+  Error resolve(MaterializationResponsibility &MR, const SymbolMap &Resolved);
 
-  void emit(const SymbolFlagsMap &Emitted);
+  Error emit(MaterializationResponsibility &MR, const SymbolFlagsMap &Emitted);
 
-  void notifyFailed(const SymbolNameSet &FailedSymbols);
+  void unlinkMaterializationResponsibility(MaterializationResponsibility &MR);
+
+  using FailedSymbolsWorklist =
+      std::vector<std::pair<JITDylib *, SymbolStringPtr>>;
+
+  static std::pair<AsynchronousSymbolQuerySet,
+                   std::shared_ptr<SymbolDependenceMap>>
+      failSymbols(FailedSymbolsWorklist);
 
   ExecutionSession &ES;
   std::string JITDylibName;
+  std::mutex GeneratorsMutex;
+  bool Open = true;
   SymbolTable Symbols;
   UnmaterializedInfosMap UnmaterializedInfos;
   MaterializingInfosMap MaterializingInfos;
-  GeneratorFunction DefGenerator;
-  JITDylibSearchList SearchOrder;
+  std::vector<std::shared_ptr<DefinitionGenerator>> DefGenerators;
+  JITDylibSearchOrder LinkOrder;
+  ResourceTrackerSP DefaultTracker;
+
+  // Map trackers to sets of symbols tracked.
+  DenseMap<ResourceTracker *, SymbolNameVector> TrackerSymbols;
+  DenseMap<MaterializationResponsibility *, ResourceTracker *> MRTrackers;
+};
+
+/// Platforms set up standard symbols and mediate interactions between dynamic
+/// initializers (e.g. C++ static constructors) and ExecutionSession state.
+/// Note that Platforms do not automatically run initializers: clients are still
+/// responsible for doing this.
+class Platform {
+public:
+  virtual ~Platform();
+
+  /// This method will be called outside the session lock each time a JITDylib
+  /// is created (unless it is created with EmptyJITDylib set) to allow the
+  /// Platform to install any JITDylib specific standard symbols (e.g
+  /// __dso_handle).
+  virtual Error setupJITDylib(JITDylib &JD) = 0;
+
+  /// This method will be called under the ExecutionSession lock each time a
+  /// MaterializationUnit is added to a JITDylib.
+  virtual Error notifyAdding(ResourceTracker &RT,
+                             const MaterializationUnit &MU) = 0;
+
+  /// This method will be called under the ExecutionSession lock when a
+  /// ResourceTracker is removed.
+  virtual Error notifyRemoving(ResourceTracker &RT) = 0;
+
+  /// A utility function for looking up initializer symbols. Performs a blocking
+  /// lookup for the given symbols in each of the given JITDylibs.
+  static Expected<DenseMap<JITDylib *, SymbolMap>>
+  lookupInitSymbols(ExecutionSession &ES,
+                    const DenseMap<JITDylib *, SymbolLookupSet> &InitSyms);
 };
 
 /// An ExecutionSession represents a running JIT program.
 class ExecutionSession {
-  // FIXME: Remove this when we remove the old ORC layers.
+  friend class InProgressLookupFlagsState;
+  friend class InProgressFullLookupState;
   friend class JITDylib;
+  friend class LookupState;
+  friend class MaterializationResponsibility;
+  friend class ResourceTracker;
 
 public:
   /// For reporting errors.
   using ErrorReporter = std::function<void(Error)>;
 
   /// For dispatching MaterializationUnit::materialize calls.
-  using DispatchMaterializationFunction = std::function<void(
-      JITDylib &JD, std::unique_ptr<MaterializationUnit> MU)>;
+  using DispatchMaterializationFunction =
+      std::function<void(std::unique_ptr<MaterializationUnit> MU,
+                         std::unique_ptr<MaterializationResponsibility> MR)>;
 
   /// Construct an ExecutionSession.
   ///
   /// SymbolStringPools may be shared between ExecutionSessions.
   ExecutionSession(std::shared_ptr<SymbolStringPool> SSP = nullptr);
 
+  /// End the session. Closes all JITDylibs.
+  Error endSession();
+
   /// Add a symbol name to the SymbolStringPool and return a pointer to it.
   SymbolStringPtr intern(StringRef SymName) { return SSP->intern(SymName); }
 
   /// Returns a shared_ptr to the SymbolStringPool for this ExecutionSession.
   std::shared_ptr<SymbolStringPool> getSymbolStringPool() const { return SSP; }
 
+  /// Set the Platform for this ExecutionSession.
+  void setPlatform(std::unique_ptr<Platform> P) { this->P = std::move(P); }
+
+  /// Get the Platform for this session.
+  /// Will return null if no Platform has been set for this ExecutionSession.
+  Platform *getPlatform() { return P.get(); }
+
   /// Run the given lambda with the session mutex locked.
-  template <typename Func> auto runSessionLocked(Func &&F) -> decltype(F()) {
+  template <typename Func> decltype(auto) runSessionLocked(Func &&F) {
     std::lock_guard<std::recursive_mutex> Lock(SessionMutex);
     return F();
   }
 
-  /// Get the "main" JITDylib, which is created automatically on construction of
-  /// the ExecutionSession.
-  JITDylib &getMainJITDylib();
+  /// Register the given ResourceManager with this ExecutionSession.
+  /// Managers will be notified of events in reverse order of registration.
+  void registerResourceManager(ResourceManager &RM);
+
+  /// Deregister the given ResourceManager with this ExecutionSession.
+  /// Manager must have been previously registered.
+  void deregisterResourceManager(ResourceManager &RM);
 
   /// Return a pointer to the "name" JITDylib.
   /// Ownership of JITDylib remains within Execution Session
   JITDylib *getJITDylibByName(StringRef Name);
 
+  /// Add a new bare JITDylib to this ExecutionSession.
+  ///
+  /// The JITDylib Name is required to be unique. Clients should verify that
+  /// names are not being re-used (E.g. by calling getJITDylibByName) if names
+  /// are based on user input.
+  ///
+  /// This call does not install any library code or symbols into the newly
+  /// created JITDylib. The client is responsible for all configuration.
+  JITDylib &createBareJITDylib(std::string Name);
+
   /// Add a new JITDylib to this ExecutionSession.
   ///
   /// The JITDylib Name is required to be unique. Clients should verify that
   /// names are not being re-used (e.g. by calling getJITDylibByName) if names
   /// are based on user input.
-  JITDylib &createJITDylib(std::string Name,
-                           bool AddToMainDylibSearchOrder = true);
-
-  /// Allocate a module key for a new module to add to the JIT.
-  VModuleKey allocateVModule() {
-    return runSessionLocked([this]() { return ++LastKey; });
-  }
-
-  /// Return a module key to the ExecutionSession so that it can be
-  ///        re-used. This should only be done once all resources associated
-  ///        with the original key have been released.
-  void releaseVModule(VModuleKey Key) { /* FIXME: Recycle keys */
-  }
+  ///
+  /// If a Platform is attached then Platform::setupJITDylib will be called to
+  /// install standard platform symbols (e.g. standard library interposes).
+  /// If no Platform is attached this call is equivalent to createBareJITDylib.
+  Expected<JITDylib &> createJITDylib(std::string Name);
 
   /// Set the error reporter function.
   ExecutionSession &setErrorReporter(ErrorReporter ReportError) {
@@ -823,19 +1313,18 @@
     return *this;
   }
 
-  void legacyFailQuery(AsynchronousSymbolQuery &Q, Error Err);
+  /// Search the given JITDylibs to find the flags associated with each of the
+  /// given symbols.
+  void lookupFlags(LookupKind K, JITDylibSearchOrder SearchOrder,
+                   SymbolLookupSet Symbols,
+                   unique_function<void(Expected<SymbolFlagsMap>)> OnComplete);
 
-  using LegacyAsyncLookupFunction = std::function<SymbolNameSet(
-      std::shared_ptr<AsynchronousSymbolQuery> Q, SymbolNameSet Names)>;
+  /// Blocking version of lookupFlags.
+  Expected<SymbolFlagsMap> lookupFlags(LookupKind K,
+                                       JITDylibSearchOrder SearchOrder,
+                                       SymbolLookupSet Symbols);
 
-  /// A legacy lookup function for JITSymbolResolverAdapter.
-  /// Do not use -- this will be removed soon.
-  Expected<SymbolMap>
-  legacyLookup(LegacyAsyncLookupFunction AsyncLookup, SymbolNameSet Names,
-               SymbolState RequiredState,
-               RegisterDependenciesFunction RegisterDependencies);
-
-  /// Search the given JITDylib list for the given symbols.
+  /// Search the given JITDylibs for the given symbols.
   ///
   /// SearchOrder lists the JITDylibs to search. For each dylib, the associated
   /// boolean indicates whether the search should match against non-exported
@@ -854,8 +1343,9 @@
   /// dependenant symbols for this query (e.g. it is being made by a top level
   /// client to get an address to call) then the value NoDependenciesToRegister
   /// can be used.
-  void lookup(const JITDylibSearchList &SearchOrder, SymbolNameSet Symbols,
-              SymbolState RequiredState, SymbolsResolvedCallback NotifyComplete,
+  void lookup(LookupKind K, const JITDylibSearchOrder &SearchOrder,
+              SymbolLookupSet Symbols, SymbolState RequiredState,
+              SymbolsResolvedCallback NotifyComplete,
               RegisterDependenciesFunction RegisterDependencies);
 
   /// Blocking version of lookup above. Returns the resolved symbol map.
@@ -865,8 +1355,9 @@
   /// or an error occurs. If WaitUntilReady is false and an error occurs
   /// after resolution, the function will return a success value, but the
   /// error will be reported via reportErrors.
-  Expected<SymbolMap> lookup(const JITDylibSearchList &SearchOrder,
-                             const SymbolNameSet &Symbols,
+  Expected<SymbolMap> lookup(const JITDylibSearchOrder &SearchOrder,
+                             const SymbolLookupSet &Symbols,
+                             LookupKind K = LookupKind::Static,
                              SymbolState RequiredState = SymbolState::Ready,
                              RegisterDependenciesFunction RegisterDependencies =
                                  NoDependenciesToRegister);
@@ -874,30 +1365,31 @@
   /// Convenience version of blocking lookup.
   /// Searches each of the JITDylibs in the search order in turn for the given
   /// symbol.
-  Expected<JITEvaluatedSymbol> lookup(const JITDylibSearchList &SearchOrder,
-                                      SymbolStringPtr Symbol);
+  Expected<JITEvaluatedSymbol>
+  lookup(const JITDylibSearchOrder &SearchOrder, SymbolStringPtr Symbol,
+         SymbolState RequiredState = SymbolState::Ready);
 
   /// Convenience version of blocking lookup.
   /// Searches each of the JITDylibs in the search order in turn for the given
   /// symbol. The search will not find non-exported symbols.
-  Expected<JITEvaluatedSymbol> lookup(ArrayRef<JITDylib *> SearchOrder,
-                                      SymbolStringPtr Symbol);
+  Expected<JITEvaluatedSymbol>
+  lookup(ArrayRef<JITDylib *> SearchOrder, SymbolStringPtr Symbol,
+         SymbolState RequiredState = SymbolState::Ready);
 
   /// Convenience version of blocking lookup.
   /// Searches each of the JITDylibs in the search order in turn for the given
   /// symbol. The search will not find non-exported symbols.
-  Expected<JITEvaluatedSymbol> lookup(ArrayRef<JITDylib *> SearchOrder,
-                                      StringRef Symbol);
+  Expected<JITEvaluatedSymbol>
+  lookup(ArrayRef<JITDylib *> SearchOrder, StringRef Symbol,
+         SymbolState RequiredState = SymbolState::Ready);
 
   /// Materialize the given unit.
-  void dispatchMaterialization(JITDylib &JD,
-                               std::unique_ptr<MaterializationUnit> MU) {
-    LLVM_DEBUG({
-      runSessionLocked([&]() {
-        dbgs() << "Dispatching " << *MU << " for " << JD.getName() << "\n";
-      });
-    });
-    DispatchMaterialization(JD, std::move(MU));
+  void
+  dispatchMaterialization(std::unique_ptr<MaterializationUnit> MU,
+                          std::unique_ptr<MaterializationResponsibility> MR) {
+    assert(MU && "MU must be non-null");
+    DEBUG_WITH_TYPE("orc", dumpDispatchInfo(MR->getTargetJITDylib(), *MU));
+    DispatchMaterialization(std::move(MU), std::move(MR));
   }
 
   /// Dump the state of all the JITDylibs in this session.
@@ -908,84 +1400,290 @@
     logAllUnhandledErrors(std::move(Err), errs(), "JIT session error: ");
   }
 
-  static void
-  materializeOnCurrentThread(JITDylib &JD,
-                             std::unique_ptr<MaterializationUnit> MU) {
-    MU->doMaterialize(JD);
+  static void materializeOnCurrentThread(
+      std::unique_ptr<MaterializationUnit> MU,
+      std::unique_ptr<MaterializationResponsibility> MR) {
+    MU->materialize(std::move(MR));
   }
 
-  void runOutstandingMUs();
+  void dispatchOutstandingMUs();
+
+  static std::unique_ptr<MaterializationResponsibility>
+  createMaterializationResponsibility(ResourceTracker &RT,
+                                      SymbolFlagsMap Symbols,
+                                      SymbolStringPtr InitSymbol) {
+    auto &JD = RT.getJITDylib();
+    std::unique_ptr<MaterializationResponsibility> MR(
+        new MaterializationResponsibility(&JD, std::move(Symbols),
+                                          std::move(InitSymbol)));
+    JD.MRTrackers[MR.get()] = &RT;
+    return MR;
+  }
+
+  Error removeResourceTracker(ResourceTracker &RT);
+  void transferResourceTracker(ResourceTracker &DstRT, ResourceTracker &SrcRT);
+  void destroyResourceTracker(ResourceTracker &RT);
+
+  // State machine functions for query application..
+
+  /// IL_updateCandidatesFor is called to remove already-defined symbols that
+  /// match a given query from the set of candidate symbols to generate
+  /// definitions for (no need to generate a definition if one already exists).
+  Error IL_updateCandidatesFor(JITDylib &JD, JITDylibLookupFlags JDLookupFlags,
+                               SymbolLookupSet &Candidates,
+                               SymbolLookupSet *NonCandidates);
+
+  /// OL_applyQueryPhase1 is an optionally re-startable loop for triggering
+  /// definition generation. It is called when a lookup is performed, and again
+  /// each time that LookupState::continueLookup is called.
+  void OL_applyQueryPhase1(std::unique_ptr<InProgressLookupState> IPLS,
+                           Error Err);
+
+  /// OL_completeLookup is run once phase 1 successfully completes for a lookup
+  /// call. It attempts to attach the symbol to all symbol table entries and
+  /// collect all MaterializationUnits to dispatch. If this method fails then
+  /// all MaterializationUnits will be left un-materialized.
+  void OL_completeLookup(std::unique_ptr<InProgressLookupState> IPLS,
+                         std::shared_ptr<AsynchronousSymbolQuery> Q,
+                         RegisterDependenciesFunction RegisterDependencies);
+
+  /// OL_completeLookupFlags is run once phase 1 successfully completes for a
+  /// lookupFlags call.
+  void OL_completeLookupFlags(
+      std::unique_ptr<InProgressLookupState> IPLS,
+      unique_function<void(Expected<SymbolFlagsMap>)> OnComplete);
+
+  // State machine functions for MaterializationResponsibility.
+  void OL_destroyMaterializationResponsibility(
+      MaterializationResponsibility &MR);
+  SymbolNameSet OL_getRequestedSymbols(const MaterializationResponsibility &MR);
+  Error OL_notifyResolved(MaterializationResponsibility &MR,
+                          const SymbolMap &Symbols);
+  Error OL_notifyEmitted(MaterializationResponsibility &MR);
+  Error OL_defineMaterializing(MaterializationResponsibility &MR,
+                               SymbolFlagsMap SymbolFlags);
+  void OL_notifyFailed(MaterializationResponsibility &MR);
+  Error OL_replace(MaterializationResponsibility &MR,
+                   std::unique_ptr<MaterializationUnit> MU);
+  Expected<std::unique_ptr<MaterializationResponsibility>>
+  OL_delegate(MaterializationResponsibility &MR, const SymbolNameSet &Symbols);
+  void OL_addDependencies(MaterializationResponsibility &MR,
+                          const SymbolStringPtr &Name,
+                          const SymbolDependenceMap &Dependencies);
+  void OL_addDependenciesForAll(MaterializationResponsibility &MR,
+                                const SymbolDependenceMap &Dependencies);
+
+#ifndef NDEBUG
+  void dumpDispatchInfo(JITDylib &JD, MaterializationUnit &MU);
+#endif // NDEBUG
 
   mutable std::recursive_mutex SessionMutex;
+  bool SessionOpen = true;
   std::shared_ptr<SymbolStringPool> SSP;
-  VModuleKey LastKey = 0;
+  std::unique_ptr<Platform> P;
   ErrorReporter ReportError = logErrorsToStdErr;
   DispatchMaterializationFunction DispatchMaterialization =
       materializeOnCurrentThread;
 
-  std::vector<std::unique_ptr<JITDylib>> JDs;
+  std::vector<ResourceManager *> ResourceManagers;
+
+  std::vector<JITDylibSP> JDs;
 
   // FIXME: Remove this (and runOutstandingMUs) once the linking layer works
   //        with callbacks from asynchronous queries.
   mutable std::recursive_mutex OutstandingMUsMutex;
-  std::vector<std::pair<JITDylib *, std::unique_ptr<MaterializationUnit>>>
+  std::vector<std::pair<std::unique_ptr<MaterializationUnit>,
+                        std::unique_ptr<MaterializationResponsibility>>>
       OutstandingMUs;
 };
 
+inline ExecutionSession &MaterializationResponsibility::getExecutionSession() {
+  return JD->getExecutionSession();
+}
+
 template <typename Func>
-auto JITDylib::withSearchOrderDo(Func &&F)
-    -> decltype(F(std::declval<const JITDylibSearchList &>())) {
-  return ES.runSessionLocked([&]() { return F(SearchOrder); });
-}
-
-template <typename MaterializationUnitType>
-Error JITDylib::define(std::unique_ptr<MaterializationUnitType> &&MU) {
-  assert(MU && "Can not define with a null MU");
-  return ES.runSessionLocked([&, this]() -> Error {
-    if (auto Err = defineImpl(*MU))
-      return Err;
-
-    /// defineImpl succeeded.
-    auto UMI = std::make_shared<UnmaterializedInfo>(std::move(MU));
-    for (auto &KV : UMI->MU->getSymbols())
-      UnmaterializedInfos[KV.first] = UMI;
-
+Error MaterializationResponsibility::withResourceKeyDo(Func &&F) const {
+  return JD->getExecutionSession().runSessionLocked([&]() -> Error {
+    auto I = JD->MRTrackers.find(this);
+    assert(I != JD->MRTrackers.end() && "No tracker for this MR");
+    if (I->second->isDefunct())
+      return make_error<ResourceTrackerDefunct>(I->second);
+    F(I->second->getKeyUnsafe());
     return Error::success();
   });
 }
 
+template <typename GeneratorT>
+GeneratorT &JITDylib::addGenerator(std::unique_ptr<GeneratorT> DefGenerator) {
+  auto &G = *DefGenerator;
+  std::lock_guard<std::mutex> Lock(GeneratorsMutex);
+  DefGenerators.push_back(std::move(DefGenerator));
+  return G;
+}
+
+template <typename Func>
+auto JITDylib::withLinkOrderDo(Func &&F)
+    -> decltype(F(std::declval<const JITDylibSearchOrder &>())) {
+  return ES.runSessionLocked([&]() { return F(LinkOrder); });
+}
+
 template <typename MaterializationUnitType>
-Error JITDylib::define(std::unique_ptr<MaterializationUnitType> &MU) {
+Error JITDylib::define(std::unique_ptr<MaterializationUnitType> &&MU,
+                       ResourceTrackerSP RT) {
   assert(MU && "Can not define with a null MU");
 
+  if (MU->getSymbols().empty()) {
+    // Empty MUs are allowable but pathological, so issue a warning.
+    DEBUG_WITH_TYPE("orc", {
+      dbgs() << "Warning: Discarding empty MU " << MU->getName() << " for "
+             << getName() << "\n";
+    });
+    return Error::success();
+  } else
+    DEBUG_WITH_TYPE("orc", {
+      dbgs() << "Defining MU " << MU->getName() << " for " << getName()
+             << " (tracker: ";
+      if (RT == getDefaultResourceTracker())
+        dbgs() << "default)";
+      else if (RT)
+        dbgs() << RT.get() << ")\n";
+      else
+        dbgs() << "0x0, default will be used)\n";
+    });
+
   return ES.runSessionLocked([&, this]() -> Error {
     if (auto Err = defineImpl(*MU))
       return Err;
 
-    /// defineImpl succeeded.
-    auto UMI = std::make_shared<UnmaterializedInfo>(std::move(MU));
-    for (auto &KV : UMI->MU->getSymbols())
-      UnmaterializedInfos[KV.first] = UMI;
+    if (!RT)
+      RT = getDefaultResourceTracker();
 
+    if (auto *P = ES.getPlatform()) {
+      if (auto Err = P->notifyAdding(*RT, *MU))
+        return Err;
+    }
+
+    installMaterializationUnit(std::move(MU), *RT);
     return Error::success();
   });
 }
 
-/// Mangles symbol names then uniques them in the context of an
-/// ExecutionSession.
-class MangleAndInterner {
+template <typename MaterializationUnitType>
+Error JITDylib::define(std::unique_ptr<MaterializationUnitType> &MU,
+                       ResourceTrackerSP RT) {
+  assert(MU && "Can not define with a null MU");
+
+  if (MU->getSymbols().empty()) {
+    // Empty MUs are allowable but pathological, so issue a warning.
+    DEBUG_WITH_TYPE("orc", {
+      dbgs() << "Warning: Discarding empty MU " << MU->getName() << getName()
+             << "\n";
+    });
+    return Error::success();
+  } else
+    DEBUG_WITH_TYPE("orc", {
+      dbgs() << "Defining MU " << MU->getName() << " for " << getName()
+             << " (tracker: ";
+      if (RT == getDefaultResourceTracker())
+        dbgs() << "default)";
+      else if (RT)
+        dbgs() << RT.get() << ")\n";
+      else
+        dbgs() << "0x0, default will be used)\n";
+    });
+
+  return ES.runSessionLocked([&, this]() -> Error {
+    if (auto Err = defineImpl(*MU))
+      return Err;
+
+    if (!RT)
+      RT = getDefaultResourceTracker();
+
+    if (auto *P = ES.getPlatform()) {
+      if (auto Err = P->notifyAdding(*RT, *MU))
+        return Err;
+    }
+
+    installMaterializationUnit(std::move(MU), *RT);
+    return Error::success();
+  });
+}
+
+/// ReexportsGenerator can be used with JITDylib::addGenerator to automatically
+/// re-export a subset of the source JITDylib's symbols in the target.
+class ReexportsGenerator : public DefinitionGenerator {
 public:
-  MangleAndInterner(ExecutionSession &ES, const DataLayout &DL);
-  SymbolStringPtr operator()(StringRef Name);
+  using SymbolPredicate = std::function<bool(SymbolStringPtr)>;
+
+  /// Create a reexports generator. If an Allow predicate is passed, only
+  /// symbols for which the predicate returns true will be reexported. If no
+  /// Allow predicate is passed, all symbols will be exported.
+  ReexportsGenerator(JITDylib &SourceJD,
+                     JITDylibLookupFlags SourceJDLookupFlags,
+                     SymbolPredicate Allow = SymbolPredicate());
+
+  Error tryToGenerate(LookupState &LS, LookupKind K, JITDylib &JD,
+                      JITDylibLookupFlags JDLookupFlags,
+                      const SymbolLookupSet &LookupSet) override;
 
 private:
-  ExecutionSession &ES;
-  const DataLayout &DL;
+  JITDylib &SourceJD;
+  JITDylibLookupFlags SourceJDLookupFlags;
+  SymbolPredicate Allow;
 };
 
+// --------------- IMPLEMENTATION --------------
+// Implementations for inline functions/methods.
+// ---------------------------------------------
+
+inline MaterializationResponsibility::~MaterializationResponsibility() {
+  JD->getExecutionSession().OL_destroyMaterializationResponsibility(*this);
+}
+
+inline SymbolNameSet MaterializationResponsibility::getRequestedSymbols() const {
+  return JD->getExecutionSession().OL_getRequestedSymbols(*this);
+}
+
+inline Error MaterializationResponsibility::notifyResolved(
+    const SymbolMap &Symbols) {
+  return JD->getExecutionSession().OL_notifyResolved(*this, Symbols);
+}
+
+inline Error MaterializationResponsibility::notifyEmitted() {
+  return JD->getExecutionSession().OL_notifyEmitted(*this);
+}
+
+inline Error MaterializationResponsibility::defineMaterializing(
+    SymbolFlagsMap SymbolFlags) {
+  return JD->getExecutionSession().OL_defineMaterializing(
+      *this, std::move(SymbolFlags));
+}
+
+inline void MaterializationResponsibility::failMaterialization() {
+  JD->getExecutionSession().OL_notifyFailed(*this);
+}
+
+inline Error MaterializationResponsibility::replace(
+    std::unique_ptr<MaterializationUnit> MU) {
+  return JD->getExecutionSession().OL_replace(*this, std::move(MU));
+}
+
+inline Expected<std::unique_ptr<MaterializationResponsibility>>
+MaterializationResponsibility::delegate(const SymbolNameSet &Symbols) {
+  return JD->getExecutionSession().OL_delegate(*this, Symbols);
+}
+
+inline void MaterializationResponsibility::addDependencies(
+    const SymbolStringPtr &Name, const SymbolDependenceMap &Dependencies) {
+  JD->getExecutionSession().OL_addDependencies(*this, Name, Dependencies);
+}
+
+inline void MaterializationResponsibility::addDependenciesForAll(
+    const SymbolDependenceMap &Dependencies) {
+  JD->getExecutionSession().OL_addDependenciesForAll(*this, Dependencies);
+}
+
 } // End namespace orc
 } // End namespace llvm
 
-#undef DEBUG_TYPE // "orc"
-
 #endif // LLVM_EXECUTIONENGINE_ORC_CORE_H
diff --git a/linux-x64/clang/include/llvm/ExecutionEngine/Orc/DebugUtils.h b/linux-x64/clang/include/llvm/ExecutionEngine/Orc/DebugUtils.h
new file mode 100644
index 0000000..4b4472e
--- /dev/null
+++ b/linux-x64/clang/include/llvm/ExecutionEngine/Orc/DebugUtils.h
@@ -0,0 +1,130 @@
+//===----- DebugUtils.h - Utilities for debugging ORC JITs ------*- 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
+//
+//===----------------------------------------------------------------------===//
+//
+// Utilities for debugging ORC-based JITs.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_EXECUTIONENGINE_ORC_DEBUGUTILS_H
+#define LLVM_EXECUTIONENGINE_ORC_DEBUGUTILS_H
+
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ExecutionEngine/Orc/Core.h"
+#include "llvm/ExecutionEngine/Orc/SymbolStringPool.h"
+#include "llvm/Support/Error.h"
+#include "llvm/Support/raw_ostream.h"
+#include <memory>
+#include <string>
+
+namespace llvm {
+
+class MemoryBuffer;
+
+namespace orc {
+
+// --raw_ostream operators for ORC types--
+
+/// Render a SymbolStringPtr.
+raw_ostream &operator<<(raw_ostream &OS, const SymbolStringPtr &Sym);
+
+/// Render a SymbolNameSet.
+raw_ostream &operator<<(raw_ostream &OS, const SymbolNameSet &Symbols);
+
+/// Render a SymbolNameVector.
+raw_ostream &operator<<(raw_ostream &OS, const SymbolNameVector &Symbols);
+
+/// Render an array of SymbolStringPtrs.
+raw_ostream &operator<<(raw_ostream &OS, ArrayRef<SymbolStringPtr> Symbols);
+
+/// Render JITSymbolFlags.
+raw_ostream &operator<<(raw_ostream &OS, const JITSymbolFlags &Flags);
+
+/// Render a SymbolFlagsMap entry.
+raw_ostream &operator<<(raw_ostream &OS, const SymbolFlagsMap::value_type &KV);
+
+/// Render a SymbolMap entry.
+raw_ostream &operator<<(raw_ostream &OS, const SymbolMap::value_type &KV);
+
+/// Render a SymbolFlagsMap.
+raw_ostream &operator<<(raw_ostream &OS, const SymbolFlagsMap &SymbolFlags);
+
+/// Render a SymbolMap.
+raw_ostream &operator<<(raw_ostream &OS, const SymbolMap &Symbols);
+
+/// Render a SymbolDependenceMap entry.
+raw_ostream &operator<<(raw_ostream &OS,
+                        const SymbolDependenceMap::value_type &KV);
+
+/// Render a SymbolDependendeMap.
+raw_ostream &operator<<(raw_ostream &OS, const SymbolDependenceMap &Deps);
+
+/// Render a MaterializationUnit.
+raw_ostream &operator<<(raw_ostream &OS, const MaterializationUnit &MU);
+
+//// Render a JITDylibLookupFlags instance.
+raw_ostream &operator<<(raw_ostream &OS,
+                        const JITDylibLookupFlags &JDLookupFlags);
+
+/// Rendar a SymbolLookupFlags instance.
+raw_ostream &operator<<(raw_ostream &OS, const SymbolLookupFlags &LookupFlags);
+
+/// Render a JITDylibLookupFlags instance.
+raw_ostream &operator<<(raw_ostream &OS, const LookupKind &K);
+
+/// Render a SymbolLookupSet entry.
+raw_ostream &operator<<(raw_ostream &OS, const SymbolLookupSet::value_type &KV);
+
+/// Render a SymbolLookupSet.
+raw_ostream &operator<<(raw_ostream &OS, const SymbolLookupSet &LookupSet);
+
+/// Render a JITDylibSearchOrder.
+raw_ostream &operator<<(raw_ostream &OS,
+                        const JITDylibSearchOrder &SearchOrder);
+
+/// Render a SymbolAliasMap.
+raw_ostream &operator<<(raw_ostream &OS, const SymbolAliasMap &Aliases);
+
+/// Render a SymbolState.
+raw_ostream &operator<<(raw_ostream &OS, const SymbolState &S);
+
+/// Render a LookupKind.
+raw_ostream &operator<<(raw_ostream &OS, const LookupKind &K);
+
+/// A function object that can be used as an ObjectTransformLayer transform
+/// to dump object files to disk at a specified path.
+class DumpObjects {
+public:
+  /// Construct a DumpObjects transform that will dump objects to disk.
+  ///
+  /// @param DumpDir specifies the path to write dumped objects to. DumpDir may
+  /// be empty, in which case files will be dumped to the working directory. If
+  /// DumpDir is non-empty then any trailing separators will be discarded.
+  ///
+  /// @param IdentifierOverride specifies a file name stem to use when dumping
+  /// objects. If empty, each MemoryBuffer's identifier will be used (with a .o
+  /// suffix added if not already present). If an identifier override is
+  /// supplied it will be used instead (since all buffers will use the same
+  /// identifier, the resulting files will be named <ident>.o, <ident>.2.o,
+  /// <ident>.3.o, and so on). IdentifierOverride should not contain an
+  /// extension, as a .o suffix will be added by DumpObjects.
+  DumpObjects(std::string DumpDir = "", std::string IdentifierOverride = "");
+
+  /// Dumps the given buffer to disk.
+  Expected<std::unique_ptr<MemoryBuffer>>
+  operator()(std::unique_ptr<MemoryBuffer> Obj);
+
+private:
+  StringRef getBufferIdentifier(MemoryBuffer &B);
+  std::string DumpDir;
+  std::string IdentifierOverride;
+};
+
+} // End namespace orc
+} // End namespace llvm
+
+#endif // LLVM_EXECUTIONENGINE_ORC_DEBUGUTILS_H
diff --git a/linux-x64/clang/include/llvm/ExecutionEngine/Orc/ExecutionUtils.h b/linux-x64/clang/include/llvm/ExecutionEngine/Orc/ExecutionUtils.h
index ae3ab8c..1dc2af4 100644
--- a/linux-x64/clang/include/llvm/ExecutionEngine/Orc/ExecutionUtils.h
+++ b/linux-x64/clang/include/llvm/ExecutionEngine/Orc/ExecutionUtils.h
@@ -17,8 +17,10 @@
 #include "llvm/ADT/iterator_range.h"
 #include "llvm/ExecutionEngine/JITSymbol.h"
 #include "llvm/ExecutionEngine/Orc/Core.h"
+#include "llvm/ExecutionEngine/Orc/Mangling.h"
 #include "llvm/ExecutionEngine/Orc/OrcError.h"
 #include "llvm/ExecutionEngine/RuntimeDyld.h"
+#include "llvm/Object/Archive.h"
 #include "llvm/Support/DynamicLibrary.h"
 #include <algorithm>
 #include <cstdint>
@@ -37,6 +39,8 @@
 
 namespace orc {
 
+class ObjectLayer;
+
 /// This iterator provides a convenient way to iterate over the elements
 ///        of an llvm.global_ctors/llvm.global_dtors instance.
 ///
@@ -90,44 +94,53 @@
 ///        array.
 iterator_range<CtorDtorIterator> getDestructors(const Module &M);
 
-/// Convenience class for recording constructor/destructor names for
-///        later execution.
-template <typename JITLayerT>
-class LegacyCtorDtorRunner {
+/// This iterator provides a convenient way to iterate over GlobalValues that
+/// have initialization effects.
+class StaticInitGVIterator {
 public:
-  /// Construct a CtorDtorRunner for the given range using the given
-  ///        name mangling function.
-  LegacyCtorDtorRunner(std::vector<std::string> CtorDtorNames, VModuleKey K)
-      : CtorDtorNames(std::move(CtorDtorNames)), K(K) {}
+  StaticInitGVIterator() = default;
 
-  /// Run the recorded constructors/destructors through the given JIT
-  ///        layer.
-  Error runViaLayer(JITLayerT &JITLayer) const {
-    using CtorDtorTy = void (*)();
-
-    for (const auto &CtorDtorName : CtorDtorNames) {
-      if (auto CtorDtorSym = JITLayer.findSymbolIn(K, CtorDtorName, false)) {
-        if (auto AddrOrErr = CtorDtorSym.getAddress()) {
-          CtorDtorTy CtorDtor =
-            reinterpret_cast<CtorDtorTy>(static_cast<uintptr_t>(*AddrOrErr));
-          CtorDtor();
-        } else
-          return AddrOrErr.takeError();
-      } else {
-        if (auto Err = CtorDtorSym.takeError())
-          return Err;
-        else
-          return make_error<JITSymbolNotFound>(CtorDtorName);
-      }
-    }
-    return Error::success();
+  StaticInitGVIterator(Module &M)
+      : I(M.global_values().begin()), E(M.global_values().end()),
+        ObjFmt(Triple(M.getTargetTriple()).getObjectFormat()) {
+    if (I != E) {
+      if (!isStaticInitGlobal(*I))
+        moveToNextStaticInitGlobal();
+    } else
+      I = E = Module::global_value_iterator();
   }
 
+  bool operator==(const StaticInitGVIterator &O) const { return I == O.I; }
+  bool operator!=(const StaticInitGVIterator &O) const { return I != O.I; }
+
+  StaticInitGVIterator &operator++() {
+    assert(I != E && "Increment past end of range");
+    moveToNextStaticInitGlobal();
+    return *this;
+  }
+
+  GlobalValue &operator*() { return *I; }
+
 private:
-  std::vector<std::string> CtorDtorNames;
-  orc::VModuleKey K;
+  bool isStaticInitGlobal(GlobalValue &GV);
+  void moveToNextStaticInitGlobal() {
+    ++I;
+    while (I != E && !isStaticInitGlobal(*I))
+      ++I;
+    if (I == E)
+      I = E = Module::global_value_iterator();
+  }
+
+  Module::global_value_iterator I, E;
+  Triple::ObjectFormatType ObjFmt;
 };
 
+/// Create an iterator range over the GlobalValues that contribute to static
+/// initialization.
+inline iterator_range<StaticInitGVIterator> getStaticInitGVs(Module &M) {
+  return make_range(StaticInitGVIterator(M), StaticInitGVIterator());
+}
+
 class CtorDtorRunner {
 public:
   CtorDtorRunner(JITDylib &JD) : JD(JD) {}
@@ -176,44 +189,35 @@
                                void *DSOHandle);
 };
 
-class LegacyLocalCXXRuntimeOverrides : public LocalCXXRuntimeOverridesBase {
-public:
-  /// Create a runtime-overrides class.
-  template <typename MangleFtorT>
-  LegacyLocalCXXRuntimeOverrides(const MangleFtorT &Mangle) {
-    addOverride(Mangle("__dso_handle"), toTargetAddress(&DSOHandleOverride));
-    addOverride(Mangle("__cxa_atexit"), toTargetAddress(&CXAAtExitOverride));
-  }
-
-  /// Search overrided symbols.
-  JITEvaluatedSymbol searchOverrides(const std::string &Name) {
-    auto I = CXXRuntimeOverrides.find(Name);
-    if (I != CXXRuntimeOverrides.end())
-      return JITEvaluatedSymbol(I->second, JITSymbolFlags::Exported);
-    return nullptr;
-  }
-
-private:
-  void addOverride(const std::string &Name, JITTargetAddress Addr) {
-    CXXRuntimeOverrides.insert(std::make_pair(Name, Addr));
-  }
-
-  StringMap<JITTargetAddress> CXXRuntimeOverrides;
-};
-
 class LocalCXXRuntimeOverrides : public LocalCXXRuntimeOverridesBase {
 public:
   Error enable(JITDylib &JD, MangleAndInterner &Mangler);
 };
 
+/// An interface for Itanium __cxa_atexit interposer implementations.
+class ItaniumCXAAtExitSupport {
+public:
+  struct AtExitRecord {
+    void (*F)(void *);
+    void *Ctx;
+  };
+
+  void registerAtExit(void (*F)(void *), void *Ctx, void *DSOHandle);
+  void runAtExits(void *DSOHandle);
+
+private:
+  std::mutex AtExitsMutex;
+  DenseMap<void *, std::vector<AtExitRecord>> AtExitRecords;
+};
+
 /// A utility class to expose symbols found via dlsym to the JIT.
 ///
 /// If an instance of this class is attached to a JITDylib as a fallback
 /// definition generator, then any symbol found in the given DynamicLibrary that
 /// passes the 'Allow' predicate will be added to the JITDylib.
-class DynamicLibrarySearchGenerator {
+class DynamicLibrarySearchGenerator : public DefinitionGenerator {
 public:
-  using SymbolPredicate = std::function<bool(SymbolStringPtr)>;
+  using SymbolPredicate = std::function<bool(const SymbolStringPtr &)>;
 
   /// Create a DynamicLibrarySearchGenerator that searches for symbols in the
   /// given sys::DynamicLibrary.
@@ -227,19 +231,21 @@
   /// Permanently loads the library at the given path and, on success, returns
   /// a DynamicLibrarySearchGenerator that will search it for symbol definitions
   /// in the library. On failure returns the reason the library failed to load.
-  static Expected<DynamicLibrarySearchGenerator>
+  static Expected<std::unique_ptr<DynamicLibrarySearchGenerator>>
   Load(const char *FileName, char GlobalPrefix,
        SymbolPredicate Allow = SymbolPredicate());
 
   /// Creates a DynamicLibrarySearchGenerator that searches for symbols in
   /// the current process.
-  static Expected<DynamicLibrarySearchGenerator>
+  static Expected<std::unique_ptr<DynamicLibrarySearchGenerator>>
   GetForCurrentProcess(char GlobalPrefix,
                        SymbolPredicate Allow = SymbolPredicate()) {
     return Load(nullptr, GlobalPrefix, std::move(Allow));
   }
 
-  Expected<SymbolNameSet> operator()(JITDylib &JD, const SymbolNameSet &Names);
+  Error tryToGenerate(LookupState &LS, LookupKind K, JITDylib &JD,
+                      JITDylibLookupFlags JDLookupFlags,
+                      const SymbolLookupSet &Symbols) override;
 
 private:
   sys::DynamicLibrary Dylib;
@@ -247,6 +253,48 @@
   char GlobalPrefix;
 };
 
+/// A utility class to expose symbols from a static library.
+///
+/// If an instance of this class is attached to a JITDylib as a fallback
+/// definition generator, then any symbol found in the archive will result in
+/// the containing object being added to the JITDylib.
+class StaticLibraryDefinitionGenerator : public DefinitionGenerator {
+public:
+  /// Try to create a StaticLibraryDefinitionGenerator from the given path.
+  ///
+  /// This call will succeed if the file at the given path is a static library
+  /// is a valid archive, otherwise it will return an error.
+  static Expected<std::unique_ptr<StaticLibraryDefinitionGenerator>>
+  Load(ObjectLayer &L, const char *FileName);
+
+  /// Try to create a StaticLibraryDefinitionGenerator from the given path.
+  ///
+  /// This call will succeed if the file at the given path is a static library
+  /// or a MachO universal binary containing a static library that is compatible
+  /// with the given triple. Otherwise it will return an error.
+  static Expected<std::unique_ptr<StaticLibraryDefinitionGenerator>>
+  Load(ObjectLayer &L, const char *FileName, const Triple &TT);
+
+  /// Try to create a StaticLibrarySearchGenerator from the given memory buffer.
+  /// This call will succeed if the buffer contains a valid archive, otherwise
+  /// it will return an error.
+  static Expected<std::unique_ptr<StaticLibraryDefinitionGenerator>>
+  Create(ObjectLayer &L, std::unique_ptr<MemoryBuffer> ArchiveBuffer);
+
+  Error tryToGenerate(LookupState &LS, LookupKind K, JITDylib &JD,
+                      JITDylibLookupFlags JDLookupFlags,
+                      const SymbolLookupSet &Symbols) override;
+
+private:
+  StaticLibraryDefinitionGenerator(ObjectLayer &L,
+                                   std::unique_ptr<MemoryBuffer> ArchiveBuffer,
+                                   Error &Err);
+
+  ObjectLayer &L;
+  std::unique_ptr<MemoryBuffer> ArchiveBuffer;
+  std::unique_ptr<object::Archive> Archive;
+};
+
 } // end namespace orc
 } // end namespace llvm
 
diff --git a/linux-x64/clang/include/llvm/ExecutionEngine/Orc/GlobalMappingLayer.h b/linux-x64/clang/include/llvm/ExecutionEngine/Orc/GlobalMappingLayer.h
deleted file mode 100644
index a4e43d4..0000000
--- a/linux-x64/clang/include/llvm/ExecutionEngine/Orc/GlobalMappingLayer.h
+++ /dev/null
@@ -1,111 +0,0 @@
-//===- GlobalMappingLayer.h - Run all IR through a functor ------*- 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
-//
-//===----------------------------------------------------------------------===//
-//
-// Convenience layer for injecting symbols that will appear in calls to
-// findSymbol.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_EXECUTIONENGINE_ORC_GLOBALMAPPINGLAYER_H
-#define LLVM_EXECUTIONENGINE_ORC_GLOBALMAPPINGLAYER_H
-
-#include "llvm/ExecutionEngine/JITSymbol.h"
-#include <map>
-#include <memory>
-#include <string>
-
-namespace llvm {
-
-class Module;
-class JITSymbolResolver;
-
-namespace orc {
-
-/// Global mapping layer.
-///
-///   This layer overrides the findSymbol method to first search a local symbol
-/// table that the client can define. It can be used to inject new symbol
-/// mappings into the JIT. Beware, however: symbols within a single IR module or
-/// object file will still resolve locally (via RuntimeDyld's symbol table) -
-/// such internal references cannot be overriden via this layer.
-template <typename BaseLayerT>
-class GlobalMappingLayer {
-public:
-
-  /// Handle to an added module.
-  using ModuleHandleT = typename BaseLayerT::ModuleHandleT;
-
-  /// Construct an GlobalMappingLayer with the given BaseLayer
-  GlobalMappingLayer(BaseLayerT &BaseLayer) : BaseLayer(BaseLayer) {}
-
-  /// Add the given module to the JIT.
-  /// @return A handle for the added modules.
-  Expected<ModuleHandleT>
-  addModule(std::shared_ptr<Module> M,
-            std::shared_ptr<JITSymbolResolver> Resolver) {
-    return BaseLayer.addModule(std::move(M), std::move(Resolver));
-  }
-
-  /// Remove the module set associated with the handle H.
-  Error removeModule(ModuleHandleT H) { return BaseLayer.removeModule(H); }
-
-  /// Manually set the address to return for the given symbol.
-  void setGlobalMapping(const std::string &Name, JITTargetAddress Addr) {
-    SymbolTable[Name] = Addr;
-  }
-
-  /// Remove the given symbol from the global mapping.
-  void eraseGlobalMapping(const std::string &Name) {
-    SymbolTable.erase(Name);
-  }
-
-  /// Search for the given named symbol.
-  ///
-  ///          This method will first search the local symbol table, returning
-  ///        any symbol found there. If the symbol is not found in the local
-  ///        table then this call will be passed through to the base layer.
-  ///
-  /// @param Name The name of the symbol to search for.
-  /// @param ExportedSymbolsOnly If true, search only for exported symbols.
-  /// @return A handle for the given named symbol, if it exists.
-  JITSymbol findSymbol(const std::string &Name, bool ExportedSymbolsOnly) {
-    auto I = SymbolTable.find(Name);
-    if (I != SymbolTable.end())
-      return JITSymbol(I->second, JITSymbolFlags::Exported);
-    return BaseLayer.findSymbol(Name, ExportedSymbolsOnly);
-  }
-
-  /// Get the address of the given symbol in the context of the of the
-  ///        module represented by the handle H. This call is forwarded to the
-  ///        base layer's implementation.
-  /// @param H The handle for the module to search in.
-  /// @param Name The name of the symbol to search for.
-  /// @param ExportedSymbolsOnly If true, search only for exported symbols.
-  /// @return A handle for the given named symbol, if it is found in the
-  ///         given module.
-  JITSymbol findSymbolIn(ModuleHandleT H, const std::string &Name,
-                         bool ExportedSymbolsOnly) {
-    return BaseLayer.findSymbolIn(H, Name, ExportedSymbolsOnly);
-  }
-
-  /// Immediately emit and finalize the module set represented by the
-  ///        given handle.
-  /// @param H Handle for module set to emit/finalize.
-  Error emitAndFinalize(ModuleHandleT H) {
-    return BaseLayer.emitAndFinalize(H);
-  }
-
-private:
-  BaseLayerT &BaseLayer;
-  std::map<std::string, JITTargetAddress> SymbolTable;
-};
-
-} // end namespace orc
-} // end namespace llvm
-
-#endif // LLVM_EXECUTIONENGINE_ORC_GLOBALMAPPINGLAYER_H
diff --git a/linux-x64/clang/include/llvm/ExecutionEngine/Orc/IRCompileLayer.h b/linux-x64/clang/include/llvm/ExecutionEngine/Orc/IRCompileLayer.h
index ecff09b..f8fdb17 100644
--- a/linux-x64/clang/include/llvm/ExecutionEngine/Orc/IRCompileLayer.h
+++ b/linux-x64/clang/include/llvm/ExecutionEngine/Orc/IRCompileLayer.h
@@ -29,101 +29,44 @@
 
 class IRCompileLayer : public IRLayer {
 public:
-  using CompileFunction =
-      std::function<Expected<std::unique_ptr<MemoryBuffer>>(Module &)>;
+  class IRCompiler {
+  public:
+    IRCompiler(IRSymbolMapper::ManglingOptions MO) : MO(std::move(MO)) {}
+    virtual ~IRCompiler();
+    const IRSymbolMapper::ManglingOptions &getManglingOptions() const {
+      return MO;
+    }
+    virtual Expected<std::unique_ptr<MemoryBuffer>> operator()(Module &M) = 0;
 
-  using NotifyCompiledFunction =
-      std::function<void(VModuleKey K, ThreadSafeModule TSM)>;
+  protected:
+    IRSymbolMapper::ManglingOptions &manglingOptions() { return MO; }
+
+  private:
+    IRSymbolMapper::ManglingOptions MO;
+  };
+
+  using NotifyCompiledFunction = std::function<void(
+      MaterializationResponsibility &R, ThreadSafeModule TSM)>;
 
   IRCompileLayer(ExecutionSession &ES, ObjectLayer &BaseLayer,
-                 CompileFunction Compile);
+                 std::unique_ptr<IRCompiler> Compile);
+
+  IRCompiler &getCompiler() { return *Compile; }
 
   void setNotifyCompiled(NotifyCompiledFunction NotifyCompiled);
 
-  void emit(MaterializationResponsibility R, ThreadSafeModule TSM) override;
+  void emit(std::unique_ptr<MaterializationResponsibility> R,
+            ThreadSafeModule TSM) override;
 
 private:
   mutable std::mutex IRLayerMutex;
   ObjectLayer &BaseLayer;
-  CompileFunction Compile;
+  std::unique_ptr<IRCompiler> Compile;
+  const IRSymbolMapper::ManglingOptions *ManglingOpts;
   NotifyCompiledFunction NotifyCompiled = NotifyCompiledFunction();
 };
 
-/// Eager IR compiling layer.
-///
-///   This layer immediately compiles each IR module added via addModule to an
-/// object file and adds this module file to the layer below, which must
-/// implement the object layer concept.
-template <typename BaseLayerT, typename CompileFtor>
-class LegacyIRCompileLayer {
-public:
-  /// Callback type for notifications when modules are compiled.
-  using NotifyCompiledCallback =
-      std::function<void(VModuleKey K, std::unique_ptr<Module>)>;
-
-  /// Construct an LegacyIRCompileLayer with the given BaseLayer, which must
-  ///        implement the ObjectLayer concept.
-  LegacyIRCompileLayer(
-      BaseLayerT &BaseLayer, CompileFtor Compile,
-      NotifyCompiledCallback NotifyCompiled = NotifyCompiledCallback())
-      : BaseLayer(BaseLayer), Compile(std::move(Compile)),
-        NotifyCompiled(std::move(NotifyCompiled)) {}
-
-  /// Get a reference to the compiler functor.
-  CompileFtor& getCompiler() { return Compile; }
-
-  /// (Re)set the NotifyCompiled callback.
-  void setNotifyCompiled(NotifyCompiledCallback NotifyCompiled) {
-    this->NotifyCompiled = std::move(NotifyCompiled);
-  }
-
-  /// Compile the module, and add the resulting object to the base layer
-  ///        along with the given memory manager and symbol resolver.
-  Error addModule(VModuleKey K, std::unique_ptr<Module> M) {
-    if (auto Err = BaseLayer.addObject(std::move(K), Compile(*M)))
-      return Err;
-    if (NotifyCompiled)
-      NotifyCompiled(std::move(K), std::move(M));
-    return Error::success();
-  }
-
-  /// Remove the module associated with the VModuleKey K.
-  Error removeModule(VModuleKey K) { return BaseLayer.removeObject(K); }
-
-  /// Search for the given named symbol.
-  /// @param Name The name of the symbol to search for.
-  /// @param ExportedSymbolsOnly If true, search only for exported symbols.
-  /// @return A handle for the given named symbol, if it exists.
-  JITSymbol findSymbol(const std::string &Name, bool ExportedSymbolsOnly) {
-    return BaseLayer.findSymbol(Name, ExportedSymbolsOnly);
-  }
-
-  /// Get the address of the given symbol in compiled module represented
-  ///        by the handle H. This call is forwarded to the base layer's
-  ///        implementation.
-  /// @param K The VModuleKey for the module to search in.
-  /// @param Name The name of the symbol to search for.
-  /// @param ExportedSymbolsOnly If true, search only for exported symbols.
-  /// @return A handle for the given named symbol, if it is found in the
-  ///         given module.
-  JITSymbol findSymbolIn(VModuleKey K, const std::string &Name,
-                         bool ExportedSymbolsOnly) {
-    return BaseLayer.findSymbolIn(K, Name, ExportedSymbolsOnly);
-  }
-
-  /// Immediately emit and finalize the module represented by the given
-  ///        handle.
-  /// @param K The VModuleKey for the module to emit/finalize.
-  Error emitAndFinalize(VModuleKey K) { return BaseLayer.emitAndFinalize(K); }
-
-private:
-  BaseLayerT &BaseLayer;
-  CompileFtor Compile;
-  NotifyCompiledCallback NotifyCompiled;
-};
-
 } // end namespace orc
-
 } // end namespace llvm
 
 #endif // LLVM_EXECUTIONENGINE_ORC_IRCOMPILINGLAYER_H
diff --git a/linux-x64/clang/include/llvm/ExecutionEngine/Orc/IRTransformLayer.h b/linux-x64/clang/include/llvm/ExecutionEngine/Orc/IRTransformLayer.h
index 8890a57..66966a0 100644
--- a/linux-x64/clang/include/llvm/ExecutionEngine/Orc/IRTransformLayer.h
+++ b/linux-x64/clang/include/llvm/ExecutionEngine/Orc/IRTransformLayer.h
@@ -13,6 +13,7 @@
 #ifndef LLVM_EXECUTIONENGINE_ORC_IRTRANSFORMLAYER_H
 #define LLVM_EXECUTIONENGINE_ORC_IRTRANSFORMLAYER_H
 
+#include "llvm/ADT/FunctionExtras.h"
 #include "llvm/ExecutionEngine/JITSymbol.h"
 #include "llvm/ExecutionEngine/Orc/Layer.h"
 #include <memory>
@@ -22,10 +23,13 @@
 class Module;
 namespace orc {
 
+/// A layer that applies a transform to emitted modules.
+/// The transform function is responsible for locking the ThreadSafeContext
+/// before operating on the module.
 class IRTransformLayer : public IRLayer {
 public:
-  using TransformFunction = std::function<Expected<ThreadSafeModule>(
-      ThreadSafeModule, const MaterializationResponsibility &R)>;
+  using TransformFunction = unique_function<Expected<ThreadSafeModule>(
+      ThreadSafeModule, MaterializationResponsibility &R)>;
 
   IRTransformLayer(ExecutionSession &ES, IRLayer &BaseLayer,
                    TransformFunction Transform = identityTransform);
@@ -34,11 +38,11 @@
     this->Transform = std::move(Transform);
   }
 
-  void emit(MaterializationResponsibility R, ThreadSafeModule TSM) override;
+  void emit(std::unique_ptr<MaterializationResponsibility> R,
+            ThreadSafeModule TSM) override;
 
-  static ThreadSafeModule
-  identityTransform(ThreadSafeModule TSM,
-                    const MaterializationResponsibility &R) {
+  static ThreadSafeModule identityTransform(ThreadSafeModule TSM,
+                                            MaterializationResponsibility &R) {
     return TSM;
   }
 
@@ -47,67 +51,6 @@
   TransformFunction Transform;
 };
 
-/// IR mutating layer.
-///
-///   This layer applies a user supplied transform to each module that is added,
-/// then adds the transformed module to the layer below.
-template <typename BaseLayerT, typename TransformFtor>
-class LegacyIRTransformLayer {
-public:
-
-  /// Construct an LegacyIRTransformLayer with the given BaseLayer
-  LegacyIRTransformLayer(BaseLayerT &BaseLayer,
-                   TransformFtor Transform = TransformFtor())
-    : BaseLayer(BaseLayer), Transform(std::move(Transform)) {}
-
-  /// Apply the transform functor to the module, then add the module to
-  ///        the layer below, along with the memory manager and symbol resolver.
-  ///
-  /// @return A handle for the added modules.
-  Error addModule(VModuleKey K, std::unique_ptr<Module> M) {
-    return BaseLayer.addModule(std::move(K), Transform(std::move(M)));
-  }
-
-  /// Remove the module associated with the VModuleKey K.
-  Error removeModule(VModuleKey K) { return BaseLayer.removeModule(K); }
-
-  /// Search for the given named symbol.
-  /// @param Name The name of the symbol to search for.
-  /// @param ExportedSymbolsOnly If true, search only for exported symbols.
-  /// @return A handle for the given named symbol, if it exists.
-  JITSymbol findSymbol(const std::string &Name, bool ExportedSymbolsOnly) {
-    return BaseLayer.findSymbol(Name, ExportedSymbolsOnly);
-  }
-
-  /// Get the address of the given symbol in the context of the module
-  ///        represented by the VModuleKey K. This call is forwarded to the base
-  ///        layer's implementation.
-  /// @param K The VModuleKey for the module to search in.
-  /// @param Name The name of the symbol to search for.
-  /// @param ExportedSymbolsOnly If true, search only for exported symbols.
-  /// @return A handle for the given named symbol, if it is found in the
-  ///         given module.
-  JITSymbol findSymbolIn(VModuleKey K, const std::string &Name,
-                         bool ExportedSymbolsOnly) {
-    return BaseLayer.findSymbolIn(K, Name, ExportedSymbolsOnly);
-  }
-
-  /// Immediately emit and finalize the module represented by the given
-  ///        VModuleKey.
-  /// @param K The VModuleKey for the module to emit/finalize.
-  Error emitAndFinalize(VModuleKey K) { return BaseLayer.emitAndFinalize(K); }
-
-  /// Access the transform functor directly.
-  TransformFtor& getTransform() { return Transform; }
-
-  /// Access the mumate functor directly.
-  const TransformFtor& getTransform() const { return Transform; }
-
-private:
-  BaseLayerT &BaseLayer;
-  TransformFtor Transform;
-};
-
 } // end namespace orc
 } // end namespace llvm
 
diff --git a/linux-x64/clang/include/llvm/ExecutionEngine/Orc/IndirectionUtils.h b/linux-x64/clang/include/llvm/ExecutionEngine/Orc/IndirectionUtils.h
index a7ed537..78e3cee 100644
--- a/linux-x64/clang/include/llvm/ExecutionEngine/Orc/IndirectionUtils.h
+++ b/linux-x64/clang/include/llvm/ExecutionEngine/Orc/IndirectionUtils.h
@@ -15,9 +15,9 @@
 
 #include "llvm/ADT/StringMap.h"
 #include "llvm/ADT/StringRef.h"
-#include "llvm/ADT/Twine.h"
 #include "llvm/ExecutionEngine/JITSymbol.h"
 #include "llvm/ExecutionEngine/Orc/Core.h"
+#include "llvm/ExecutionEngine/Orc/OrcABISupport.h"
 #include "llvm/Support/Error.h"
 #include "llvm/Support/Memory.h"
 #include "llvm/Support/Process.h"
@@ -26,6 +26,7 @@
 #include <cassert>
 #include <cstdint>
 #include <functional>
+#include <future>
 #include <map>
 #include <memory>
 #include <system_error>
@@ -42,6 +43,7 @@
 class Module;
 class PointerType;
 class Triple;
+class Twine;
 class Value;
 
 namespace orc {
@@ -53,41 +55,19 @@
 /// are used by various ORC APIs to support lazy compilation
 class TrampolinePool {
 public:
-  virtual ~TrampolinePool() {}
+  using NotifyLandingResolvedFunction =
+      unique_function<void(JITTargetAddress) const>;
+
+  using ResolveLandingFunction = unique_function<void(
+      JITTargetAddress TrampolineAddr,
+      NotifyLandingResolvedFunction OnLandingResolved) const>;
+
+  virtual ~TrampolinePool();
 
   /// Get an available trampoline address.
   /// Returns an error if no trampoline can be created.
-  virtual Expected<JITTargetAddress> getTrampoline() = 0;
-
-private:
-  virtual void anchor();
-};
-
-/// A trampoline pool for trampolines within the current process.
-template <typename ORCABI> class LocalTrampolinePool : public TrampolinePool {
-public:
-  using GetTrampolineLandingFunction =
-      std::function<JITTargetAddress(JITTargetAddress TrampolineAddr)>;
-
-  /// Creates a LocalTrampolinePool with the given RunCallback function.
-  /// Returns an error if this function is unable to correctly allocate, write
-  /// and protect the resolver code block.
-  static Expected<std::unique_ptr<LocalTrampolinePool>>
-  Create(GetTrampolineLandingFunction GetTrampolineLanding) {
-    Error Err = Error::success();
-
-    auto LTP = std::unique_ptr<LocalTrampolinePool>(
-        new LocalTrampolinePool(std::move(GetTrampolineLanding), Err));
-
-    if (Err)
-      return std::move(Err);
-    return std::move(LTP);
-  }
-
-  /// Get a free trampoline. Returns an error if one can not be provide (e.g.
-  /// because the pool is empty and can not be grown).
-  Expected<JITTargetAddress> getTrampoline() override {
-    std::lock_guard<std::mutex> Lock(LTPMutex);
+  Expected<JITTargetAddress> getTrampoline() {
+    std::lock_guard<std::mutex> Lock(TPMutex);
     if (AvailableTrampolines.empty()) {
       if (auto Err = grow())
         return std::move(Err);
@@ -100,21 +80,52 @@
 
   /// Returns the given trampoline to the pool for re-use.
   void releaseTrampoline(JITTargetAddress TrampolineAddr) {
-    std::lock_guard<std::mutex> Lock(LTPMutex);
+    std::lock_guard<std::mutex> Lock(TPMutex);
     AvailableTrampolines.push_back(TrampolineAddr);
   }
 
+protected:
+  virtual Error grow() = 0;
+
+  std::mutex TPMutex;
+  std::vector<JITTargetAddress> AvailableTrampolines;
+};
+
+/// A trampoline pool for trampolines within the current process.
+template <typename ORCABI> class LocalTrampolinePool : public TrampolinePool {
+public:
+  /// Creates a LocalTrampolinePool with the given RunCallback function.
+  /// Returns an error if this function is unable to correctly allocate, write
+  /// and protect the resolver code block.
+  static Expected<std::unique_ptr<LocalTrampolinePool>>
+  Create(ResolveLandingFunction ResolveLanding) {
+    Error Err = Error::success();
+
+    auto LTP = std::unique_ptr<LocalTrampolinePool>(
+        new LocalTrampolinePool(std::move(ResolveLanding), Err));
+
+    if (Err)
+      return std::move(Err);
+    return std::move(LTP);
+  }
+
 private:
   static JITTargetAddress reenter(void *TrampolinePoolPtr, void *TrampolineId) {
     LocalTrampolinePool<ORCABI> *TrampolinePool =
         static_cast<LocalTrampolinePool *>(TrampolinePoolPtr);
-    return TrampolinePool->GetTrampolineLanding(static_cast<JITTargetAddress>(
-        reinterpret_cast<uintptr_t>(TrampolineId)));
+
+    std::promise<JITTargetAddress> LandingAddressP;
+    auto LandingAddressF = LandingAddressP.get_future();
+
+    TrampolinePool->ResolveLanding(pointerToJITTargetAddress(TrampolineId),
+                                   [&](JITTargetAddress LandingAddress) {
+                                     LandingAddressP.set_value(LandingAddress);
+                                   });
+    return LandingAddressF.get();
   }
 
-  LocalTrampolinePool(GetTrampolineLandingFunction GetTrampolineLanding,
-                      Error &Err)
-      : GetTrampolineLanding(std::move(GetTrampolineLanding)) {
+  LocalTrampolinePool(ResolveLandingFunction ResolveLanding, Error &Err)
+      : ResolveLanding(std::move(ResolveLanding)) {
 
     ErrorAsOutParameter _(&Err);
 
@@ -128,8 +139,10 @@
       return;
     }
 
-    ORCABI::writeResolverCode(static_cast<uint8_t *>(ResolverBlock.base()),
-                              &reenter, this);
+    ORCABI::writeResolverCode(static_cast<char *>(ResolverBlock.base()),
+                              pointerToJITTargetAddress(ResolverBlock.base()),
+                              pointerToJITTargetAddress(&reenter),
+                              pointerToJITTargetAddress(this));
 
     EC = sys::Memory::protectMappedMemory(ResolverBlock.getMemoryBlock(),
                                           sys::Memory::MF_READ |
@@ -140,8 +153,8 @@
     }
   }
 
-  Error grow() {
-    assert(this->AvailableTrampolines.empty() && "Growing prematurely?");
+  Error grow() override {
+    assert(AvailableTrampolines.empty() && "Growing prematurely?");
 
     std::error_code EC;
     auto TrampolineBlock =
@@ -155,14 +168,14 @@
         (sys::Process::getPageSizeEstimate() - ORCABI::PointerSize) /
         ORCABI::TrampolineSize;
 
-    uint8_t *TrampolineMem = static_cast<uint8_t *>(TrampolineBlock.base());
-    ORCABI::writeTrampolines(TrampolineMem, ResolverBlock.base(),
-                             NumTrampolines);
+    char *TrampolineMem = static_cast<char *>(TrampolineBlock.base());
+    ORCABI::writeTrampolines(
+        TrampolineMem, pointerToJITTargetAddress(TrampolineMem),
+        pointerToJITTargetAddress(ResolverBlock.base()), NumTrampolines);
 
     for (unsigned I = 0; I < NumTrampolines; ++I)
-      this->AvailableTrampolines.push_back(
-          static_cast<JITTargetAddress>(reinterpret_cast<uintptr_t>(
-              TrampolineMem + (I * ORCABI::TrampolineSize))));
+      AvailableTrampolines.push_back(pointerToJITTargetAddress(
+          TrampolineMem + (I * ORCABI::TrampolineSize)));
 
     if (auto EC = sys::Memory::protectMappedMemory(
                     TrampolineBlock.getMemoryBlock(),
@@ -173,12 +186,10 @@
     return Error::success();
   }
 
-  GetTrampolineLandingFunction GetTrampolineLanding;
+  ResolveLandingFunction ResolveLanding;
 
-  std::mutex LTPMutex;
   sys::OwningMemoryBlock ResolverBlock;
   std::vector<sys::OwningMemoryBlock> TrampolineBlocks;
-  std::vector<JITTargetAddress> AvailableTrampolines;
 };
 
 /// Target-independent base class for compile callback management.
@@ -201,7 +212,7 @@
                             ExecutionSession &ES,
                             JITTargetAddress ErrorHandlerAddress)
       : TP(std::move(TP)), ES(ES),
-        CallbacksJD(ES.createJITDylib("<Callbacks>")),
+        CallbacksJD(ES.createBareJITDylib("<Callbacks>")),
         ErrorHandlerAddress(ErrorHandlerAddress) {}
 
   void setTrampolinePool(std::unique_ptr<TrampolinePool> TP) {
@@ -241,10 +252,14 @@
                                  JITTargetAddress ErrorHandlerAddress,
                                  Error &Err)
       : JITCompileCallbackManager(nullptr, ES, ErrorHandlerAddress) {
+    using NotifyLandingResolvedFunction =
+        TrampolinePool::NotifyLandingResolvedFunction;
+
     ErrorAsOutParameter _(&Err);
     auto TP = LocalTrampolinePool<ORCABI>::Create(
-        [this](JITTargetAddress TrampolineAddr) {
-          return executeCompileCallback(TrampolineAddr);
+        [this](JITTargetAddress TrampolineAddr,
+               NotifyLandingResolvedFunction NotifyLandingResolved) {
+          NotifyLandingResolved(executeCompileCallback(TrampolineAddr));
         });
 
     if (!TP) {
@@ -287,6 +302,61 @@
   virtual void anchor();
 };
 
+template <typename ORCABI> class LocalIndirectStubsInfo {
+public:
+  LocalIndirectStubsInfo(unsigned NumStubs, sys::OwningMemoryBlock StubsMem)
+      : NumStubs(NumStubs), StubsMem(std::move(StubsMem)) {}
+
+  static Expected<LocalIndirectStubsInfo> create(unsigned MinStubs,
+                                                 unsigned PageSize) {
+    auto ISAS = getIndirectStubsBlockSizes<ORCABI>(MinStubs, PageSize);
+
+    assert((ISAS.StubBytes % PageSize == 0) &&
+           "StubBytes is not a page size multiple");
+    uint64_t PointerAlloc = alignTo(ISAS.PointerBytes, PageSize);
+
+    // Allocate memory for stubs and pointers in one call.
+    std::error_code EC;
+    auto StubsAndPtrsMem =
+        sys::OwningMemoryBlock(sys::Memory::allocateMappedMemory(
+            ISAS.StubBytes + PointerAlloc, nullptr,
+            sys::Memory::MF_READ | sys::Memory::MF_WRITE, EC));
+    if (EC)
+      return errorCodeToError(EC);
+
+    sys::MemoryBlock StubsBlock(StubsAndPtrsMem.base(), ISAS.StubBytes);
+    auto StubsBlockMem = static_cast<char *>(StubsAndPtrsMem.base());
+    auto PtrBlockAddress =
+        pointerToJITTargetAddress(StubsBlockMem) + ISAS.StubBytes;
+
+    ORCABI::writeIndirectStubsBlock(StubsBlockMem,
+                                    pointerToJITTargetAddress(StubsBlockMem),
+                                    PtrBlockAddress, ISAS.NumStubs);
+
+    if (auto EC = sys::Memory::protectMappedMemory(
+            StubsBlock, sys::Memory::MF_READ | sys::Memory::MF_EXEC))
+      return errorCodeToError(EC);
+
+    return LocalIndirectStubsInfo(ISAS.NumStubs, std::move(StubsAndPtrsMem));
+  }
+
+  unsigned getNumStubs() const { return NumStubs; }
+
+  void *getStub(unsigned Idx) const {
+    return static_cast<char *>(StubsMem.base()) + Idx * ORCABI::StubSize;
+  }
+
+  void **getPtr(unsigned Idx) const {
+    char *PtrsBase =
+        static_cast<char *>(StubsMem.base()) + NumStubs * ORCABI::StubSize;
+    return reinterpret_cast<void **>(PtrsBase) + Idx;
+  }
+
+private:
+  unsigned NumStubs = 0;
+  sys::OwningMemoryBlock StubsMem;
+};
+
 /// IndirectStubsManager implementation for the host architecture, e.g.
 ///        OrcX86_64. (See OrcArchitectureSupport.h).
 template <typename TargetT>
@@ -364,13 +434,13 @@
 
     unsigned NewStubsRequired = NumStubs - FreeStubs.size();
     unsigned NewBlockId = IndirectStubsInfos.size();
-    typename TargetT::IndirectStubsInfo ISI;
-    if (auto Err =
-            TargetT::emitIndirectStubsBlock(ISI, NewStubsRequired, nullptr))
-      return Err;
-    for (unsigned I = 0; I < ISI.getNumStubs(); ++I)
+    auto ISI =
+        LocalIndirectStubsInfo<TargetT>::create(NewStubsRequired, PageSize);
+    if (!ISI)
+      return ISI.takeError();
+    for (unsigned I = 0; I < ISI->getNumStubs(); ++I)
       FreeStubs.push_back(std::make_pair(NewBlockId, I));
-    IndirectStubsInfos.push_back(std::move(ISI));
+    IndirectStubsInfos.push_back(std::move(*ISI));
     return Error::success();
   }
 
@@ -379,12 +449,13 @@
     auto Key = FreeStubs.back();
     FreeStubs.pop_back();
     *IndirectStubsInfos[Key.first].getPtr(Key.second) =
-        reinterpret_cast<void *>(static_cast<uintptr_t>(InitAddr));
+        jitTargetAddressToPointer<void *>(InitAddr);
     StubIndexes[StubName] = std::make_pair(Key, StubFlags);
   }
 
+  unsigned PageSize = sys::Process::getPageSizeEstimate();
   std::mutex StubsMutex;
-  std::vector<typename TargetT::IndirectStubsInfo> IndirectStubsInfos;
+  std::vector<LocalIndirectStubsInfo<TargetT>> IndirectStubsInfos;
   using StubKey = std::pair<uint16_t, uint16_t>;
   std::vector<StubKey> FreeStubs;
   StringMap<std::pair<StubKey, JITSymbolFlags>> StubIndexes;
diff --git a/linux-x64/clang/include/llvm/ExecutionEngine/Orc/JITTargetMachineBuilder.h b/linux-x64/clang/include/llvm/ExecutionEngine/Orc/JITTargetMachineBuilder.h
index bcbd72e..c4109a8 100644
--- a/linux-x64/clang/include/llvm/ExecutionEngine/Orc/JITTargetMachineBuilder.h
+++ b/linux-x64/clang/include/llvm/ExecutionEngine/Orc/JITTargetMachineBuilder.h
@@ -25,6 +25,9 @@
 #include <vector>
 
 namespace llvm {
+
+class raw_ostream;
+
 namespace orc {
 
 /// A utility class for building TargetMachines for JITs.
@@ -79,18 +82,30 @@
     return *this;
   }
 
+  /// Get the relocation model.
+  const Optional<Reloc::Model> &getRelocationModel() const { return RM; }
+
   /// Set the code model.
   JITTargetMachineBuilder &setCodeModel(Optional<CodeModel::Model> CM) {
     this->CM = std::move(CM);
     return *this;
   }
 
+  /// Get the code model.
+  const Optional<CodeModel::Model> &getCodeModel() const { return CM; }
+
   /// Set the LLVM CodeGen optimization level.
   JITTargetMachineBuilder &setCodeGenOptLevel(CodeGenOpt::Level OptLevel) {
     this->OptLevel = OptLevel;
     return *this;
   }
 
+  /// Set subtarget features.
+  JITTargetMachineBuilder &setFeatures(StringRef FeatureString) {
+    Features = SubtargetFeatures(FeatureString);
+    return *this;
+  }
+
   /// Add subtarget features.
   JITTargetMachineBuilder &
   addFeatures(const std::vector<std::string> &FeatureVec);
@@ -101,6 +116,17 @@
   /// Access subtarget features.
   const SubtargetFeatures &getFeatures() const { return Features; }
 
+  /// Set TargetOptions.
+  ///
+  /// Note: This operation will overwrite any previously configured options,
+  /// including EmulatedTLS and ExplicitEmulatedTLS which
+  /// the JITTargetMachineBuilder sets by default. Clients are responsible
+  /// for re-enabling these overwritten options.
+  JITTargetMachineBuilder &setOptions(TargetOptions Options) {
+    this->Options = std::move(Options);
+    return *this;
+  }
+
   /// Access TargetOptions.
   TargetOptions &getOptions() { return Options; }
 
@@ -113,6 +139,12 @@
   /// Access Triple.
   const Triple &getTargetTriple() const { return TT; }
 
+#ifndef NDEBUG
+  /// Debug-dump a JITTargetMachineBuilder.
+  friend raw_ostream &operator<<(raw_ostream &OS,
+                                 const JITTargetMachineBuilder &JTMB);
+#endif
+
 private:
   Triple TT;
   std::string CPU;
@@ -120,7 +152,7 @@
   TargetOptions Options;
   Optional<Reloc::Model> RM;
   Optional<CodeModel::Model> CM;
-  CodeGenOpt::Level OptLevel = CodeGenOpt::None;
+  CodeGenOpt::Level OptLevel = CodeGenOpt::Default;
 };
 
 } // end namespace orc
diff --git a/linux-x64/clang/include/llvm/ExecutionEngine/Orc/LLJIT.h b/linux-x64/clang/include/llvm/ExecutionEngine/Orc/LLJIT.h
index b54c7d8..ff0aa02 100644
--- a/linux-x64/clang/include/llvm/ExecutionEngine/Orc/LLJIT.h
+++ b/linux-x64/clang/include/llvm/ExecutionEngine/Orc/LLJIT.h
@@ -19,8 +19,8 @@
 #include "llvm/ExecutionEngine/Orc/IRCompileLayer.h"
 #include "llvm/ExecutionEngine/Orc/IRTransformLayer.h"
 #include "llvm/ExecutionEngine/Orc/JITTargetMachineBuilder.h"
-#include "llvm/ExecutionEngine/Orc/ObjectTransformLayer.h"
 #include "llvm/ExecutionEngine/Orc/ThreadSafeModule.h"
+#include "llvm/Support/Debug.h"
 #include "llvm/Support/ThreadPool.h"
 
 namespace llvm {
@@ -28,6 +28,8 @@
 
 class LLJITBuilderState;
 class LLLazyJITBuilderState;
+class ObjectTransformLayer;
+class TargetProcessControl;
 
 /// A pre-fabricated ORC JIT stack that can serve as an alternative to MCJIT.
 ///
@@ -35,8 +37,22 @@
 class LLJIT {
   template <typename, typename, typename> friend class LLJITBuilderSetters;
 
+  friend void setUpGenericLLVMIRPlatform(LLJIT &J);
+
 public:
-  static Expected<std::unique_ptr<LLJIT>> Create(LLJITBuilderState &S);
+  /// Initializer support for LLJIT.
+  class PlatformSupport {
+  public:
+    virtual ~PlatformSupport();
+
+    virtual Error initialize(JITDylib &JD) = 0;
+
+    virtual Error deinitialize(JITDylib &JD) = 0;
+
+  protected:
+    static void setInitTransform(LLJIT &J,
+                                 IRTransformLayer::TransformFunction T);
+  };
 
   /// Destruct this instance. If a multi-threaded instance, waits for all
   /// compile threads to complete.
@@ -45,11 +61,14 @@
   /// Returns the ExecutionSession for this instance.
   ExecutionSession &getExecutionSession() { return *ES; }
 
+  /// Returns a reference to the triple for this instance.
+  const Triple &getTargetTriple() const { return TT; }
+
   /// Returns a reference to the DataLayout for this instance.
   const DataLayout &getDataLayout() const { return DL; }
 
   /// Returns a reference to the JITDylib representing the JIT'd main program.
-  JITDylib &getMainJITDylib() { return Main; }
+  JITDylib &getMainJITDylib() { return *Main; }
 
   /// Returns the JITDylib with the given name, or nullptr if no JITDylib with
   /// that name exists.
@@ -63,39 +82,49 @@
   /// input or elsewhere in the environment then the client should check
   /// (e.g. by calling getJITDylibByName) that the given name is not already in
   /// use.
-  JITDylib &createJITDylib(std::string Name) {
+  Expected<JITDylib &> createJITDylib(std::string Name) {
     return ES->createJITDylib(std::move(Name));
   }
 
-  /// Convenience method for defining an absolute symbol.
-  Error defineAbsolute(StringRef Name, JITEvaluatedSymbol Address);
+  /// Adds an IR module with the given ResourceTracker.
+  Error addIRModule(ResourceTrackerSP RT, ThreadSafeModule TSM);
 
   /// Adds an IR module to the given JITDylib.
   Error addIRModule(JITDylib &JD, ThreadSafeModule TSM);
 
   /// Adds an IR module to the Main JITDylib.
   Error addIRModule(ThreadSafeModule TSM) {
-    return addIRModule(Main, std::move(TSM));
+    return addIRModule(*Main, std::move(TSM));
   }
 
   /// Adds an object file to the given JITDylib.
+  Error addObjectFile(ResourceTrackerSP RT, std::unique_ptr<MemoryBuffer> Obj);
+
+  /// Adds an object file to the given JITDylib.
   Error addObjectFile(JITDylib &JD, std::unique_ptr<MemoryBuffer> Obj);
 
   /// Adds an object file to the given JITDylib.
   Error addObjectFile(std::unique_ptr<MemoryBuffer> Obj) {
-    return addObjectFile(Main, std::move(Obj));
+    return addObjectFile(*Main, std::move(Obj));
   }
 
   /// Look up a symbol in JITDylib JD by the symbol's linker-mangled name (to
   /// look up symbols based on their IR name use the lookup function instead).
   Expected<JITEvaluatedSymbol> lookupLinkerMangled(JITDylib &JD,
-                                                   StringRef Name);
+                                                   SymbolStringPtr Name);
+
+  /// Look up a symbol in JITDylib JD by the symbol's linker-mangled name (to
+  /// look up symbols based on their IR name use the lookup function instead).
+  Expected<JITEvaluatedSymbol> lookupLinkerMangled(JITDylib &JD,
+                                                   StringRef Name) {
+    return lookupLinkerMangled(JD, ES->intern(Name));
+  }
 
   /// Look up a symbol in the main JITDylib by the symbol's linker-mangled name
   /// (to look up symbols based on their IR name use the lookup function
   /// instead).
   Expected<JITEvaluatedSymbol> lookupLinkerMangled(StringRef Name) {
-    return lookupLinkerMangled(Main, Name);
+    return lookupLinkerMangled(*Main, Name);
   }
 
   /// Look up a symbol in JITDylib JD based on its IR symbol name.
@@ -105,41 +134,85 @@
 
   /// Look up a symbol in the main JITDylib based on its IR symbol name.
   Expected<JITEvaluatedSymbol> lookup(StringRef UnmangledName) {
-    return lookup(Main, UnmangledName);
+    return lookup(*Main, UnmangledName);
   }
 
-  /// Runs all not-yet-run static constructors.
-  Error runConstructors() { return CtorRunner.run(); }
+  /// Set the PlatformSupport instance.
+  void setPlatformSupport(std::unique_ptr<PlatformSupport> PS) {
+    this->PS = std::move(PS);
+  }
 
-  /// Runs all not-yet-run static destructors.
-  Error runDestructors() { return DtorRunner.run(); }
+  /// Get the PlatformSupport instance.
+  PlatformSupport *getPlatformSupport() { return PS.get(); }
+
+  /// Run the initializers for the given JITDylib.
+  Error initialize(JITDylib &JD) {
+    DEBUG_WITH_TYPE("orc", {
+      dbgs() << "LLJIT running initializers for JITDylib \"" << JD.getName()
+             << "\"\n";
+    });
+    assert(PS && "PlatformSupport must be set to run initializers.");
+    return PS->initialize(JD);
+  }
+
+  /// Run the deinitializers for the given JITDylib.
+  Error deinitialize(JITDylib &JD) {
+    DEBUG_WITH_TYPE("orc", {
+      dbgs() << "LLJIT running deinitializers for JITDylib \"" << JD.getName()
+             << "\"\n";
+    });
+    assert(PS && "PlatformSupport must be set to run initializers.");
+    return PS->deinitialize(JD);
+  }
 
   /// Returns a reference to the ObjLinkingLayer
   ObjectLayer &getObjLinkingLayer() { return *ObjLinkingLayer; }
 
+  /// Returns a reference to the object transform layer.
+  ObjectTransformLayer &getObjTransformLayer() { return *ObjTransformLayer; }
+
+  /// Returns a reference to the IR transform layer.
+  IRTransformLayer &getIRTransformLayer() { return *TransformLayer; }
+
+  /// Returns a reference to the IR compile layer.
+  IRCompileLayer &getIRCompileLayer() { return *CompileLayer; }
+
+  /// Returns a linker-mangled version of UnmangledName.
+  std::string mangle(StringRef UnmangledName) const;
+
+  /// Returns an interned, linker-mangled version of UnmangledName.
+  SymbolStringPtr mangleAndIntern(StringRef UnmangledName) const {
+    return ES->intern(mangle(UnmangledName));
+  }
+
 protected:
-  static std::unique_ptr<ObjectLayer>
+  static Expected<std::unique_ptr<ObjectLayer>>
   createObjectLinkingLayer(LLJITBuilderState &S, ExecutionSession &ES);
 
+  static Expected<std::unique_ptr<IRCompileLayer::IRCompiler>>
+  createCompileFunction(LLJITBuilderState &S, JITTargetMachineBuilder JTMB);
+
   /// Create an LLJIT instance with a single compile thread.
   LLJIT(LLJITBuilderState &S, Error &Err);
 
-  std::string mangle(StringRef UnmangledName);
-
   Error applyDataLayout(Module &M);
 
   void recordCtorDtors(Module &M);
 
   std::unique_ptr<ExecutionSession> ES;
-  JITDylib &Main;
+  std::unique_ptr<PlatformSupport> PS;
+
+  JITDylib *Main = nullptr;
 
   DataLayout DL;
+  Triple TT;
   std::unique_ptr<ThreadPool> CompileThreads;
 
   std::unique_ptr<ObjectLayer> ObjLinkingLayer;
+  std::unique_ptr<ObjectTransformLayer> ObjTransformLayer;
   std::unique_ptr<IRCompileLayer> CompileLayer;
-
-  CtorDtorRunner CtorRunner, DtorRunner;
+  std::unique_ptr<IRTransformLayer> TransformLayer;
+  std::unique_ptr<IRTransformLayer> InitHelperTransformLayer;
 };
 
 /// An extended version of LLJIT that supports lazy function-at-a-time
@@ -149,24 +222,21 @@
 
 public:
 
-  /// Set an IR transform (e.g. pass manager pipeline) to run on each function
-  /// when it is compiled.
-  void setLazyCompileTransform(IRTransformLayer::TransformFunction Transform) {
-    TransformLayer->setTransform(std::move(Transform));
-  }
-
   /// Sets the partition function.
   void
   setPartitionFunction(CompileOnDemandLayer::PartitionFunction Partition) {
     CODLayer->setPartitionFunction(std::move(Partition));
   }
 
+  /// Returns a reference to the on-demand layer.
+  CompileOnDemandLayer &getCompileOnDemandLayer() { return *CODLayer; }
+
   /// Add a module to be lazily compiled to JITDylib JD.
   Error addLazyIRModule(JITDylib &JD, ThreadSafeModule M);
 
   /// Add a module to be lazily compiled to the main JITDylib.
   Error addLazyIRModule(ThreadSafeModule M) {
-    return addLazyIRModule(Main, std::move(M));
+    return addLazyIRModule(*Main, std::move(M));
   }
 
 private:
@@ -175,19 +245,29 @@
   LLLazyJIT(LLLazyJITBuilderState &S, Error &Err);
 
   std::unique_ptr<LazyCallThroughManager> LCTMgr;
-  std::unique_ptr<IRTransformLayer> TransformLayer;
   std::unique_ptr<CompileOnDemandLayer> CODLayer;
 };
 
 class LLJITBuilderState {
 public:
-  using CreateObjectLinkingLayerFunction =
-      std::function<std::unique_ptr<ObjectLayer>(ExecutionSession &)>;
+  using ObjectLinkingLayerCreator =
+      std::function<Expected<std::unique_ptr<ObjectLayer>>(ExecutionSession &,
+                                                           const Triple &)>;
+
+  using CompileFunctionCreator =
+      std::function<Expected<std::unique_ptr<IRCompileLayer::IRCompiler>>(
+          JITTargetMachineBuilder JTMB)>;
+
+  using PlatformSetupFunction = std::function<Error(LLJIT &J)>;
 
   std::unique_ptr<ExecutionSession> ES;
   Optional<JITTargetMachineBuilder> JTMB;
-  CreateObjectLinkingLayerFunction CreateObjectLinkingLayer;
+  Optional<DataLayout> DL;
+  ObjectLinkingLayerCreator CreateObjectLinkingLayer;
+  CompileFunctionCreator CreateCompileFunction;
+  PlatformSetupFunction SetUpPlatform;
   unsigned NumCompileThreads = 0;
+  TargetProcessControl *TPC = nullptr;
 
   /// Called prior to JIT class construcion to fix up defaults.
   Error prepareForConstruction();
@@ -196,6 +276,13 @@
 template <typename JITType, typename SetterImpl, typename State>
 class LLJITBuilderSetters {
 public:
+
+  /// Set an ExecutionSession for this instance.
+  SetterImpl &setExecutionSession(std::unique_ptr<ExecutionSession> ES) {
+    impl().ES = std::move(ES);
+    return impl();
+  }
+
   /// Set the JITTargetMachineBuilder for this instance.
   ///
   /// If this method is not called, JITTargetMachineBuilder::detectHost will be
@@ -211,17 +298,45 @@
     return impl().JTMB;
   }
 
+  /// Set a DataLayout for this instance. If no data layout is specified then
+  /// the target's default data layout will be used.
+  SetterImpl &setDataLayout(Optional<DataLayout> DL) {
+    impl().DL = std::move(DL);
+    return impl();
+  }
+
   /// Set an ObjectLinkingLayer creation function.
   ///
   /// If this method is not called, a default creation function will be used
   /// that will construct an RTDyldObjectLinkingLayer.
-  SetterImpl &setCreateObjectLinkingLayer(
-      LLJITBuilderState::CreateObjectLinkingLayerFunction
-          CreateObjectLinkingLayer) {
+  SetterImpl &setObjectLinkingLayerCreator(
+      LLJITBuilderState::ObjectLinkingLayerCreator CreateObjectLinkingLayer) {
     impl().CreateObjectLinkingLayer = std::move(CreateObjectLinkingLayer);
     return impl();
   }
 
+  /// Set a CompileFunctionCreator.
+  ///
+  /// If this method is not called, a default creation function wil be used
+  /// that will construct a basic IR compile function that is compatible with
+  /// the selected number of threads (SimpleCompiler for '0' compile threads,
+  /// ConcurrentIRCompiler otherwise).
+  SetterImpl &setCompileFunctionCreator(
+      LLJITBuilderState::CompileFunctionCreator CreateCompileFunction) {
+    impl().CreateCompileFunction = std::move(CreateCompileFunction);
+    return impl();
+  }
+
+  /// Set up an PlatformSetupFunction.
+  ///
+  /// If this method is not called then setUpGenericLLVMIRPlatform
+  /// will be used to configure the JIT's platform support.
+  SetterImpl &
+  setPlatformSetUp(LLJITBuilderState::PlatformSetupFunction SetUpPlatform) {
+    impl().SetUpPlatform = std::move(SetUpPlatform);
+    return impl();
+  }
+
   /// Set the number of compile threads to use.
   ///
   /// If set to zero, compilation will be performed on the execution thread when
@@ -235,6 +350,17 @@
     return impl();
   }
 
+  /// Set a TargetProcessControl object.
+  ///
+  /// If the platform uses ObjectLinkingLayer by default and no
+  /// ObjectLinkingLayerCreator has been set then the TargetProcessControl
+  /// object will be used to supply the memory manager for the
+  /// ObjectLinkingLayer.
+  SetterImpl &setTargetProcessControl(TargetProcessControl &TPC) {
+    impl().TPC = &TPC;
+    return impl();
+  }
+
   /// Create an instance of the JIT.
   Expected<std::unique_ptr<JITType>> create() {
     if (auto Err = impl().prepareForConstruction())
@@ -310,6 +436,26 @@
       public LLLazyJITBuilderSetters<LLLazyJIT, LLLazyJITBuilder,
                                      LLLazyJITBuilderState> {};
 
+/// Configure the LLJIT instance to scrape modules for llvm.global_ctors and
+/// llvm.global_dtors variables and (if present) build initialization and
+/// deinitialization functions. Platform specific initialization configurations
+/// should be preferred where available.
+void setUpGenericLLVMIRPlatform(LLJIT &J);
+
+/// Configure the LLJIT instance to use MachOPlatform support.
+///
+/// Warning: MachOPlatform *requires* that LLJIT be configured to use
+/// ObjectLinkingLayer (default on platforms supported by JITLink). If
+/// MachOPlatform is used with RTDyldObjectLinkingLayer it will result in
+/// undefined behavior).
+///
+/// MachOPlatform installs an ObjectLinkingLayer plugin to scrape initializers
+/// from the __mod_inits section. It also provides interposes for the dlfcn
+/// functions (dlopen, dlclose, dlsym, dlerror) that work for JITDylibs as
+/// well as regular libraries (JITDylibs will be preferenced, so make sure
+/// your JITDylib names do not shadow any real library paths).
+Error setUpMachOPlatform(LLJIT &J);
+
 } // End namespace orc
 } // End namespace llvm
 
diff --git a/linux-x64/clang/include/llvm/ExecutionEngine/Orc/LambdaResolver.h b/linux-x64/clang/include/llvm/ExecutionEngine/Orc/LambdaResolver.h
deleted file mode 100644
index 92efded..0000000
--- a/linux-x64/clang/include/llvm/ExecutionEngine/Orc/LambdaResolver.h
+++ /dev/null
@@ -1,58 +0,0 @@
-//===- LambdaResolverMM - Redirect symbol lookup via a functor --*- 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::SymbolResolver subclass that uses a user-supplied
-// functor for symbol resolution.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_EXECUTIONENGINE_ORC_LAMBDARESOLVER_H
-#define LLVM_EXECUTIONENGINE_ORC_LAMBDARESOLVER_H
-
-#include "llvm/ADT/STLExtras.h"
-#include "llvm/ExecutionEngine/JITSymbol.h"
-#include <memory>
-
-namespace llvm {
-namespace orc {
-
-template <typename DylibLookupFtorT, typename ExternalLookupFtorT>
-class LambdaResolver : public LegacyJITSymbolResolver {
-public:
-  LambdaResolver(DylibLookupFtorT DylibLookupFtor,
-                 ExternalLookupFtorT ExternalLookupFtor)
-      : DylibLookupFtor(DylibLookupFtor),
-        ExternalLookupFtor(ExternalLookupFtor) {}
-
-  JITSymbol findSymbolInLogicalDylib(const std::string &Name) final {
-    return DylibLookupFtor(Name);
-  }
-
-  JITSymbol findSymbol(const std::string &Name) final {
-    return ExternalLookupFtor(Name);
-  }
-
-private:
-  DylibLookupFtorT DylibLookupFtor;
-  ExternalLookupFtorT ExternalLookupFtor;
-};
-
-template <typename DylibLookupFtorT,
-          typename ExternalLookupFtorT>
-std::shared_ptr<LambdaResolver<DylibLookupFtorT, ExternalLookupFtorT>>
-createLambdaResolver(DylibLookupFtorT DylibLookupFtor,
-                     ExternalLookupFtorT ExternalLookupFtor) {
-  using LR = LambdaResolver<DylibLookupFtorT, ExternalLookupFtorT>;
-  return make_unique<LR>(std::move(DylibLookupFtor),
-                         std::move(ExternalLookupFtor));
-}
-
-} // end namespace orc
-} // end namespace llvm
-
-#endif // LLVM_EXECUTIONENGINE_ORC_LAMBDARESOLVER_H
diff --git a/linux-x64/clang/include/llvm/ExecutionEngine/Orc/Layer.h b/linux-x64/clang/include/llvm/ExecutionEngine/Orc/Layer.h
index 8f9bd70..f9cc155 100644
--- a/linux-x64/clang/include/llvm/ExecutionEngine/Orc/Layer.h
+++ b/linux-x64/clang/include/llvm/ExecutionEngine/Orc/Layer.h
@@ -14,6 +14,7 @@
 #define LLVM_EXECUTIONENGINE_ORC_LAYER_H
 
 #include "llvm/ExecutionEngine/Orc/Core.h"
+#include "llvm/ExecutionEngine/Orc/Mangling.h"
 #include "llvm/ExecutionEngine/Orc/ThreadSafeModule.h"
 #include "llvm/IR/Module.h"
 #include "llvm/Support/MemoryBuffer.h"
@@ -21,15 +22,62 @@
 namespace llvm {
 namespace orc {
 
+/// IRMaterializationUnit is a convenient base class for MaterializationUnits
+/// wrapping LLVM IR. Represents materialization responsibility for all symbols
+/// in the given module. If symbols are overridden by other definitions, then
+/// their linkage is changed to available-externally.
+class IRMaterializationUnit : public MaterializationUnit {
+public:
+  using SymbolNameToDefinitionMap = std::map<SymbolStringPtr, GlobalValue *>;
+
+  /// Create an IRMaterializationLayer. Scans the module to build the
+  /// SymbolFlags and SymbolToDefinition maps.
+  IRMaterializationUnit(ExecutionSession &ES,
+                        const IRSymbolMapper::ManglingOptions &MO,
+                        ThreadSafeModule TSM);
+
+  /// Create an IRMaterializationLayer from a module, and pre-existing
+  /// SymbolFlags and SymbolToDefinition maps. The maps must provide
+  /// entries for each definition in M.
+  /// This constructor is useful for delegating work from one
+  /// IRMaterializationUnit to another.
+  IRMaterializationUnit(ThreadSafeModule TSM, SymbolFlagsMap SymbolFlags,
+                        SymbolStringPtr InitSymbol,
+                        SymbolNameToDefinitionMap SymbolToDefinition);
+
+  /// Return the ModuleIdentifier as the name for this MaterializationUnit.
+  StringRef getName() const override;
+
+  /// Return a reference to the contained ThreadSafeModule.
+  const ThreadSafeModule &getModule() const { return TSM; }
+
+protected:
+  ThreadSafeModule TSM;
+  SymbolNameToDefinitionMap SymbolToDefinition;
+
+private:
+  static SymbolStringPtr getInitSymbol(ExecutionSession &ES,
+                                       const ThreadSafeModule &TSM);
+
+  void discard(const JITDylib &JD, const SymbolStringPtr &Name) override;
+};
+
 /// Interface for layers that accept LLVM IR.
 class IRLayer {
 public:
-  IRLayer(ExecutionSession &ES);
+  IRLayer(ExecutionSession &ES, const IRSymbolMapper::ManglingOptions *&MO)
+      : ES(ES), MO(MO) {}
+
   virtual ~IRLayer();
 
   /// Returns the ExecutionSession for this layer.
   ExecutionSession &getExecutionSession() { return ES; }
 
+  /// Get the mangling options for this layer.
+  const IRSymbolMapper::ManglingOptions *&getManglingOptions() const {
+    return MO;
+  }
+
   /// Sets the CloneToNewContextOnEmit flag (false by default).
   ///
   /// When set, IR modules added to this layer will be cloned on to a new
@@ -46,67 +94,38 @@
   /// Returns the current value of the CloneToNewContextOnEmit flag.
   bool getCloneToNewContextOnEmit() const { return CloneToNewContextOnEmit; }
 
+  /// Add a MaterializatinoUnit representing the given IR to the JITDylib
+  /// targeted by the given tracker.
+  virtual Error add(ResourceTrackerSP RT, ThreadSafeModule TSM);
+
   /// Adds a MaterializationUnit representing the given IR to the given
-  /// JITDylib.
-  virtual Error add(JITDylib &JD, ThreadSafeModule TSM,
-                    VModuleKey K = VModuleKey());
+  /// JITDylib. If RT is not specif
+  Error add(JITDylib &JD, ThreadSafeModule TSM) {
+    return add(JD.getDefaultResourceTracker(), std::move(TSM));
+  }
 
   /// Emit should materialize the given IR.
-  virtual void emit(MaterializationResponsibility R, ThreadSafeModule TSM) = 0;
+  virtual void emit(std::unique_ptr<MaterializationResponsibility> R,
+                    ThreadSafeModule TSM) = 0;
 
 private:
   bool CloneToNewContextOnEmit = false;
   ExecutionSession &ES;
-};
-
-/// IRMaterializationUnit is a convenient base class for MaterializationUnits
-/// wrapping LLVM IR. Represents materialization responsibility for all symbols
-/// in the given module. If symbols are overridden by other definitions, then
-/// their linkage is changed to available-externally.
-class IRMaterializationUnit : public MaterializationUnit {
-public:
-  using SymbolNameToDefinitionMap = std::map<SymbolStringPtr, GlobalValue *>;
-
-  /// Create an IRMaterializationLayer. Scans the module to build the
-  /// SymbolFlags and SymbolToDefinition maps.
-  IRMaterializationUnit(ExecutionSession &ES, ThreadSafeModule TSM,
-                        VModuleKey K);
-
-  /// Create an IRMaterializationLayer from a module, and pre-existing
-  /// SymbolFlags and SymbolToDefinition maps. The maps must provide
-  /// entries for each definition in M.
-  /// This constructor is useful for delegating work from one
-  /// IRMaterializationUnit to another.
-  IRMaterializationUnit(ThreadSafeModule TSM, VModuleKey K,
-                        SymbolFlagsMap SymbolFlags,
-                        SymbolNameToDefinitionMap SymbolToDefinition);
-
-  /// Return the ModuleIdentifier as the name for this MaterializationUnit.
-  StringRef getName() const override;
-
-  const ThreadSafeModule &getModule() const { return TSM; }
-
-protected:
-  ThreadSafeModule TSM;
-  SymbolNameToDefinitionMap SymbolToDefinition;
-
-private:
-  void discard(const JITDylib &JD, const SymbolStringPtr &Name) override;
+  const IRSymbolMapper::ManglingOptions *&MO;
 };
 
 /// MaterializationUnit that materializes modules by calling the 'emit' method
 /// on the given IRLayer.
 class BasicIRLayerMaterializationUnit : public IRMaterializationUnit {
 public:
-  BasicIRLayerMaterializationUnit(IRLayer &L, VModuleKey K,
+  BasicIRLayerMaterializationUnit(IRLayer &L,
+                                  const IRSymbolMapper::ManglingOptions &MO,
                                   ThreadSafeModule TSM);
 
 private:
-
-  void materialize(MaterializationResponsibility R) override;
+  void materialize(std::unique_ptr<MaterializationResponsibility> R) override;
 
   IRLayer &L;
-  VModuleKey K;
 };
 
 /// Interface for Layers that accept object files.
@@ -120,11 +139,14 @@
 
   /// Adds a MaterializationUnit representing the given IR to the given
   /// JITDylib.
-  virtual Error add(JITDylib &JD, std::unique_ptr<MemoryBuffer> O,
-                    VModuleKey K = VModuleKey());
+  virtual Error add(ResourceTrackerSP RT, std::unique_ptr<MemoryBuffer> O);
+
+  Error add(JITDylib &JD, std::unique_ptr<MemoryBuffer> O) {
+    return add(JD.getDefaultResourceTracker(), std::move(O));
+  }
 
   /// Emit should materialize the given IR.
-  virtual void emit(MaterializationResponsibility R,
+  virtual void emit(std::unique_ptr<MaterializationResponsibility> R,
                     std::unique_ptr<MemoryBuffer> O) = 0;
 
 private:
@@ -136,30 +158,24 @@
 class BasicObjectLayerMaterializationUnit : public MaterializationUnit {
 public:
   static Expected<std::unique_ptr<BasicObjectLayerMaterializationUnit>>
-  Create(ObjectLayer &L, VModuleKey K, std::unique_ptr<MemoryBuffer> O);
+  Create(ObjectLayer &L, std::unique_ptr<MemoryBuffer> O);
 
-  BasicObjectLayerMaterializationUnit(ObjectLayer &L, VModuleKey K,
+  BasicObjectLayerMaterializationUnit(ObjectLayer &L,
                                       std::unique_ptr<MemoryBuffer> O,
-                                      SymbolFlagsMap SymbolFlags);
+                                      SymbolFlagsMap SymbolFlags,
+                                      SymbolStringPtr InitSymbol);
 
   /// Return the buffer's identifier as the name for this MaterializationUnit.
   StringRef getName() const override;
 
 private:
-
-  void materialize(MaterializationResponsibility R) override;
+  void materialize(std::unique_ptr<MaterializationResponsibility> R) override;
   void discard(const JITDylib &JD, const SymbolStringPtr &Name) override;
 
   ObjectLayer &L;
   std::unique_ptr<MemoryBuffer> O;
 };
 
-/// Returns a SymbolFlagsMap for the object file represented by the given
-/// buffer, or an error if the buffer does not contain a valid object file.
-// FIXME: Maybe move to Core.h?
-Expected<SymbolFlagsMap> getObjectSymbolFlags(ExecutionSession &ES,
-                                              MemoryBufferRef ObjBuffer);
-
 } // End namespace orc
 } // End namespace llvm
 
diff --git a/linux-x64/clang/include/llvm/ExecutionEngine/Orc/LazyEmittingLayer.h b/linux-x64/clang/include/llvm/ExecutionEngine/Orc/LazyEmittingLayer.h
deleted file mode 100644
index e5c5feb..0000000
--- a/linux-x64/clang/include/llvm/ExecutionEngine/Orc/LazyEmittingLayer.h
+++ /dev/null
@@ -1,260 +0,0 @@
-//===- LazyEmittingLayer.h - Lazily emit IR to lower JIT layers -*- 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
-//
-//===----------------------------------------------------------------------===//
-//
-// Contains the definition for a lazy-emitting layer for the JIT.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_EXECUTIONENGINE_ORC_LAZYEMITTINGLAYER_H
-#define LLVM_EXECUTIONENGINE_ORC_LAZYEMITTINGLAYER_H
-
-#include "llvm/ADT/STLExtras.h"
-#include "llvm/ADT/StringMap.h"
-#include "llvm/ADT/StringRef.h"
-#include "llvm/ExecutionEngine/JITSymbol.h"
-#include "llvm/ExecutionEngine/Orc/Core.h"
-#include "llvm/IR/GlobalValue.h"
-#include "llvm/IR/Mangler.h"
-#include "llvm/IR/Module.h"
-#include "llvm/Support/ErrorHandling.h"
-#include "llvm/Support/raw_ostream.h"
-#include <algorithm>
-#include <cassert>
-#include <list>
-#include <memory>
-#include <string>
-
-namespace llvm {
-namespace orc {
-
-/// Lazy-emitting IR layer.
-///
-///   This layer accepts LLVM IR Modules (via addModule) but does not
-/// immediately emit them the layer below. Instead, emission to the base layer
-/// is deferred until the first time the client requests the address (via
-/// JITSymbol::getAddress) for a symbol contained in this layer.
-template <typename BaseLayerT> class LazyEmittingLayer {
-private:
-  class EmissionDeferredModule {
-  public:
-    EmissionDeferredModule(VModuleKey K, std::unique_ptr<Module> M)
-        : K(std::move(K)), M(std::move(M)) {}
-
-    JITSymbol find(StringRef Name, bool ExportedSymbolsOnly, BaseLayerT &B) {
-      switch (EmitState) {
-      case NotEmitted:
-        if (auto GV = searchGVs(Name, ExportedSymbolsOnly)) {
-          // Create a std::string version of Name to capture here - the argument
-          // (a StringRef) may go away before the lambda is executed.
-          // FIXME: Use capture-init when we move to C++14.
-          std::string PName = Name;
-          JITSymbolFlags Flags = JITSymbolFlags::fromGlobalValue(*GV);
-          auto GetAddress =
-            [this, ExportedSymbolsOnly, PName, &B]() -> Expected<JITTargetAddress> {
-              if (this->EmitState == Emitting)
-                return 0;
-              else if (this->EmitState == NotEmitted) {
-                this->EmitState = Emitting;
-                if (auto Err = this->emitToBaseLayer(B))
-                  return std::move(Err);
-                this->EmitState = Emitted;
-              }
-              if (auto Sym = B.findSymbolIn(K, PName, ExportedSymbolsOnly))
-                return Sym.getAddress();
-              else if (auto Err = Sym.takeError())
-                return std::move(Err);
-              else
-                llvm_unreachable("Successful symbol lookup should return "
-                                 "definition address here");
-          };
-          return JITSymbol(std::move(GetAddress), Flags);
-        } else
-          return nullptr;
-      case Emitting:
-        // Calling "emit" can trigger a recursive call to 'find' (e.g. to check
-        // for pre-existing definitions of common-symbol), but any symbol in
-        // this module would already have been found internally (in the
-        // RuntimeDyld that did the lookup), so just return a nullptr here.
-        return nullptr;
-      case Emitted:
-        return B.findSymbolIn(K, Name, ExportedSymbolsOnly);
-      }
-      llvm_unreachable("Invalid emit-state.");
-    }
-
-    Error removeModuleFromBaseLayer(BaseLayerT& BaseLayer) {
-      return EmitState != NotEmitted ? BaseLayer.removeModule(K)
-                                     : Error::success();
-    }
-
-    void emitAndFinalize(BaseLayerT &BaseLayer) {
-      assert(EmitState != Emitting &&
-             "Cannot emitAndFinalize while already emitting");
-      if (EmitState == NotEmitted) {
-        EmitState = Emitting;
-        emitToBaseLayer(BaseLayer);
-        EmitState = Emitted;
-      }
-      BaseLayer.emitAndFinalize(K);
-    }
-
-  private:
-
-    const GlobalValue* searchGVs(StringRef Name,
-                                 bool ExportedSymbolsOnly) const {
-      // FIXME: We could clean all this up if we had a way to reliably demangle
-      //        names: We could just demangle name and search, rather than
-      //        mangling everything else.
-
-      // If we have already built the mangled name set then just search it.
-      if (MangledSymbols) {
-        auto VI = MangledSymbols->find(Name);
-        if (VI == MangledSymbols->end())
-          return nullptr;
-        auto GV = VI->second;
-        if (!ExportedSymbolsOnly || GV->hasDefaultVisibility())
-          return GV;
-        return nullptr;
-      }
-
-      // If we haven't built the mangled name set yet, try to build it. As an
-      // optimization this will leave MangledNames set to nullptr if we find
-      // Name in the process of building the set.
-      return buildMangledSymbols(Name, ExportedSymbolsOnly);
-    }
-
-    Error emitToBaseLayer(BaseLayerT &BaseLayer) {
-      // We don't need the mangled names set any more: Once we've emitted this
-      // to the base layer we'll just look for symbols there.
-      MangledSymbols.reset();
-      return BaseLayer.addModule(std::move(K), std::move(M));
-    }
-
-    // If the mangled name of the given GlobalValue matches the given search
-    // name (and its visibility conforms to the ExportedSymbolsOnly flag) then
-    // return the symbol. Otherwise, add the mangled name to the Names map and
-    // return nullptr.
-    const GlobalValue* addGlobalValue(StringMap<const GlobalValue*> &Names,
-                                      const GlobalValue &GV,
-                                      const Mangler &Mang, StringRef SearchName,
-                                      bool ExportedSymbolsOnly) const {
-      // Modules don't "provide" decls or common symbols.
-      if (GV.isDeclaration() || GV.hasCommonLinkage())
-        return nullptr;
-
-      // Mangle the GV name.
-      std::string MangledName;
-      {
-        raw_string_ostream MangledNameStream(MangledName);
-        Mang.getNameWithPrefix(MangledNameStream, &GV, false);
-      }
-
-      // Check whether this is the name we were searching for, and if it is then
-      // bail out early.
-      if (MangledName == SearchName)
-        if (!ExportedSymbolsOnly || GV.hasDefaultVisibility())
-          return &GV;
-
-      // Otherwise add this to the map for later.
-      Names[MangledName] = &GV;
-      return nullptr;
-    }
-
-    // Build the MangledSymbols map. Bails out early (with MangledSymbols left set
-    // to nullptr) if the given SearchName is found while building the map.
-    const GlobalValue* buildMangledSymbols(StringRef SearchName,
-                                           bool ExportedSymbolsOnly) const {
-      assert(!MangledSymbols && "Mangled symbols map already exists?");
-
-      auto Symbols = llvm::make_unique<StringMap<const GlobalValue*>>();
-
-      Mangler Mang;
-
-      for (const auto &GO : M->global_objects())
-          if (auto GV = addGlobalValue(*Symbols, GO, Mang, SearchName,
-                                       ExportedSymbolsOnly))
-            return GV;
-
-      MangledSymbols = std::move(Symbols);
-      return nullptr;
-    }
-
-    enum { NotEmitted, Emitting, Emitted } EmitState = NotEmitted;
-    VModuleKey K;
-    std::unique_ptr<Module> M;
-    mutable std::unique_ptr<StringMap<const GlobalValue*>> MangledSymbols;
-  };
-
-  BaseLayerT &BaseLayer;
-  std::map<VModuleKey, std::unique_ptr<EmissionDeferredModule>> ModuleMap;
-
-public:
-
-  /// Construct a lazy emitting layer.
-  LazyEmittingLayer(BaseLayerT &BaseLayer) : BaseLayer(BaseLayer) {}
-
-  /// Add the given module to the lazy emitting layer.
-  Error addModule(VModuleKey K, std::unique_ptr<Module> M) {
-    assert(!ModuleMap.count(K) && "VModuleKey K already in use");
-    ModuleMap[K] =
-        llvm::make_unique<EmissionDeferredModule>(std::move(K), std::move(M));
-    return Error::success();
-  }
-
-  /// Remove the module represented by the given handle.
-  ///
-  ///   This method will free the memory associated with the given module, both
-  /// in this layer, and the base layer.
-  Error removeModule(VModuleKey K) {
-    auto I = ModuleMap.find(K);
-    assert(I != ModuleMap.end() && "VModuleKey K not valid here");
-    auto EDM = std::move(I.second);
-    ModuleMap.erase(I);
-    return EDM->removeModuleFromBaseLayer(BaseLayer);
-  }
-
-  /// Search for the given named symbol.
-  /// @param Name The name of the symbol to search for.
-  /// @param ExportedSymbolsOnly If true, search only for exported symbols.
-  /// @return A handle for the given named symbol, if it exists.
-  JITSymbol findSymbol(const std::string &Name, bool ExportedSymbolsOnly) {
-    // Look for the symbol among existing definitions.
-    if (auto Symbol = BaseLayer.findSymbol(Name, ExportedSymbolsOnly))
-      return Symbol;
-
-    // If not found then search the deferred modules. If any of these contain a
-    // definition of 'Name' then they will return a JITSymbol that will emit
-    // the corresponding module when the symbol address is requested.
-    for (auto &KV : ModuleMap)
-      if (auto Symbol = KV.second->find(Name, ExportedSymbolsOnly, BaseLayer))
-        return Symbol;
-
-    // If no definition found anywhere return a null symbol.
-    return nullptr;
-  }
-
-  /// Get the address of the given symbol in the context of the of
-  ///        compiled modules represented by the key K.
-  JITSymbol findSymbolIn(VModuleKey K, const std::string &Name,
-                         bool ExportedSymbolsOnly) {
-    assert(ModuleMap.count(K) && "VModuleKey K not valid here");
-    return ModuleMap[K]->find(Name, ExportedSymbolsOnly, BaseLayer);
-  }
-
-  /// Immediately emit and finalize the module represented by the given
-  ///        key.
-  Error emitAndFinalize(VModuleKey K) {
-    assert(ModuleMap.count(K) && "VModuleKey K not valid here");
-    return ModuleMap[K]->emitAndFinalize(BaseLayer);
-  }
-};
-
-} // end namespace orc
-} // end namespace llvm
-
-#endif // LLVM_EXECUTIONENGINE_ORC_LAZYEMITTINGLAYER_H
diff --git a/linux-x64/clang/include/llvm/ExecutionEngine/Orc/LazyReexports.h b/linux-x64/clang/include/llvm/ExecutionEngine/Orc/LazyReexports.h
index 9fdd1d1..e6a9d89 100644
--- a/linux-x64/clang/include/llvm/ExecutionEngine/Orc/LazyReexports.h
+++ b/linux-x64/clang/include/llvm/ExecutionEngine/Orc/LazyReexports.h
@@ -16,8 +16,10 @@
 #ifndef LLVM_EXECUTIONENGINE_ORC_LAZYREEXPORTS_H
 #define LLVM_EXECUTIONENGINE_ORC_LAZYREEXPORTS_H
 
+#include "llvm/ADT/STLExtras.h"
 #include "llvm/ExecutionEngine/Orc/Core.h"
 #include "llvm/ExecutionEngine/Orc/IndirectionUtils.h"
+#include "llvm/ExecutionEngine/Orc/Speculation.h"
 
 namespace llvm {
 
@@ -35,73 +37,48 @@
 /// function.
 class LazyCallThroughManager {
 public:
-  /// Clients will want to take some action on first resolution, e.g. updating
-  /// a stub pointer. Instances of this class can be used to implement this.
-  class NotifyResolvedFunction {
-  public:
-    virtual ~NotifyResolvedFunction() {}
+  using NotifyResolvedFunction =
+      unique_function<Error(JITTargetAddress ResolvedAddr)>;
 
-    /// Called the first time a lazy call through is executed and the target
-    /// symbol resolved.
-    virtual Error operator()(JITDylib &SourceJD,
-                             const SymbolStringPtr &SymbolName,
-                             JITTargetAddress ResolvedAddr) = 0;
-
-  private:
-    virtual void anchor();
-  };
-
-  template <typename NotifyResolvedImpl>
-  class NotifyResolvedFunctionImpl : public NotifyResolvedFunction {
-  public:
-    NotifyResolvedFunctionImpl(NotifyResolvedImpl NotifyResolved)
-        : NotifyResolved(std::move(NotifyResolved)) {}
-    Error operator()(JITDylib &SourceJD, const SymbolStringPtr &SymbolName,
-                     JITTargetAddress ResolvedAddr) {
-      return NotifyResolved(SourceJD, SymbolName, ResolvedAddr);
-    }
-
-  private:
-    NotifyResolvedImpl NotifyResolved;
-  };
-
-  /// Create a shared NotifyResolvedFunction from a given type that is
-  /// callable with the correct signature.
-  template <typename NotifyResolvedImpl>
-  static std::unique_ptr<NotifyResolvedFunction>
-  createNotifyResolvedFunction(NotifyResolvedImpl NotifyResolved) {
-    return llvm::make_unique<NotifyResolvedFunctionImpl<NotifyResolvedImpl>>(
-        std::move(NotifyResolved));
-  }
+  LazyCallThroughManager(ExecutionSession &ES,
+                         JITTargetAddress ErrorHandlerAddr, TrampolinePool *TP);
 
   // Return a free call-through trampoline and bind it to look up and call
   // through to the given symbol.
-  Expected<JITTargetAddress> getCallThroughTrampoline(
-      JITDylib &SourceJD, SymbolStringPtr SymbolName,
-      std::shared_ptr<NotifyResolvedFunction> NotifyResolved);
+  Expected<JITTargetAddress>
+  getCallThroughTrampoline(JITDylib &SourceJD, SymbolStringPtr SymbolName,
+                           NotifyResolvedFunction NotifyResolved);
+
+  void resolveTrampolineLandingAddress(
+      JITTargetAddress TrampolineAddr,
+      TrampolinePool::NotifyLandingResolvedFunction NotifyLandingResolved);
+
+  virtual ~LazyCallThroughManager() = default;
 
 protected:
-  LazyCallThroughManager(ExecutionSession &ES,
-                         JITTargetAddress ErrorHandlerAddr,
-                         std::unique_ptr<TrampolinePool> TP);
+  using NotifyLandingResolvedFunction =
+      TrampolinePool::NotifyLandingResolvedFunction;
 
-  JITTargetAddress callThroughToSymbol(JITTargetAddress TrampolineAddr);
+  struct ReexportsEntry {
+    JITDylib *SourceJD;
+    SymbolStringPtr SymbolName;
+  };
 
-  void setTrampolinePool(std::unique_ptr<TrampolinePool> TP) {
-    this->TP = std::move(TP);
-  }
+  JITTargetAddress reportCallThroughError(Error Err);
+  Expected<ReexportsEntry> findReexport(JITTargetAddress TrampolineAddr);
+  Error notifyResolved(JITTargetAddress TrampolineAddr,
+                       JITTargetAddress ResolvedAddr);
+  void setTrampolinePool(TrampolinePool &TP) { this->TP = &TP; }
 
 private:
-  using ReexportsMap =
-      std::map<JITTargetAddress, std::pair<JITDylib *, SymbolStringPtr>>;
+  using ReexportsMap = std::map<JITTargetAddress, ReexportsEntry>;
 
-  using NotifiersMap =
-      std::map<JITTargetAddress, std::shared_ptr<NotifyResolvedFunction>>;
+  using NotifiersMap = std::map<JITTargetAddress, NotifyResolvedFunction>;
 
   std::mutex LCTMMutex;
   ExecutionSession &ES;
   JITTargetAddress ErrorHandlerAddr;
-  std::unique_ptr<TrampolinePool> TP;
+  TrampolinePool *TP = nullptr;
   ReexportsMap Reexports;
   NotifiersMap Notifiers;
 };
@@ -109,23 +86,31 @@
 /// A lazy call-through manager that builds trampolines in the current process.
 class LocalLazyCallThroughManager : public LazyCallThroughManager {
 private:
+  using NotifyTargetResolved = unique_function<void(JITTargetAddress)>;
+
   LocalLazyCallThroughManager(ExecutionSession &ES,
                               JITTargetAddress ErrorHandlerAddr)
       : LazyCallThroughManager(ES, ErrorHandlerAddr, nullptr) {}
 
   template <typename ORCABI> Error init() {
     auto TP = LocalTrampolinePool<ORCABI>::Create(
-        [this](JITTargetAddress TrampolineAddr) {
-          return callThroughToSymbol(TrampolineAddr);
+        [this](JITTargetAddress TrampolineAddr,
+               TrampolinePool::NotifyLandingResolvedFunction
+                   NotifyLandingResolved) {
+          resolveTrampolineLandingAddress(TrampolineAddr,
+                                          std::move(NotifyLandingResolved));
         });
 
     if (!TP)
       return TP.takeError();
 
-    setTrampolinePool(std::move(*TP));
+    this->TP = std::move(*TP);
+    setTrampolinePool(*this->TP);
     return Error::success();
   }
 
+  std::unique_ptr<TrampolinePool> TP;
+
 public:
   /// Create a LocalLazyCallThroughManager using the given ABI. See
   /// createLocalLazyCallThroughManager.
@@ -159,12 +144,12 @@
                                    IndirectStubsManager &ISManager,
                                    JITDylib &SourceJD,
                                    SymbolAliasMap CallableAliases,
-                                   VModuleKey K);
+                                   ImplSymbolMap *SrcJDLoc);
 
   StringRef getName() const override;
 
 private:
-  void materialize(MaterializationResponsibility R) override;
+  void materialize(std::unique_ptr<MaterializationResponsibility> R) override;
   void discard(const JITDylib &JD, const SymbolStringPtr &Name) override;
   static SymbolFlagsMap extractFlags(const SymbolAliasMap &Aliases);
 
@@ -172,8 +157,7 @@
   IndirectStubsManager &ISManager;
   JITDylib &SourceJD;
   SymbolAliasMap CallableAliases;
-  std::shared_ptr<LazyCallThroughManager::NotifyResolvedFunction>
-      NotifyResolved;
+  ImplSymbolMap *AliaseeTable;
 };
 
 /// Define lazy-reexports based on the given SymbolAliasMap. Each lazy re-export
@@ -182,10 +166,10 @@
 inline std::unique_ptr<LazyReexportsMaterializationUnit>
 lazyReexports(LazyCallThroughManager &LCTManager,
               IndirectStubsManager &ISManager, JITDylib &SourceJD,
-              SymbolAliasMap CallableAliases, VModuleKey K = VModuleKey()) {
-  return llvm::make_unique<LazyReexportsMaterializationUnit>(
-      LCTManager, ISManager, SourceJD, std::move(CallableAliases),
-      std::move(K));
+              SymbolAliasMap CallableAliases,
+              ImplSymbolMap *SrcJDLoc = nullptr) {
+  return std::make_unique<LazyReexportsMaterializationUnit>(
+      LCTManager, ISManager, SourceJD, std::move(CallableAliases), SrcJDLoc);
 }
 
 } // End namespace orc
diff --git a/linux-x64/clang/include/llvm/ExecutionEngine/Orc/Legacy.h b/linux-x64/clang/include/llvm/ExecutionEngine/Orc/Legacy.h
deleted file mode 100644
index f9cbbf6..0000000
--- a/linux-x64/clang/include/llvm/ExecutionEngine/Orc/Legacy.h
+++ /dev/null
@@ -1,215 +0,0 @@
-//===--- Legacy.h -- Adapters for ExecutionEngine API interop ---*- 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
-//
-//===----------------------------------------------------------------------===//
-//
-// Contains core ORC APIs.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_EXECUTIONENGINE_ORC_LEGACY_H
-#define LLVM_EXECUTIONENGINE_ORC_LEGACY_H
-
-#include "llvm/ExecutionEngine/JITSymbol.h"
-#include "llvm/ExecutionEngine/Orc/Core.h"
-
-namespace llvm {
-namespace orc {
-
-/// SymbolResolver is a composable interface for looking up symbol flags
-///        and addresses using the AsynchronousSymbolQuery type. It will
-///        eventually replace the LegacyJITSymbolResolver interface as the
-///        stardard ORC symbol resolver type.
-///
-/// FIXME: SymbolResolvers should go away and be replaced with VSOs with
-///        defenition generators.
-class SymbolResolver {
-public:
-  virtual ~SymbolResolver() = default;
-
-  /// Returns the subset of the given symbols that the caller is responsible for
-  /// materializing.
-  virtual SymbolNameSet getResponsibilitySet(const SymbolNameSet &Symbols) = 0;
-
-  /// For each symbol in Symbols that can be found, assigns that symbols
-  /// value in Query. Returns the set of symbols that could not be found.
-  virtual SymbolNameSet lookup(std::shared_ptr<AsynchronousSymbolQuery> Query,
-                               SymbolNameSet Symbols) = 0;
-
-private:
-  virtual void anchor();
-};
-
-/// Implements SymbolResolver with a pair of supplied function objects
-///        for convenience. See createSymbolResolver.
-template <typename GetResponsibilitySetFn, typename LookupFn>
-class LambdaSymbolResolver final : public SymbolResolver {
-public:
-  template <typename GetResponsibilitySetFnRef, typename LookupFnRef>
-  LambdaSymbolResolver(GetResponsibilitySetFnRef &&GetResponsibilitySet,
-                       LookupFnRef &&Lookup)
-      : GetResponsibilitySet(
-            std::forward<GetResponsibilitySetFnRef>(GetResponsibilitySet)),
-        Lookup(std::forward<LookupFnRef>(Lookup)) {}
-
-  SymbolNameSet getResponsibilitySet(const SymbolNameSet &Symbols) final {
-    return GetResponsibilitySet(Symbols);
-  }
-
-  SymbolNameSet lookup(std::shared_ptr<AsynchronousSymbolQuery> Query,
-                       SymbolNameSet Symbols) final {
-    return Lookup(std::move(Query), std::move(Symbols));
-  }
-
-private:
-  GetResponsibilitySetFn GetResponsibilitySet;
-  LookupFn Lookup;
-};
-
-/// Creates a SymbolResolver implementation from the pair of supplied
-///        function objects.
-template <typename GetResponsibilitySetFn, typename LookupFn>
-std::unique_ptr<LambdaSymbolResolver<
-    typename std::remove_cv<
-        typename std::remove_reference<GetResponsibilitySetFn>::type>::type,
-    typename std::remove_cv<
-        typename std::remove_reference<LookupFn>::type>::type>>
-createSymbolResolver(GetResponsibilitySetFn &&GetResponsibilitySet,
-                     LookupFn &&Lookup) {
-  using LambdaSymbolResolverImpl = LambdaSymbolResolver<
-      typename std::remove_cv<
-          typename std::remove_reference<GetResponsibilitySetFn>::type>::type,
-      typename std::remove_cv<
-          typename std::remove_reference<LookupFn>::type>::type>;
-  return llvm::make_unique<LambdaSymbolResolverImpl>(
-      std::forward<GetResponsibilitySetFn>(GetResponsibilitySet),
-      std::forward<LookupFn>(Lookup));
-}
-
-/// Legacy adapter. Remove once we kill off the old ORC layers.
-class JITSymbolResolverAdapter : public JITSymbolResolver {
-public:
-  JITSymbolResolverAdapter(ExecutionSession &ES, SymbolResolver &R,
-                           MaterializationResponsibility *MR);
-  Expected<LookupSet> getResponsibilitySet(const LookupSet &Symbols) override;
-  void lookup(const LookupSet &Symbols, OnResolvedFunction OnResolved) override;
-
-private:
-  ExecutionSession &ES;
-  std::set<SymbolStringPtr> ResolvedStrings;
-  SymbolResolver &R;
-  MaterializationResponsibility *MR;
-};
-
-/// Use the given legacy-style FindSymbol function (i.e. a function that takes
-/// a const std::string& or StringRef and returns a JITSymbol) to get the
-/// subset of symbols that the caller is responsible for materializing. If any
-/// JITSymbol returned by FindSymbol is in an error state the function returns
-/// immediately with that error.
-///
-/// Useful for implementing getResponsibilitySet bodies that query legacy
-/// resolvers.
-template <typename FindSymbolFn>
-Expected<SymbolNameSet>
-getResponsibilitySetWithLegacyFn(const SymbolNameSet &Symbols,
-                                 FindSymbolFn FindSymbol) {
-  SymbolNameSet Result;
-
-  for (auto &S : Symbols) {
-    if (JITSymbol Sym = FindSymbol(*S)) {
-      if (!Sym.getFlags().isStrong())
-        Result.insert(S);
-    } else if (auto Err = Sym.takeError())
-      return std::move(Err);
-  }
-
-  return Result;
-}
-
-/// Use the given legacy-style FindSymbol function (i.e. a function that
-///        takes a const std::string& or StringRef and returns a JITSymbol) to
-///        find the address and flags for each symbol in Symbols and store the
-///        result in Query. If any JITSymbol returned by FindSymbol is in an
-///        error then Query.notifyFailed(...) is called with that error and the
-///        function returns immediately. On success, returns the set of symbols
-///        not found.
-///
-/// Useful for implementing lookup bodies that query legacy resolvers.
-template <typename FindSymbolFn>
-SymbolNameSet
-lookupWithLegacyFn(ExecutionSession &ES, AsynchronousSymbolQuery &Query,
-                   const SymbolNameSet &Symbols, FindSymbolFn FindSymbol) {
-  SymbolNameSet SymbolsNotFound;
-  bool NewSymbolsResolved = false;
-
-  for (auto &S : Symbols) {
-    if (JITSymbol Sym = FindSymbol(*S)) {
-      if (auto Addr = Sym.getAddress()) {
-        Query.notifySymbolMetRequiredState(
-            S, JITEvaluatedSymbol(*Addr, Sym.getFlags()));
-        NewSymbolsResolved = true;
-      } else {
-        ES.legacyFailQuery(Query, Addr.takeError());
-        return SymbolNameSet();
-      }
-    } else if (auto Err = Sym.takeError()) {
-      ES.legacyFailQuery(Query, std::move(Err));
-      return SymbolNameSet();
-    } else
-      SymbolsNotFound.insert(S);
-  }
-
-  if (NewSymbolsResolved && Query.isComplete())
-    Query.handleComplete();
-
-  return SymbolsNotFound;
-}
-
-/// An ORC SymbolResolver implementation that uses a legacy
-///        findSymbol-like function to perform lookup;
-template <typename LegacyLookupFn>
-class LegacyLookupFnResolver final : public SymbolResolver {
-public:
-  using ErrorReporter = std::function<void(Error)>;
-
-  LegacyLookupFnResolver(ExecutionSession &ES, LegacyLookupFn LegacyLookup,
-                         ErrorReporter ReportError)
-      : ES(ES), LegacyLookup(std::move(LegacyLookup)),
-        ReportError(std::move(ReportError)) {}
-
-  SymbolNameSet getResponsibilitySet(const SymbolNameSet &Symbols) final {
-    if (auto ResponsibilitySet =
-            getResponsibilitySetWithLegacyFn(Symbols, LegacyLookup))
-      return std::move(*ResponsibilitySet);
-    else {
-      ReportError(ResponsibilitySet.takeError());
-      return SymbolNameSet();
-    }
-  }
-
-  SymbolNameSet lookup(std::shared_ptr<AsynchronousSymbolQuery> Query,
-                       SymbolNameSet Symbols) final {
-    return lookupWithLegacyFn(ES, *Query, Symbols, LegacyLookup);
-  }
-
-private:
-  ExecutionSession &ES;
-  LegacyLookupFn LegacyLookup;
-  ErrorReporter ReportError;
-};
-
-template <typename LegacyLookupFn>
-std::shared_ptr<LegacyLookupFnResolver<LegacyLookupFn>>
-createLegacyLookupResolver(ExecutionSession &ES, LegacyLookupFn LegacyLookup,
-                           std::function<void(Error)> ErrorReporter) {
-  return std::make_shared<LegacyLookupFnResolver<LegacyLookupFn>>(
-      ES, std::move(LegacyLookup), std::move(ErrorReporter));
-}
-
-} // End namespace orc
-} // End namespace llvm
-
-#endif // LLVM_EXECUTIONENGINE_ORC_LEGACY_H
diff --git a/linux-x64/clang/include/llvm/ExecutionEngine/Orc/MachOPlatform.h b/linux-x64/clang/include/llvm/ExecutionEngine/Orc/MachOPlatform.h
new file mode 100644
index 0000000..90e1d47
--- /dev/null
+++ b/linux-x64/clang/include/llvm/ExecutionEngine/Orc/MachOPlatform.h
@@ -0,0 +1,173 @@
+//===-- MachOPlatform.h - Utilities for executing MachO in Orc --*- 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
+//
+//===----------------------------------------------------------------------===//
+//
+// Utilities for executing JIT'd MachO in Orc.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_EXECUTIONENGINE_ORC_MACHOPLATFORM_H
+#define LLVM_EXECUTIONENGINE_ORC_MACHOPLATFORM_H
+
+#include "llvm/ADT/StringRef.h"
+#include "llvm/ExecutionEngine/Orc/Core.h"
+#include "llvm/ExecutionEngine/Orc/ExecutionUtils.h"
+#include "llvm/ExecutionEngine/Orc/ObjectLinkingLayer.h"
+
+#include <future>
+#include <thread>
+#include <vector>
+
+namespace llvm {
+namespace orc {
+
+/// Enable registration of JIT'd ObjC classes and selectors.
+Error enableObjCRegistration(const char *PathToLibObjC);
+bool objCRegistrationEnabled();
+
+class MachOJITDylibInitializers {
+public:
+  struct SectionExtent {
+    SectionExtent() = default;
+    SectionExtent(JITTargetAddress Address, uint64_t NumPtrs)
+        : Address(Address), NumPtrs(NumPtrs) {}
+    JITTargetAddress Address = 0;
+    uint64_t NumPtrs = 0;
+  };
+
+  using RawPointerSectionList = std::vector<SectionExtent>;
+
+  void setObjCImageInfoAddr(JITTargetAddress ObjCImageInfoAddr) {
+    this->ObjCImageInfoAddr = ObjCImageInfoAddr;
+  }
+
+  void addModInitsSection(SectionExtent ModInit) {
+    ModInitSections.push_back(std::move(ModInit));
+  }
+
+  const RawPointerSectionList &getModInitsSections() const {
+    return ModInitSections;
+  }
+
+  void addObjCSelRefsSection(SectionExtent ObjCSelRefs) {
+    ObjCSelRefsSections.push_back(std::move(ObjCSelRefs));
+  }
+
+  const RawPointerSectionList &getObjCSelRefsSections() const {
+    return ObjCSelRefsSections;
+  }
+
+  void addObjCClassListSection(SectionExtent ObjCClassList) {
+    ObjCClassListSections.push_back(std::move(ObjCClassList));
+  }
+
+  const RawPointerSectionList &getObjCClassListSections() const {
+    return ObjCClassListSections;
+  }
+
+  void runModInits() const;
+  void registerObjCSelectors() const;
+  Error registerObjCClasses() const;
+
+private:
+
+  JITTargetAddress ObjCImageInfoAddr;
+  RawPointerSectionList ModInitSections;
+  RawPointerSectionList ObjCSelRefsSections;
+  RawPointerSectionList ObjCClassListSections;
+};
+
+class MachOJITDylibDeinitializers {};
+
+/// Mediates between MachO initialization and ExecutionSession state.
+class MachOPlatform : public Platform {
+public:
+  using InitializerSequence =
+      std::vector<std::pair<JITDylib *, MachOJITDylibInitializers>>;
+
+  using DeinitializerSequence =
+      std::vector<std::pair<JITDylib *, MachOJITDylibDeinitializers>>;
+
+  MachOPlatform(ExecutionSession &ES, ObjectLinkingLayer &ObjLinkingLayer,
+                std::unique_ptr<MemoryBuffer> StandardSymbolsObject);
+
+  ExecutionSession &getExecutionSession() const { return ES; }
+
+  Error setupJITDylib(JITDylib &JD) override;
+  Error notifyAdding(ResourceTracker &RT,
+                     const MaterializationUnit &MU) override;
+  Error notifyRemoving(ResourceTracker &RT) override;
+
+  Expected<InitializerSequence> getInitializerSequence(JITDylib &JD);
+
+  Expected<DeinitializerSequence> getDeinitializerSequence(JITDylib &JD);
+
+private:
+  // This ObjectLinkingLayer plugin scans JITLink graphs for __mod_init_func,
+  // __objc_classlist and __sel_ref sections and records their extents so that
+  // they can be run in the target process.
+  class InitScraperPlugin : public ObjectLinkingLayer::Plugin {
+  public:
+    InitScraperPlugin(MachOPlatform &MP) : MP(MP) {}
+
+    void modifyPassConfig(MaterializationResponsibility &MR, const Triple &TT,
+                          jitlink::PassConfiguration &Config) override;
+
+    LocalDependenciesMap getSyntheticSymbolLocalDependencies(
+        MaterializationResponsibility &MR) override;
+
+    // FIXME: We should be tentatively tracking scraped sections and discarding
+    // if the MR fails.
+    Error notifyFailed(MaterializationResponsibility &MR) override {
+      return Error::success();
+    }
+
+    Error notifyRemovingResources(ResourceKey K) override {
+      return Error::success();
+    }
+
+    void notifyTransferringResources(ResourceKey DstKey,
+                                     ResourceKey SrcKey) override {}
+
+  private:
+    using InitSymbolDepMap =
+        DenseMap<MaterializationResponsibility *, JITLinkSymbolVector>;
+
+    void preserveInitSectionIfPresent(JITLinkSymbolVector &Syms,
+                                      jitlink::LinkGraph &G,
+                                      StringRef SectionName);
+
+    Error processObjCImageInfo(jitlink::LinkGraph &G,
+                               MaterializationResponsibility &MR);
+
+    std::mutex InitScraperMutex;
+    MachOPlatform &MP;
+    DenseMap<JITDylib *, std::pair<uint32_t, uint32_t>> ObjCImageInfos;
+    InitSymbolDepMap InitSymbolDeps;
+  };
+
+  void registerInitInfo(JITDylib &JD, JITTargetAddress ObjCImageInfoAddr,
+                        MachOJITDylibInitializers::SectionExtent ModInits,
+                        MachOJITDylibInitializers::SectionExtent ObjCSelRefs,
+                        MachOJITDylibInitializers::SectionExtent ObjCClassList);
+
+  ExecutionSession &ES;
+  ObjectLinkingLayer &ObjLinkingLayer;
+  std::unique_ptr<MemoryBuffer> StandardSymbolsObject;
+
+  DenseMap<JITDylib *, SymbolLookupSet> RegisteredInitSymbols;
+
+  // InitSeqs gets its own mutex to avoid locking the whole session when
+  // aggregating data from the jitlink.
+  std::mutex InitSeqsMutex;
+  DenseMap<JITDylib *, MachOJITDylibInitializers> InitSeqs;
+};
+
+} // end namespace orc
+} // end namespace llvm
+
+#endif // LLVM_EXECUTIONENGINE_ORC_MACHOPLATFORM_H
diff --git a/linux-x64/clang/include/llvm/ExecutionEngine/Orc/Mangling.h b/linux-x64/clang/include/llvm/ExecutionEngine/Orc/Mangling.h
new file mode 100644
index 0000000..e0f770a
--- /dev/null
+++ b/linux-x64/clang/include/llvm/ExecutionEngine/Orc/Mangling.h
@@ -0,0 +1,66 @@
+//===------ Mangling.h -- Name Mangling Utilities for ORC -------*- 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
+//
+//===----------------------------------------------------------------------===//
+//
+// Name mangling utilities for ORC.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_EXECUTIONENGINE_ORC_MANGLING_H
+#define LLVM_EXECUTIONENGINE_ORC_MANGLING_H
+
+#include "llvm/ExecutionEngine/Orc/Core.h"
+#include "llvm/ExecutionEngine/Orc/ThreadSafeModule.h"
+#include "llvm/IR/Module.h"
+#include "llvm/Support/MemoryBuffer.h"
+
+namespace llvm {
+namespace orc {
+
+/// Mangles symbol names then uniques them in the context of an
+/// ExecutionSession.
+class MangleAndInterner {
+public:
+  MangleAndInterner(ExecutionSession &ES, const DataLayout &DL);
+  SymbolStringPtr operator()(StringRef Name);
+
+private:
+  ExecutionSession &ES;
+  const DataLayout &DL;
+};
+
+/// Maps IR global values to their linker symbol names / flags.
+///
+/// This utility can be used when adding new IR globals in the JIT.
+class IRSymbolMapper {
+public:
+  struct ManglingOptions {
+    bool EmulatedTLS = false;
+  };
+
+  using SymbolNameToDefinitionMap = std::map<SymbolStringPtr, GlobalValue *>;
+
+  /// Add mangled symbols for the given GlobalValues to SymbolFlags.
+  /// If a SymbolToDefinitionMap pointer is supplied then it will be populated
+  /// with Name-to-GlobalValue* mappings. Note that this mapping is not
+  /// necessarily one-to-one: thread-local GlobalValues, for example, may
+  /// produce more than one symbol, in which case the map will contain duplicate
+  /// values.
+  static void add(ExecutionSession &ES, const ManglingOptions &MO,
+                  ArrayRef<GlobalValue *> GVs, SymbolFlagsMap &SymbolFlags,
+                  SymbolNameToDefinitionMap *SymbolToDefinition = nullptr);
+};
+
+/// Returns a SymbolFlagsMap for the object file represented by the given
+/// buffer, or an error if the buffer does not contain a valid object file.
+Expected<std::pair<SymbolFlagsMap, SymbolStringPtr>>
+getObjectSymbolInfo(ExecutionSession &ES, MemoryBufferRef ObjBuffer);
+
+} // End namespace orc
+} // End namespace llvm
+
+#endif // LLVM_EXECUTIONENGINE_ORC_MANGLING_H
diff --git a/linux-x64/clang/include/llvm/ExecutionEngine/Orc/NullResolver.h b/linux-x64/clang/include/llvm/ExecutionEngine/Orc/NullResolver.h
deleted file mode 100644
index ffa37a1..0000000
--- a/linux-x64/clang/include/llvm/ExecutionEngine/Orc/NullResolver.h
+++ /dev/null
@@ -1,43 +0,0 @@
-//===------ NullResolver.h - Reject symbol lookup requests ------*- 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::SymbolResolver subclass that rejects all symbol
-// resolution requests, for clients that have no cross-object fixups.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_EXECUTIONENGINE_ORC_NULLRESOLVER_H
-#define LLVM_EXECUTIONENGINE_ORC_NULLRESOLVER_H
-
-#include "llvm/ExecutionEngine/Orc/Legacy.h"
-#include "llvm/ExecutionEngine/RuntimeDyld.h"
-
-namespace llvm {
-namespace orc {
-
-class NullResolver : public SymbolResolver {
-public:
-  SymbolNameSet getResponsibilitySet(const SymbolNameSet &Symbols) final;
-
-  SymbolNameSet lookup(std::shared_ptr<AsynchronousSymbolQuery> Query,
-                       SymbolNameSet Symbols) final;
-};
-
-/// SymbolResolver impliementation that rejects all resolution requests.
-/// Useful for clients that have no cross-object fixups.
-class NullLegacyResolver : public LegacyJITSymbolResolver {
-public:
-  JITSymbol findSymbol(const std::string &Name) final;
-
-  JITSymbol findSymbolInLogicalDylib(const std::string &Name) final;
-};
-
-} // End namespace orc.
-} // End namespace llvm.
-
-#endif // LLVM_EXECUTIONENGINE_ORC_NULLRESOLVER_H
diff --git a/linux-x64/clang/include/llvm/ExecutionEngine/Orc/ObjectLinkingLayer.h b/linux-x64/clang/include/llvm/ExecutionEngine/Orc/ObjectLinkingLayer.h
index c1e7d27..f2975e2 100644
--- a/linux-x64/clang/include/llvm/ExecutionEngine/Orc/ObjectLinkingLayer.h
+++ b/linux-x64/clang/include/llvm/ExecutionEngine/Orc/ObjectLinkingLayer.h
@@ -35,6 +35,8 @@
 
 namespace jitlink {
 class EHFrameRegistrar;
+class LinkGraph;
+class Symbol;
 } // namespace jitlink
 
 namespace object {
@@ -50,7 +52,7 @@
 /// Clients can use this class to add relocatable object files to an
 /// ExecutionSession, and it typically serves as the base layer (underneath
 /// a compiling layer like IRCompileLayer) for the rest of the JIT.
-class ObjectLinkingLayer : public ObjectLayer {
+class ObjectLinkingLayer : public ObjectLayer, private ResourceManager {
   friend class ObjectLinkingLayerJITLinkContext;
 
 public:
@@ -59,28 +61,57 @@
   /// configured.
   class Plugin {
   public:
+    using JITLinkSymbolVector = std::vector<const jitlink::Symbol *>;
+    using LocalDependenciesMap = DenseMap<SymbolStringPtr, JITLinkSymbolVector>;
+
     virtual ~Plugin();
     virtual void modifyPassConfig(MaterializationResponsibility &MR,
                                   const Triple &TT,
                                   jitlink::PassConfiguration &Config) {}
+
     virtual void notifyLoaded(MaterializationResponsibility &MR) {}
     virtual Error notifyEmitted(MaterializationResponsibility &MR) {
       return Error::success();
     }
-    virtual Error notifyRemovingModule(VModuleKey K) {
-      return Error::success();
+    virtual Error notifyFailed(MaterializationResponsibility &MR) = 0;
+    virtual Error notifyRemovingResources(ResourceKey K) = 0;
+    virtual void notifyTransferringResources(ResourceKey DstKey,
+                                             ResourceKey SrcKey) = 0;
+
+    /// Return any dependencies that synthetic symbols (e.g. init symbols)
+    /// have on locally scoped jitlink::Symbols. This is used by the
+    /// ObjectLinkingLayer to update the dependencies for the synthetic
+    /// symbols.
+    virtual LocalDependenciesMap
+    getSyntheticSymbolLocalDependencies(MaterializationResponsibility &MR) {
+      return LocalDependenciesMap();
     }
-    virtual Error notifyRemovingAllModules() { return Error::success(); }
   };
 
-  /// Construct an ObjectLinkingLayer with the given NotifyLoaded,
-  /// and NotifyEmitted functors.
+  using ReturnObjectBufferFunction =
+      std::function<void(std::unique_ptr<MemoryBuffer>)>;
+
+  /// Construct an ObjectLinkingLayer.
   ObjectLinkingLayer(ExecutionSession &ES,
                      jitlink::JITLinkMemoryManager &MemMgr);
 
+  /// Construct an ObjectLinkingLayer. Takes ownership of the given
+  /// JITLinkMemoryManager. This method is a temporary hack to simplify
+  /// co-existence with RTDyldObjectLinkingLayer (which also owns its
+  /// allocators).
+  ObjectLinkingLayer(ExecutionSession &ES,
+                     std::unique_ptr<jitlink::JITLinkMemoryManager> MemMgr);
+
   /// Destruct an ObjectLinkingLayer.
   ~ObjectLinkingLayer();
 
+  /// Set an object buffer return function. By default object buffers are
+  /// deleted once the JIT has linked them. If a return function is set then
+  /// it will be called to transfer ownership of the buffer instead.
+  void setReturnObjectBuffer(ReturnObjectBufferFunction ReturnObjectBuffer) {
+    this->ReturnObjectBuffer = std::move(ReturnObjectBuffer);
+  }
+
   /// Add a pass-config modifier.
   ObjectLinkingLayer &addPlugin(std::unique_ptr<Plugin> P) {
     std::lock_guard<std::mutex> Lock(LayerMutex);
@@ -88,10 +119,14 @@
     return *this;
   }
 
-  /// Emit the object.
-  void emit(MaterializationResponsibility R,
+  /// Emit an object file.
+  void emit(std::unique_ptr<MaterializationResponsibility> R,
             std::unique_ptr<MemoryBuffer> O) override;
 
+  /// Emit a LinkGraph.
+  void emit(std::unique_ptr<MaterializationResponsibility> R,
+            std::unique_ptr<jitlink::LinkGraph> G);
+
   /// Instructs this ObjectLinkingLayer instance to override the symbol flags
   /// found in the AtomGraph with the flags supplied by the
   /// MaterializationResponsibility instance. This is a workaround to support
@@ -131,32 +166,44 @@
   void notifyLoaded(MaterializationResponsibility &MR);
   Error notifyEmitted(MaterializationResponsibility &MR, AllocPtr Alloc);
 
-  Error removeModule(VModuleKey K);
-  Error removeAllModules();
+  Error handleRemoveResources(ResourceKey K) override;
+  void handleTransferResources(ResourceKey DstKey, ResourceKey SrcKey) override;
 
   mutable std::mutex LayerMutex;
   jitlink::JITLinkMemoryManager &MemMgr;
+  std::unique_ptr<jitlink::JITLinkMemoryManager> MemMgrOwnership;
   bool OverrideObjectFlags = false;
   bool AutoClaimObjectSymbols = false;
-  DenseMap<VModuleKey, AllocPtr> TrackedAllocs;
-  std::vector<AllocPtr> UntrackedAllocs;
+  ReturnObjectBufferFunction ReturnObjectBuffer;
+  DenseMap<ResourceKey, std::vector<AllocPtr>> Allocs;
   std::vector<std::unique_ptr<Plugin>> Plugins;
 };
 
 class EHFrameRegistrationPlugin : public ObjectLinkingLayer::Plugin {
 public:
-  EHFrameRegistrationPlugin(jitlink::EHFrameRegistrar &Registrar);
-  Error notifyEmitted(MaterializationResponsibility &MR) override;
+  EHFrameRegistrationPlugin(
+      ExecutionSession &ES,
+      std::unique_ptr<jitlink::EHFrameRegistrar> Registrar);
   void modifyPassConfig(MaterializationResponsibility &MR, const Triple &TT,
                         jitlink::PassConfiguration &PassConfig) override;
-  Error notifyRemovingModule(VModuleKey K) override;
-  Error notifyRemovingAllModules() override;
+  Error notifyEmitted(MaterializationResponsibility &MR) override;
+  Error notifyFailed(MaterializationResponsibility &MR) override;
+  Error notifyRemovingResources(ResourceKey K) override;
+  void notifyTransferringResources(ResourceKey DstKey,
+                                   ResourceKey SrcKey) override;
 
 private:
-  jitlink::EHFrameRegistrar &Registrar;
-  DenseMap<MaterializationResponsibility *, JITTargetAddress> InProcessLinks;
-  DenseMap<VModuleKey, JITTargetAddress> TrackedEHFrameAddrs;
-  std::vector<JITTargetAddress> UntrackedEHFrameAddrs;
+
+  struct EHFrameRange {
+    JITTargetAddress Addr = 0;
+    size_t Size;
+  };
+
+  std::mutex EHFramePluginMutex;
+  ExecutionSession &ES;
+  std::unique_ptr<jitlink::EHFrameRegistrar> Registrar;
+  DenseMap<MaterializationResponsibility *, EHFrameRange> InProcessLinks;
+  DenseMap<ResourceKey, std::vector<EHFrameRange>> EHFrameRanges;
 };
 
 } // end namespace orc
diff --git a/linux-x64/clang/include/llvm/ExecutionEngine/Orc/ObjectTransformLayer.h b/linux-x64/clang/include/llvm/ExecutionEngine/Orc/ObjectTransformLayer.h
index de4603f..d8395ab 100644
--- a/linux-x64/clang/include/llvm/ExecutionEngine/Orc/ObjectTransformLayer.h
+++ b/linux-x64/clang/include/llvm/ExecutionEngine/Orc/ObjectTransformLayer.h
@@ -29,84 +29,20 @@
           std::unique_ptr<MemoryBuffer>)>;
 
   ObjectTransformLayer(ExecutionSession &ES, ObjectLayer &BaseLayer,
-                       TransformFunction Transform);
+                       TransformFunction Transform = TransformFunction());
 
-  void emit(MaterializationResponsibility R,
+  void emit(std::unique_ptr<MaterializationResponsibility> R,
             std::unique_ptr<MemoryBuffer> O) override;
 
+  void setTransform(TransformFunction Transform) {
+    this->Transform = std::move(Transform);
+  }
+
 private:
   ObjectLayer &BaseLayer;
   TransformFunction Transform;
 };
 
-/// Object mutating layer.
-///
-///   This layer accepts sets of ObjectFiles (via addObject). It
-/// immediately applies the user supplied functor to each object, then adds
-/// the set of transformed objects to the layer below.
-template <typename BaseLayerT, typename TransformFtor>
-class LegacyObjectTransformLayer {
-public:
-  /// Construct an ObjectTransformLayer with the given BaseLayer
-  LegacyObjectTransformLayer(BaseLayerT &BaseLayer,
-                             TransformFtor Transform = TransformFtor())
-      : BaseLayer(BaseLayer), Transform(std::move(Transform)) {}
-
-  /// Apply the transform functor to each object in the object set, then
-  ///        add the resulting set of objects to the base layer, along with the
-  ///        memory manager and symbol resolver.
-  ///
-  /// @return A handle for the added objects.
-  template <typename ObjectPtr> Error addObject(VModuleKey K, ObjectPtr Obj) {
-    return BaseLayer.addObject(std::move(K), Transform(std::move(Obj)));
-  }
-
-  /// Remove the object set associated with the VModuleKey K.
-  Error removeObject(VModuleKey K) { return BaseLayer.removeObject(K); }
-
-  /// Search for the given named symbol.
-  /// @param Name The name of the symbol to search for.
-  /// @param ExportedSymbolsOnly If true, search only for exported symbols.
-  /// @return A handle for the given named symbol, if it exists.
-  JITSymbol findSymbol(const std::string &Name, bool ExportedSymbolsOnly) {
-    return BaseLayer.findSymbol(Name, ExportedSymbolsOnly);
-  }
-
-  /// Get the address of the given symbol in the context of the set of
-  ///        objects represented by the VModuleKey K. This call is forwarded to
-  ///        the base layer's implementation.
-  /// @param K The VModuleKey associated with the object set to search in.
-  /// @param Name The name of the symbol to search for.
-  /// @param ExportedSymbolsOnly If true, search only for exported symbols.
-  /// @return A handle for the given named symbol, if it is found in the
-  ///         given object set.
-  JITSymbol findSymbolIn(VModuleKey K, const std::string &Name,
-                         bool ExportedSymbolsOnly) {
-    return BaseLayer.findSymbolIn(K, Name, ExportedSymbolsOnly);
-  }
-
-  /// Immediately emit and finalize the object set represented by the
-  ///        given VModuleKey K.
-  Error emitAndFinalize(VModuleKey K) { return BaseLayer.emitAndFinalize(K); }
-
-  /// Map section addresses for the objects associated with the
-  /// VModuleKey K.
-  void mapSectionAddress(VModuleKey K, const void *LocalAddress,
-                         JITTargetAddress TargetAddr) {
-    BaseLayer.mapSectionAddress(K, LocalAddress, TargetAddr);
-  }
-
-  /// Access the transform functor directly.
-  TransformFtor &getTransform() { return Transform; }
-
-  /// Access the mumate functor directly.
-  const TransformFtor &getTransform() const { return Transform; }
-
-private:
-  BaseLayerT &BaseLayer;
-  TransformFtor Transform;
-};
-
 } // end namespace orc
 } // end namespace llvm
 
diff --git a/linux-x64/clang/include/llvm/ExecutionEngine/Orc/OrcABISupport.h b/linux-x64/clang/include/llvm/ExecutionEngine/Orc/OrcABISupport.h
index 38246bc..5061c15 100644
--- a/linux-x64/clang/include/llvm/ExecutionEngine/Orc/OrcABISupport.h
+++ b/linux-x64/clang/include/llvm/ExecutionEngine/Orc/OrcABISupport.h
@@ -20,128 +20,107 @@
 #include "llvm/ExecutionEngine/JITSymbol.h"
 #include "llvm/Support/Error.h"
 #include "llvm/Support/ErrorHandling.h"
-#include "llvm/Support/Memory.h"
+#include "llvm/Support/MathExtras.h"
 #include <algorithm>
 #include <cstdint>
 
 namespace llvm {
 namespace orc {
 
+struct IndirectStubsAllocationSizes {
+  uint64_t StubBytes = 0;
+  uint64_t PointerBytes = 0;
+  unsigned NumStubs = 0;
+};
+
+template <typename ORCABI>
+IndirectStubsAllocationSizes
+getIndirectStubsBlockSizes(unsigned MinStubs, unsigned RoundToMultipleOf = 0) {
+  assert(
+      (RoundToMultipleOf == 0 || (RoundToMultipleOf % ORCABI::StubSize == 0)) &&
+      "RoundToMultipleOf is not a multiple of stub size");
+  uint64_t StubBytes = MinStubs * ORCABI::StubSize;
+  if (RoundToMultipleOf)
+    StubBytes = alignTo(StubBytes, RoundToMultipleOf);
+  unsigned NumStubs = StubBytes / ORCABI::StubSize;
+  uint64_t PointerBytes = NumStubs * ORCABI::PointerSize;
+  return {StubBytes, PointerBytes, NumStubs};
+}
+
 /// Generic ORC ABI support.
 ///
-/// This class can be substituted as the target architecure support class for
+/// This class can be substituted as the target architecture support class for
 /// ORC templates that require one (e.g. IndirectStubsManagers). It does not
 /// support lazy JITing however, and any attempt to use that functionality
 /// will result in execution of an llvm_unreachable.
 class OrcGenericABI {
 public:
-  static const unsigned PointerSize = sizeof(uintptr_t);
-  static const unsigned TrampolineSize = 1;
-  static const unsigned ResolverCodeSize = 1;
+  static constexpr unsigned PointerSize = sizeof(uintptr_t);
+  static constexpr unsigned TrampolineSize = 1;
+  static constexpr unsigned StubSize = 1;
+  static constexpr unsigned StubToPointerMaxDisplacement = 1;
+  static constexpr unsigned ResolverCodeSize = 1;
 
-  using JITReentryFn = JITTargetAddress (*)(void *CallbackMgr,
-                                            void *TrampolineId);
-
-  static void writeResolverCode(uint8_t *ResolveMem, JITReentryFn Reentry,
-                                void *CallbackMgr) {
+  static void writeResolverCode(char *ResolveWorkingMem,
+                                JITTargetAddress ResolverTargetAddr,
+                                JITTargetAddress ReentryFnAddr,
+                                JITTargetAddress ReentryCtxAddr) {
     llvm_unreachable("writeResolverCode is not supported by the generic host "
                      "support class");
   }
 
-  static void writeTrampolines(uint8_t *TrampolineMem, void *ResolverAddr,
+  static void writeTrampolines(char *TrampolineBlockWorkingMem,
+                               JITTargetAddress TrampolineBlockTargetAddr,
+                               JITTargetAddress ResolverAddr,
                                unsigned NumTrampolines) {
     llvm_unreachable("writeTrampolines is not supported by the generic host "
                      "support class");
   }
 
-  class IndirectStubsInfo {
-  public:
-    const static unsigned StubSize = 1;
-
-    unsigned getNumStubs() const { llvm_unreachable("Not supported"); }
-    void *getStub(unsigned Idx) const { llvm_unreachable("Not supported"); }
-    void **getPtr(unsigned Idx) const { llvm_unreachable("Not supported"); }
-  };
-
-  static Error emitIndirectStubsBlock(IndirectStubsInfo &StubsInfo,
-                                      unsigned MinStubs, void *InitialPtrVal) {
-    llvm_unreachable("emitIndirectStubsBlock is not supported by the generic "
-                     "host support class");
+  static void writeIndirectStubsBlock(
+      char *StubsBlockWorkingMem, JITTargetAddress StubsBlockTargetAddress,
+      JITTargetAddress PointersBlockTargetAddress, unsigned NumStubs) {
+    llvm_unreachable(
+        "writeIndirectStubsBlock is not supported by the generic host "
+        "support class");
   }
 };
 
-/// Provide information about stub blocks generated by the
-///        makeIndirectStubsBlock function.
-template <unsigned StubSizeVal> class GenericIndirectStubsInfo {
-public:
-  const static unsigned StubSize = StubSizeVal;
-
-  GenericIndirectStubsInfo() = default;
-  GenericIndirectStubsInfo(unsigned NumStubs, sys::OwningMemoryBlock StubsMem)
-      : NumStubs(NumStubs), StubsMem(std::move(StubsMem)) {}
-  GenericIndirectStubsInfo(GenericIndirectStubsInfo &&Other)
-      : NumStubs(Other.NumStubs), StubsMem(std::move(Other.StubsMem)) {
-    Other.NumStubs = 0;
-  }
-
-  GenericIndirectStubsInfo &operator=(GenericIndirectStubsInfo &&Other) {
-    NumStubs = Other.NumStubs;
-    Other.NumStubs = 0;
-    StubsMem = std::move(Other.StubsMem);
-    return *this;
-  }
-
-  /// Number of stubs in this block.
-  unsigned getNumStubs() const { return NumStubs; }
-
-  /// Get a pointer to the stub at the given index, which must be in
-  ///        the range 0 .. getNumStubs() - 1.
-  void *getStub(unsigned Idx) const {
-    return static_cast<char *>(StubsMem.base()) + Idx * StubSize;
-  }
-
-  /// Get a pointer to the implementation-pointer at the given index,
-  ///        which must be in the range 0 .. getNumStubs() - 1.
-  void **getPtr(unsigned Idx) const {
-    char *PtrsBase = static_cast<char *>(StubsMem.base()) + NumStubs * StubSize;
-    return reinterpret_cast<void **>(PtrsBase) + Idx;
-  }
-
-private:
-  unsigned NumStubs = 0;
-  sys::OwningMemoryBlock StubsMem;
-};
-
 class OrcAArch64 {
 public:
-  static const unsigned PointerSize = 8;
-  static const unsigned TrampolineSize = 12;
-  static const unsigned ResolverCodeSize = 0x120;
+  static constexpr unsigned PointerSize = 8;
+  static constexpr unsigned TrampolineSize = 12;
+  static constexpr unsigned StubSize = 8;
+  static constexpr unsigned StubToPointerMaxDisplacement = 1U << 27;
+  static constexpr unsigned ResolverCodeSize = 0x120;
 
-  using IndirectStubsInfo = GenericIndirectStubsInfo<8>;
+  /// Write the resolver code into the given memory. The user is
+  /// responsible for allocating the memory and setting permissions.
+  ///
+  /// ReentryFnAddr should be the address of a function whose signature matches
+  /// void* (*)(void *TrampolineAddr, void *ReentryCtxAddr). The ReentryCtxAddr
+  /// argument of writeResolverCode will be passed as the second argument to
+  /// the function at ReentryFnAddr.
+  static void writeResolverCode(char *ResolverWorkingMem,
+                                JITTargetAddress ResolverTargetAddress,
+                                JITTargetAddress ReentryFnAddr,
+                                JITTargetAddress RentryCtxAddr);
 
-  using JITReentryFn = JITTargetAddress (*)(void *CallbackMgr,
-                                            void *TrampolineId);
-
-  /// Write the resolver code into the given memory. The user is be
-  ///        responsible for allocating the memory and setting permissions.
-  static void writeResolverCode(uint8_t *ResolveMem, JITReentryFn Reentry,
-                                void *CallbackMgr);
-
-  /// Write the requsted number of trampolines into the given memory,
-  ///        which must be big enough to hold 1 pointer, plus NumTrampolines
-  ///        trampolines.
-  static void writeTrampolines(uint8_t *TrampolineMem, void *ResolverAddr,
+  /// Write the requested number of trampolines into the given memory,
+  /// which must be big enough to hold 1 pointer, plus NumTrampolines
+  /// trampolines.
+  static void writeTrampolines(char *TrampolineBlockWorkingMem,
+                               JITTargetAddress TrampolineBlockTargetAddress,
+                               JITTargetAddress ResolverAddr,
                                unsigned NumTrampolines);
 
-  /// Emit at least MinStubs worth of indirect call stubs, rounded out to
-  ///        the nearest page size.
-  ///
-  ///   E.g. Asking for 4 stubs on x86-64, where stubs are 8-bytes, with 4k
-  /// pages will return a block of 512 stubs (4096 / 8 = 512). Asking for 513
-  /// will return a block of 1024 (2-pages worth).
-  static Error emitIndirectStubsBlock(IndirectStubsInfo &StubsInfo,
-                                      unsigned MinStubs, void *InitialPtrVal);
+  /// Write NumStubs indirect stubs to working memory at StubsBlockWorkingMem.
+  /// Stubs will be written as if linked at StubsBlockTargetAddress, with the
+  /// Nth stub using the Nth pointer in memory starting at
+  /// PointersBlockTargetAddress.
+  static void writeIndirectStubsBlock(
+      char *StubsBlockWorkingMem, JITTargetAddress StubsBlockTargetAddress,
+      JITTargetAddress PointersBlockTargetAddress, unsigned MinStubs);
 };
 
 /// X86_64 code that's common to all ABIs.
@@ -149,25 +128,26 @@
 /// X86_64 supports lazy JITing.
 class OrcX86_64_Base {
 public:
-  static const unsigned PointerSize = 8;
-  static const unsigned TrampolineSize = 8;
+  static constexpr unsigned PointerSize = 8;
+  static constexpr unsigned TrampolineSize = 8;
+  static constexpr unsigned StubSize = 8;
+  static constexpr unsigned StubToPointerMaxDisplacement = 1 << 31;
 
-  using IndirectStubsInfo = GenericIndirectStubsInfo<8>;
-
-  /// Write the requsted number of trampolines into the given memory,
-  ///        which must be big enough to hold 1 pointer, plus NumTrampolines
-  ///        trampolines.
-  static void writeTrampolines(uint8_t *TrampolineMem, void *ResolverAddr,
+  /// Write the requested number of trampolines into the given memory,
+  /// which must be big enough to hold 1 pointer, plus NumTrampolines
+  /// trampolines.
+  static void writeTrampolines(char *TrampolineBlockWorkingMem,
+                               JITTargetAddress TrampolineBlockTargetAddress,
+                               JITTargetAddress ResolverAddr,
                                unsigned NumTrampolines);
 
-  /// Emit at least MinStubs worth of indirect call stubs, rounded out to
-  ///        the nearest page size.
-  ///
-  ///   E.g. Asking for 4 stubs on x86-64, where stubs are 8-bytes, with 4k
-  /// pages will return a block of 512 stubs (4096 / 8 = 512). Asking for 513
-  /// will return a block of 1024 (2-pages worth).
-  static Error emitIndirectStubsBlock(IndirectStubsInfo &StubsInfo,
-                                      unsigned MinStubs, void *InitialPtrVal);
+  /// Write NumStubs indirect stubs to working memory at StubsBlockWorkingMem.
+  /// Stubs will be written as if linked at StubsBlockTargetAddress, with the
+  /// Nth stub using the Nth pointer in memory starting at
+  /// PointersBlockTargetAddress.
+  static void writeIndirectStubsBlock(
+      char *StubsBlockWorkingMem, JITTargetAddress StubsBlockTargetAddress,
+      JITTargetAddress PointersBlockTargetAddress, unsigned NumStubs);
 };
 
 /// X86_64 support for SysV ABI (Linux, MacOSX).
@@ -175,15 +155,19 @@
 /// X86_64_SysV supports lazy JITing.
 class OrcX86_64_SysV : public OrcX86_64_Base {
 public:
-  static const unsigned ResolverCodeSize = 0x6C;
+  static constexpr unsigned ResolverCodeSize = 0x6C;
 
-  using JITReentryFn = JITTargetAddress (*)(void *CallbackMgr,
-                                            void *TrampolineId);
-
-  /// Write the resolver code into the given memory. The user is be
-  ///        responsible for allocating the memory and setting permissions.
-  static void writeResolverCode(uint8_t *ResolveMem, JITReentryFn Reentry,
-                                void *CallbackMgr);
+  /// Write the resolver code into the given memory. The user is
+  /// responsible for allocating the memory and setting permissions.
+  ///
+  /// ReentryFnAddr should be the address of a function whose signature matches
+  /// void* (*)(void *TrampolineAddr, void *ReentryCtxAddr). The ReentryCtxAddr
+  /// argument of writeResolverCode will be passed as the second argument to
+  /// the function at ReentryFnAddr.
+  static void writeResolverCode(char *ResolverWorkingMem,
+                                JITTargetAddress ResolverTargetAddress,
+                                JITTargetAddress ReentryFnAddr,
+                                JITTargetAddress ReentryCtxAddr);
 };
 
 /// X86_64 support for Win32.
@@ -191,15 +175,19 @@
 /// X86_64_Win32 supports lazy JITing.
 class OrcX86_64_Win32 : public OrcX86_64_Base {
 public:
-  static const unsigned ResolverCodeSize = 0x74;
+  static constexpr unsigned ResolverCodeSize = 0x74;
 
-  using JITReentryFn = JITTargetAddress (*)(void *CallbackMgr,
-                                            void *TrampolineId);
-
-  /// Write the resolver code into the given memory. The user is be
-  ///        responsible for allocating the memory and setting permissions.
-  static void writeResolverCode(uint8_t *ResolveMem, JITReentryFn Reentry,
-                                void *CallbackMgr);
+  /// Write the resolver code into the given memory. The user is
+  /// responsible for allocating the memory and setting permissions.
+  ///
+  /// ReentryFnAddr should be the address of a function whose signature matches
+  /// void* (*)(void *TrampolineAddr, void *ReentryCtxAddr). The ReentryCtxAddr
+  /// argument of writeResolverCode will be passed as the second argument to
+  /// the function at ReentryFnAddr.
+  static void writeResolverCode(char *ResolverWorkingMem,
+                                JITTargetAddress ResolverTargetAddress,
+                                JITTargetAddress ReentryFnAddr,
+                                JITTargetAddress ReentryCtxAddr);
 };
 
 /// I386 support.
@@ -207,34 +195,39 @@
 /// I386 supports lazy JITing.
 class OrcI386 {
 public:
-  static const unsigned PointerSize = 4;
-  static const unsigned TrampolineSize = 8;
-  static const unsigned ResolverCodeSize = 0x4a;
+  static constexpr unsigned PointerSize = 4;
+  static constexpr unsigned TrampolineSize = 8;
+  static constexpr unsigned StubSize = 8;
+  static constexpr unsigned StubToPointerMaxDisplacement = 1 << 31;
+  static constexpr unsigned ResolverCodeSize = 0x4a;
 
-  using IndirectStubsInfo = GenericIndirectStubsInfo<8>;
+  /// Write the resolver code into the given memory. The user is
+  /// responsible for allocating the memory and setting permissions.
+  ///
+  /// ReentryFnAddr should be the address of a function whose signature matches
+  /// void* (*)(void *TrampolineAddr, void *ReentryCtxAddr). The ReentryCtxAddr
+  /// argument of writeResolverCode will be passed as the second argument to
+  /// the function at ReentryFnAddr.
+  static void writeResolverCode(char *ResolverWorkingMem,
+                                JITTargetAddress ResolverTargetAddress,
+                                JITTargetAddress ReentryFnAddr,
+                                JITTargetAddress ReentryCtxAddr);
 
-  using JITReentryFn = JITTargetAddress (*)(void *CallbackMgr,
-                                            void *TrampolineId);
-
-  /// Write the resolver code into the given memory. The user is be
-  ///        responsible for allocating the memory and setting permissions.
-  static void writeResolverCode(uint8_t *ResolveMem, JITReentryFn Reentry,
-                                void *CallbackMgr);
-
-  /// Write the requsted number of trampolines into the given memory,
-  ///        which must be big enough to hold 1 pointer, plus NumTrampolines
-  ///        trampolines.
-  static void writeTrampolines(uint8_t *TrampolineMem, void *ResolverAddr,
+  /// Write the requested number of trampolines into the given memory,
+  /// which must be big enough to hold 1 pointer, plus NumTrampolines
+  /// trampolines.
+  static void writeTrampolines(char *TrampolineBlockWorkingMem,
+                               JITTargetAddress TrampolineBlockTargetAddress,
+                               JITTargetAddress ResolverAddr,
                                unsigned NumTrampolines);
 
-  /// Emit at least MinStubs worth of indirect call stubs, rounded out to
-  ///        the nearest page size.
-  ///
-  ///   E.g. Asking for 4 stubs on i386, where stubs are 8-bytes, with 4k
-  /// pages will return a block of 512 stubs (4096 / 8 = 512). Asking for 513
-  /// will return a block of 1024 (2-pages worth).
-  static Error emitIndirectStubsBlock(IndirectStubsInfo &StubsInfo,
-                                      unsigned MinStubs, void *InitialPtrVal);
+  /// Write NumStubs indirect stubs to working memory at StubsBlockWorkingMem.
+  /// Stubs will be written as if linked at StubsBlockTargetAddress, with the
+  /// Nth stub using the Nth pointer in memory starting at
+  /// PointersBlockTargetAddress.
+  static void writeIndirectStubsBlock(
+      char *StubsBlockWorkingMem, JITTargetAddress StubsBlockTargetAddress,
+      JITTargetAddress PointersBlockTargetAddress, unsigned NumStubs);
 };
 
 // @brief Mips32 support.
@@ -242,41 +235,61 @@
 // Mips32 supports lazy JITing.
 class OrcMips32_Base {
 public:
-  static const unsigned PointerSize = 4;
-  static const unsigned TrampolineSize = 20;
-  static const unsigned ResolverCodeSize = 0xfc;
-  using IndirectStubsInfo = GenericIndirectStubsInfo<16>;
+  static constexpr unsigned PointerSize = 4;
+  static constexpr unsigned TrampolineSize = 20;
+  static constexpr unsigned StubSize = 8;
+  static constexpr unsigned StubToPointerMaxDisplacement = 1 << 31;
+  static constexpr unsigned ResolverCodeSize = 0xfc;
 
-  using JITReentryFn = JITTargetAddress (*)(void *CallbackMgr,
-                                            void *TrampolineId);
-  /// @brief Write the requsted number of trampolines into the given memory,
-  ///        which must be big enough to hold 1 pointer, plus NumTrampolines
-  ///        trampolines.
-  static void writeTrampolines(uint8_t *TrampolineMem, void *ResolverAddr,unsigned NumTrampolines);
+  /// Write the requested number of trampolines into the given memory,
+  /// which must be big enough to hold 1 pointer, plus NumTrampolines
+  /// trampolines.
+  static void writeTrampolines(char *TrampolineBlockWorkingMem,
+                               JITTargetAddress TrampolineBlockTargetAddress,
+                               JITTargetAddress ResolverAddr,
+                               unsigned NumTrampolines);
 
-  /// @brief Write the resolver code into the given memory. The user is be
-  ///        responsible for allocating the memory and setting permissions.
-  static void writeResolverCode(uint8_t *ResolveMem, JITReentryFn Reentry,void *CallbackMgr, bool isBigEndian);
-  /// @brief Emit at least MinStubs worth of indirect call stubs, rounded out to
-  ///        the nearest page size.
+  /// Write the resolver code into the given memory. The user is
+  /// responsible for allocating the memory and setting permissions.
   ///
-  ///   E.g. Asking for 4 stubs on Mips32, where stubs are 8-bytes, with 4k
-  /// pages will return a block of 512 stubs (4096 / 8 = 512). Asking for 513
-  /// will return a block of 1024 (2-pages worth).
-  static Error emitIndirectStubsBlock(IndirectStubsInfo &StubsInfo,unsigned MinStubs, void *InitialPtrVal);
+  /// ReentryFnAddr should be the address of a function whose signature matches
+  /// void* (*)(void *TrampolineAddr, void *ReentryCtxAddr). The ReentryCtxAddr
+  /// argument of writeResolverCode will be passed as the second argument to
+  /// the function at ReentryFnAddr.
+  static void writeResolverCode(char *ResolverBlockWorkingMem,
+                                JITTargetAddress ResolverBlockTargetAddress,
+                                JITTargetAddress ReentryFnAddr,
+                                JITTargetAddress ReentryCtxAddr,
+                                bool isBigEndian);
+  /// Write NumStubs indirect stubs to working memory at StubsBlockWorkingMem.
+  /// Stubs will be written as if linked at StubsBlockTargetAddress, with the
+  /// Nth stub using the Nth pointer in memory starting at
+  /// PointersBlockTargetAddress.
+  static void writeIndirectStubsBlock(
+      char *StubsBlockWorkingMem, JITTargetAddress StubsBlockTargetAddress,
+      JITTargetAddress PointersBlockTargetAddress, unsigned NumStubs);
 };
 
-
 class OrcMips32Le : public OrcMips32_Base {
 public:
-  static void writeResolverCode(uint8_t *ResolveMem, JITReentryFn Reentry,void *CallbackMgr)
-  { OrcMips32_Base::writeResolverCode(ResolveMem, Reentry, CallbackMgr, false); }
+  static void writeResolverCode(char *ResolverWorkingMem,
+                                JITTargetAddress ResolverTargetAddress,
+                                JITTargetAddress ReentryFnAddr,
+                                JITTargetAddress ReentryCtxAddr) {
+    OrcMips32_Base::writeResolverCode(ResolverWorkingMem, ResolverTargetAddress,
+                                      ReentryFnAddr, ReentryCtxAddr, false);
+  }
 };
 
 class OrcMips32Be : public OrcMips32_Base {
 public:
-  static void writeResolverCode(uint8_t *ResolveMem, JITReentryFn Reentry,void *CallbackMgr)
-  { OrcMips32_Base::writeResolverCode(ResolveMem, Reentry, CallbackMgr, true); }
+  static void writeResolverCode(char *ResolverWorkingMem,
+                                JITTargetAddress ResolverTargetAddress,
+                                JITTargetAddress ReentryFnAddr,
+                                JITTargetAddress ReentryCtxAddr) {
+    OrcMips32_Base::writeResolverCode(ResolverWorkingMem, ResolverTargetAddress,
+                                      ReentryFnAddr, ReentryCtxAddr, true);
+  }
 };
 
 // @brief Mips64 support.
@@ -284,31 +297,41 @@
 // Mips64 supports lazy JITing.
 class OrcMips64 {
 public:
-  static const unsigned PointerSize = 8;
-  static const unsigned TrampolineSize = 40;
-  static const unsigned ResolverCodeSize = 0x120;
+  static constexpr unsigned PointerSize = 8;
+  static constexpr unsigned TrampolineSize = 40;
+  static constexpr unsigned StubSize = 32;
+  static constexpr unsigned StubToPointerMaxDisplacement = 1 << 31;
+  static constexpr unsigned ResolverCodeSize = 0x120;
 
-  using IndirectStubsInfo = GenericIndirectStubsInfo<32>;
-  using JITReentryFn = JITTargetAddress (*)(void *CallbackMgr,
-                                            void *TrampolineId);
-  /// @brief Write the resolver code into the given memory. The user is be
-  ///        responsible for allocating the memory and setting permissions.
-  static void writeResolverCode(uint8_t *ResolveMem, JITReentryFn Reentry,void *CallbackMgr);
-
-  /// @brief Write the requsted number of trampolines into the given memory,
-  ///        which must be big enough to hold 1 pointer, plus NumTrampolines
-  ///        trampolines.
-  static void writeTrampolines(uint8_t *TrampolineMem, void *ResolverAddr,unsigned NumTrampolines);
-
-  /// @brief Emit at least MinStubs worth of indirect call stubs, rounded out to
-  ///        the nearest page size.
+  /// Write the resolver code into the given memory. The user is
+  /// responsible for allocating the memory and setting permissions.
   ///
-  ///   E.g. Asking for 4 stubs on Mips64, where stubs are 8-bytes, with 4k
-  /// pages will return a block of 512 stubs (4096 / 8 = 512). Asking for 513
-  /// will return a block of 1024 (2-pages worth).
-  static Error emitIndirectStubsBlock(IndirectStubsInfo &StubsInfo,unsigned MinStubs, void *InitialPtrVal);
+  /// ReentryFnAddr should be the address of a function whose signature matches
+  /// void* (*)(void *TrampolineAddr, void *ReentryCtxAddr). The ReentryCtxAddr
+  /// argument of writeResolverCode will be passed as the second argument to
+  /// the function at ReentryFnAddr.
+  static void writeResolverCode(char *ResolverWorkingMem,
+                                JITTargetAddress ResolverTargetAddress,
+                                JITTargetAddress ReentryFnAddr,
+                                JITTargetAddress ReentryCtxAddr);
+
+  /// Write the requested number of trampolines into the given memory,
+  /// which must be big enough to hold 1 pointer, plus NumTrampolines
+  /// trampolines.
+  static void writeTrampolines(char *TrampolineBlockWorkingMem,
+                               JITTargetAddress TrampolineBlockTargetAddress,
+                               JITTargetAddress ResolverFnAddr,
+                               unsigned NumTrampolines);
+  /// Write NumStubs indirect stubs to working memory at StubsBlockWorkingMem.
+  /// Stubs will be written as if linked at StubsBlockTargetAddress, with the
+  /// Nth stub using the Nth pointer in memory starting at
+  /// PointersBlockTargetAddress.
+  static void writeIndirectStubsBlock(
+      char *StubsBlockWorkingMem, JITTargetAddress StubsBlockTargetAddress,
+      JITTargetAddress PointersBlockTargetAddress, unsigned NumStubs);
 };
 
- } // end namespace orc
- } // end namespace llvm
+} // end namespace orc
+} // end namespace llvm
+
 #endif // LLVM_EXECUTIONENGINE_ORC_ORCABISUPPORT_H
diff --git a/linux-x64/clang/include/llvm/ExecutionEngine/Orc/OrcError.h b/linux-x64/clang/include/llvm/ExecutionEngine/Orc/OrcError.h
index e5d6a3e..9b0d941 100644
--- a/linux-x64/clang/include/llvm/ExecutionEngine/Orc/OrcError.h
+++ b/linux-x64/clang/include/llvm/ExecutionEngine/Orc/OrcError.h
@@ -14,6 +14,8 @@
 #define LLVM_EXECUTIONENGINE_ORC_ORCERROR_H
 
 #include "llvm/Support/Error.h"
+#include "llvm/Support/raw_ostream.h"
+#include <string>
 #include <system_error>
 
 namespace llvm {
@@ -35,7 +37,9 @@
   UnexpectedRPCCall,
   UnexpectedRPCResponse,
   UnknownErrorCodeFromRemote,
-  UnknownResourceHandle
+  UnknownResourceHandle,
+  MissingSymbolDefinitions,
+  UnexpectedSymbolDefinitions,
 };
 
 std::error_code orcError(OrcErrorCode ErrCode);
diff --git a/linux-x64/clang/include/llvm/ExecutionEngine/Orc/OrcRPCTargetProcessControl.h b/linux-x64/clang/include/llvm/ExecutionEngine/Orc/OrcRPCTargetProcessControl.h
new file mode 100644
index 0000000..1097ae6
--- /dev/null
+++ b/linux-x64/clang/include/llvm/ExecutionEngine/Orc/OrcRPCTargetProcessControl.h
@@ -0,0 +1,415 @@
+//===--- OrcRPCTargetProcessControl.h - Remote target control ---*- 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
+//
+//===----------------------------------------------------------------------===//
+//
+// Utilities for interacting with target processes.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_EXECUTIONENGINE_ORC_ORCRPCTARGETPROCESSCONTROL_H
+#define LLVM_EXECUTIONENGINE_ORC_ORCRPCTARGETPROCESSCONTROL_H
+
+#include "llvm/ExecutionEngine/Orc/Shared/RPCUtils.h"
+#include "llvm/ExecutionEngine/Orc/Shared/RawByteChannel.h"
+#include "llvm/ExecutionEngine/Orc/TargetProcess/OrcRPCTPCServer.h"
+#include "llvm/ExecutionEngine/Orc/TargetProcessControl.h"
+#include "llvm/Support/MSVCErrorWorkarounds.h"
+
+namespace llvm {
+namespace orc {
+
+/// JITLinkMemoryManager implementation for a process connected via an ORC RPC
+/// endpoint.
+template <typename OrcRPCTPCImplT>
+class OrcRPCTPCJITLinkMemoryManager : public jitlink::JITLinkMemoryManager {
+private:
+  struct HostAlloc {
+    std::unique_ptr<char[]> Mem;
+    uint64_t Size;
+  };
+
+  struct TargetAlloc {
+    JITTargetAddress Address = 0;
+    uint64_t AllocatedSize = 0;
+  };
+
+  using HostAllocMap = DenseMap<int, HostAlloc>;
+  using TargetAllocMap = DenseMap<int, TargetAlloc>;
+
+public:
+  class OrcRPCAllocation : public Allocation {
+  public:
+    OrcRPCAllocation(OrcRPCTPCJITLinkMemoryManager<OrcRPCTPCImplT> &Parent,
+                     HostAllocMap HostAllocs, TargetAllocMap TargetAllocs)
+        : Parent(Parent), HostAllocs(std::move(HostAllocs)),
+          TargetAllocs(std::move(TargetAllocs)) {
+      assert(HostAllocs.size() == TargetAllocs.size() &&
+             "HostAllocs size should match TargetAllocs");
+    }
+
+    ~OrcRPCAllocation() override {
+      assert(TargetAllocs.empty() && "failed to deallocate");
+    }
+
+    MutableArrayRef<char> getWorkingMemory(ProtectionFlags Seg) override {
+      auto I = HostAllocs.find(Seg);
+      assert(I != HostAllocs.end() && "No host allocation for segment");
+      auto &HA = I->second;
+      return {HA.Mem.get(), static_cast<size_t>(HA.Size)};
+    }
+
+    JITTargetAddress getTargetMemory(ProtectionFlags Seg) override {
+      auto I = TargetAllocs.find(Seg);
+      assert(I != TargetAllocs.end() && "No target allocation for segment");
+      return I->second.Address;
+    }
+
+    void finalizeAsync(FinalizeContinuation OnFinalize) override {
+
+      std::vector<tpctypes::BufferWrite> BufferWrites;
+      orcrpctpc::ReleaseOrFinalizeMemRequest FMR;
+
+      for (auto &KV : HostAllocs) {
+        assert(TargetAllocs.count(KV.first) &&
+               "No target allocation for buffer");
+        auto &HA = KV.second;
+        auto &TA = TargetAllocs[KV.first];
+        BufferWrites.push_back({TA.Address, StringRef(HA.Mem.get(), HA.Size)});
+        FMR.push_back({orcrpctpc::toWireProtectionFlags(
+                           static_cast<sys::Memory::ProtectionFlags>(KV.first)),
+                       TA.Address, TA.AllocatedSize});
+      }
+
+      DEBUG_WITH_TYPE("orc", {
+        dbgs() << "finalizeAsync " << (void *)this << ":\n";
+        auto FMRI = FMR.begin();
+        for (auto &B : BufferWrites) {
+          auto Prot = FMRI->Prot;
+          ++FMRI;
+          dbgs() << "  Writing " << formatv("{0:x16}", B.Buffer.size())
+                 << " bytes to " << ((Prot & orcrpctpc::WPF_Read) ? 'R' : '-')
+                 << ((Prot & orcrpctpc::WPF_Write) ? 'W' : '-')
+                 << ((Prot & orcrpctpc::WPF_Exec) ? 'X' : '-')
+                 << " segment: local " << (const void *)B.Buffer.data()
+                 << " -> target " << formatv("{0:x16}", B.Address) << "\n";
+        }
+      });
+      if (auto Err =
+              Parent.Parent.getMemoryAccess().writeBuffers(BufferWrites)) {
+        OnFinalize(std::move(Err));
+        return;
+      }
+
+      DEBUG_WITH_TYPE("orc", dbgs() << " Applying permissions...\n");
+      if (auto Err =
+              Parent.getEndpoint().template callAsync<orcrpctpc::FinalizeMem>(
+                  [OF = std::move(OnFinalize)](Error Err2) {
+                    // FIXME: Dispatch to work queue.
+                    std::thread([OF = std::move(OF),
+                                 Err3 = std::move(Err2)]() mutable {
+                      DEBUG_WITH_TYPE(
+                          "orc", { dbgs() << "  finalizeAsync complete\n"; });
+                      OF(std::move(Err3));
+                    }).detach();
+                    return Error::success();
+                  },
+                  FMR)) {
+        DEBUG_WITH_TYPE("orc", dbgs() << "    failed.\n");
+        Parent.getEndpoint().abandonPendingResponses();
+        Parent.reportError(std::move(Err));
+      }
+      DEBUG_WITH_TYPE("orc", {
+        dbgs() << "Leaving finalizeAsync (finalization may continue in "
+                  "background)\n";
+      });
+    }
+
+    Error deallocate() override {
+      orcrpctpc::ReleaseOrFinalizeMemRequest RMR;
+      for (auto &KV : TargetAllocs)
+        RMR.push_back({orcrpctpc::toWireProtectionFlags(
+                           static_cast<sys::Memory::ProtectionFlags>(KV.first)),
+                       KV.second.Address, KV.second.AllocatedSize});
+      TargetAllocs.clear();
+
+      return Parent.getEndpoint().template callB<orcrpctpc::ReleaseMem>(RMR);
+    }
+
+  private:
+    OrcRPCTPCJITLinkMemoryManager<OrcRPCTPCImplT> &Parent;
+    HostAllocMap HostAllocs;
+    TargetAllocMap TargetAllocs;
+  };
+
+  OrcRPCTPCJITLinkMemoryManager(OrcRPCTPCImplT &Parent) : Parent(Parent) {}
+
+  Expected<std::unique_ptr<Allocation>>
+  allocate(const jitlink::JITLinkDylib *JD,
+           const SegmentsRequestMap &Request) override {
+    orcrpctpc::ReserveMemRequest RMR;
+    HostAllocMap HostAllocs;
+
+    for (auto &KV : Request) {
+      assert(KV.second.getContentSize() <= std::numeric_limits<size_t>::max() &&
+             "Content size is out-of-range for host");
+
+      RMR.push_back({orcrpctpc::toWireProtectionFlags(
+                         static_cast<sys::Memory::ProtectionFlags>(KV.first)),
+                     KV.second.getContentSize() + KV.second.getZeroFillSize(),
+                     KV.second.getAlignment()});
+      HostAllocs[KV.first] = {
+          std::make_unique<char[]>(KV.second.getContentSize()),
+          KV.second.getContentSize()};
+    }
+
+    DEBUG_WITH_TYPE("orc", {
+      dbgs() << "Orc remote memmgr got request:\n";
+      for (auto &KV : Request)
+        dbgs() << "  permissions: "
+               << ((KV.first & sys::Memory::MF_READ) ? 'R' : '-')
+               << ((KV.first & sys::Memory::MF_WRITE) ? 'W' : '-')
+               << ((KV.first & sys::Memory::MF_EXEC) ? 'X' : '-')
+               << ", content size: "
+               << formatv("{0:x16}", KV.second.getContentSize())
+               << " + zero-fill-size: "
+               << formatv("{0:x16}", KV.second.getZeroFillSize())
+               << ", align: " << KV.second.getAlignment() << "\n";
+    });
+
+    // FIXME: LLVM RPC needs to be fixed to support alt
+    // serialization/deserialization on return types. For now just
+    // translate from std::map to DenseMap manually.
+    auto TmpTargetAllocs =
+        Parent.getEndpoint().template callB<orcrpctpc::ReserveMem>(RMR);
+    if (!TmpTargetAllocs)
+      return TmpTargetAllocs.takeError();
+
+    if (TmpTargetAllocs->size() != RMR.size())
+      return make_error<StringError>(
+          "Number of target allocations does not match request",
+          inconvertibleErrorCode());
+
+    TargetAllocMap TargetAllocs;
+    for (auto &E : *TmpTargetAllocs)
+      TargetAllocs[orcrpctpc::fromWireProtectionFlags(E.Prot)] = {
+          E.Address, E.AllocatedSize};
+
+    DEBUG_WITH_TYPE("orc", {
+      auto HAI = HostAllocs.begin();
+      for (auto &KV : TargetAllocs)
+        dbgs() << "  permissions: "
+               << ((KV.first & sys::Memory::MF_READ) ? 'R' : '-')
+               << ((KV.first & sys::Memory::MF_WRITE) ? 'W' : '-')
+               << ((KV.first & sys::Memory::MF_EXEC) ? 'X' : '-')
+               << " assigned local " << (void *)HAI->second.Mem.get()
+               << ", target " << formatv("{0:x16}", KV.second.Address) << "\n";
+    });
+
+    return std::make_unique<OrcRPCAllocation>(*this, std::move(HostAllocs),
+                                              std::move(TargetAllocs));
+  }
+
+private:
+  void reportError(Error Err) { Parent.reportError(std::move(Err)); }
+
+  decltype(std::declval<OrcRPCTPCImplT>().getEndpoint()) getEndpoint() {
+    return Parent.getEndpoint();
+  }
+
+  OrcRPCTPCImplT &Parent;
+};
+
+/// TargetProcessControl::MemoryAccess implementation for a process connected
+/// via an ORC RPC endpoint.
+template <typename OrcRPCTPCImplT>
+class OrcRPCTPCMemoryAccess : public TargetProcessControl::MemoryAccess {
+public:
+  OrcRPCTPCMemoryAccess(OrcRPCTPCImplT &Parent) : Parent(Parent) {}
+
+  void writeUInt8s(ArrayRef<tpctypes::UInt8Write> Ws,
+                   WriteResultFn OnWriteComplete) override {
+    writeViaRPC<orcrpctpc::WriteUInt8s>(Ws, std::move(OnWriteComplete));
+  }
+
+  void writeUInt16s(ArrayRef<tpctypes::UInt16Write> Ws,
+                    WriteResultFn OnWriteComplete) override {
+    writeViaRPC<orcrpctpc::WriteUInt16s>(Ws, std::move(OnWriteComplete));
+  }
+
+  void writeUInt32s(ArrayRef<tpctypes::UInt32Write> Ws,
+                    WriteResultFn OnWriteComplete) override {
+    writeViaRPC<orcrpctpc::WriteUInt32s>(Ws, std::move(OnWriteComplete));
+  }
+
+  void writeUInt64s(ArrayRef<tpctypes::UInt64Write> Ws,
+                    WriteResultFn OnWriteComplete) override {
+    writeViaRPC<orcrpctpc::WriteUInt64s>(Ws, std::move(OnWriteComplete));
+  }
+
+  void writeBuffers(ArrayRef<tpctypes::BufferWrite> Ws,
+                    WriteResultFn OnWriteComplete) override {
+    writeViaRPC<orcrpctpc::WriteBuffers>(Ws, std::move(OnWriteComplete));
+  }
+
+private:
+  template <typename WriteRPCFunction, typename WriteElementT>
+  void writeViaRPC(ArrayRef<WriteElementT> Ws, WriteResultFn OnWriteComplete) {
+    if (auto Err = Parent.getEndpoint().template callAsync<WriteRPCFunction>(
+            [OWC = std::move(OnWriteComplete)](Error Err2) mutable -> Error {
+              OWC(std::move(Err2));
+              return Error::success();
+            },
+            Ws)) {
+      Parent.reportError(std::move(Err));
+      Parent.getEndpoint().abandonPendingResponses();
+    }
+  }
+
+  OrcRPCTPCImplT &Parent;
+};
+
+// TargetProcessControl for a process connected via an ORC RPC Endpoint.
+template <typename RPCEndpointT>
+class OrcRPCTargetProcessControlBase : public TargetProcessControl {
+public:
+  using ErrorReporter = unique_function<void(Error)>;
+
+  using OnCloseConnectionFunction = unique_function<Error(Error)>;
+
+  OrcRPCTargetProcessControlBase(std::shared_ptr<SymbolStringPool> SSP,
+                                 RPCEndpointT &EP, ErrorReporter ReportError)
+      : TargetProcessControl(std::move(SSP)),
+        ReportError(std::move(ReportError)), EP(EP) {}
+
+  void reportError(Error Err) { ReportError(std::move(Err)); }
+
+  RPCEndpointT &getEndpoint() { return EP; }
+
+  Expected<tpctypes::DylibHandle> loadDylib(const char *DylibPath) override {
+    DEBUG_WITH_TYPE("orc", {
+      dbgs() << "Loading dylib \"" << (DylibPath ? DylibPath : "") << "\" ";
+      if (!DylibPath)
+        dbgs() << "(process symbols)";
+      dbgs() << "\n";
+    });
+    if (!DylibPath)
+      DylibPath = "";
+    auto H = EP.template callB<orcrpctpc::LoadDylib>(DylibPath);
+    DEBUG_WITH_TYPE("orc", {
+      if (H)
+        dbgs() << "  got handle " << formatv("{0:x16}", *H) << "\n";
+      else
+        dbgs() << "  error, unable to load\n";
+    });
+    return H;
+  }
+
+  Expected<std::vector<tpctypes::LookupResult>>
+  lookupSymbols(ArrayRef<tpctypes::LookupRequest> Request) override {
+    std::vector<orcrpctpc::RemoteLookupRequest> RR;
+    for (auto &E : Request) {
+      RR.push_back({});
+      RR.back().first = E.Handle;
+      for (auto &KV : E.Symbols)
+        RR.back().second.push_back(
+            {(*KV.first).str(),
+             KV.second == SymbolLookupFlags::WeaklyReferencedSymbol});
+    }
+    DEBUG_WITH_TYPE("orc", {
+      dbgs() << "Compound lookup:\n";
+      for (auto &R : Request) {
+        dbgs() << "  In " << formatv("{0:x16}", R.Handle) << ": {";
+        bool First = true;
+        for (auto &KV : R.Symbols) {
+          dbgs() << (First ? "" : ",") << " " << *KV.first;
+          First = false;
+        }
+        dbgs() << " }\n";
+      }
+    });
+    return EP.template callB<orcrpctpc::LookupSymbols>(RR);
+  }
+
+  Expected<int32_t> runAsMain(JITTargetAddress MainFnAddr,
+                              ArrayRef<std::string> Args) override {
+    DEBUG_WITH_TYPE("orc", {
+      dbgs() << "Running as main: " << formatv("{0:x16}", MainFnAddr)
+             << ", args = [";
+      for (unsigned I = 0; I != Args.size(); ++I)
+        dbgs() << (I ? "," : "") << " \"" << Args[I] << "\"";
+      dbgs() << "]\n";
+    });
+    auto Result = EP.template callB<orcrpctpc::RunMain>(MainFnAddr, Args);
+    DEBUG_WITH_TYPE("orc", {
+      dbgs() << "  call to " << formatv("{0:x16}", MainFnAddr);
+      if (Result)
+        dbgs() << " returned result " << *Result << "\n";
+      else
+        dbgs() << " failed\n";
+    });
+    return Result;
+  }
+
+  Expected<tpctypes::WrapperFunctionResult>
+  runWrapper(JITTargetAddress WrapperFnAddr,
+             ArrayRef<uint8_t> ArgBuffer) override {
+    DEBUG_WITH_TYPE("orc", {
+      dbgs() << "Running as wrapper function "
+             << formatv("{0:x16}", WrapperFnAddr) << " with "
+             << formatv("{0:x16}", ArgBuffer.size()) << " argument buffer\n";
+    });
+    auto Result =
+        EP.template callB<orcrpctpc::RunWrapper>(WrapperFnAddr, ArgBuffer);
+    // dbgs() << "Returned from runWrapper...\n";
+    return Result;
+  }
+
+  Error closeConnection(OnCloseConnectionFunction OnCloseConnection) {
+    DEBUG_WITH_TYPE("orc", dbgs() << "Closing connection to remote\n");
+    return EP.template callAsync<orcrpctpc::CloseConnection>(
+        std::move(OnCloseConnection));
+  }
+
+  Error closeConnectionAndWait() {
+    std::promise<MSVCPError> P;
+    auto F = P.get_future();
+    if (auto Err = closeConnection([&](Error Err2) -> Error {
+          P.set_value(std::move(Err2));
+          return Error::success();
+        })) {
+      EP.abandonAllPendingResponses();
+      return joinErrors(std::move(Err), F.get());
+    }
+    return F.get();
+  }
+
+protected:
+  /// Subclasses must call this during construction to initialize the
+  /// TargetTriple and PageSize members.
+  Error initializeORCRPCTPCBase() {
+    if (auto TripleOrErr = EP.template callB<orcrpctpc::GetTargetTriple>())
+      TargetTriple = Triple(*TripleOrErr);
+    else
+      return TripleOrErr.takeError();
+
+    if (auto PageSizeOrErr = EP.template callB<orcrpctpc::GetPageSize>())
+      PageSize = *PageSizeOrErr;
+    else
+      return PageSizeOrErr.takeError();
+
+    return Error::success();
+  }
+
+private:
+  ErrorReporter ReportError;
+  RPCEndpointT &EP;
+};
+
+} // end namespace orc
+} // end namespace llvm
+
+#endif // LLVM_EXECUTIONENGINE_ORC_ORCRPCTARGETPROCESSCONTROL_H
diff --git a/linux-x64/clang/include/llvm/ExecutionEngine/Orc/OrcRemoteTargetClient.h b/linux-x64/clang/include/llvm/ExecutionEngine/Orc/OrcRemoteTargetClient.h
index 8b875b7..3d13974 100644
--- a/linux-x64/clang/include/llvm/ExecutionEngine/Orc/OrcRemoteTargetClient.h
+++ b/linux-x64/clang/include/llvm/ExecutionEngine/Orc/OrcRemoteTargetClient.h
@@ -20,6 +20,7 @@
 #include "llvm/ADT/StringMap.h"
 #include "llvm/ADT/StringRef.h"
 #include "llvm/ExecutionEngine/JITSymbol.h"
+#include "llvm/ExecutionEngine/JITLink/JITLinkMemoryManager.h"
 #include "llvm/ExecutionEngine/Orc/IndirectionUtils.h"
 #include "llvm/ExecutionEngine/Orc/OrcRemoteTargetRPCAPI.h"
 #include "llvm/ExecutionEngine/RuntimeDyld.h"
@@ -53,7 +54,7 @@
 /// OrcRemoteTargetServer class) via an RPC system (see RPCUtils.h) to carry out
 /// its actions.
 class OrcRemoteTargetClient
-    : public rpc::SingleThreadedRPCEndpoint<rpc::RawByteChannel> {
+    : public shared::SingleThreadedRPCEndpoint<shared::RawByteChannel> {
 public:
   /// Remote-mapped RuntimeDyld-compatible memory manager.
   class RemoteRTDyldMemoryManager : public RuntimeDyld::MemoryManager {
@@ -329,6 +330,221 @@
     std::vector<EHFrame> RegisteredEHFrames;
   };
 
+  class RPCMMAlloc : public jitlink::JITLinkMemoryManager::Allocation {
+    using AllocationMap = DenseMap<unsigned, sys::MemoryBlock>;
+    using FinalizeContinuation =
+        jitlink::JITLinkMemoryManager::Allocation::FinalizeContinuation;
+    using ProtectionFlags = sys::Memory::ProtectionFlags;
+    using SegmentsRequestMap =
+        DenseMap<unsigned, jitlink::JITLinkMemoryManager::SegmentRequest>;
+
+    RPCMMAlloc(OrcRemoteTargetClient &Client, ResourceIdMgr::ResourceId Id)
+        : Client(Client), Id(Id) {}
+
+  public:
+    static Expected<std::unique_ptr<RPCMMAlloc>>
+    Create(OrcRemoteTargetClient &Client, ResourceIdMgr::ResourceId Id,
+           const SegmentsRequestMap &Request) {
+      auto *MM = new RPCMMAlloc(Client, Id);
+
+      if (Error Err = MM->allocateHostBlocks(Request))
+        return std::move(Err);
+
+      if (Error Err = MM->allocateTargetBlocks())
+        return std::move(Err);
+
+      return std::unique_ptr<RPCMMAlloc>(MM);
+    }
+
+    MutableArrayRef<char> getWorkingMemory(ProtectionFlags Seg) override {
+      assert(HostSegBlocks.count(Seg) && "No allocation for segment");
+      return {static_cast<char *>(HostSegBlocks[Seg].base()),
+              HostSegBlocks[Seg].allocatedSize()};
+    }
+
+    JITTargetAddress getTargetMemory(ProtectionFlags Seg) override {
+      assert(TargetSegBlocks.count(Seg) && "No allocation for segment");
+      return pointerToJITTargetAddress(TargetSegBlocks[Seg].base());
+    }
+
+    void finalizeAsync(FinalizeContinuation OnFinalize) override {
+      // Host allocations (working memory) remain ReadWrite.
+      OnFinalize(copyAndProtect());
+    }
+
+    Error deallocate() override {
+      // TODO: Cannot release target allocation. RPCAPI has no function
+      // symmetric to reserveMem(). Add RPC call like freeMem()?
+      return errorCodeToError(sys::Memory::releaseMappedMemory(HostAllocation));
+    }
+
+  private:
+    OrcRemoteTargetClient &Client;
+    ResourceIdMgr::ResourceId Id;
+    AllocationMap HostSegBlocks;
+    AllocationMap TargetSegBlocks;
+    JITTargetAddress TargetSegmentAddr;
+    sys::MemoryBlock HostAllocation;
+
+    Error allocateHostBlocks(const SegmentsRequestMap &Request) {
+      unsigned TargetPageSize = Client.getPageSize();
+
+      if (!isPowerOf2_64(static_cast<uint64_t>(TargetPageSize)))
+        return make_error<StringError>("Host page size is not a power of 2",
+                                       inconvertibleErrorCode());
+
+      auto TotalSize = calcTotalAllocSize(Request, TargetPageSize);
+      if (!TotalSize)
+        return TotalSize.takeError();
+
+      // Allocate one slab to cover all the segments.
+      const sys::Memory::ProtectionFlags ReadWrite =
+          static_cast<sys::Memory::ProtectionFlags>(sys::Memory::MF_READ |
+                                                    sys::Memory::MF_WRITE);
+      std::error_code EC;
+      HostAllocation =
+          sys::Memory::allocateMappedMemory(*TotalSize, nullptr, ReadWrite, EC);
+      if (EC)
+        return errorCodeToError(EC);
+
+      char *SlabAddr = static_cast<char *>(HostAllocation.base());
+#ifndef NDEBUG
+      char *SlabAddrEnd = SlabAddr + HostAllocation.allocatedSize();
+#endif
+
+      // Allocate segment memory from the slab.
+      for (auto &KV : Request) {
+        const auto &Seg = KV.second;
+
+        uint64_t SegmentSize = Seg.getContentSize() + Seg.getZeroFillSize();
+        uint64_t AlignedSegmentSize = alignTo(SegmentSize, TargetPageSize);
+
+        // Zero out zero-fill memory.
+        char *ZeroFillBegin = SlabAddr + Seg.getContentSize();
+        memset(ZeroFillBegin, 0, Seg.getZeroFillSize());
+
+        // Record the block for this segment.
+        HostSegBlocks[KV.first] =
+            sys::MemoryBlock(SlabAddr, AlignedSegmentSize);
+
+        SlabAddr += AlignedSegmentSize;
+        assert(SlabAddr <= SlabAddrEnd && "Out of range");
+      }
+
+      return Error::success();
+    }
+
+    Error allocateTargetBlocks() {
+      // Reserve memory for all blocks on the target. We need as much space on
+      // the target as we allocated on the host.
+      TargetSegmentAddr = Client.reserveMem(Id, HostAllocation.allocatedSize(),
+                                            Client.getPageSize());
+      if (!TargetSegmentAddr)
+        return make_error<StringError>("Failed to reserve memory on the target",
+                                       inconvertibleErrorCode());
+
+      // Map memory blocks into the allocation, that match the host allocation.
+      JITTargetAddress TargetAllocAddr = TargetSegmentAddr;
+      for (const auto &KV : HostSegBlocks) {
+        size_t TargetAllocSize = KV.second.allocatedSize();
+
+        TargetSegBlocks[KV.first] =
+            sys::MemoryBlock(jitTargetAddressToPointer<void *>(TargetAllocAddr),
+                             TargetAllocSize);
+
+        TargetAllocAddr += TargetAllocSize;
+        assert(TargetAllocAddr - TargetSegmentAddr <=
+                   HostAllocation.allocatedSize() &&
+               "Out of range on target");
+      }
+
+      return Error::success();
+    }
+
+    Error copyAndProtect() {
+      unsigned Permissions = 0u;
+
+      // Copy segments one by one.
+      for (auto &KV : TargetSegBlocks) {
+        Permissions |= KV.first;
+
+        const sys::MemoryBlock &TargetBlock = KV.second;
+        const sys::MemoryBlock &HostBlock = HostSegBlocks.lookup(KV.first);
+
+        size_t TargetAllocSize = TargetBlock.allocatedSize();
+        auto TargetAllocAddr = pointerToJITTargetAddress(TargetBlock.base());
+        auto *HostAllocBegin = static_cast<const char *>(HostBlock.base());
+
+        bool CopyErr =
+            Client.writeMem(TargetAllocAddr, HostAllocBegin, TargetAllocSize);
+        if (CopyErr)
+          return createStringError(inconvertibleErrorCode(),
+                                   "Failed to copy %d segment to the target",
+                                   KV.first);
+      }
+
+      // Set permission flags for all segments at once.
+      bool ProtectErr =
+          Client.setProtections(Id, TargetSegmentAddr, Permissions);
+      if (ProtectErr)
+        return createStringError(inconvertibleErrorCode(),
+                                 "Failed to apply permissions for %d segment "
+                                 "on the target",
+                                 Permissions);
+      return Error::success();
+    }
+
+    static Expected<size_t>
+    calcTotalAllocSize(const SegmentsRequestMap &Request,
+                       unsigned TargetPageSize) {
+      size_t TotalSize = 0;
+      for (const auto &KV : Request) {
+        const auto &Seg = KV.second;
+
+        if (Seg.getAlignment() > TargetPageSize)
+          return make_error<StringError>("Cannot request alignment higher than "
+                                         "page alignment on target",
+                                         inconvertibleErrorCode());
+
+        TotalSize = alignTo(TotalSize, TargetPageSize);
+        TotalSize += Seg.getContentSize();
+        TotalSize += Seg.getZeroFillSize();
+      }
+
+      return TotalSize;
+    }
+  };
+
+  class RemoteJITLinkMemoryManager : public jitlink::JITLinkMemoryManager {
+  public:
+    RemoteJITLinkMemoryManager(OrcRemoteTargetClient &Client,
+                               ResourceIdMgr::ResourceId Id)
+        : Client(Client), Id(Id) {}
+
+    RemoteJITLinkMemoryManager(const RemoteJITLinkMemoryManager &) = delete;
+    RemoteJITLinkMemoryManager(RemoteJITLinkMemoryManager &&) = default;
+
+    RemoteJITLinkMemoryManager &
+    operator=(const RemoteJITLinkMemoryManager &) = delete;
+    RemoteJITLinkMemoryManager &
+    operator=(RemoteJITLinkMemoryManager &&) = delete;
+
+    ~RemoteJITLinkMemoryManager() {
+      Client.destroyRemoteAllocator(Id);
+      LLVM_DEBUG(dbgs() << "Destroyed remote allocator " << Id << "\n");
+    }
+
+    Expected<std::unique_ptr<Allocation>>
+    allocate(const jitlink::JITLinkDylib *JD,
+             const SegmentsRequestMap &Request) override {
+      return RPCMMAlloc::Create(Client, Id, Request);
+    }
+
+  private:
+    OrcRemoteTargetClient &Client;
+    ResourceIdMgr::ResourceId Id;
+  };
+
   /// Remote indirect stubs manager.
   class RemoteIndirectStubsManager : public IndirectStubsManager {
   public:
@@ -453,20 +669,8 @@
   public:
     RemoteTrampolinePool(OrcRemoteTargetClient &Client) : Client(Client) {}
 
-    Expected<JITTargetAddress> getTrampoline() override {
-      std::lock_guard<std::mutex> Lock(RTPMutex);
-      if (AvailableTrampolines.empty()) {
-        if (auto Err = grow())
-          return std::move(Err);
-      }
-      assert(!AvailableTrampolines.empty() && "Failed to grow trampoline pool");
-      auto TrampolineAddr = AvailableTrampolines.back();
-      AvailableTrampolines.pop_back();
-      return TrampolineAddr;
-    }
-
   private:
-    Error grow() {
+    Error grow() override {
       JITTargetAddress BlockAddr = 0;
       uint32_t NumTrampolines = 0;
       if (auto TrampolineInfoOrErr = Client.emitTrampolineBlock())
@@ -476,14 +680,12 @@
 
       uint32_t TrampolineSize = Client.getTrampolineSize();
       for (unsigned I = 0; I < NumTrampolines; ++I)
-        this->AvailableTrampolines.push_back(BlockAddr + (I * TrampolineSize));
+        AvailableTrampolines.push_back(BlockAddr + (I * TrampolineSize));
 
       return Error::success();
     }
 
-    std::mutex RTPMutex;
     OrcRemoteTargetClient &Client;
-    std::vector<JITTargetAddress> AvailableTrampolines;
   };
 
   /// Remote compile callback manager.
@@ -493,7 +695,7 @@
                                  ExecutionSession &ES,
                                  JITTargetAddress ErrorHandlerAddress)
         : JITCompileCallbackManager(
-              llvm::make_unique<RemoteTrampolinePool>(Client), ES,
+              std::make_unique<RemoteTrampolinePool>(Client), ES,
               ErrorHandlerAddress) {}
   };
 
@@ -501,7 +703,7 @@
   /// Channel is the ChannelT instance to communicate on. It is assumed that
   /// the channel is ready to be read from and written to.
   static Expected<std::unique_ptr<OrcRemoteTargetClient>>
-  Create(rpc::RawByteChannel &Channel, ExecutionSession &ES) {
+  Create(shared::RawByteChannel &Channel, ExecutionSession &ES) {
     Error Err = Error::success();
     auto Client = std::unique_ptr<OrcRemoteTargetClient>(
         new OrcRemoteTargetClient(Channel, ES, Err));
@@ -518,6 +720,14 @@
     return callB<exec::CallIntVoid>(Addr);
   }
 
+  /// Call the int(int) function at the given address in the target and return
+  /// its result.
+  Expected<int> callIntInt(JITTargetAddress Addr, int Arg) {
+    LLVM_DEBUG(dbgs() << "Calling int(*)(int) " << format("0x%016" PRIx64, Addr)
+                      << "\n");
+    return callB<exec::CallIntInt>(Addr, Arg);
+  }
+
   /// Call the int(int, char*[]) function at the given address in the target and
   /// return its result.
   Expected<int> callMain(JITTargetAddress Addr,
@@ -546,6 +756,18 @@
         new RemoteRTDyldMemoryManager(*this, Id));
   }
 
+  /// Create a JITLink-compatible memory manager which will allocate working
+  /// memory on the host and target memory on the remote target.
+  Expected<std::unique_ptr<RemoteJITLinkMemoryManager>>
+  createRemoteJITLinkMemoryManager() {
+    auto Id = AllocatorIds.getNext();
+    if (auto Err = callB<mem::CreateRemoteAllocator>(Id))
+      return std::move(Err);
+    LLVM_DEBUG(dbgs() << "Created remote allocator " << Id << "\n");
+    return std::unique_ptr<RemoteJITLinkMemoryManager>(
+        new RemoteJITLinkMemoryManager(*this, Id));
+  }
+
   /// Create an RCIndirectStubsManager that will allocate stubs on the remote
   /// target.
   Expected<std::unique_ptr<RemoteIndirectStubsManager>>
@@ -553,7 +775,7 @@
     auto Id = IndirectStubOwnerIds.getNext();
     if (auto Err = callB<stubs::CreateIndirectStubsOwner>(Id))
       return std::move(Err);
-    return llvm::make_unique<RemoteIndirectStubsManager>(*this, Id);
+    return std::make_unique<RemoteIndirectStubsManager>(*this, Id);
   }
 
   Expected<RemoteCompileCallbackManager &>
@@ -583,9 +805,10 @@
   Error terminateSession() { return callB<utils::TerminateSession>(); }
 
 private:
-  OrcRemoteTargetClient(rpc::RawByteChannel &Channel, ExecutionSession &ES,
+  OrcRemoteTargetClient(shared::RawByteChannel &Channel, ExecutionSession &ES,
                         Error &Err)
-      : rpc::SingleThreadedRPCEndpoint<rpc::RawByteChannel>(Channel, true),
+      : shared::SingleThreadedRPCEndpoint<shared::RawByteChannel>(Channel,
+                                                                  true),
         ES(ES) {
     ErrorAsOutParameter EAO(&Err);
 
diff --git a/linux-x64/clang/include/llvm/ExecutionEngine/Orc/OrcRemoteTargetRPCAPI.h b/linux-x64/clang/include/llvm/ExecutionEngine/Orc/OrcRemoteTargetRPCAPI.h
index e7b598d..367bfb3 100644
--- a/linux-x64/clang/include/llvm/ExecutionEngine/Orc/OrcRemoteTargetRPCAPI.h
+++ b/linux-x64/clang/include/llvm/ExecutionEngine/Orc/OrcRemoteTargetRPCAPI.h
@@ -16,8 +16,8 @@
 #define LLVM_EXECUTIONENGINE_ORC_ORCREMOTETARGETRPCAPI_H
 
 #include "llvm/ExecutionEngine/JITSymbol.h"
-#include "llvm/ExecutionEngine/Orc/RPCUtils.h"
-#include "llvm/ExecutionEngine/Orc/RawByteChannel.h"
+#include "llvm/ExecutionEngine/Orc/Shared/RPCUtils.h"
+#include "llvm/ExecutionEngine/Orc/Shared/RawByteChannel.h"
 
 namespace llvm {
 namespace orc {
@@ -73,10 +73,9 @@
 
 } // end namespace remote
 
-namespace rpc {
+namespace shared {
 
-template <>
-class RPCTypeName<JITSymbolFlags> {
+template <> class SerializationTypeName<JITSymbolFlags> {
 public:
   static const char *getName() { return "JITSymbolFlags"; }
 };
@@ -100,7 +99,7 @@
   }
 };
 
-template <> class RPCTypeName<remote::DirectBufferWriter> {
+template <> class SerializationTypeName<remote::DirectBufferWriter> {
 public:
   static const char *getName() { return "DirectBufferWriter"; }
 };
@@ -108,8 +107,7 @@
 template <typename ChannelT>
 class SerializationTraits<
     ChannelT, remote::DirectBufferWriter, remote::DirectBufferWriter,
-    typename std::enable_if<
-        std::is_base_of<RawByteChannel, ChannelT>::value>::type> {
+    std::enable_if_t<std::is_base_of<RawByteChannel, ChannelT>::value>> {
 public:
   static Error serialize(ChannelT &C, const remote::DirectBufferWriter &DBW) {
     if (auto EC = serializeSeq(C, DBW.getDst()))
@@ -134,7 +132,7 @@
   }
 };
 
-} // end namespace rpc
+} // end namespace shared
 
 namespace remote {
 
@@ -168,20 +166,20 @@
 namespace eh {
 
   /// Registers EH frames on the remote.
-  class RegisterEHFrames
-      : public rpc::Function<RegisterEHFrames,
-                             void(JITTargetAddress Addr, uint32_t Size)> {
-  public:
-    static const char *getName() { return "RegisterEHFrames"; }
-  };
+class RegisterEHFrames
+    : public shared::RPCFunction<RegisterEHFrames,
+                                 void(JITTargetAddress Addr, uint32_t Size)> {
+public:
+  static const char *getName() { return "RegisterEHFrames"; }
+};
 
   /// Deregisters EH frames on the remote.
-  class DeregisterEHFrames
-      : public rpc::Function<DeregisterEHFrames,
-                             void(JITTargetAddress Addr, uint32_t Size)> {
-  public:
-    static const char *getName() { return "DeregisterEHFrames"; }
-  };
+class DeregisterEHFrames
+    : public shared::RPCFunction<DeregisterEHFrames,
+                                 void(JITTargetAddress Addr, uint32_t Size)> {
+public:
+  static const char *getName() { return "DeregisterEHFrames"; }
+};
 
 } // end namespace eh
 
@@ -190,28 +188,38 @@
 
   /// Call an 'int32_t()'-type function on the remote, returns the called
   /// function's return value.
-  class CallIntVoid
-      : public rpc::Function<CallIntVoid, int32_t(JITTargetAddress Addr)> {
-  public:
-    static const char *getName() { return "CallIntVoid"; }
-  };
+class CallIntVoid
+    : public shared::RPCFunction<CallIntVoid, int32_t(JITTargetAddress Addr)> {
+public:
+  static const char *getName() { return "CallIntVoid"; }
+};
+
+  /// Call an 'int32_t(int32_t)'-type function on the remote, returns the called
+  /// function's return value.
+class CallIntInt
+    : public shared::RPCFunction<CallIntInt,
+                                 int32_t(JITTargetAddress Addr, int)> {
+public:
+  static const char *getName() { return "CallIntInt"; }
+};
 
   /// Call an 'int32_t(int32_t, char**)'-type function on the remote, returns the
   /// called function's return value.
-  class CallMain
-      : public rpc::Function<CallMain, int32_t(JITTargetAddress Addr,
-                                               std::vector<std::string> Args)> {
-  public:
-    static const char *getName() { return "CallMain"; }
-  };
+class CallMain
+    : public shared::RPCFunction<CallMain,
+                                 int32_t(JITTargetAddress Addr,
+                                         std::vector<std::string> Args)> {
+public:
+  static const char *getName() { return "CallMain"; }
+};
 
   /// Calls a 'void()'-type function on the remote, returns when the called
   /// function completes.
-  class CallVoidVoid
-      : public rpc::Function<CallVoidVoid, void(JITTargetAddress FnAddr)> {
-  public:
-    static const char *getName() { return "CallVoidVoid"; }
-  };
+class CallVoidVoid
+    : public shared::RPCFunction<CallVoidVoid, void(JITTargetAddress FnAddr)> {
+public:
+  static const char *getName() { return "CallVoidVoid"; }
+};
 
 } // end namespace exec
 
@@ -219,60 +227,62 @@
 namespace mem {
 
   /// Creates a memory allocator on the remote.
-  class CreateRemoteAllocator
-      : public rpc::Function<CreateRemoteAllocator,
-                             void(ResourceIdMgr::ResourceId AllocatorID)> {
-  public:
-    static const char *getName() { return "CreateRemoteAllocator"; }
-  };
+class CreateRemoteAllocator
+    : public shared::RPCFunction<CreateRemoteAllocator,
+                                 void(ResourceIdMgr::ResourceId AllocatorID)> {
+public:
+  static const char *getName() { return "CreateRemoteAllocator"; }
+};
 
   /// Destroys a remote allocator, freeing any memory allocated by it.
-  class DestroyRemoteAllocator
-      : public rpc::Function<DestroyRemoteAllocator,
-                             void(ResourceIdMgr::ResourceId AllocatorID)> {
-  public:
-    static const char *getName() { return "DestroyRemoteAllocator"; }
-  };
+class DestroyRemoteAllocator
+    : public shared::RPCFunction<DestroyRemoteAllocator,
+                                 void(ResourceIdMgr::ResourceId AllocatorID)> {
+public:
+  static const char *getName() { return "DestroyRemoteAllocator"; }
+};
 
   /// Read a remote memory block.
-  class ReadMem
-      : public rpc::Function<ReadMem, std::vector<uint8_t>(JITTargetAddress Src,
-                                                           uint64_t Size)> {
-  public:
-    static const char *getName() { return "ReadMem"; }
-  };
+class ReadMem
+    : public shared::RPCFunction<
+          ReadMem, std::vector<uint8_t>(JITTargetAddress Src, uint64_t Size)> {
+public:
+  static const char *getName() { return "ReadMem"; }
+};
 
   /// Reserve a block of memory on the remote via the given allocator.
-  class ReserveMem
-      : public rpc::Function<ReserveMem,
-                             JITTargetAddress(ResourceIdMgr::ResourceId AllocID,
-                                              uint64_t Size, uint32_t Align)> {
-  public:
-    static const char *getName() { return "ReserveMem"; }
-  };
+class ReserveMem
+    : public shared::RPCFunction<
+          ReserveMem, JITTargetAddress(ResourceIdMgr::ResourceId AllocID,
+                                       uint64_t Size, uint32_t Align)> {
+public:
+  static const char *getName() { return "ReserveMem"; }
+};
 
   /// Set the memory protection on a memory block.
-  class SetProtections
-      : public rpc::Function<SetProtections,
-                             void(ResourceIdMgr::ResourceId AllocID,
-                                  JITTargetAddress Dst, uint32_t ProtFlags)> {
-  public:
-    static const char *getName() { return "SetProtections"; }
-  };
+class SetProtections
+    : public shared::RPCFunction<
+          SetProtections, void(ResourceIdMgr::ResourceId AllocID,
+                               JITTargetAddress Dst, uint32_t ProtFlags)> {
+public:
+  static const char *getName() { return "SetProtections"; }
+};
 
   /// Write to a remote memory block.
-  class WriteMem
-      : public rpc::Function<WriteMem, void(remote::DirectBufferWriter DB)> {
-  public:
-    static const char *getName() { return "WriteMem"; }
-  };
+class WriteMem
+    : public shared::RPCFunction<WriteMem,
+                                 void(remote::DirectBufferWriter DB)> {
+public:
+  static const char *getName() { return "WriteMem"; }
+};
 
   /// Write to a remote pointer.
-  class WritePtr : public rpc::Function<WritePtr, void(JITTargetAddress Dst,
-                                                       JITTargetAddress Val)> {
-  public:
-    static const char *getName() { return "WritePtr"; }
-  };
+class WritePtr
+    : public shared::RPCFunction<WritePtr, void(JITTargetAddress Dst,
+                                                JITTargetAddress Val)> {
+public:
+  static const char *getName() { return "WritePtr"; }
+};
 
 } // end namespace mem
 
@@ -280,45 +290,46 @@
 namespace stubs {
 
   /// Creates an indirect stub owner on the remote.
-  class CreateIndirectStubsOwner
-      : public rpc::Function<CreateIndirectStubsOwner,
-                             void(ResourceIdMgr::ResourceId StubOwnerID)> {
-  public:
-    static const char *getName() { return "CreateIndirectStubsOwner"; }
-  };
+class CreateIndirectStubsOwner
+    : public shared::RPCFunction<CreateIndirectStubsOwner,
+                                 void(ResourceIdMgr::ResourceId StubOwnerID)> {
+public:
+  static const char *getName() { return "CreateIndirectStubsOwner"; }
+};
 
   /// RPC function for destroying an indirect stubs owner.
-  class DestroyIndirectStubsOwner
-      : public rpc::Function<DestroyIndirectStubsOwner,
-                             void(ResourceIdMgr::ResourceId StubsOwnerID)> {
-  public:
-    static const char *getName() { return "DestroyIndirectStubsOwner"; }
-  };
+class DestroyIndirectStubsOwner
+    : public shared::RPCFunction<DestroyIndirectStubsOwner,
+                                 void(ResourceIdMgr::ResourceId StubsOwnerID)> {
+public:
+  static const char *getName() { return "DestroyIndirectStubsOwner"; }
+};
 
   /// EmitIndirectStubs result is (StubsBase, PtrsBase, NumStubsEmitted).
-  class EmitIndirectStubs
-      : public rpc::Function<
-            EmitIndirectStubs,
-            std::tuple<JITTargetAddress, JITTargetAddress, uint32_t>(
-                ResourceIdMgr::ResourceId StubsOwnerID,
-                uint32_t NumStubsRequired)> {
-  public:
-    static const char *getName() { return "EmitIndirectStubs"; }
-  };
+class EmitIndirectStubs
+    : public shared::RPCFunction<
+          EmitIndirectStubs,
+          std::tuple<JITTargetAddress, JITTargetAddress, uint32_t>(
+              ResourceIdMgr::ResourceId StubsOwnerID,
+              uint32_t NumStubsRequired)> {
+public:
+  static const char *getName() { return "EmitIndirectStubs"; }
+};
 
   /// RPC function to emit the resolver block and return its address.
-  class EmitResolverBlock : public rpc::Function<EmitResolverBlock, void()> {
-  public:
-    static const char *getName() { return "EmitResolverBlock"; }
-  };
+class EmitResolverBlock
+    : public shared::RPCFunction<EmitResolverBlock, void()> {
+public:
+  static const char *getName() { return "EmitResolverBlock"; }
+};
 
   /// EmitTrampolineBlock result is (BlockAddr, NumTrampolines).
-  class EmitTrampolineBlock
-      : public rpc::Function<EmitTrampolineBlock,
-                             std::tuple<JITTargetAddress, uint32_t>()> {
-  public:
-    static const char *getName() { return "EmitTrampolineBlock"; }
-  };
+class EmitTrampolineBlock
+    : public shared::RPCFunction<EmitTrampolineBlock,
+                                 std::tuple<JITTargetAddress, uint32_t>()> {
+public:
+  static const char *getName() { return "EmitTrampolineBlock"; }
+};
 
 } // end namespace stubs
 
@@ -327,44 +338,44 @@
 
   /// GetRemoteInfo result is (Triple, PointerSize, PageSize, TrampolineSize,
   ///                          IndirectStubsSize).
-  class GetRemoteInfo
-      : public rpc::Function<
-            GetRemoteInfo,
-            std::tuple<std::string, uint32_t, uint32_t, uint32_t, uint32_t>()> {
-  public:
-    static const char *getName() { return "GetRemoteInfo"; }
-  };
+class GetRemoteInfo
+    : public shared::RPCFunction<
+          GetRemoteInfo,
+          std::tuple<std::string, uint32_t, uint32_t, uint32_t, uint32_t>()> {
+public:
+  static const char *getName() { return "GetRemoteInfo"; }
+};
 
   /// Get the address of a remote symbol.
-  class GetSymbolAddress
-      : public rpc::Function<GetSymbolAddress,
-                             JITTargetAddress(std::string SymbolName)> {
-  public:
-    static const char *getName() { return "GetSymbolAddress"; }
-  };
+class GetSymbolAddress
+    : public shared::RPCFunction<GetSymbolAddress,
+                                 JITTargetAddress(std::string SymbolName)> {
+public:
+  static const char *getName() { return "GetSymbolAddress"; }
+};
 
   /// Request that the host execute a compile callback.
-  class RequestCompile
-      : public rpc::Function<
-            RequestCompile, JITTargetAddress(JITTargetAddress TrampolineAddr)> {
-  public:
-    static const char *getName() { return "RequestCompile"; }
-  };
+class RequestCompile
+    : public shared::RPCFunction<
+          RequestCompile, JITTargetAddress(JITTargetAddress TrampolineAddr)> {
+public:
+  static const char *getName() { return "RequestCompile"; }
+};
 
   /// Notify the remote and terminate the session.
-  class TerminateSession : public rpc::Function<TerminateSession, void()> {
-  public:
-    static const char *getName() { return "TerminateSession"; }
-  };
+class TerminateSession : public shared::RPCFunction<TerminateSession, void()> {
+public:
+  static const char *getName() { return "TerminateSession"; }
+};
 
 } // namespace utils
 
 class OrcRemoteTargetRPCAPI
-    : public rpc::SingleThreadedRPCEndpoint<rpc::RawByteChannel> {
+    : public shared::SingleThreadedRPCEndpoint<shared::RawByteChannel> {
 public:
   // FIXME: Remove constructors once MSVC supports synthesizing move-ops.
-  OrcRemoteTargetRPCAPI(rpc::RawByteChannel &C)
-      : rpc::SingleThreadedRPCEndpoint<rpc::RawByteChannel>(C, true) {}
+  OrcRemoteTargetRPCAPI(shared::RawByteChannel &C)
+      : shared::SingleThreadedRPCEndpoint<shared::RawByteChannel>(C, true) {}
 };
 
 } // end namespace remote
diff --git a/linux-x64/clang/include/llvm/ExecutionEngine/Orc/OrcRemoteTargetServer.h b/linux-x64/clang/include/llvm/ExecutionEngine/Orc/OrcRemoteTargetServer.h
index 4c8e2ea..68eccf4 100644
--- a/linux-x64/clang/include/llvm/ExecutionEngine/Orc/OrcRemoteTargetServer.h
+++ b/linux-x64/clang/include/llvm/ExecutionEngine/Orc/OrcRemoteTargetServer.h
@@ -15,6 +15,7 @@
 #define LLVM_EXECUTIONENGINE_ORC_ORCREMOTETARGETSERVER_H
 
 #include "llvm/ExecutionEngine/JITSymbol.h"
+#include "llvm/ExecutionEngine/Orc/IndirectionUtils.h"
 #include "llvm/ExecutionEngine/Orc/OrcError.h"
 #include "llvm/ExecutionEngine/Orc/OrcRemoteTargetRPCAPI.h"
 #include "llvm/Support/Debug.h"
@@ -45,7 +46,7 @@
 
 template <typename ChannelT, typename TargetT>
 class OrcRemoteTargetServer
-    : public rpc::SingleThreadedRPCEndpoint<rpc::RawByteChannel> {
+    : public shared::SingleThreadedRPCEndpoint<shared::RawByteChannel> {
 public:
   using SymbolLookupFtor =
       std::function<JITTargetAddress(const std::string &Name)>;
@@ -56,12 +57,14 @@
   OrcRemoteTargetServer(ChannelT &Channel, SymbolLookupFtor SymbolLookup,
                         EHFrameRegistrationFtor EHFramesRegister,
                         EHFrameRegistrationFtor EHFramesDeregister)
-      : rpc::SingleThreadedRPCEndpoint<rpc::RawByteChannel>(Channel, true),
+      : shared::SingleThreadedRPCEndpoint<shared::RawByteChannel>(Channel,
+                                                                  true),
         SymbolLookup(std::move(SymbolLookup)),
         EHFramesRegister(std::move(EHFramesRegister)),
         EHFramesDeregister(std::move(EHFramesDeregister)) {
-    using ThisT = typename std::remove_reference<decltype(*this)>::type;
+    using ThisT = std::remove_reference_t<decltype(*this)>;
     addHandler<exec::CallIntVoid>(*this, &ThisT::handleCallIntVoid);
+    addHandler<exec::CallIntInt>(*this, &ThisT::handleCallIntInt);
     addHandler<exec::CallMain>(*this, &ThisT::handleCallMain);
     addHandler<exec::CallVoidVoid>(*this, &ThisT::handleCallVoidVoid);
     addHandler<mem::CreateRemoteAllocator>(*this,
@@ -167,6 +170,19 @@
     return Result;
   }
 
+  Expected<int32_t> handleCallIntInt(JITTargetAddress Addr, int Arg) {
+    using IntIntFnTy = int (*)(int);
+
+    IntIntFnTy Fn = reinterpret_cast<IntIntFnTy>(static_cast<uintptr_t>(Addr));
+
+    LLVM_DEBUG(dbgs() << "  Calling " << format("0x%016x", Addr)
+                      << " with argument " << Arg << "\n");
+    int Result = Fn(Arg);
+    LLVM_DEBUG(dbgs() << "  Result = " << Result << "\n");
+
+    return Result;
+  }
+
   Expected<int32_t> handleCallMain(JITTargetAddress Addr,
                                    std::vector<std::string> Args) {
     using MainFnTy = int (*)(int, const char *[]);
@@ -262,19 +278,17 @@
       return errorCodeToError(
                orcError(OrcErrorCode::RemoteIndirectStubsOwnerDoesNotExist));
 
-    typename TargetT::IndirectStubsInfo IS;
-    if (auto Err =
-            TargetT::emitIndirectStubsBlock(IS, NumStubsRequired, nullptr))
-      return std::move(Err);
+    auto IS = LocalIndirectStubsInfo<TargetT>::create(
+        NumStubsRequired, sys::Process::getPageSizeEstimate());
+    if (!IS)
+      return IS.takeError();
 
-    JITTargetAddress StubsBase = static_cast<JITTargetAddress>(
-        reinterpret_cast<uintptr_t>(IS.getStub(0)));
-    JITTargetAddress PtrsBase = static_cast<JITTargetAddress>(
-        reinterpret_cast<uintptr_t>(IS.getPtr(0)));
-    uint32_t NumStubsEmitted = IS.getNumStubs();
+    JITTargetAddress StubsBase = pointerToJITTargetAddress(IS->getStub(0));
+    JITTargetAddress PtrsBase = pointerToJITTargetAddress(IS->getPtr(0));
+    uint32_t NumStubsEmitted = IS->getNumStubs();
 
     auto &BlockList = StubOwnerItr->second;
-    BlockList.push_back(std::move(IS));
+    BlockList.push_back(std::move(*IS));
 
     return std::make_tuple(StubsBase, PtrsBase, NumStubsEmitted);
   }
@@ -287,8 +301,10 @@
     if (EC)
       return errorCodeToError(EC);
 
-    TargetT::writeResolverCode(static_cast<uint8_t *>(ResolverBlock.base()),
-                               &reenter, this);
+    TargetT::writeResolverCode(static_cast<char *>(ResolverBlock.base()),
+                               pointerToJITTargetAddress(ResolverBlock.base()),
+                               pointerToJITTargetAddress(&reenter),
+                               pointerToJITTargetAddress(this));
 
     return errorCodeToError(sys::Memory::protectMappedMemory(
         ResolverBlock.getMemoryBlock(),
@@ -308,9 +324,10 @@
         (sys::Process::getPageSizeEstimate() - TargetT::PointerSize) /
         TargetT::TrampolineSize;
 
-    uint8_t *TrampolineMem = static_cast<uint8_t *>(TrampolineBlock.base());
-    TargetT::writeTrampolines(TrampolineMem, ResolverBlock.base(),
-                              NumTrampolines);
+    char *TrampolineMem = static_cast<char *>(TrampolineBlock.base());
+    TargetT::writeTrampolines(
+        TrampolineMem, pointerToJITTargetAddress(TrampolineMem),
+        pointerToJITTargetAddress(ResolverBlock.base()), NumTrampolines);
 
     EC = sys::Memory::protectMappedMemory(TrampolineBlock.getMemoryBlock(),
                                           sys::Memory::MF_READ |
@@ -318,10 +335,8 @@
 
     TrampolineBlocks.push_back(std::move(TrampolineBlock));
 
-    auto TrampolineBaseAddr = static_cast<JITTargetAddress>(
-        reinterpret_cast<uintptr_t>(TrampolineMem));
-
-    return std::make_tuple(TrampolineBaseAddr, NumTrampolines);
+    return std::make_tuple(pointerToJITTargetAddress(TrampolineMem),
+                           NumTrampolines);
   }
 
   Expected<JITTargetAddress> handleGetSymbolAddress(const std::string &Name) {
@@ -337,7 +352,7 @@
     uint32_t PointerSize = TargetT::PointerSize;
     uint32_t PageSize = sys::Process::getPageSizeEstimate();
     uint32_t TrampolineSize = TargetT::TrampolineSize;
-    uint32_t IndirectStubSize = TargetT::IndirectStubsInfo::StubSize;
+    uint32_t IndirectStubSize = TargetT::StubSize;
     LLVM_DEBUG(dbgs() << "  Remote info:\n"
                       << "    triple             = '" << ProcessTriple << "'\n"
                       << "    pointer size       = " << PointerSize << "\n"
@@ -433,7 +448,7 @@
   SymbolLookupFtor SymbolLookup;
   EHFrameRegistrationFtor EHFramesRegister, EHFramesDeregister;
   std::map<ResourceIdMgr::ResourceId, Allocator> Allocators;
-  using ISBlockOwnerList = std::vector<typename TargetT::IndirectStubsInfo>;
+  using ISBlockOwnerList = std::vector<LocalIndirectStubsInfo<TargetT>>;
   std::map<ResourceIdMgr::ResourceId, ISBlockOwnerList> IndirectStubsOwners;
   sys::OwningMemoryBlock ResolverBlock;
   std::vector<sys::OwningMemoryBlock> TrampolineBlocks;
diff --git a/linux-x64/clang/include/llvm/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.h b/linux-x64/clang/include/llvm/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.h
index 479658b..7dfbf32 100644
--- a/linux-x64/clang/include/llvm/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.h
+++ b/linux-x64/clang/include/llvm/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.h
@@ -16,10 +16,10 @@
 #include "llvm/ADT/STLExtras.h"
 #include "llvm/ADT/StringMap.h"
 #include "llvm/ADT/StringRef.h"
+#include "llvm/ExecutionEngine/JITEventListener.h"
 #include "llvm/ExecutionEngine/JITSymbol.h"
 #include "llvm/ExecutionEngine/Orc/Core.h"
 #include "llvm/ExecutionEngine/Orc/Layer.h"
-#include "llvm/ExecutionEngine/Orc/Legacy.h"
 #include "llvm/ExecutionEngine/RuntimeDyld.h"
 #include "llvm/Object/ObjectFile.h"
 #include "llvm/Support/Error.h"
@@ -35,16 +35,16 @@
 namespace llvm {
 namespace orc {
 
-class RTDyldObjectLinkingLayer : public ObjectLayer {
+class RTDyldObjectLinkingLayer : public ObjectLayer, private ResourceManager {
 public:
   /// Functor for receiving object-loaded notifications.
-  using NotifyLoadedFunction =
-      std::function<void(VModuleKey, const object::ObjectFile &Obj,
-                         const RuntimeDyld::LoadedObjectInfo &)>;
+  using NotifyLoadedFunction = std::function<void(
+      MaterializationResponsibility &R, const object::ObjectFile &Obj,
+      const RuntimeDyld::LoadedObjectInfo &)>;
 
   /// Functor for receiving finalization notifications.
-  using NotifyEmittedFunction =
-      std::function<void(VModuleKey, std::unique_ptr<MemoryBuffer>)>;
+  using NotifyEmittedFunction = std::function<void(
+      MaterializationResponsibility &R, std::unique_ptr<MemoryBuffer>)>;
 
   using GetMemoryManagerFunction =
       std::function<std::unique_ptr<RuntimeDyld::MemoryManager>()>;
@@ -54,8 +54,10 @@
   RTDyldObjectLinkingLayer(ExecutionSession &ES,
                            GetMemoryManagerFunction GetMemoryManager);
 
+  ~RTDyldObjectLinkingLayer();
+
   /// Emit the object.
-  void emit(MaterializationResponsibility R,
+  void emit(std::unique_ptr<MaterializationResponsibility> R,
             std::unique_ptr<MemoryBuffer> O) override;
 
   /// Set the NotifyLoaded callback.
@@ -113,15 +115,30 @@
     return *this;
   }
 
+  /// Register a JITEventListener.
+  void registerJITEventListener(JITEventListener &L);
+
+  /// Unregister a JITEventListener.
+  void unregisterJITEventListener(JITEventListener &L);
+
 private:
-  Error onObjLoad(VModuleKey K, MaterializationResponsibility &R,
-                  object::ObjectFile &Obj,
-                  std::unique_ptr<RuntimeDyld::LoadedObjectInfo> LoadedObjInfo,
+  using MemoryManagerUP = std::unique_ptr<RuntimeDyld::MemoryManager>;
+
+  Error onObjLoad(MaterializationResponsibility &R,
+                  const object::ObjectFile &Obj,
+                  RuntimeDyld::MemoryManager &MemMgr,
+                  RuntimeDyld::LoadedObjectInfo &LoadedObjInfo,
                   std::map<StringRef, JITEvaluatedSymbol> Resolved,
                   std::set<StringRef> &InternalSymbols);
 
-  void onObjEmit(VModuleKey K, std::unique_ptr<MemoryBuffer> ObjBuffer,
-                 MaterializationResponsibility &R, Error Err);
+  void onObjEmit(MaterializationResponsibility &R,
+                 object::OwningBinary<object::ObjectFile> O,
+                 std::unique_ptr<RuntimeDyld::MemoryManager> MemMgr,
+                 std::unique_ptr<RuntimeDyld::LoadedObjectInfo> LoadedObjInfo,
+                 Error Err);
+
+  Error handleRemoveResources(ResourceKey K) override;
+  void handleTransferResources(ResourceKey DstKey, ResourceKey SrcKey) override;
 
   mutable std::mutex RTDyldLayerMutex;
   GetMemoryManagerFunction GetMemoryManager;
@@ -130,340 +147,8 @@
   bool ProcessAllSections = false;
   bool OverrideObjectFlags = false;
   bool AutoClaimObjectSymbols = false;
-  std::vector<std::unique_ptr<RuntimeDyld::MemoryManager>> MemMgrs;
-};
-
-class LegacyRTDyldObjectLinkingLayerBase {
-public:
-  using ObjectPtr = std::unique_ptr<MemoryBuffer>;
-
-protected:
-
-  /// Holds an object to be allocated/linked as a unit in the JIT.
-  ///
-  /// An instance of this class will be created for each object added
-  /// via JITObjectLayer::addObject. Deleting the instance (via
-  /// removeObject) frees its memory, removing all symbol definitions that
-  /// had been provided by this instance. Higher level layers are responsible
-  /// for taking any action required to handle the missing symbols.
-  class LinkedObject {
-  public:
-    LinkedObject() = default;
-    LinkedObject(const LinkedObject&) = delete;
-    void operator=(const LinkedObject&) = delete;
-    virtual ~LinkedObject() = default;
-
-    virtual Error finalize() = 0;
-
-    virtual JITSymbol::GetAddressFtor
-    getSymbolMaterializer(std::string Name) = 0;
-
-    virtual void mapSectionAddress(const void *LocalAddress,
-                                   JITTargetAddress TargetAddr) const = 0;
-
-    JITSymbol getSymbol(StringRef Name, bool ExportedSymbolsOnly) {
-      auto SymEntry = SymbolTable.find(Name);
-      if (SymEntry == SymbolTable.end())
-        return nullptr;
-      if (!SymEntry->second.getFlags().isExported() && ExportedSymbolsOnly)
-        return nullptr;
-      if (!Finalized)
-        return JITSymbol(getSymbolMaterializer(Name),
-                         SymEntry->second.getFlags());
-      return JITSymbol(SymEntry->second);
-    }
-
-  protected:
-    StringMap<JITEvaluatedSymbol> SymbolTable;
-    bool Finalized = false;
-  };
-};
-
-/// Bare bones object linking layer.
-///
-///   This class is intended to be used as the base layer for a JIT. It allows
-/// object files to be loaded into memory, linked, and the addresses of their
-/// symbols queried. All objects added to this layer can see each other's
-/// symbols.
-class LegacyRTDyldObjectLinkingLayer : public LegacyRTDyldObjectLinkingLayerBase {
-public:
-
-  using LegacyRTDyldObjectLinkingLayerBase::ObjectPtr;
-
-  /// Functor for receiving object-loaded notifications.
-  using NotifyLoadedFtor =
-      std::function<void(VModuleKey, const object::ObjectFile &Obj,
-                         const RuntimeDyld::LoadedObjectInfo &)>;
-
-  /// Functor for receiving finalization notifications.
-  using NotifyFinalizedFtor =
-      std::function<void(VModuleKey, const object::ObjectFile &Obj,
-                         const RuntimeDyld::LoadedObjectInfo &)>;
-
-  /// Functor for receiving deallocation notifications.
-  using NotifyFreedFtor = std::function<void(VModuleKey, const object::ObjectFile &Obj)>;
-
-private:
-  using OwnedObject = object::OwningBinary<object::ObjectFile>;
-
-  template <typename MemoryManagerPtrT>
-  class ConcreteLinkedObject : public LinkedObject {
-  public:
-    ConcreteLinkedObject(LegacyRTDyldObjectLinkingLayer &Parent, VModuleKey K,
-                         OwnedObject Obj, MemoryManagerPtrT MemMgr,
-                         std::shared_ptr<SymbolResolver> Resolver,
-                         bool ProcessAllSections)
-        : K(std::move(K)),
-          Parent(Parent),
-          MemMgr(std::move(MemMgr)),
-          PFC(llvm::make_unique<PreFinalizeContents>(
-              std::move(Obj), std::move(Resolver),
-              ProcessAllSections)) {
-      buildInitialSymbolTable(PFC->Obj);
-    }
-
-    ~ConcreteLinkedObject() override {
-      if (this->Parent.NotifyFreed && ObjForNotify.getBinary())
-        this->Parent.NotifyFreed(K, *ObjForNotify.getBinary());
-
-      MemMgr->deregisterEHFrames();
-    }
-
-    Error finalize() override {
-      assert(PFC && "mapSectionAddress called on finalized LinkedObject");
-
-      JITSymbolResolverAdapter ResolverAdapter(Parent.ES, *PFC->Resolver,
-					       nullptr);
-      PFC->RTDyld = llvm::make_unique<RuntimeDyld>(*MemMgr, ResolverAdapter);
-      PFC->RTDyld->setProcessAllSections(PFC->ProcessAllSections);
-
-      Finalized = true;
-
-      std::unique_ptr<RuntimeDyld::LoadedObjectInfo> Info =
-          PFC->RTDyld->loadObject(*PFC->Obj.getBinary());
-
-      // Copy the symbol table out of the RuntimeDyld instance.
-      {
-        auto SymTab = PFC->RTDyld->getSymbolTable();
-        for (auto &KV : SymTab)
-          SymbolTable[KV.first] = KV.second;
-      }
-
-      if (Parent.NotifyLoaded)
-        Parent.NotifyLoaded(K, *PFC->Obj.getBinary(), *Info);
-
-      PFC->RTDyld->finalizeWithMemoryManagerLocking();
-
-      if (PFC->RTDyld->hasError())
-        return make_error<StringError>(PFC->RTDyld->getErrorString(),
-                                       inconvertibleErrorCode());
-
-      if (Parent.NotifyFinalized)
-        Parent.NotifyFinalized(K, *PFC->Obj.getBinary(), *Info);
-
-      // Release resources.
-      if (this->Parent.NotifyFreed)
-        ObjForNotify = std::move(PFC->Obj); // needed for callback
-      PFC = nullptr;
-      return Error::success();
-    }
-
-    JITSymbol::GetAddressFtor getSymbolMaterializer(std::string Name) override {
-      return [this, Name]() -> Expected<JITTargetAddress> {
-        // The symbol may be materialized between the creation of this lambda
-        // and its execution, so we need to double check.
-        if (!this->Finalized)
-          if (auto Err = this->finalize())
-            return std::move(Err);
-        return this->getSymbol(Name, false).getAddress();
-      };
-    }
-
-    void mapSectionAddress(const void *LocalAddress,
-                           JITTargetAddress TargetAddr) const override {
-      assert(PFC && "mapSectionAddress called on finalized LinkedObject");
-      assert(PFC->RTDyld && "mapSectionAddress called on raw LinkedObject");
-      PFC->RTDyld->mapSectionAddress(LocalAddress, TargetAddr);
-    }
-
-  private:
-    void buildInitialSymbolTable(const OwnedObject &Obj) {
-      for (auto &Symbol : Obj.getBinary()->symbols()) {
-        if (Symbol.getFlags() & object::SymbolRef::SF_Undefined)
-          continue;
-        Expected<StringRef> SymbolName = Symbol.getName();
-        // FIXME: Raise an error for bad symbols.
-        if (!SymbolName) {
-          consumeError(SymbolName.takeError());
-          continue;
-        }
-        // FIXME: Raise an error for bad symbols.
-        auto Flags = JITSymbolFlags::fromObjectSymbol(Symbol);
-        if (!Flags) {
-          consumeError(Flags.takeError());
-          continue;
-        }
-        SymbolTable.insert(
-            std::make_pair(*SymbolName, JITEvaluatedSymbol(0, *Flags)));
-      }
-    }
-
-    // Contains the information needed prior to finalization: the object files,
-    // memory manager, resolver, and flags needed for RuntimeDyld.
-    struct PreFinalizeContents {
-      PreFinalizeContents(OwnedObject Obj,
-                          std::shared_ptr<SymbolResolver> Resolver,
-                          bool ProcessAllSections)
-          : Obj(std::move(Obj)),
-            Resolver(std::move(Resolver)),
-            ProcessAllSections(ProcessAllSections) {}
-
-      OwnedObject Obj;
-      std::shared_ptr<SymbolResolver> Resolver;
-      bool ProcessAllSections;
-      std::unique_ptr<RuntimeDyld> RTDyld;
-    };
-
-    VModuleKey K;
-    LegacyRTDyldObjectLinkingLayer &Parent;
-    MemoryManagerPtrT MemMgr;
-    OwnedObject ObjForNotify;
-    std::unique_ptr<PreFinalizeContents> PFC;
-  };
-
-  template <typename MemoryManagerPtrT>
-  std::unique_ptr<ConcreteLinkedObject<MemoryManagerPtrT>>
-  createLinkedObject(LegacyRTDyldObjectLinkingLayer &Parent, VModuleKey K,
-                     OwnedObject Obj, MemoryManagerPtrT MemMgr,
-                     std::shared_ptr<SymbolResolver> Resolver,
-                     bool ProcessAllSections) {
-    using LOS = ConcreteLinkedObject<MemoryManagerPtrT>;
-    return llvm::make_unique<LOS>(Parent, std::move(K), std::move(Obj),
-                                  std::move(MemMgr), std::move(Resolver),
-                                  ProcessAllSections);
-  }
-
-public:
-  struct Resources {
-    std::shared_ptr<RuntimeDyld::MemoryManager> MemMgr;
-    std::shared_ptr<SymbolResolver> Resolver;
-  };
-
-  using ResourcesGetter = std::function<Resources(VModuleKey)>;
-
-  /// Construct an ObjectLinkingLayer with the given NotifyLoaded,
-  ///        and NotifyFinalized functors.
-  LegacyRTDyldObjectLinkingLayer(
-      ExecutionSession &ES, ResourcesGetter GetResources,
-      NotifyLoadedFtor NotifyLoaded = NotifyLoadedFtor(),
-      NotifyFinalizedFtor NotifyFinalized = NotifyFinalizedFtor(),
-      NotifyFreedFtor NotifyFreed = NotifyFreedFtor())
-      : ES(ES), GetResources(std::move(GetResources)),
-        NotifyLoaded(std::move(NotifyLoaded)),
-        NotifyFinalized(std::move(NotifyFinalized)),
-        NotifyFreed(std::move(NotifyFreed)),
-        ProcessAllSections(false) {
-  }
-
-  /// Set the 'ProcessAllSections' flag.
-  ///
-  /// If set to true, all sections in each object file will be allocated using
-  /// the memory manager, rather than just the sections required for execution.
-  ///
-  /// This is kludgy, and may be removed in the future.
-  void setProcessAllSections(bool ProcessAllSections) {
-    this->ProcessAllSections = ProcessAllSections;
-  }
-
-  /// Add an object to the JIT.
-  Error addObject(VModuleKey K, ObjectPtr ObjBuffer) {
-
-    auto Obj =
-        object::ObjectFile::createObjectFile(ObjBuffer->getMemBufferRef());
-    if (!Obj)
-      return Obj.takeError();
-
-    assert(!LinkedObjects.count(K) && "VModuleKey already in use");
-
-    auto R = GetResources(K);
-
-    LinkedObjects[K] = createLinkedObject(
-        *this, K, OwnedObject(std::move(*Obj), std::move(ObjBuffer)),
-        std::move(R.MemMgr), std::move(R.Resolver), ProcessAllSections);
-
-    return Error::success();
-  }
-
-  /// Remove the object associated with VModuleKey K.
-  ///
-  ///   All memory allocated for the object will be freed, and the sections and
-  /// symbols it provided will no longer be available. No attempt is made to
-  /// re-emit the missing symbols, and any use of these symbols (directly or
-  /// indirectly) will result in undefined behavior. If dependence tracking is
-  /// required to detect or resolve such issues it should be added at a higher
-  /// layer.
-  Error removeObject(VModuleKey K) {
-    assert(LinkedObjects.count(K) && "VModuleKey not associated with object");
-    // How do we invalidate the symbols in H?
-    LinkedObjects.erase(K);
-    return Error::success();
-  }
-
-  /// Search for the given named symbol.
-  /// @param Name The name of the symbol to search for.
-  /// @param ExportedSymbolsOnly If true, search only for exported symbols.
-  /// @return A handle for the given named symbol, if it exists.
-  JITSymbol findSymbol(StringRef Name, bool ExportedSymbolsOnly) {
-    for (auto &KV : LinkedObjects)
-      if (auto Sym = KV.second->getSymbol(Name, ExportedSymbolsOnly))
-        return Sym;
-      else if (auto Err = Sym.takeError())
-        return std::move(Err);
-
-    return nullptr;
-  }
-
-  /// Search for the given named symbol in the context of the loaded
-  ///        object represented by the VModuleKey K.
-  /// @param K The VModuleKey for the object to search in.
-  /// @param Name The name of the symbol to search for.
-  /// @param ExportedSymbolsOnly If true, search only for exported symbols.
-  /// @return A handle for the given named symbol, if it is found in the
-  ///         given object.
-  JITSymbol findSymbolIn(VModuleKey K, StringRef Name,
-                         bool ExportedSymbolsOnly) {
-    assert(LinkedObjects.count(K) && "VModuleKey not associated with object");
-    return LinkedObjects[K]->getSymbol(Name, ExportedSymbolsOnly);
-  }
-
-  /// Map section addresses for the object associated with the
-  ///        VModuleKey K.
-  void mapSectionAddress(VModuleKey K, const void *LocalAddress,
-                         JITTargetAddress TargetAddr) {
-    assert(LinkedObjects.count(K) && "VModuleKey not associated with object");
-    LinkedObjects[K]->mapSectionAddress(LocalAddress, TargetAddr);
-  }
-
-  /// Immediately emit and finalize the object represented by the given
-  ///        VModuleKey.
-  /// @param K VModuleKey for object to emit/finalize.
-  Error emitAndFinalize(VModuleKey K) {
-    assert(LinkedObjects.count(K) && "VModuleKey not associated with object");
-    return LinkedObjects[K]->finalize();
-  }
-
-private:
-  ExecutionSession &ES;
-
-  ResourcesGetter GetResources;
-  NotifyLoadedFtor NotifyLoaded;
-  NotifyFinalizedFtor NotifyFinalized;
-  NotifyFreedFtor NotifyFreed;
-
-  // NB!  `LinkedObjects` needs to be destroyed before `NotifyFreed` because
-  // `~ConcreteLinkedObject` calls `NotifyFreed`
-  std::map<VModuleKey, std::unique_ptr<LinkedObject>> LinkedObjects;
-  bool ProcessAllSections = false;
+  DenseMap<ResourceKey, std::vector<MemoryManagerUP>> MemMgrs;
+  std::vector<JITEventListener *> EventListeners;
 };
 
 } // end namespace orc
diff --git a/linux-x64/clang/include/llvm/ExecutionEngine/Orc/RemoteObjectLayer.h b/linux-x64/clang/include/llvm/ExecutionEngine/Orc/RemoteObjectLayer.h
deleted file mode 100644
index 9550edc..0000000
--- a/linux-x64/clang/include/llvm/ExecutionEngine/Orc/RemoteObjectLayer.h
+++ /dev/null
@@ -1,528 +0,0 @@
-//===------ RemoteObjectLayer.h - Forwards objs to a remote -----*- 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
-//
-//===----------------------------------------------------------------------===//
-//
-// Forwards objects to a remote object layer via RPC.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_EXECUTIONENGINE_ORC_REMOTEOBJECTLAYER_H
-#define LLVM_EXECUTIONENGINE_ORC_REMOTEOBJECTLAYER_H
-
-#include "llvm/ExecutionEngine/Orc/OrcRemoteTargetRPCAPI.h"
-#include "llvm/Object/ObjectFile.h"
-#include "llvm/ExecutionEngine/Orc/LambdaResolver.h"
-#include <map>
-
-namespace llvm {
-namespace orc {
-
-/// RPC API needed by RemoteObjectClientLayer and RemoteObjectServerLayer.
-class RemoteObjectLayerAPI {
-public:
-
-  using ObjHandleT = remote::ResourceIdMgr::ResourceId;
-
-protected:
-
-  using RemoteSymbolId = remote::ResourceIdMgr::ResourceId;
-  using RemoteSymbol = std::pair<RemoteSymbolId, JITSymbolFlags>;
-
-public:
-
-  using BadSymbolHandleError = remote::ResourceNotFound<RemoteSymbolId>;
-  using BadObjectHandleError = remote::ResourceNotFound<ObjHandleT>;
-
-protected:
-
-  static const ObjHandleT InvalidObjectHandleId = 0;
-  static const RemoteSymbolId NullSymbolId = 0;
-
-  class AddObject
-    : public rpc::Function<AddObject, Expected<ObjHandleT>(std::string)> {
-  public:
-    static const char *getName() { return "AddObject"; }
-  };
-
-  class RemoveObject
-    : public rpc::Function<RemoveObject, Error(ObjHandleT)> {
-  public:
-    static const char *getName() { return "RemoveObject"; }
-  };
-
-  class FindSymbol
-    : public rpc::Function<FindSymbol, Expected<RemoteSymbol>(std::string,
-                                                              bool)> {
-  public:
-    static const char *getName() { return "FindSymbol"; }
-  };
-
-  class FindSymbolIn
-    : public rpc::Function<FindSymbolIn,
-                           Expected<RemoteSymbol>(ObjHandleT, std::string,
-                                                  bool)> {
-  public:
-    static const char *getName() { return "FindSymbolIn"; }
-  };
-
-  class EmitAndFinalize
-    : public rpc::Function<EmitAndFinalize,
-                           Error(ObjHandleT)> {
-  public:
-    static const char *getName() { return "EmitAndFinalize"; }
-  };
-
-  class Lookup
-    : public rpc::Function<Lookup,
-                           Expected<RemoteSymbol>(ObjHandleT, std::string)> {
-  public:
-    static const char *getName() { return "Lookup"; }
-  };
-
-  class LookupInLogicalDylib
-    : public rpc::Function<LookupInLogicalDylib,
-                           Expected<RemoteSymbol>(ObjHandleT, std::string)> {
-  public:
-    static const char *getName() { return "LookupInLogicalDylib"; }
-  };
-
-  class ReleaseRemoteSymbol
-    : public rpc::Function<ReleaseRemoteSymbol, Error(RemoteSymbolId)> {
-  public:
-    static const char *getName() { return "ReleaseRemoteSymbol"; }
-  };
-
-  class MaterializeRemoteSymbol
-    : public rpc::Function<MaterializeRemoteSymbol,
-                           Expected<JITTargetAddress>(RemoteSymbolId)> {
-  public:
-    static const char *getName() { return "MaterializeRemoteSymbol"; }
-  };
-};
-
-/// Base class containing common utilities for RemoteObjectClientLayer and
-/// RemoteObjectServerLayer.
-template <typename RPCEndpoint>
-class RemoteObjectLayer : public RemoteObjectLayerAPI {
-public:
-
-  RemoteObjectLayer(RPCEndpoint &Remote,
-                    std::function<void(Error)> ReportError)
-      : Remote(Remote), ReportError(std::move(ReportError)),
-        SymbolIdMgr(NullSymbolId + 1) {
-    using ThisT = RemoteObjectLayer<RPCEndpoint>;
-    Remote.template addHandler<ReleaseRemoteSymbol>(
-             *this, &ThisT::handleReleaseRemoteSymbol);
-    Remote.template addHandler<MaterializeRemoteSymbol>(
-             *this, &ThisT::handleMaterializeRemoteSymbol);
-  }
-
-protected:
-
-  /// This class is used as the symbol materializer for JITSymbols returned by
-  /// RemoteObjectLayerClient/RemoteObjectLayerServer -- the materializer knows
-  /// how to call back to the other RPC endpoint to get the address when
-  /// requested.
-  class RemoteSymbolMaterializer {
-  public:
-
-    /// Construct a RemoteSymbolMaterializer for the given RemoteObjectLayer
-    /// with the given Id.
-    RemoteSymbolMaterializer(RemoteObjectLayer &C,
-                             RemoteSymbolId Id)
-      : C(C), Id(Id) {}
-
-    RemoteSymbolMaterializer(const RemoteSymbolMaterializer &Other)
-      : C(Other.C), Id(Other.Id) {
-      // FIXME: This is a horrible, auto_ptr-style, copy-as-move operation.
-      //        It should be removed as soon as LLVM has C++14's generalized
-      //        lambda capture (at which point the materializer can be moved
-      //        into the lambda in remoteToJITSymbol below).
-      const_cast<RemoteSymbolMaterializer&>(Other).Id = 0;
-    }
-
-    RemoteSymbolMaterializer&
-    operator=(const RemoteSymbolMaterializer&) = delete;
-
-    /// Release the remote symbol.
-    ~RemoteSymbolMaterializer() {
-      if (Id)
-        C.releaseRemoteSymbol(Id);
-    }
-
-    /// Materialize the symbol on the remote and get its address.
-    Expected<JITTargetAddress> materialize() {
-      auto Addr = C.materializeRemoteSymbol(Id);
-      Id = 0;
-      return Addr;
-    }
-
-  private:
-    RemoteObjectLayer &C;
-    RemoteSymbolId Id;
-  };
-
-  /// Convenience function for getting a null remote symbol value.
-  RemoteSymbol nullRemoteSymbol() {
-    return RemoteSymbol(0, JITSymbolFlags());
-  }
-
-  /// Creates a StringError that contains a copy of Err's log message, then
-  /// sends that StringError to ReportError.
-  ///
-  /// This allows us to locally log error messages for errors that will actually
-  /// be delivered to the remote.
-  Error teeLog(Error Err) {
-    return handleErrors(std::move(Err),
-                        [this](std::unique_ptr<ErrorInfoBase> EIB) {
-                          ReportError(make_error<StringError>(
-                                        EIB->message(),
-                                        EIB->convertToErrorCode()));
-                          return Error(std::move(EIB));
-                        });
-  }
-
-  Error badRemoteSymbolIdError(RemoteSymbolId Id) {
-    return make_error<BadSymbolHandleError>(Id, "Remote JIT Symbol");
-  }
-
-  Error badObjectHandleError(ObjHandleT H) {
-    return make_error<RemoteObjectLayerAPI::BadObjectHandleError>(
-             H, "Bad object handle");
-  }
-
-  /// Create a RemoteSymbol wrapping the given JITSymbol.
-  Expected<RemoteSymbol> jitSymbolToRemote(JITSymbol Sym) {
-    if (Sym) {
-      auto Id = SymbolIdMgr.getNext();
-      auto Flags = Sym.getFlags();
-      assert(!InUseSymbols.count(Id) && "Symbol id already in use");
-      InUseSymbols.insert(std::make_pair(Id, std::move(Sym)));
-      return RemoteSymbol(Id, Flags);
-    } else if (auto Err = Sym.takeError())
-      return teeLog(std::move(Err));
-    // else...
-    return nullRemoteSymbol();
-  }
-
-  /// Convert an Expected<RemoteSymbol> to a JITSymbol.
-  JITSymbol remoteToJITSymbol(Expected<RemoteSymbol> RemoteSymOrErr) {
-    if (RemoteSymOrErr) {
-      auto &RemoteSym = *RemoteSymOrErr;
-      if (RemoteSym == nullRemoteSymbol())
-        return nullptr;
-      // else...
-      RemoteSymbolMaterializer RSM(*this, RemoteSym.first);
-      auto Sym =
-        JITSymbol([RSM]() mutable { return RSM.materialize(); },
-                  RemoteSym.second);
-      return Sym;
-    } else
-      return RemoteSymOrErr.takeError();
-  }
-
-  RPCEndpoint &Remote;
-  std::function<void(Error)> ReportError;
-
-private:
-
-  /// Notify the remote to release the given JITSymbol.
-  void releaseRemoteSymbol(RemoteSymbolId Id) {
-    if (auto Err = Remote.template callB<ReleaseRemoteSymbol>(Id))
-      ReportError(std::move(Err));
-  }
-
-  /// Notify the remote to materialize the JITSymbol with the given Id and
-  /// return its address.
-  Expected<JITTargetAddress> materializeRemoteSymbol(RemoteSymbolId Id) {
-    return Remote.template callB<MaterializeRemoteSymbol>(Id);
-  }
-
-  /// Release the JITSymbol with the given Id.
-  Error handleReleaseRemoteSymbol(RemoteSymbolId Id) {
-    auto SI = InUseSymbols.find(Id);
-    if (SI != InUseSymbols.end()) {
-      InUseSymbols.erase(SI);
-      return Error::success();
-    } else
-      return teeLog(badRemoteSymbolIdError(Id));
-  }
-
-  /// Run the materializer for the JITSymbol with the given Id and return its
-  /// address.
-  Expected<JITTargetAddress> handleMaterializeRemoteSymbol(RemoteSymbolId Id) {
-    auto SI = InUseSymbols.find(Id);
-    if (SI != InUseSymbols.end()) {
-      auto AddrOrErr = SI->second.getAddress();
-      InUseSymbols.erase(SI);
-      SymbolIdMgr.release(Id);
-      if (AddrOrErr)
-        return *AddrOrErr;
-      else
-        return teeLog(AddrOrErr.takeError());
-    } else {
-      return teeLog(badRemoteSymbolIdError(Id));
-    }
-  }
-
-  remote::ResourceIdMgr SymbolIdMgr;
-  std::map<RemoteSymbolId, JITSymbol> InUseSymbols;
-};
-
-/// RemoteObjectClientLayer forwards the ORC Object Layer API over an RPC
-/// connection.
-///
-/// This class can be used as the base layer of a JIT stack on the client and
-/// will forward operations to a corresponding RemoteObjectServerLayer on the
-/// server (which can be composed on top of a "real" object layer like
-/// RTDyldObjectLinkingLayer to actually carry out the operations).
-///
-/// Sending relocatable objects to the server (rather than fully relocated
-/// bits) allows JIT'd code to be cached on the server side and re-used in
-/// subsequent JIT sessions.
-template <typename RPCEndpoint>
-class RemoteObjectClientLayer : public RemoteObjectLayer<RPCEndpoint> {
-private:
-
-  using AddObject = RemoteObjectLayerAPI::AddObject;
-  using RemoveObject = RemoteObjectLayerAPI::RemoveObject;
-  using FindSymbol = RemoteObjectLayerAPI::FindSymbol;
-  using FindSymbolIn = RemoteObjectLayerAPI::FindSymbolIn;
-  using EmitAndFinalize = RemoteObjectLayerAPI::EmitAndFinalize;
-  using Lookup = RemoteObjectLayerAPI::Lookup;
-  using LookupInLogicalDylib = RemoteObjectLayerAPI::LookupInLogicalDylib;
-
-  using RemoteObjectLayer<RPCEndpoint>::teeLog;
-  using RemoteObjectLayer<RPCEndpoint>::badObjectHandleError;
-  using RemoteObjectLayer<RPCEndpoint>::remoteToJITSymbol;
-
-public:
-
-  using ObjHandleT = RemoteObjectLayerAPI::ObjHandleT;
-  using RemoteSymbol = RemoteObjectLayerAPI::RemoteSymbol;
-
-  using ObjectPtr = std::unique_ptr<MemoryBuffer>;
-
-  /// Create a RemoteObjectClientLayer that communicates with a
-  /// RemoteObjectServerLayer instance via the given RPCEndpoint.
-  ///
-  /// The ReportError functor can be used locally log errors that are intended
-  /// to be sent  sent
-  RemoteObjectClientLayer(RPCEndpoint &Remote,
-                          std::function<void(Error)> ReportError)
-      : RemoteObjectLayer<RPCEndpoint>(Remote, std::move(ReportError)) {
-    using ThisT = RemoteObjectClientLayer<RPCEndpoint>;
-    Remote.template addHandler<Lookup>(*this, &ThisT::lookup);
-    Remote.template addHandler<LookupInLogicalDylib>(
-            *this, &ThisT::lookupInLogicalDylib);
-  }
-
-  /// Add an object to the JIT.
-  ///
-  /// @return A handle that can be used to refer to the loaded object (for
-  ///         symbol searching, finalization, freeing memory, etc.).
-  Expected<ObjHandleT>
-  addObject(ObjectPtr ObjBuffer,
-            std::shared_ptr<LegacyJITSymbolResolver> Resolver) {
-    if (auto HandleOrErr =
-            this->Remote.template callB<AddObject>(ObjBuffer->getBuffer())) {
-      auto &Handle = *HandleOrErr;
-      // FIXME: Return an error for this:
-      assert(!Resolvers.count(Handle) && "Handle already in use?");
-      Resolvers[Handle] = std::move(Resolver);
-      return Handle;
-    } else
-      return HandleOrErr.takeError();
-  }
-
-  /// Remove the given object from the JIT.
-  Error removeObject(ObjHandleT H) {
-    return this->Remote.template callB<RemoveObject>(H);
-  }
-
-  /// Search for the given named symbol.
-  JITSymbol findSymbol(StringRef Name, bool ExportedSymbolsOnly) {
-    return remoteToJITSymbol(
-             this->Remote.template callB<FindSymbol>(Name,
-                                                     ExportedSymbolsOnly));
-  }
-
-  /// Search for the given named symbol within the given context.
-  JITSymbol findSymbolIn(ObjHandleT H, StringRef Name, bool ExportedSymbolsOnly) {
-    return remoteToJITSymbol(
-             this->Remote.template callB<FindSymbolIn>(H, Name,
-                                                       ExportedSymbolsOnly));
-  }
-
-  /// Immediately emit and finalize the object with the given handle.
-  Error emitAndFinalize(ObjHandleT H) {
-    return this->Remote.template callB<EmitAndFinalize>(H);
-  }
-
-private:
-
-  Expected<RemoteSymbol> lookup(ObjHandleT H, const std::string &Name) {
-    auto RI = Resolvers.find(H);
-    if (RI != Resolvers.end()) {
-      return this->jitSymbolToRemote(RI->second->findSymbol(Name));
-    } else
-      return teeLog(badObjectHandleError(H));
-  }
-
-  Expected<RemoteSymbol> lookupInLogicalDylib(ObjHandleT H,
-                                              const std::string &Name) {
-    auto RI = Resolvers.find(H);
-    if (RI != Resolvers.end())
-      return this->jitSymbolToRemote(
-               RI->second->findSymbolInLogicalDylib(Name));
-    else
-      return teeLog(badObjectHandleError(H));
-  }
-
-  std::map<remote::ResourceIdMgr::ResourceId,
-           std::shared_ptr<LegacyJITSymbolResolver>>
-      Resolvers;
-};
-
-/// RemoteObjectServerLayer acts as a server and handling RPC calls for the
-/// object layer API from the given RPC connection.
-///
-/// This class can be composed on top of a 'real' object layer (e.g.
-/// RTDyldObjectLinkingLayer) to do the actual work of relocating objects
-/// and making them executable.
-template <typename BaseLayerT, typename RPCEndpoint>
-class RemoteObjectServerLayer : public RemoteObjectLayer<RPCEndpoint> {
-private:
-
-  using ObjHandleT = RemoteObjectLayerAPI::ObjHandleT;
-  using RemoteSymbol = RemoteObjectLayerAPI::RemoteSymbol;
-
-  using AddObject = RemoteObjectLayerAPI::AddObject;
-  using RemoveObject = RemoteObjectLayerAPI::RemoveObject;
-  using FindSymbol = RemoteObjectLayerAPI::FindSymbol;
-  using FindSymbolIn = RemoteObjectLayerAPI::FindSymbolIn;
-  using EmitAndFinalize = RemoteObjectLayerAPI::EmitAndFinalize;
-  using Lookup = RemoteObjectLayerAPI::Lookup;
-  using LookupInLogicalDylib = RemoteObjectLayerAPI::LookupInLogicalDylib;
-
-  using RemoteObjectLayer<RPCEndpoint>::teeLog;
-  using RemoteObjectLayer<RPCEndpoint>::badObjectHandleError;
-  using RemoteObjectLayer<RPCEndpoint>::remoteToJITSymbol;
-
-public:
-
-  /// Create a RemoteObjectServerLayer with the given base layer (which must be
-  /// an object layer), RPC endpoint, and error reporter function.
-  RemoteObjectServerLayer(BaseLayerT &BaseLayer,
-                          RPCEndpoint &Remote,
-                          std::function<void(Error)> ReportError)
-    : RemoteObjectLayer<RPCEndpoint>(Remote, std::move(ReportError)),
-      BaseLayer(BaseLayer), HandleIdMgr(1) {
-    using ThisT = RemoteObjectServerLayer<BaseLayerT, RPCEndpoint>;
-
-    Remote.template addHandler<AddObject>(*this, &ThisT::addObject);
-    Remote.template addHandler<RemoveObject>(*this, &ThisT::removeObject);
-    Remote.template addHandler<FindSymbol>(*this, &ThisT::findSymbol);
-    Remote.template addHandler<FindSymbolIn>(*this, &ThisT::findSymbolIn);
-    Remote.template addHandler<EmitAndFinalize>(*this, &ThisT::emitAndFinalize);
-  }
-
-private:
-
-  class StringMemoryBuffer : public MemoryBuffer {
-  public:
-    StringMemoryBuffer(std::string Buffer)
-      : Buffer(std::move(Buffer)) {
-      init(this->Buffer.data(), this->Buffer.data() + this->Buffer.size(),
-           false);
-    }
-
-    BufferKind getBufferKind() const override { return MemoryBuffer_Malloc; }
-  private:
-    std::string Buffer;
-  };
-
-  JITSymbol lookup(ObjHandleT Id, const std::string &Name) {
-    return remoteToJITSymbol(
-             this->Remote.template callB<Lookup>(Id, Name));
-  }
-
-  JITSymbol lookupInLogicalDylib(ObjHandleT Id, const std::string &Name) {
-    return remoteToJITSymbol(
-             this->Remote.template callB<LookupInLogicalDylib>(Id, Name));
-  }
-
-  Expected<ObjHandleT> addObject(std::string ObjBuffer) {
-    auto Buffer = llvm::make_unique<StringMemoryBuffer>(std::move(ObjBuffer));
-    auto Id = HandleIdMgr.getNext();
-    assert(!BaseLayerHandles.count(Id) && "Id already in use?");
-
-    auto Resolver = createLambdaResolver(
-        [this, Id](const std::string &Name) { return lookup(Id, Name); },
-        [this, Id](const std::string &Name) {
-          return lookupInLogicalDylib(Id, Name);
-        });
-
-    if (auto HandleOrErr =
-            BaseLayer.addObject(std::move(Buffer), std::move(Resolver))) {
-      BaseLayerHandles[Id] = std::move(*HandleOrErr);
-      return Id;
-    } else
-      return teeLog(HandleOrErr.takeError());
-  }
-
-  Error removeObject(ObjHandleT H) {
-    auto HI = BaseLayerHandles.find(H);
-    if (HI != BaseLayerHandles.end()) {
-      if (auto Err = BaseLayer.removeObject(HI->second))
-        return teeLog(std::move(Err));
-      return Error::success();
-    } else
-      return teeLog(badObjectHandleError(H));
-  }
-
-  Expected<RemoteSymbol> findSymbol(const std::string &Name,
-                                    bool ExportedSymbolsOnly) {
-    if (auto Sym = BaseLayer.findSymbol(Name, ExportedSymbolsOnly))
-      return this->jitSymbolToRemote(std::move(Sym));
-    else if (auto Err = Sym.takeError())
-      return teeLog(std::move(Err));
-    return this->nullRemoteSymbol();
-  }
-
-  Expected<RemoteSymbol> findSymbolIn(ObjHandleT H, const std::string &Name,
-                                      bool ExportedSymbolsOnly) {
-    auto HI = BaseLayerHandles.find(H);
-    if (HI != BaseLayerHandles.end()) {
-      if (auto Sym = BaseLayer.findSymbolIn(HI->second, Name, ExportedSymbolsOnly))
-        return this->jitSymbolToRemote(std::move(Sym));
-      else if (auto Err = Sym.takeError())
-        return teeLog(std::move(Err));
-      return this->nullRemoteSymbol();
-    } else
-      return teeLog(badObjectHandleError(H));
-  }
-
-  Error emitAndFinalize(ObjHandleT H) {
-    auto HI = BaseLayerHandles.find(H);
-    if (HI != BaseLayerHandles.end()) {
-      if (auto Err = BaseLayer.emitAndFinalize(HI->second))
-        return teeLog(std::move(Err));
-      return Error::success();
-    } else
-      return teeLog(badObjectHandleError(H));
-  }
-
-  BaseLayerT &BaseLayer;
-  remote::ResourceIdMgr HandleIdMgr;
-  std::map<ObjHandleT, typename BaseLayerT::ObjHandleT> BaseLayerHandles;
-};
-
-} // end namespace orc
-} // end namespace llvm
-
-#endif // LLVM_EXECUTIONENGINE_ORC_REMOTEOBJECTLAYER_H
diff --git a/linux-x64/clang/include/llvm/ExecutionEngine/Orc/Shared/FDRawByteChannel.h b/linux-x64/clang/include/llvm/ExecutionEngine/Orc/Shared/FDRawByteChannel.h
new file mode 100644
index 0000000..3f96fe3
--- /dev/null
+++ b/linux-x64/clang/include/llvm/ExecutionEngine/Orc/Shared/FDRawByteChannel.h
@@ -0,0 +1,79 @@
+//===- FDRawByteChannel.h - File descriptor based byte-channel -*- 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
+//
+//===----------------------------------------------------------------------===//
+//
+// File descriptor based RawByteChannel.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_EXECUTIONENGINE_ORC_SHARED_FDRAWBYTECHANNEL_H
+#define LLVM_EXECUTIONENGINE_ORC_SHARED_FDRAWBYTECHANNEL_H
+
+#include "llvm/ExecutionEngine/Orc/Shared/RawByteChannel.h"
+
+#if !defined(_MSC_VER) && !defined(__MINGW32__)
+#include <unistd.h>
+#else
+#include <io.h>
+#endif
+
+namespace llvm {
+namespace orc {
+namespace shared {
+
+/// Serialization channel that reads from and writes from file descriptors.
+class FDRawByteChannel final : public RawByteChannel {
+public:
+  FDRawByteChannel(int InFD, int OutFD) : InFD(InFD), OutFD(OutFD) {}
+
+  llvm::Error readBytes(char *Dst, unsigned Size) override {
+    assert(Dst && "Attempt to read into null.");
+    ssize_t Completed = 0;
+    while (Completed < static_cast<ssize_t>(Size)) {
+      ssize_t Read = ::read(InFD, Dst + Completed, Size - Completed);
+      if (Read <= 0) {
+        auto ErrNo = errno;
+        if (ErrNo == EAGAIN || ErrNo == EINTR)
+          continue;
+        else
+          return llvm::errorCodeToError(
+              std::error_code(errno, std::generic_category()));
+      }
+      Completed += Read;
+    }
+    return llvm::Error::success();
+  }
+
+  llvm::Error appendBytes(const char *Src, unsigned Size) override {
+    assert(Src && "Attempt to append from null.");
+    ssize_t Completed = 0;
+    while (Completed < static_cast<ssize_t>(Size)) {
+      ssize_t Written = ::write(OutFD, Src + Completed, Size - Completed);
+      if (Written < 0) {
+        auto ErrNo = errno;
+        if (ErrNo == EAGAIN || ErrNo == EINTR)
+          continue;
+        else
+          return llvm::errorCodeToError(
+              std::error_code(errno, std::generic_category()));
+      }
+      Completed += Written;
+    }
+    return llvm::Error::success();
+  }
+
+  llvm::Error send() override { return llvm::Error::success(); }
+
+private:
+  int InFD, OutFD;
+};
+
+} // namespace shared
+} // namespace orc
+} // namespace llvm
+
+#endif // LLVM_EXECUTIONENGINE_ORC_SHARED_FDRAWBYTECHANNEL_H
diff --git a/linux-x64/clang/include/llvm/ExecutionEngine/Orc/RPCUtils.h b/linux-x64/clang/include/llvm/ExecutionEngine/Orc/Shared/RPCUtils.h
similarity index 85%
rename from linux-x64/clang/include/llvm/ExecutionEngine/Orc/RPCUtils.h
rename to linux-x64/clang/include/llvm/ExecutionEngine/Orc/Shared/RPCUtils.h
index 3b11e1b..1c8b8e0 100644
--- a/linux-x64/clang/include/llvm/ExecutionEngine/Orc/RPCUtils.h
+++ b/linux-x64/clang/include/llvm/ExecutionEngine/Orc/Shared/RPCUtils.h
@@ -14,8 +14,8 @@
 //
 //===----------------------------------------------------------------------===//
 
-#ifndef LLVM_EXECUTIONENGINE_ORC_RPCUTILS_H
-#define LLVM_EXECUTIONENGINE_ORC_RPCUTILS_H
+#ifndef LLVM_EXECUTIONENGINE_ORC_SHARED_RPCUTILS_H
+#define LLVM_EXECUTIONENGINE_ORC_SHARED_RPCUTILS_H
 
 #include <map>
 #include <thread>
@@ -23,14 +23,14 @@
 
 #include "llvm/ADT/STLExtras.h"
 #include "llvm/ExecutionEngine/Orc/OrcError.h"
-#include "llvm/ExecutionEngine/Orc/RPCSerialization.h"
+#include "llvm/ExecutionEngine/Orc/Shared/Serialization.h"
 #include "llvm/Support/MSVCErrorWorkarounds.h"
 
 #include <future>
 
 namespace llvm {
 namespace orc {
-namespace rpc {
+namespace shared {
 
 /// Base class of all fatal RPC errors (those that necessarily result in the
 /// termination of the RPC session).
@@ -56,7 +56,7 @@
 /// function id it cannot parse the call.
 template <typename FnIdT, typename SeqNoT>
 class BadFunctionCall
-  : public ErrorInfo<BadFunctionCall<FnIdT, SeqNoT>, RPCFatalError> {
+    : public ErrorInfo<BadFunctionCall<FnIdT, SeqNoT>, RPCFatalError> {
 public:
   static char ID;
 
@@ -68,8 +68,10 @@
   }
 
   void log(raw_ostream &OS) const override {
-    OS << "Call to invalid RPC function id '" << FnId << "' with "
-          "sequence number " << SeqNo;
+    OS << "Call to invalid RPC function id '" << FnId
+       << "' with "
+          "sequence number "
+       << SeqNo;
   }
 
 private:
@@ -89,12 +91,12 @@
 /// a result parser for this sequence number it can't do that.
 template <typename SeqNoT>
 class InvalidSequenceNumberForResponse
-    : public ErrorInfo<InvalidSequenceNumberForResponse<SeqNoT>, RPCFatalError> {
+    : public ErrorInfo<InvalidSequenceNumberForResponse<SeqNoT>,
+                       RPCFatalError> {
 public:
   static char ID;
 
-  InvalidSequenceNumberForResponse(SeqNoT SeqNo)
-      : SeqNo(std::move(SeqNo)) {}
+  InvalidSequenceNumberForResponse(SeqNoT SeqNo) : SeqNo(std::move(SeqNo)) {}
 
   std::error_code convertToErrorCode() const override {
     return orcError(OrcErrorCode::UnexpectedRPCCall);
@@ -103,6 +105,7 @@
   void log(raw_ostream &OS) const override {
     OS << "Response has unknown sequence number " << SeqNo;
   }
+
 private:
   SeqNoT SeqNo;
 };
@@ -131,17 +134,18 @@
   std::error_code convertToErrorCode() const override;
   void log(raw_ostream &OS) const override;
   const std::string &getSignature() const { return Signature; }
+
 private:
   std::string Signature;
 };
 
-template <typename DerivedFunc, typename FnT> class Function;
+template <typename DerivedFunc, typename FnT> class RPCFunction;
 
 // RPC Function class.
 // DerivedFunc should be a user defined class with a static 'getName()' method
 // returning a const char* representing the function's name.
 template <typename DerivedFunc, typename RetT, typename... ArgTs>
-class Function<DerivedFunc, RetT(ArgTs...)> {
+class RPCFunction<DerivedFunc, RetT(ArgTs...)> {
 public:
   /// User defined function type.
   using Type = RetT(ArgTs...);
@@ -154,8 +158,9 @@
     static std::string Name = [] {
       std::string Name;
       raw_string_ostream(Name)
-          << RPCTypeName<RetT>::getName() << " " << DerivedFunc::getName()
-          << "(" << llvm::orc::rpc::RPCTypeNameSequence<ArgTs...>() << ")";
+          << SerializationTypeName<RetT>::getName() << " "
+          << DerivedFunc::getName() << "("
+          << SerializationTypeNameSequence<ArgTs...>() << ")";
       return Name;
     }();
     return Name.data();
@@ -184,8 +189,7 @@
 /// This specialization of RPCFunctionIdAllocator provides a default
 /// implementation for integral types.
 template <typename T>
-class RPCFunctionIdAllocator<
-    T, typename std::enable_if<std::is_integral<T>::value>::type> {
+class RPCFunctionIdAllocator<T, std::enable_if_t<std::is_integral<T>::value>> {
 public:
   static T getInvalidId() { return T(0); }
   static T getResponseId() { return T(1); }
@@ -200,13 +204,12 @@
 namespace detail {
 
 /// Provides a typedef for a tuple containing the decayed argument types.
-template <typename T> class FunctionArgsTuple;
+template <typename T> class RPCFunctionArgsTuple;
 
 template <typename RetT, typename... ArgTs>
-class FunctionArgsTuple<RetT(ArgTs...)> {
+class RPCFunctionArgsTuple<RetT(ArgTs...)> {
 public:
-  using Type = std::tuple<typename std::decay<
-      typename std::remove_reference<ArgTs>::type>::type...>;
+  using Type = std::tuple<std::decay_t<std::remove_reference_t<ArgTs>>...>;
 };
 
 // ResultTraits provides typedefs and utilities specific to the return type
@@ -289,34 +292,28 @@
 
 // Determines whether an RPC function's defined error return type supports
 // error return value.
-template <typename T>
-class SupportsErrorReturn {
+template <typename T> class SupportsErrorReturn {
 public:
   static const bool value = false;
 };
 
-template <>
-class SupportsErrorReturn<Error> {
+template <> class SupportsErrorReturn<Error> {
 public:
   static const bool value = true;
 };
 
-template <typename T>
-class SupportsErrorReturn<Expected<T>> {
+template <typename T> class SupportsErrorReturn<Expected<T>> {
 public:
   static const bool value = true;
 };
 
 // RespondHelper packages return values based on whether or not the declared
 // RPC function return type supports error returns.
-template <bool FuncSupportsErrorReturn>
-class RespondHelper;
+template <bool FuncSupportsErrorReturn> class RespondHelper;
 
 // RespondHelper specialization for functions that support error returns.
-template <>
-class RespondHelper<true> {
+template <> class RespondHelper<true> {
 public:
-
   // Send Expected<T>.
   template <typename WireRetT, typename HandlerRetT, typename ChannelT,
             typename FunctionIdT, typename SequenceNumberT>
@@ -332,13 +329,14 @@
 
     // Serialize the result.
     if (auto Err =
-        SerializationTraits<ChannelT, WireRetT,
-                            Expected<HandlerRetT>>::serialize(
-                                                     C, std::move(ResultOrErr)))
+            SerializationTraits<ChannelT, WireRetT, Expected<HandlerRetT>>::
+                serialize(C, std::move(ResultOrErr)))
       return Err;
 
     // Close the response message.
-    return C.endSendMessage();
+    if (auto Err = C.endSendMessage())
+      return Err;
+    return C.send();
   }
 
   template <typename ChannelT, typename FunctionIdT, typename SequenceNumberT>
@@ -350,16 +348,15 @@
       return Err2;
     if (auto Err2 = serializeSeq(C, std::move(Err)))
       return Err2;
-    return C.endSendMessage();
+    if (auto Err2 = C.endSendMessage())
+      return Err2;
+    return C.send();
   }
-
 };
 
 // RespondHelper specialization for functions that do not support error returns.
-template <>
-class RespondHelper<false> {
+template <> class RespondHelper<false> {
 public:
-
   template <typename WireRetT, typename HandlerRetT, typename ChannelT,
             typename FunctionIdT, typename SequenceNumberT>
   static Error sendResult(ChannelT &C, const FunctionIdT &ResponseId,
@@ -374,12 +371,15 @@
 
     // Serialize the result.
     if (auto Err =
-        SerializationTraits<ChannelT, WireRetT, HandlerRetT>::serialize(
-                                                               C, *ResultOrErr))
+            SerializationTraits<ChannelT, WireRetT, HandlerRetT>::serialize(
+                C, *ResultOrErr))
       return Err;
 
-    // Close the response message.
-    return C.endSendMessage();
+    // End the response message.
+    if (auto Err = C.endSendMessage())
+      return Err;
+
+    return C.send();
   }
 
   template <typename ChannelT, typename FunctionIdT, typename SequenceNumberT>
@@ -389,20 +389,21 @@
       return Err;
     if (auto Err2 = C.startSendMessage(ResponseId, SeqNo))
       return Err2;
-    return C.endSendMessage();
+    if (auto Err2 = C.endSendMessage())
+      return Err2;
+    return C.send();
   }
-
 };
 
-
 // Send a response of the given wire return type (WireRetT) over the
 // channel, with the given sequence number.
 template <typename WireRetT, typename HandlerRetT, typename ChannelT,
           typename FunctionIdT, typename SequenceNumberT>
-Error respond(ChannelT &C, const FunctionIdT &ResponseId,
-              SequenceNumberT SeqNo, Expected<HandlerRetT> ResultOrErr) {
+Error respond(ChannelT &C, const FunctionIdT &ResponseId, SequenceNumberT SeqNo,
+              Expected<HandlerRetT> ResultOrErr) {
   return RespondHelper<SupportsErrorReturn<WireRetT>::value>::
-    template sendResult<WireRetT>(C, ResponseId, SeqNo, std::move(ResultOrErr));
+      template sendResult<WireRetT>(C, ResponseId, SeqNo,
+                                    std::move(ResultOrErr));
 }
 
 // Send an empty response message on the given channel to indicate that
@@ -411,8 +412,8 @@
           typename SequenceNumberT>
 Error respond(ChannelT &C, const FunctionIdT &ResponseId, SequenceNumberT SeqNo,
               Error Err) {
-  return RespondHelper<SupportsErrorReturn<WireRetT>::value>::
-    sendResult(C, ResponseId, SeqNo, std::move(Err));
+  return RespondHelper<SupportsErrorReturn<WireRetT>::value>::sendResult(
+      C, ResponseId, SeqNo, std::move(Err));
 }
 
 // Converts a given type to the equivalent error return type.
@@ -446,7 +447,8 @@
 template <typename FnT> class AsyncHandlerTraits;
 
 template <typename ResultT, typename... ArgTs>
-class AsyncHandlerTraits<Error(std::function<Error(Expected<ResultT>)>, ArgTs...)> {
+class AsyncHandlerTraits<Error(std::function<Error(Expected<ResultT>)>,
+                               ArgTs...)> {
 public:
   using Type = Error(ArgTs...);
   using ResultType = Expected<ResultT>;
@@ -474,18 +476,18 @@
 };
 
 template <typename ResponseHandlerT, typename... ArgTs>
-class AsyncHandlerTraits<Error(ResponseHandlerT, ArgTs...)> :
-    public AsyncHandlerTraits<Error(typename std::decay<ResponseHandlerT>::type,
-                                    ArgTs...)> {};
+class AsyncHandlerTraits<Error(ResponseHandlerT, ArgTs...)>
+    : public AsyncHandlerTraits<Error(std::decay_t<ResponseHandlerT>,
+                                      ArgTs...)> {};
 
 // This template class provides utilities related to RPC function handlers.
 // The base case applies to non-function types (the template class is
 // specialized for function types) and inherits from the appropriate
 // speciilization for the given non-function type's call operator.
 template <typename HandlerT>
-class HandlerTraits : public HandlerTraits<decltype(
-                          &std::remove_reference<HandlerT>::type::operator())> {
-};
+class HandlerTraits
+    : public HandlerTraits<
+          decltype(&std::remove_reference<HandlerT>::type::operator())> {};
 
 // Traits for handlers with a given function type.
 template <typename RetT, typename... ArgTs>
@@ -502,7 +504,7 @@
   static typename WrappedHandlerReturn<RetT>::Type
   unpackAndRun(HandlerT &Handler, std::tuple<TArgTs...> &Args) {
     return unpackAndRunHelper(Handler, Args,
-                              llvm::index_sequence_for<TArgTs...>());
+                              std::index_sequence_for<TArgTs...>());
   }
 
   // Call the given handler with the given arguments.
@@ -510,23 +512,22 @@
   static Error unpackAndRunAsync(HandlerT &Handler, ResponderT &Responder,
                                  std::tuple<TArgTs...> &Args) {
     return unpackAndRunAsyncHelper(Handler, Responder, Args,
-                                   llvm::index_sequence_for<TArgTs...>());
+                                   std::index_sequence_for<TArgTs...>());
   }
 
   // Call the given handler with the given arguments.
   template <typename HandlerT>
-  static typename std::enable_if<
-      std::is_void<typename HandlerTraits<HandlerT>::ReturnType>::value,
-      Error>::type
-  run(HandlerT &Handler, ArgTs &&... Args) {
+  static std::enable_if_t<
+      std::is_void<typename HandlerTraits<HandlerT>::ReturnType>::value, Error>
+  run(HandlerT &Handler, ArgTs &&...Args) {
     Handler(std::move(Args)...);
     return Error::success();
   }
 
   template <typename HandlerT, typename... TArgTs>
-  static typename std::enable_if<
+  static std::enable_if_t<
       !std::is_void<typename HandlerTraits<HandlerT>::ReturnType>::value,
-      typename HandlerTraits<HandlerT>::ReturnType>::type
+      typename HandlerTraits<HandlerT>::ReturnType>
   run(HandlerT &Handler, TArgTs... Args) {
     return Handler(std::move(Args)...);
   }
@@ -540,14 +541,13 @@
   // Deserialize arguments from the channel.
   template <typename ChannelT, typename... CArgTs>
   static Error deserializeArgs(ChannelT &C, std::tuple<CArgTs...> &Args) {
-    return deserializeArgsHelper(C, Args,
-                                 llvm::index_sequence_for<CArgTs...>());
+    return deserializeArgsHelper(C, Args, std::index_sequence_for<CArgTs...>());
   }
 
 private:
   template <typename ChannelT, typename... CArgTs, size_t... Indexes>
   static Error deserializeArgsHelper(ChannelT &C, std::tuple<CArgTs...> &Args,
-                                     llvm::index_sequence<Indexes...> _) {
+                                     std::index_sequence<Indexes...> _) {
     return SequenceSerialization<ChannelT, ArgTs...>::deserialize(
         C, std::get<Indexes>(Args)...);
   }
@@ -556,26 +556,24 @@
   static typename WrappedHandlerReturn<
       typename HandlerTraits<HandlerT>::ReturnType>::Type
   unpackAndRunHelper(HandlerT &Handler, ArgTuple &Args,
-                     llvm::index_sequence<Indexes...>) {
+                     std::index_sequence<Indexes...>) {
     return run(Handler, std::move(std::get<Indexes>(Args))...);
   }
 
-
   template <typename HandlerT, typename ResponderT, typename ArgTuple,
             size_t... Indexes>
   static typename WrappedHandlerReturn<
       typename HandlerTraits<HandlerT>::ReturnType>::Type
   unpackAndRunAsyncHelper(HandlerT &Handler, ResponderT &Responder,
-                          ArgTuple &Args,
-                          llvm::index_sequence<Indexes...>) {
+                          ArgTuple &Args, std::index_sequence<Indexes...>) {
     return run(Handler, Responder, std::move(std::get<Indexes>(Args))...);
   }
 };
 
 // Handler traits for free functions.
 template <typename RetT, typename... ArgTs>
-class HandlerTraits<RetT(*)(ArgTs...)>
-  : public HandlerTraits<RetT(ArgTs...)> {};
+class HandlerTraits<RetT (*)(ArgTs...)> : public HandlerTraits<RetT(ArgTs...)> {
+};
 
 // Handler traits for class methods (especially call operators for lambdas).
 template <typename Class, typename RetT, typename... ArgTs>
@@ -711,9 +709,8 @@
         typename HandlerTraits<HandlerT>::Type>::ArgType;
     HandlerArgType Result((typename HandlerArgType::value_type()));
 
-    if (auto Err =
-            SerializationTraits<ChannelT, Expected<FuncRetT>,
-                                HandlerArgType>::deserialize(C, Result))
+    if (auto Err = SerializationTraits<ChannelT, Expected<FuncRetT>,
+                                       HandlerArgType>::deserialize(C, Result))
       return Err;
     if (auto Err = C.endReceiveMessage())
       return Err;
@@ -743,11 +740,15 @@
   // to the user defined handler.
   Error handleResponse(ChannelT &C) override {
     Error Result = Error::success();
-    if (auto Err =
-            SerializationTraits<ChannelT, Error, Error>::deserialize(C, Result))
+    if (auto Err = SerializationTraits<ChannelT, Error, Error>::deserialize(
+            C, Result)) {
+      consumeError(std::move(Result));
       return Err;
-    if (auto Err = C.endReceiveMessage())
+    }
+    if (auto Err = C.endReceiveMessage()) {
+      consumeError(std::move(Result));
       return Err;
+    }
     return Handler(std::move(Result));
   }
 
@@ -767,7 +768,7 @@
 // Create a ResponseHandler from a given user handler.
 template <typename ChannelT, typename FuncRetT, typename HandlerT>
 std::unique_ptr<ResponseHandler<ChannelT>> createResponseHandler(HandlerT H) {
-  return llvm::make_unique<ResponseHandlerImpl<ChannelT, FuncRetT, HandlerT>>(
+  return std::make_unique<ResponseHandlerImpl<ChannelT, FuncRetT, HandlerT>>(
       std::move(H));
 }
 
@@ -779,7 +780,7 @@
   using MethodT = RetT (ClassT::*)(ArgTs...);
   MemberFnWrapper(ClassT &Instance, MethodT Method)
       : Instance(Instance), Method(Method) {}
-  RetT operator()(ArgTs &&... Args) {
+  RetT operator()(ArgTs &&...Args) {
     return (Instance.*Method)(std::move(Args)...);
   }
 
@@ -797,10 +798,9 @@
 template <typename ArgT, typename... ArgTs>
 class ReadArgs<ArgT, ArgTs...> : public ReadArgs<ArgTs...> {
 public:
-  ReadArgs(ArgT &Arg, ArgTs &... Args)
-      : ReadArgs<ArgTs...>(Args...), Arg(Arg) {}
+  ReadArgs(ArgT &Arg, ArgTs &...Args) : ReadArgs<ArgTs...>(Args...), Arg(Arg) {}
 
-  Error operator()(ArgT &ArgVal, ArgTs &... ArgVals) {
+  Error operator()(ArgT &ArgVal, ArgTs &...ArgVals) {
     this->Arg = std::move(ArgVal);
     return ReadArgs<ArgTs...>::operator()(ArgVals...);
   }
@@ -865,8 +865,8 @@
 template <template <class, class> class P, typename T1Sig, typename T2Sig>
 class RPCArgTypeCheck {
 public:
-  using T1Tuple = typename FunctionArgsTuple<T1Sig>::Type;
-  using T2Tuple = typename FunctionArgsTuple<T2Sig>::Type;
+  using T1Tuple = typename RPCFunctionArgsTuple<T1Sig>::Type;
+  using T2Tuple = typename RPCFunctionArgsTuple<T2Sig>::Type;
 
   static_assert(std::tuple_size<T1Tuple>::value >=
                     std::tuple_size<T2Tuple>::value,
@@ -884,12 +884,12 @@
   using S = SerializationTraits<ChannelT, WireT, ConcreteT>;
 
   template <typename T>
-  static std::true_type
-  check(typename std::enable_if<
-        std::is_same<decltype(T::serialize(std::declval<ChannelT &>(),
-                                           std::declval<const ConcreteT &>())),
-                     Error>::value,
-        void *>::type);
+  static std::true_type check(
+      std::enable_if_t<std::is_same<decltype(T::serialize(
+                                        std::declval<ChannelT &>(),
+                                        std::declval<const ConcreteT &>())),
+                                    Error>::value,
+                       void *>);
 
   template <typename> static std::false_type check(...);
 
@@ -904,11 +904,11 @@
 
   template <typename T>
   static std::true_type
-  check(typename std::enable_if<
-        std::is_same<decltype(T::deserialize(std::declval<ChannelT &>(),
-                                             std::declval<ConcreteT &>())),
-                     Error>::value,
-        void *>::type);
+      check(std::enable_if_t<
+            std::is_same<decltype(T::deserialize(std::declval<ChannelT &>(),
+                                                 std::declval<ConcreteT &>())),
+                         Error>::value,
+            void *>);
 
   template <typename> static std::false_type check(...);
 
@@ -930,18 +930,18 @@
           typename SequenceNumberT>
 class RPCEndpointBase {
 protected:
-  class OrcRPCInvalid : public Function<OrcRPCInvalid, void()> {
+  class OrcRPCInvalid : public RPCFunction<OrcRPCInvalid, void()> {
   public:
     static const char *getName() { return "__orc_rpc$invalid"; }
   };
 
-  class OrcRPCResponse : public Function<OrcRPCResponse, void()> {
+  class OrcRPCResponse : public RPCFunction<OrcRPCResponse, void()> {
   public:
     static const char *getName() { return "__orc_rpc$response"; }
   };
 
   class OrcRPCNegotiate
-      : public Function<OrcRPCNegotiate, FunctionIdT(std::string)> {
+      : public RPCFunction<OrcRPCNegotiate, FunctionIdT(std::string)> {
   public:
     static const char *getName() { return "__orc_rpc$negotiate"; }
   };
@@ -987,7 +987,6 @@
         [this](const std::string &Name) { return handleNegotiate(Name); });
   }
 
-
   /// Negotiate a function id for Func with the other end of the channel.
   template <typename Func> Error negotiateFunction(bool Retry = false) {
     return getRemoteFunctionId<Func>(true, Retry).takeError();
@@ -999,7 +998,7 @@
   /// or an Error (if Func::ReturnType is void). The handler will be called
   /// with an error if the return value is abandoned due to a channel error.
   template <typename Func, typename HandlerT, typename... ArgTs>
-  Error appendCallAsync(HandlerT Handler, const ArgTs &... Args) {
+  Error appendCallAsync(HandlerT Handler, const ArgTs &...Args) {
 
     static_assert(
         detail::RPCArgTypeCheck<CanSerializeCheck, typename Func::Type,
@@ -1029,8 +1028,8 @@
 
       // Install the user handler.
       PendingResponses[SeqNo] =
-        detail::createResponseHandler<ChannelT, typename Func::ReturnType>(
-            std::move(Handler));
+          detail::createResponseHandler<ChannelT, typename Func::ReturnType>(
+              std::move(Handler));
     }
 
     // Open the function call message.
@@ -1058,7 +1057,7 @@
   Error sendAppendedCalls() { return C.send(); };
 
   template <typename Func, typename HandlerT, typename... ArgTs>
-  Error callAsync(HandlerT Handler, const ArgTs &... Args) {
+  Error callAsync(HandlerT Handler, const ArgTs &...Args) {
     if (auto Err = appendCallAsync<Func>(std::move(Handler), Args...))
       return Err;
     return C.send();
@@ -1097,7 +1096,7 @@
   ///     /* Handle Args */ ;
   ///
   template <typename... ArgTs>
-  static detail::ReadArgs<ArgTs...> readArgs(ArgTs &... Args) {
+  static detail::ReadArgs<ArgTs...> readArgs(ArgTs &...Args) {
     return detail::ReadArgs<ArgTs...>(Args...);
   }
 
@@ -1121,8 +1120,7 @@
 
   /// Remove the handler for the given function.
   /// A handler must currently be registered for this function.
-  template <typename Func>
-  void removeHandler() {
+  template <typename Func> void removeHandler() {
     auto IdItr = LocalFunctionIds.find(Func::getPrototype());
     assert(IdItr != LocalFunctionIds.end() &&
            "Function does not have a registered handler");
@@ -1133,12 +1131,9 @@
   }
 
   /// Clear all handlers.
-  void clearHandlers() {
-    Handlers.clear();
-  }
+  void clearHandlers() { Handlers.clear(); }
 
 protected:
-
   FunctionIdT getInvalidFunctionId() const {
     return FnIdAllocator.getInvalidId();
   }
@@ -1161,12 +1156,12 @@
   template <typename Func, typename HandlerT>
   void addAsyncHandlerImpl(HandlerT Handler) {
 
-    static_assert(detail::RPCArgTypeCheck<
-                      CanDeserializeCheck, typename Func::Type,
-                      typename detail::AsyncHandlerTraits<
-                        typename detail::HandlerTraits<HandlerT>::Type
-                      >::Type>::value,
-                  "");
+    static_assert(
+        detail::RPCArgTypeCheck<
+            CanDeserializeCheck, typename Func::Type,
+            typename detail::AsyncHandlerTraits<
+                typename detail::HandlerTraits<HandlerT>::Type>::Type>::value,
+        "");
 
     FunctionIdT NewFnId = FnIdAllocator.template allocate<Func>();
     LocalFunctionIds[Func::getPrototype()] = NewFnId;
@@ -1190,8 +1185,8 @@
         // Unlock the pending results map to prevent recursive lock.
         Lock.unlock();
         abandonPendingResponses();
-        return make_error<
-                 InvalidSequenceNumberForResponse<SequenceNumberT>>(SeqNo);
+        return make_error<InvalidSequenceNumberForResponse<SequenceNumberT>>(
+            SeqNo);
       }
     }
 
@@ -1234,7 +1229,7 @@
     if (DoNegotiate) {
       auto &Impl = static_cast<ImplT &>(*this);
       if (auto RemoteIdOrErr =
-          Impl.template callB<OrcRPCNegotiate>(Func::getPrototype())) {
+              Impl.template callB<OrcRPCNegotiate>(Func::getPrototype())) {
         RemoteFunctionIds[Func::getPrototype()] = *RemoteIdOrErr;
         if (*RemoteIdOrErr == getInvalidFunctionId())
           return make_error<CouldNotNegotiate>(Func::getPrototype());
@@ -1257,9 +1252,8 @@
     return [this, Handler](ChannelT &Channel,
                            SequenceNumberT SeqNo) mutable -> Error {
       // Start by deserializing the arguments.
-      using ArgsTuple =
-          typename detail::FunctionArgsTuple<
-            typename detail::HandlerTraits<HandlerT>::Type>::Type;
+      using ArgsTuple = typename detail::RPCFunctionArgsTuple<
+          typename detail::HandlerTraits<HandlerT>::Type>::Type;
       auto Args = std::make_shared<ArgsTuple>();
 
       if (auto Err =
@@ -1291,9 +1285,9 @@
                            SequenceNumberT SeqNo) mutable -> Error {
       // Start by deserializing the arguments.
       using AHTraits = detail::AsyncHandlerTraits<
-                         typename detail::HandlerTraits<HandlerT>::Type>;
+          typename detail::HandlerTraits<HandlerT>::Type>;
       using ArgsTuple =
-          typename detail::FunctionArgsTuple<typename AHTraits::Type>::Type;
+          typename detail::RPCFunctionArgsTuple<typename AHTraits::Type>::Type;
       auto Args = std::make_shared<ArgsTuple>();
 
       if (auto Err =
@@ -1312,11 +1306,11 @@
 
       using HTraits = detail::HandlerTraits<HandlerT>;
       using FuncReturn = typename Func::ReturnType;
-      auto Responder =
-        [this, SeqNo](typename AHTraits::ResultType RetVal) -> Error {
-          return detail::respond<FuncReturn>(C, ResponseId, SeqNo,
-                                             std::move(RetVal));
-        };
+      auto Responder = [this,
+                        SeqNo](typename AHTraits::ResultType RetVal) -> Error {
+        return detail::respond<FuncReturn>(C, ResponseId, SeqNo,
+                                           std::move(RetVal));
+      };
 
       return HTraits::unpackAndRunAsync(Handler, Responder, *Args);
     };
@@ -1349,17 +1343,16 @@
           MultiThreadedRPCEndpoint<ChannelT, FunctionIdT, SequenceNumberT>,
           ChannelT, FunctionIdT, SequenceNumberT> {
 private:
-  using BaseClass =
-      detail::RPCEndpointBase<
-        MultiThreadedRPCEndpoint<ChannelT, FunctionIdT, SequenceNumberT>,
-        ChannelT, FunctionIdT, SequenceNumberT>;
+  using BaseClass = detail::RPCEndpointBase<
+      MultiThreadedRPCEndpoint<ChannelT, FunctionIdT, SequenceNumberT>,
+      ChannelT, FunctionIdT, SequenceNumberT>;
 
 public:
   MultiThreadedRPCEndpoint(ChannelT &C, bool LazyAutoNegotiation)
       : BaseClass(C, LazyAutoNegotiation) {}
 
   /// Add a handler for the given RPC function.
-  /// This installs the given handler functor for the given RPC Function, and
+  /// This installs the given handler functor for the given RPCFunction, and
   /// makes the RPC function available for negotiation/calling from the remote.
   template <typename Func, typename HandlerT>
   void addHandler(HandlerT Handler) {
@@ -1370,7 +1363,7 @@
   template <typename Func, typename ClassT, typename RetT, typename... ArgTs>
   void addHandler(ClassT &Object, RetT (ClassT::*Method)(ArgTs...)) {
     addHandler<Func>(
-      detail::MemberFnWrapper<ClassT, RetT, ArgTs...>(Object, Method));
+        detail::MemberFnWrapper<ClassT, RetT, ArgTs...>(Object, Method));
   }
 
   template <typename Func, typename HandlerT>
@@ -1382,7 +1375,7 @@
   template <typename Func, typename ClassT, typename RetT, typename... ArgTs>
   void addAsyncHandler(ClassT &Object, RetT (ClassT::*Method)(ArgTs...)) {
     addAsyncHandler<Func>(
-      detail::MemberFnWrapper<ClassT, RetT, ArgTs...>(Object, Method));
+        detail::MemberFnWrapper<ClassT, RetT, ArgTs...>(Object, Method));
   }
 
   /// Return type for non-blocking call primitives.
@@ -1398,19 +1391,17 @@
   /// result. In multi-threaded mode the appendCallNB method, which does not
   /// return the sequence numeber, should be preferred.
   template <typename Func, typename... ArgTs>
-  Expected<NonBlockingCallResult<Func>> appendCallNB(const ArgTs &... Args) {
+  Expected<NonBlockingCallResult<Func>> appendCallNB(const ArgTs &...Args) {
     using RTraits = detail::ResultTraits<typename Func::ReturnType>;
     using ErrorReturn = typename RTraits::ErrorReturnType;
     using ErrorReturnPromise = typename RTraits::ReturnPromiseType;
 
-    // FIXME: Stack allocate and move this into the handler once LLVM builds
-    //        with C++14.
-    auto Promise = std::make_shared<ErrorReturnPromise>();
-    auto FutureResult = Promise->get_future();
+    ErrorReturnPromise Promise;
+    auto FutureResult = Promise.get_future();
 
     if (auto Err = this->template appendCallAsync<Func>(
-            [Promise](ErrorReturn RetOrErr) {
-              Promise->set_value(std::move(RetOrErr));
+            [Promise = std::move(Promise)](ErrorReturn RetOrErr) mutable {
+              Promise.set_value(std::move(RetOrErr));
               return Error::success();
             },
             Args...)) {
@@ -1423,7 +1414,7 @@
   /// The same as appendCallNBWithSeq, except that it calls C.send() to
   /// flush the channel after serializing the call.
   template <typename Func, typename... ArgTs>
-  Expected<NonBlockingCallResult<Func>> callNB(const ArgTs &... Args) {
+  Expected<NonBlockingCallResult<Func>> callNB(const ArgTs &...Args) {
     auto Result = appendCallNB<Func>(Args...);
     if (!Result)
       return Result;
@@ -1444,7 +1435,7 @@
   template <typename Func, typename... ArgTs,
             typename AltRetT = typename Func::ReturnType>
   typename detail::ResultTraits<AltRetT>::ErrorReturnType
-  callB(const ArgTs &... Args) {
+  callB(const ArgTs &...Args) {
     if (auto FutureResOrErr = callNB<Func>(Args...))
       return FutureResOrErr->get();
     else
@@ -1467,10 +1458,9 @@
           SingleThreadedRPCEndpoint<ChannelT, FunctionIdT, SequenceNumberT>,
           ChannelT, FunctionIdT, SequenceNumberT> {
 private:
-  using BaseClass =
-      detail::RPCEndpointBase<
-        SingleThreadedRPCEndpoint<ChannelT, FunctionIdT, SequenceNumberT>,
-        ChannelT, FunctionIdT, SequenceNumberT>;
+  using BaseClass = detail::RPCEndpointBase<
+      SingleThreadedRPCEndpoint<ChannelT, FunctionIdT, SequenceNumberT>,
+      ChannelT, FunctionIdT, SequenceNumberT>;
 
 public:
   SingleThreadedRPCEndpoint(ChannelT &C, bool LazyAutoNegotiation)
@@ -1496,13 +1486,13 @@
   template <typename Func, typename ClassT, typename RetT, typename... ArgTs>
   void addAsyncHandler(ClassT &Object, RetT (ClassT::*Method)(ArgTs...)) {
     addAsyncHandler<Func>(
-      detail::MemberFnWrapper<ClassT, RetT, ArgTs...>(Object, Method));
+        detail::MemberFnWrapper<ClassT, RetT, ArgTs...>(Object, Method));
   }
 
   template <typename Func, typename... ArgTs,
             typename AltRetT = typename Func::ReturnType>
   typename detail::ResultTraits<AltRetT>::ErrorReturnType
-  callB(const ArgTs &... Args) {
+  callB(const ArgTs &...Args) {
     bool ReceivedResponse = false;
     using ResultType = typename detail::ResultTraits<AltRetT>::ErrorReturnType;
     auto Result = detail::ResultTraits<AltRetT>::createBlankErrorReturnValue();
@@ -1523,6 +1513,12 @@
       return std::move(Err);
     }
 
+    if (auto Err = this->C.send()) {
+      detail::ResultTraits<typename Func::ReturnType>::consumeAbandoned(
+          std::move(Result));
+      return std::move(Err);
+    }
+
     while (!ReceivedResponse) {
       if (auto Err = this->handleOne()) {
         detail::ResultTraits<typename Func::ReturnType>::consumeAbandoned(
@@ -1536,13 +1532,12 @@
 };
 
 /// Asynchronous dispatch for a function on an RPC endpoint.
-template <typename RPCClass, typename Func>
-class RPCAsyncDispatch {
+template <typename RPCClass, typename Func> class RPCAsyncDispatch {
 public:
   RPCAsyncDispatch(RPCClass &Endpoint) : Endpoint(Endpoint) {}
 
   template <typename HandlerT, typename... ArgTs>
-  Error operator()(HandlerT Handler, const ArgTs &... Args) const {
+  Error operator()(HandlerT Handler, const ArgTs &...Args) const {
     return Endpoint.template appendCallAsync<Func>(std::move(Handler), Args...);
   }
 
@@ -1560,7 +1555,6 @@
 ///        waited on as a group.
 class ParallelCallGroup {
 public:
-
   ParallelCallGroup() = default;
   ParallelCallGroup(const ParallelCallGroup &) = delete;
   ParallelCallGroup &operator=(const ParallelCallGroup &) = delete;
@@ -1568,7 +1562,7 @@
   /// Make as asynchronous call.
   template <typename AsyncDispatcher, typename HandlerT, typename... ArgTs>
   Error call(const AsyncDispatcher &AsyncDispatch, HandlerT Handler,
-             const ArgTs &... Args) {
+             const ArgTs &...Args) {
     // Increment the count of outstanding calls. This has to happen before
     // we invoke the call, as the handler may (depending on scheduling)
     // be run immediately on another thread, and we don't want the decrement
@@ -1582,8 +1576,7 @@
     // outstanding calls count, then poke the condition variable.
     using ArgType = typename detail::ResponseHandlerArg<
         typename detail::HandlerTraits<HandlerT>::Type>::ArgType;
-    // FIXME: Move handler into wrapped handler once we have C++14.
-    auto WrappedHandler = [this, Handler](ArgType Arg) {
+    auto WrappedHandler = [this, Handler = std::move(Handler)](ArgType Arg) {
       auto Err = Handler(std::move(Arg));
       std::unique_lock<std::mutex> Lock(M);
       --NumOutstandingCalls;
@@ -1608,70 +1601,57 @@
   uint32_t NumOutstandingCalls = 0;
 };
 
-/// Convenience class for grouping RPC Functions into APIs that can be
+/// Convenience class for grouping RPCFunctions into APIs that can be
 ///        negotiated as a block.
 ///
-template <typename... Funcs>
-class APICalls {
+template <typename... Funcs> class APICalls {
 public:
-
   /// Test whether this API contains Function F.
-  template <typename F>
-  class Contains {
+  template <typename F> class Contains {
   public:
     static const bool value = false;
   };
 
   /// Negotiate all functions in this API.
-  template <typename RPCEndpoint>
-  static Error negotiate(RPCEndpoint &R) {
+  template <typename RPCEndpoint> static Error negotiate(RPCEndpoint &R) {
     return Error::success();
   }
 };
 
-template <typename Func, typename... Funcs>
-class APICalls<Func, Funcs...> {
+template <typename Func, typename... Funcs> class APICalls<Func, Funcs...> {
 public:
-
-  template <typename F>
-  class Contains {
+  template <typename F> class Contains {
   public:
     static const bool value = std::is_same<F, Func>::value |
                               APICalls<Funcs...>::template Contains<F>::value;
   };
 
-  template <typename RPCEndpoint>
-  static Error negotiate(RPCEndpoint &R) {
+  template <typename RPCEndpoint> static Error negotiate(RPCEndpoint &R) {
     if (auto Err = R.template negotiateFunction<Func>())
       return Err;
     return APICalls<Funcs...>::negotiate(R);
   }
-
 };
 
 template <typename... InnerFuncs, typename... Funcs>
 class APICalls<APICalls<InnerFuncs...>, Funcs...> {
 public:
-
-  template <typename F>
-  class Contains {
+  template <typename F> class Contains {
   public:
     static const bool value =
-      APICalls<InnerFuncs...>::template Contains<F>::value |
-      APICalls<Funcs...>::template Contains<F>::value;
+        APICalls<InnerFuncs...>::template Contains<F>::value |
+        APICalls<Funcs...>::template Contains<F>::value;
   };
 
-  template <typename RPCEndpoint>
-  static Error negotiate(RPCEndpoint &R) {
+  template <typename RPCEndpoint> static Error negotiate(RPCEndpoint &R) {
     if (auto Err = APICalls<InnerFuncs...>::negotiate(R))
       return Err;
     return APICalls<Funcs...>::negotiate(R);
   }
-
 };
 
-} // end namespace rpc
+} // end namespace shared
 } // end namespace orc
 } // end namespace llvm
 
-#endif
+#endif // LLVM_EXECUTIONENGINE_ORC_SHARED_RPCUTILS_H
diff --git a/linux-x64/clang/include/llvm/ExecutionEngine/Orc/RawByteChannel.h b/linux-x64/clang/include/llvm/ExecutionEngine/Orc/Shared/RawByteChannel.h
similarity index 74%
rename from linux-x64/clang/include/llvm/ExecutionEngine/Orc/RawByteChannel.h
rename to linux-x64/clang/include/llvm/ExecutionEngine/Orc/Shared/RawByteChannel.h
index 46b7c59..2ee4719 100644
--- a/linux-x64/clang/include/llvm/ExecutionEngine/Orc/RawByteChannel.h
+++ b/linux-x64/clang/include/llvm/ExecutionEngine/Orc/Shared/RawByteChannel.h
@@ -1,4 +1,4 @@
-//===- llvm/ExecutionEngine/Orc/RawByteChannel.h ----------------*- C++ -*-===//
+//===- RawByteChannel.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.
@@ -6,11 +6,11 @@
 //
 //===----------------------------------------------------------------------===//
 
-#ifndef LLVM_EXECUTIONENGINE_ORC_RAWBYTECHANNEL_H
-#define LLVM_EXECUTIONENGINE_ORC_RAWBYTECHANNEL_H
+#ifndef LLVM_EXECUTIONENGINE_ORC_SHARED_RAWBYTECHANNEL_H
+#define LLVM_EXECUTIONENGINE_ORC_SHARED_RAWBYTECHANNEL_H
 
 #include "llvm/ADT/StringRef.h"
-#include "llvm/ExecutionEngine/Orc/RPCSerialization.h"
+#include "llvm/ExecutionEngine/Orc/Shared/Serialization.h"
 #include "llvm/Support/Endian.h"
 #include "llvm/Support/Error.h"
 #include <cstdint>
@@ -20,9 +20,9 @@
 
 namespace llvm {
 namespace orc {
-namespace rpc {
+namespace shared {
 
-/// Interface for byte-streams to be used with RPC.
+/// Interface for byte-streams to be used with ORC Serialization.
 class RawByteChannel {
 public:
   virtual ~RawByteChannel() = default;
@@ -87,13 +87,13 @@
 template <typename ChannelT, typename T>
 class SerializationTraits<
     ChannelT, T, T,
-    typename std::enable_if<
+    std::enable_if_t<
         std::is_base_of<RawByteChannel, ChannelT>::value &&
         (std::is_same<T, uint8_t>::value || std::is_same<T, int8_t>::value ||
          std::is_same<T, uint16_t>::value || std::is_same<T, int16_t>::value ||
          std::is_same<T, uint32_t>::value || std::is_same<T, int32_t>::value ||
          std::is_same<T, uint64_t>::value || std::is_same<T, int64_t>::value ||
-         std::is_same<T, char>::value)>::type> {
+         std::is_same<T, char>::value)>> {
 public:
   static Error serialize(ChannelT &C, T V) {
     support::endian::byte_swap<T, support::big>(V);
@@ -109,14 +109,13 @@
 };
 
 template <typename ChannelT>
-class SerializationTraits<ChannelT, bool, bool,
-                          typename std::enable_if<std::is_base_of<
-                              RawByteChannel, ChannelT>::value>::type> {
+class SerializationTraits<
+    ChannelT, bool, bool,
+    std::enable_if_t<std::is_base_of<RawByteChannel, ChannelT>::value>> {
 public:
   static Error serialize(ChannelT &C, bool V) {
     uint8_t Tmp = V ? 1 : 0;
-    if (auto Err =
-          C.appendBytes(reinterpret_cast<const char *>(&Tmp), 1))
+    if (auto Err = C.appendBytes(reinterpret_cast<const char *>(&Tmp), 1))
       return Err;
     return Error::success();
   }
@@ -131,11 +130,11 @@
 };
 
 template <typename ChannelT>
-class SerializationTraits<ChannelT, std::string, StringRef,
-                          typename std::enable_if<std::is_base_of<
-                              RawByteChannel, ChannelT>::value>::type> {
+class SerializationTraits<
+    ChannelT, std::string, StringRef,
+    std::enable_if_t<std::is_base_of<RawByteChannel, ChannelT>::value>> {
 public:
-  /// RPC channel serialization for std::strings.
+  /// Serialization channel serialization for std::strings.
   static Error serialize(RawByteChannel &C, StringRef S) {
     if (auto Err = serializeSeq(C, static_cast<uint64_t>(S.size())))
       return Err;
@@ -144,11 +143,11 @@
 };
 
 template <typename ChannelT, typename T>
-class SerializationTraits<ChannelT, std::string, T,
-                          typename std::enable_if<
-                            std::is_base_of<RawByteChannel, ChannelT>::value &&
-                            (std::is_same<T, const char*>::value ||
-                             std::is_same<T, char*>::value)>::type> {
+class SerializationTraits<
+    ChannelT, std::string, T,
+    std::enable_if_t<std::is_base_of<RawByteChannel, ChannelT>::value &&
+                     (std::is_same<T, const char *>::value ||
+                      std::is_same<T, char *>::value)>> {
 public:
   static Error serialize(RawByteChannel &C, const char *S) {
     return SerializationTraits<ChannelT, std::string, StringRef>::serialize(C,
@@ -157,17 +156,17 @@
 };
 
 template <typename ChannelT>
-class SerializationTraits<ChannelT, std::string, std::string,
-                          typename std::enable_if<std::is_base_of<
-                              RawByteChannel, ChannelT>::value>::type> {
+class SerializationTraits<
+    ChannelT, std::string, std::string,
+    std::enable_if_t<std::is_base_of<RawByteChannel, ChannelT>::value>> {
 public:
-  /// RPC channel serialization for std::strings.
+  /// Serialization channel serialization for std::strings.
   static Error serialize(RawByteChannel &C, const std::string &S) {
     return SerializationTraits<ChannelT, std::string, StringRef>::serialize(C,
                                                                             S);
   }
 
-  /// RPC channel deserialization for std::strings.
+  /// Serialization channel deserialization for std::strings.
   static Error deserialize(RawByteChannel &C, std::string &S) {
     uint64_t Count = 0;
     if (auto Err = deserializeSeq(C, Count))
@@ -177,8 +176,8 @@
   }
 };
 
-} // end namespace rpc
+} // end namespace shared
 } // end namespace orc
 } // end namespace llvm
 
-#endif // LLVM_EXECUTIONENGINE_ORC_RAWBYTECHANNEL_H
+#endif // LLVM_EXECUTIONENGINE_ORC_SHARED_RAWBYTECHANNEL_H
diff --git a/linux-x64/clang/include/llvm/ExecutionEngine/Orc/RPCSerialization.h b/linux-x64/clang/include/llvm/ExecutionEngine/Orc/Shared/Serialization.h
similarity index 61%
rename from linux-x64/clang/include/llvm/ExecutionEngine/Orc/RPCSerialization.h
rename to linux-x64/clang/include/llvm/ExecutionEngine/Orc/Shared/Serialization.h
index 07c7471..64a4ab8 100644
--- a/linux-x64/clang/include/llvm/ExecutionEngine/Orc/RPCSerialization.h
+++ b/linux-x64/clang/include/llvm/ExecutionEngine/Orc/Shared/Serialization.h
@@ -1,4 +1,4 @@
-//===- llvm/ExecutionEngine/Orc/RPCSerialization.h --------------*- C++ -*-===//
+//===- Serialization.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.
@@ -6,10 +6,12 @@
 //
 //===----------------------------------------------------------------------===//
 
-#ifndef LLVM_EXECUTIONENGINE_ORC_RPCSERIALIZATION_H
-#define LLVM_EXECUTIONENGINE_ORC_RPCSERIALIZATION_H
+#ifndef LLVM_EXECUTIONENGINE_ORC_SHARED_SERIALIZATION_H
+#define LLVM_EXECUTIONENGINE_ORC_SHARED_SERIALIZATION_H
 
-#include "OrcError.h"
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ExecutionEngine/Orc/OrcError.h"
 #include "llvm/Support/thread.h"
 #include <map>
 #include <mutex>
@@ -20,118 +22,104 @@
 
 namespace llvm {
 namespace orc {
-namespace rpc {
+namespace shared {
 
-template <typename T>
-class RPCTypeName;
+template <typename T> class SerializationTypeName;
 
 /// TypeNameSequence is a utility for rendering sequences of types to a string
 /// by rendering each type, separated by ", ".
-template <typename... ArgTs> class RPCTypeNameSequence {};
+template <typename... ArgTs> class SerializationTypeNameSequence {};
 
 /// Render an empty TypeNameSequence to an ostream.
 template <typename OStream>
-OStream &operator<<(OStream &OS, const RPCTypeNameSequence<> &V) {
+OStream &operator<<(OStream &OS, const SerializationTypeNameSequence<> &V) {
   return OS;
 }
 
 /// Render a TypeNameSequence of a single type to an ostream.
 template <typename OStream, typename ArgT>
-OStream &operator<<(OStream &OS, const RPCTypeNameSequence<ArgT> &V) {
-  OS << RPCTypeName<ArgT>::getName();
+OStream &operator<<(OStream &OS, const SerializationTypeNameSequence<ArgT> &V) {
+  OS << SerializationTypeName<ArgT>::getName();
   return OS;
 }
 
 /// Render a TypeNameSequence of more than one type to an ostream.
 template <typename OStream, typename ArgT1, typename ArgT2, typename... ArgTs>
-OStream&
-operator<<(OStream &OS, const RPCTypeNameSequence<ArgT1, ArgT2, ArgTs...> &V) {
-  OS << RPCTypeName<ArgT1>::getName() << ", "
-     << RPCTypeNameSequence<ArgT2, ArgTs...>();
+OStream &
+operator<<(OStream &OS,
+           const SerializationTypeNameSequence<ArgT1, ArgT2, ArgTs...> &V) {
+  OS << SerializationTypeName<ArgT1>::getName() << ", "
+     << SerializationTypeNameSequence<ArgT2, ArgTs...>();
   return OS;
 }
 
-template <>
-class RPCTypeName<void> {
+template <> class SerializationTypeName<void> {
 public:
-  static const char* getName() { return "void"; }
+  static const char *getName() { return "void"; }
 };
 
-template <>
-class RPCTypeName<int8_t> {
+template <> class SerializationTypeName<int8_t> {
 public:
-  static const char* getName() { return "int8_t"; }
+  static const char *getName() { return "int8_t"; }
 };
 
-template <>
-class RPCTypeName<uint8_t> {
+template <> class SerializationTypeName<uint8_t> {
 public:
-  static const char* getName() { return "uint8_t"; }
+  static const char *getName() { return "uint8_t"; }
 };
 
-template <>
-class RPCTypeName<int16_t> {
+template <> class SerializationTypeName<int16_t> {
 public:
-  static const char* getName() { return "int16_t"; }
+  static const char *getName() { return "int16_t"; }
 };
 
-template <>
-class RPCTypeName<uint16_t> {
+template <> class SerializationTypeName<uint16_t> {
 public:
-  static const char* getName() { return "uint16_t"; }
+  static const char *getName() { return "uint16_t"; }
 };
 
-template <>
-class RPCTypeName<int32_t> {
+template <> class SerializationTypeName<int32_t> {
 public:
-  static const char* getName() { return "int32_t"; }
+  static const char *getName() { return "int32_t"; }
 };
 
-template <>
-class RPCTypeName<uint32_t> {
+template <> class SerializationTypeName<uint32_t> {
 public:
-  static const char* getName() { return "uint32_t"; }
+  static const char *getName() { return "uint32_t"; }
 };
 
-template <>
-class RPCTypeName<int64_t> {
+template <> class SerializationTypeName<int64_t> {
 public:
-  static const char* getName() { return "int64_t"; }
+  static const char *getName() { return "int64_t"; }
 };
 
-template <>
-class RPCTypeName<uint64_t> {
+template <> class SerializationTypeName<uint64_t> {
 public:
-  static const char* getName() { return "uint64_t"; }
+  static const char *getName() { return "uint64_t"; }
 };
 
-template <>
-class RPCTypeName<bool> {
+template <> class SerializationTypeName<bool> {
 public:
-  static const char* getName() { return "bool"; }
+  static const char *getName() { return "bool"; }
 };
 
-template <>
-class RPCTypeName<std::string> {
+template <> class SerializationTypeName<std::string> {
 public:
-  static const char* getName() { return "std::string"; }
+  static const char *getName() { return "std::string"; }
 };
 
-template <>
-class RPCTypeName<Error> {
+template <> class SerializationTypeName<Error> {
 public:
-  static const char* getName() { return "Error"; }
+  static const char *getName() { return "Error"; }
 };
 
-template <typename T>
-class RPCTypeName<Expected<T>> {
+template <typename T> class SerializationTypeName<Expected<T>> {
 public:
-  static const char* getName() {
+  static const char *getName() {
     static std::string Name = [] {
       std::string Name;
-      raw_string_ostream(Name) << "Expected<"
-                               << RPCTypeNameSequence<T>()
-                               << ">";
+      raw_string_ostream(Name)
+          << "Expected<" << SerializationTypeNameSequence<T>() << ">";
       return Name;
     }();
     return Name.data();
@@ -139,67 +127,78 @@
 };
 
 template <typename T1, typename T2>
-class RPCTypeName<std::pair<T1, T2>> {
-public:
-  static const char* getName() {
-    static std::string Name = [] {
-      std::string Name;
-      raw_string_ostream(Name) << "std::pair<" << RPCTypeNameSequence<T1, T2>()
-                               << ">";
-      return Name;
-    }();
-    return Name.data();
-  }
-};
-
-template <typename... ArgTs>
-class RPCTypeName<std::tuple<ArgTs...>> {
-public:
-  static const char* getName() {
-    static std::string Name = [] {
-      std::string Name;
-      raw_string_ostream(Name) << "std::tuple<"
-                               << RPCTypeNameSequence<ArgTs...>() << ">";
-      return Name;
-    }();
-    return Name.data();
-  }
-};
-
-template <typename T>
-class RPCTypeName<std::vector<T>> {
-public:
-  static const char*getName() {
-    static std::string Name = [] {
-      std::string Name;
-      raw_string_ostream(Name) << "std::vector<" << RPCTypeName<T>::getName()
-                               << ">";
-      return Name;
-    }();
-    return Name.data();
-  }
-};
-
-template <typename T> class RPCTypeName<std::set<T>> {
+class SerializationTypeName<std::pair<T1, T2>> {
 public:
   static const char *getName() {
     static std::string Name = [] {
       std::string Name;
       raw_string_ostream(Name)
-          << "std::set<" << RPCTypeName<T>::getName() << ">";
+          << "std::pair<" << SerializationTypeNameSequence<T1, T2>() << ">";
       return Name;
     }();
     return Name.data();
   }
 };
 
-template <typename K, typename V> class RPCTypeName<std::map<K, V>> {
+template <typename... ArgTs> class SerializationTypeName<std::tuple<ArgTs...>> {
 public:
   static const char *getName() {
     static std::string Name = [] {
       std::string Name;
       raw_string_ostream(Name)
-          << "std::map<" << RPCTypeNameSequence<K, V>() << ">";
+          << "std::tuple<" << SerializationTypeNameSequence<ArgTs...>() << ">";
+      return Name;
+    }();
+    return Name.data();
+  }
+};
+
+template <typename T> class SerializationTypeName<Optional<T>> {
+public:
+  static const char *getName() {
+    static std::string Name = [] {
+      std::string Name;
+      raw_string_ostream(Name)
+          << "Optional<" << SerializationTypeName<T>::getName() << ">";
+      return Name;
+    }();
+    return Name.data();
+  }
+};
+
+template <typename T> class SerializationTypeName<std::vector<T>> {
+public:
+  static const char *getName() {
+    static std::string Name = [] {
+      std::string Name;
+      raw_string_ostream(Name)
+          << "std::vector<" << SerializationTypeName<T>::getName() << ">";
+      return Name;
+    }();
+    return Name.data();
+  }
+};
+
+template <typename T> class SerializationTypeName<std::set<T>> {
+public:
+  static const char *getName() {
+    static std::string Name = [] {
+      std::string Name;
+      raw_string_ostream(Name)
+          << "std::set<" << SerializationTypeName<T>::getName() << ">";
+      return Name;
+    }();
+    return Name.data();
+  }
+};
+
+template <typename K, typename V> class SerializationTypeName<std::map<K, V>> {
+public:
+  static const char *getName() {
+    static std::string Name = [] {
+      std::string Name;
+      raw_string_ostream(Name)
+          << "std::map<" << SerializationTypeNameSequence<K, V>() << ">";
       return Name;
     }();
     return Name.data();
@@ -230,9 +229,9 @@
 ///
 ///   template <DerivedChannelT>
 ///   class SerializationTraits<DerivedChannelT, bool,
-///         typename std::enable_if<
+///         std::enable_if_t<
 ///           std::is_base_of<VirtChannel, DerivedChannel>::value
-///         >::type> {
+///         >> {
 ///   public:
 ///     static const char* getName() { ... };
 ///   }
@@ -242,8 +241,7 @@
           typename ConcreteType = WireType, typename = void>
 class SerializationTraits;
 
-template <typename ChannelT>
-class SequenceTraits {
+template <typename ChannelT> class SequenceTraits {
 public:
   static Error emitSeparator(ChannelT &C) { return Error::success(); }
   static Error consumeSeparator(ChannelT &C) { return Error::success(); }
@@ -258,11 +256,9 @@
 /// is a SerializationTraits specialization
 /// SerializeTraits<ChannelT, ArgT, CArgT> with methods that can serialize the
 /// caller argument to over-the-wire value.
-template <typename ChannelT, typename... ArgTs>
-class SequenceSerialization;
+template <typename ChannelT, typename... ArgTs> class SequenceSerialization;
 
-template <typename ChannelT>
-class SequenceSerialization<ChannelT> {
+template <typename ChannelT> class SequenceSerialization<ChannelT> {
 public:
   static Error serialize(ChannelT &C) { return Error::success(); }
   static Error deserialize(ChannelT &C) { return Error::success(); }
@@ -271,16 +267,12 @@
 template <typename ChannelT, typename ArgT>
 class SequenceSerialization<ChannelT, ArgT> {
 public:
-
-  template <typename CArgT>
-  static Error serialize(ChannelT &C, CArgT &&CArg) {
-    return SerializationTraits<ChannelT, ArgT,
-                               typename std::decay<CArgT>::type>::
-             serialize(C, std::forward<CArgT>(CArg));
+  template <typename CArgT> static Error serialize(ChannelT &C, CArgT &&CArg) {
+    return SerializationTraits<ChannelT, ArgT, std::decay_t<CArgT>>::serialize(
+        C, std::forward<CArgT>(CArg));
   }
 
-  template <typename CArgT>
-  static Error deserialize(ChannelT &C, CArgT &CArg) {
+  template <typename CArgT> static Error deserialize(ChannelT &C, CArgT &CArg) {
     return SerializationTraits<ChannelT, ArgT, CArgT>::deserialize(C, CArg);
   }
 };
@@ -288,25 +280,22 @@
 template <typename ChannelT, typename ArgT, typename... ArgTs>
 class SequenceSerialization<ChannelT, ArgT, ArgTs...> {
 public:
-
   template <typename CArgT, typename... CArgTs>
-  static Error serialize(ChannelT &C, CArgT &&CArg,
-                         CArgTs &&... CArgs) {
+  static Error serialize(ChannelT &C, CArgT &&CArg, CArgTs &&...CArgs) {
     if (auto Err =
-        SerializationTraits<ChannelT, ArgT, typename std::decay<CArgT>::type>::
-          serialize(C, std::forward<CArgT>(CArg)))
+            SerializationTraits<ChannelT, ArgT, std::decay_t<CArgT>>::serialize(
+                C, std::forward<CArgT>(CArg)))
       return Err;
     if (auto Err = SequenceTraits<ChannelT>::emitSeparator(C))
       return Err;
-    return SequenceSerialization<ChannelT, ArgTs...>::
-             serialize(C, std::forward<CArgTs>(CArgs)...);
+    return SequenceSerialization<ChannelT, ArgTs...>::serialize(
+        C, std::forward<CArgTs>(CArgs)...);
   }
 
   template <typename CArgT, typename... CArgTs>
-  static Error deserialize(ChannelT &C, CArgT &CArg,
-                           CArgTs &... CArgs) {
+  static Error deserialize(ChannelT &C, CArgT &CArg, CArgTs &...CArgs) {
     if (auto Err =
-        SerializationTraits<ChannelT, ArgT, CArgT>::deserialize(C, CArg))
+            SerializationTraits<ChannelT, ArgT, CArgT>::deserialize(C, CArg))
       return Err;
     if (auto Err = SequenceTraits<ChannelT>::consumeSeparator(C))
       return Err;
@@ -315,25 +304,23 @@
 };
 
 template <typename ChannelT, typename... ArgTs>
-Error serializeSeq(ChannelT &C, ArgTs &&... Args) {
-  return SequenceSerialization<ChannelT, typename std::decay<ArgTs>::type...>::
-           serialize(C, std::forward<ArgTs>(Args)...);
+Error serializeSeq(ChannelT &C, ArgTs &&...Args) {
+  return SequenceSerialization<ChannelT, std::decay_t<ArgTs>...>::serialize(
+      C, std::forward<ArgTs>(Args)...);
 }
 
 template <typename ChannelT, typename... ArgTs>
-Error deserializeSeq(ChannelT &C, ArgTs &... Args) {
+Error deserializeSeq(ChannelT &C, ArgTs &...Args) {
   return SequenceSerialization<ChannelT, ArgTs...>::deserialize(C, Args...);
 }
 
-template <typename ChannelT>
-class SerializationTraits<ChannelT, Error> {
+template <typename ChannelT> class SerializationTraits<ChannelT, Error> {
 public:
-
   using WrappedErrorSerializer =
-    std::function<Error(ChannelT &C, const ErrorInfoBase&)>;
+      std::function<Error(ChannelT &C, const ErrorInfoBase &)>;
 
   using WrappedErrorDeserializer =
-    std::function<Error(ChannelT &C, Error &Err)>;
+      std::function<Error(ChannelT &C, Error &Err)>;
 
   template <typename ErrorInfoT, typename SerializeFtor,
             typename DeserializeFtor>
@@ -344,24 +331,23 @@
 
     const std::string *KeyName = nullptr;
     {
-      // We're abusing the stability of std::map here: We take a reference to the
-      // key of the deserializers map to save us from duplicating the string in
-      // the serializer. This should be changed to use a stringpool if we switch
-      // to a map type that may move keys in memory.
+      // We're abusing the stability of std::map here: We take a reference to
+      // the key of the deserializers map to save us from duplicating the string
+      // in the serializer. This should be changed to use a stringpool if we
+      // switch to a map type that may move keys in memory.
       std::lock_guard<std::recursive_mutex> Lock(DeserializersMutex);
-      auto I =
-        Deserializers.insert(Deserializers.begin(),
-                             std::make_pair(std::move(Name),
-                                            std::move(Deserialize)));
+      auto I = Deserializers.insert(
+          Deserializers.begin(),
+          std::make_pair(std::move(Name), std::move(Deserialize)));
       KeyName = &I->first;
     }
 
     {
       assert(KeyName != nullptr && "No keyname pointer");
       std::lock_guard<std::recursive_mutex> Lock(SerializersMutex);
-      // FIXME: Move capture Serialize once we have C++14.
       Serializers[ErrorInfoT::classID()] =
-          [KeyName, Serialize](ChannelT &C, const ErrorInfoBase &EIB) -> Error {
+          [KeyName, Serialize = std::move(Serialize)](
+              ChannelT &C, const ErrorInfoBase &EIB) -> Error {
         assert(EIB.dynamicClassID() == ErrorInfoT::classID() &&
                "Serializer called for wrong error type");
         if (auto Err = serializeSeq(C, *KeyName))
@@ -377,13 +363,12 @@
     if (!Err)
       return serializeSeq(C, std::string());
 
-    return handleErrors(std::move(Err),
-                        [&C](const ErrorInfoBase &EIB) {
-                          auto SI = Serializers.find(EIB.dynamicClassID());
-                          if (SI == Serializers.end())
-                            return serializeAsStringError(C, EIB);
-                          return (SI->second)(C, EIB);
-                        });
+    return handleErrors(std::move(Err), [&C](const ErrorInfoBase &EIB) {
+      auto SI = Serializers.find(EIB.dynamicClassID());
+      if (SI == Serializers.end())
+        return serializeAsStringError(C, EIB);
+      return (SI->second)(C, EIB);
+    });
   }
 
   static Error deserialize(ChannelT &C, Error &Err) {
@@ -405,7 +390,6 @@
   }
 
 private:
-
   static Error serializeAsStringError(ChannelT &C, const ErrorInfoBase &EIB) {
     std::string ErrMsg;
     {
@@ -418,7 +402,7 @@
 
   static std::recursive_mutex SerializersMutex;
   static std::recursive_mutex DeserializersMutex;
-  static std::map<const void*, WrappedErrorSerializer> Serializers;
+  static std::map<const void *, WrappedErrorSerializer> Serializers;
   static std::map<std::string, WrappedErrorDeserializer> Deserializers;
 };
 
@@ -429,14 +413,14 @@
 std::recursive_mutex SerializationTraits<ChannelT, Error>::DeserializersMutex;
 
 template <typename ChannelT>
-std::map<const void*,
+std::map<const void *,
          typename SerializationTraits<ChannelT, Error>::WrappedErrorSerializer>
-SerializationTraits<ChannelT, Error>::Serializers;
+    SerializationTraits<ChannelT, Error>::Serializers;
 
 template <typename ChannelT>
-std::map<std::string,
-         typename SerializationTraits<ChannelT, Error>::WrappedErrorDeserializer>
-SerializationTraits<ChannelT, Error>::Deserializers;
+std::map<std::string, typename SerializationTraits<
+                          ChannelT, Error>::WrappedErrorDeserializer>
+    SerializationTraits<ChannelT, Error>::Deserializers;
 
 /// Registers a serializer and deserializer for the given error type on the
 /// given channel type.
@@ -445,32 +429,29 @@
 void registerErrorSerialization(std::string Name, SerializeFtor &&Serialize,
                                 DeserializeFtor &&Deserialize) {
   SerializationTraits<ChannelT, Error>::template registerErrorType<ErrorInfoT>(
-    std::move(Name),
-    std::forward<SerializeFtor>(Serialize),
-    std::forward<DeserializeFtor>(Deserialize));
+      std::move(Name), std::forward<SerializeFtor>(Serialize),
+      std::forward<DeserializeFtor>(Deserialize));
 }
 
 /// Registers serialization/deserialization for StringError.
-template <typename ChannelT>
-void registerStringError() {
+template <typename ChannelT> void registerStringError() {
   static bool AlreadyRegistered = false;
   if (!AlreadyRegistered) {
     registerErrorSerialization<ChannelT, StringError>(
-      "StringError",
-      [](ChannelT &C, const StringError &SE) {
-        return serializeSeq(C, SE.getMessage());
-      },
-      [](ChannelT &C, Error &Err) -> Error {
-        ErrorAsOutParameter EAO(&Err);
-        std::string Msg;
-        if (auto E2 = deserializeSeq(C, Msg))
-          return E2;
-        Err =
-          make_error<StringError>(std::move(Msg),
-                                  orcError(
-                                    OrcErrorCode::UnknownErrorCodeFromRemote));
-        return Error::success();
-      });
+        "StringError",
+        [](ChannelT &C, const StringError &SE) {
+          return serializeSeq(C, SE.getMessage());
+        },
+        [](ChannelT &C, Error &Err) -> Error {
+          ErrorAsOutParameter EAO(&Err);
+          std::string Msg;
+          if (auto E2 = deserializeSeq(C, Msg))
+            return E2;
+          Err = make_error<StringError>(
+              std::move(Msg),
+              orcError(OrcErrorCode::UnknownErrorCodeFromRemote));
+          return Error::success();
+        });
     AlreadyRegistered = true;
   }
 }
@@ -479,7 +460,6 @@
 template <typename ChannelT, typename T1, typename T2>
 class SerializationTraits<ChannelT, Expected<T1>, Expected<T2>> {
 public:
-
   static Error serialize(ChannelT &C, Expected<T2> &&ValOrErr) {
     if (ValOrErr) {
       if (auto Err = serializeSeq(C, true))
@@ -510,7 +490,6 @@
 template <typename ChannelT, typename T1, typename T2>
 class SerializationTraits<ChannelT, Expected<T1>, T2> {
 public:
-
   static Error serialize(ChannelT &C, T2 &&Val) {
     return serializeSeq(C, Expected<T2>(std::forward<T2>(Val)));
   }
@@ -520,7 +499,6 @@
 template <typename ChannelT, typename T>
 class SerializationTraits<ChannelT, Expected<T>, Error> {
 public:
-
   static Error serialize(ChannelT &C, Error &&Err) {
     return serializeSeq(C, Expected<T>(std::move(Err)));
   }
@@ -548,38 +526,61 @@
 template <typename ChannelT, typename... ArgTs>
 class SerializationTraits<ChannelT, std::tuple<ArgTs...>> {
 public:
-
   /// RPC channel serialization for std::tuple.
   static Error serialize(ChannelT &C, const std::tuple<ArgTs...> &V) {
-    return serializeTupleHelper(C, V, llvm::index_sequence_for<ArgTs...>());
+    return serializeTupleHelper(C, V, std::index_sequence_for<ArgTs...>());
   }
 
   /// RPC channel deserialization for std::tuple.
   static Error deserialize(ChannelT &C, std::tuple<ArgTs...> &V) {
-    return deserializeTupleHelper(C, V, llvm::index_sequence_for<ArgTs...>());
+    return deserializeTupleHelper(C, V, std::index_sequence_for<ArgTs...>());
   }
 
 private:
   // Serialization helper for std::tuple.
   template <size_t... Is>
   static Error serializeTupleHelper(ChannelT &C, const std::tuple<ArgTs...> &V,
-                                    llvm::index_sequence<Is...> _) {
+                                    std::index_sequence<Is...> _) {
     return serializeSeq(C, std::get<Is>(V)...);
   }
 
   // Serialization helper for std::tuple.
   template <size_t... Is>
   static Error deserializeTupleHelper(ChannelT &C, std::tuple<ArgTs...> &V,
-                                      llvm::index_sequence<Is...> _) {
+                                      std::index_sequence<Is...> _) {
     return deserializeSeq(C, std::get<Is>(V)...);
   }
 };
 
+template <typename ChannelT, typename T>
+class SerializationTraits<ChannelT, Optional<T>> {
+public:
+  /// Serialize an Optional<T>.
+  static Error serialize(ChannelT &C, const Optional<T> &O) {
+    if (auto Err = serializeSeq(C, O != None))
+      return Err;
+    if (O)
+      if (auto Err = serializeSeq(C, *O))
+        return Err;
+    return Error::success();
+  }
+
+  /// Deserialize an Optional<T>.
+  static Error deserialize(ChannelT &C, Optional<T> &O) {
+    bool HasValue = false;
+    if (auto Err = deserializeSeq(C, HasValue))
+      return Err;
+    if (HasValue)
+      if (auto Err = deserializeSeq(C, *O))
+        return Err;
+    return Error::success();
+  };
+};
+
 /// SerializationTraits default specialization for std::vector.
 template <typename ChannelT, typename T>
 class SerializationTraits<ChannelT, std::vector<T>> {
 public:
-
   /// Serialize a std::vector<T> from std::vector<T>.
   static Error serialize(ChannelT &C, const std::vector<T> &V) {
     if (auto Err = serializeSeq(C, static_cast<uint64_t>(V.size())))
@@ -610,6 +611,22 @@
   }
 };
 
+/// Enable vector serialization from an ArrayRef.
+template <typename ChannelT, typename T>
+class SerializationTraits<ChannelT, std::vector<T>, ArrayRef<T>> {
+public:
+  static Error serialize(ChannelT &C, ArrayRef<T> V) {
+    if (auto Err = serializeSeq(C, static_cast<uint64_t>(V.size())))
+      return Err;
+
+    for (const auto &E : V)
+      if (auto Err = serializeSeq(C, E))
+        return Err;
+
+    return Error::success();
+  }
+};
+
 template <typename ChannelT, typename T, typename T2>
 class SerializationTraits<ChannelT, std::set<T>, std::set<T2>> {
 public:
@@ -696,8 +713,57 @@
   }
 };
 
-} // end namespace rpc
+template <typename ChannelT, typename K, typename V, typename K2, typename V2>
+class SerializationTraits<ChannelT, std::map<K, V>, DenseMap<K2, V2>> {
+public:
+  /// Serialize a std::map<K, V> from DenseMap<K2, V2>.
+  static Error serialize(ChannelT &C, const DenseMap<K2, V2> &M) {
+    if (auto Err = serializeSeq(C, static_cast<uint64_t>(M.size())))
+      return Err;
+
+    for (auto &E : M) {
+      if (auto Err =
+              SerializationTraits<ChannelT, K, K2>::serialize(C, E.first))
+        return Err;
+
+      if (auto Err =
+              SerializationTraits<ChannelT, V, V2>::serialize(C, E.second))
+        return Err;
+    }
+
+    return Error::success();
+  }
+
+  /// Serialize a std::map<K, V> from DenseMap<K2, V2>.
+  static Error deserialize(ChannelT &C, DenseMap<K2, V2> &M) {
+    assert(M.empty() && "Expected default-constructed map to deserialize into");
+
+    uint64_t Count = 0;
+    if (auto Err = deserializeSeq(C, Count))
+      return Err;
+
+    while (Count-- != 0) {
+      std::pair<K2, V2> Val;
+      if (auto Err =
+              SerializationTraits<ChannelT, K, K2>::deserialize(C, Val.first))
+        return Err;
+
+      if (auto Err =
+              SerializationTraits<ChannelT, V, V2>::deserialize(C, Val.second))
+        return Err;
+
+      auto Added = M.insert(Val).second;
+      if (!Added)
+        return make_error<StringError>("Duplicate element in deserialized map",
+                                       orcError(OrcErrorCode::UnknownORCError));
+    }
+
+    return Error::success();
+  }
+};
+
+} // namespace shared
 } // end namespace orc
 } // end namespace llvm
 
-#endif // LLVM_EXECUTIONENGINE_ORC_RPCSERIALIZATION_H
+#endif // LLVM_EXECUTIONENGINE_ORC_RPC_RPCSERIALIZATION_H
diff --git a/linux-x64/clang/include/llvm/ExecutionEngine/Orc/Shared/TargetProcessControlTypes.h b/linux-x64/clang/include/llvm/ExecutionEngine/Orc/Shared/TargetProcessControlTypes.h
new file mode 100644
index 0000000..f43b929
--- /dev/null
+++ b/linux-x64/clang/include/llvm/ExecutionEngine/Orc/Shared/TargetProcessControlTypes.h
@@ -0,0 +1,174 @@
+//===--- TargetProcessControlTypes.h -- Shared Core/TPC types ---*- 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
+//
+//===----------------------------------------------------------------------===//
+//
+// TargetProcessControl types that are used by both the Orc and
+// OrcTargetProcess libraries.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_EXECUTIONENGINE_ORC_SHARED_TARGETPROCESSCONTROLTYPES_H
+#define LLVM_EXECUTIONENGINE_ORC_SHARED_TARGETPROCESSCONTROLTYPES_H
+
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/ExecutionEngine/JITSymbol.h"
+#include "llvm/ExecutionEngine/Orc/Core.h"
+
+#include <vector>
+
+namespace llvm {
+namespace orc {
+namespace tpctypes {
+
+template <typename T> struct UIntWrite {
+  UIntWrite() = default;
+  UIntWrite(JITTargetAddress Address, T Value)
+      : Address(Address), Value(Value) {}
+
+  JITTargetAddress Address = 0;
+  T Value = 0;
+};
+
+/// Describes a write to a uint8_t.
+using UInt8Write = UIntWrite<uint8_t>;
+
+/// Describes a write to a uint16_t.
+using UInt16Write = UIntWrite<uint16_t>;
+
+/// Describes a write to a uint32_t.
+using UInt32Write = UIntWrite<uint32_t>;
+
+/// Describes a write to a uint64_t.
+using UInt64Write = UIntWrite<uint64_t>;
+
+/// Describes a write to a buffer.
+/// For use with TargetProcessControl::MemoryAccess objects.
+struct BufferWrite {
+  BufferWrite() = default;
+  BufferWrite(JITTargetAddress Address, StringRef Buffer)
+      : Address(Address), Buffer(Buffer) {}
+
+  JITTargetAddress Address = 0;
+  StringRef Buffer;
+};
+
+/// A handle used to represent a loaded dylib in the target process.
+using DylibHandle = JITTargetAddress;
+
+/// A pair of a dylib and a set of symbols to be looked up.
+struct LookupRequest {
+  LookupRequest(DylibHandle Handle, const SymbolLookupSet &Symbols)
+      : Handle(Handle), Symbols(Symbols) {}
+  DylibHandle Handle;
+  const SymbolLookupSet &Symbols;
+};
+
+using LookupResult = std::vector<JITTargetAddress>;
+
+/// Either a uint8_t array or a uint8_t*.
+union CWrapperFunctionResultData {
+  uint8_t Value[8];
+  uint8_t *ValuePtr;
+};
+
+/// C ABI compatible wrapper function result.
+///
+/// This can be safely returned from extern "C" functions, but should be used
+/// to construct a WrapperFunctionResult for safety.
+struct CWrapperFunctionResult {
+  uint64_t Size;
+  CWrapperFunctionResultData Data;
+  void (*Destroy)(CWrapperFunctionResultData Data, uint64_t Size);
+};
+
+/// C++ wrapper function result: Same as CWrapperFunctionResult but
+/// auto-releases memory.
+class WrapperFunctionResult {
+public:
+  /// Create a default WrapperFunctionResult.
+  WrapperFunctionResult() { zeroInit(R); }
+
+  /// Create a WrapperFunctionResult from a CWrapperFunctionResult. This
+  /// instance takes ownership of the result object and will automatically
+  /// call the Destroy member upon destruction.
+  WrapperFunctionResult(CWrapperFunctionResult R) : R(R) {}
+
+  WrapperFunctionResult(const WrapperFunctionResult &) = delete;
+  WrapperFunctionResult &operator=(const WrapperFunctionResult &) = delete;
+
+  WrapperFunctionResult(WrapperFunctionResult &&Other) {
+    zeroInit(R);
+    std::swap(R, Other.R);
+  }
+
+  WrapperFunctionResult &operator=(WrapperFunctionResult &&Other) {
+    CWrapperFunctionResult Tmp;
+    zeroInit(Tmp);
+    std::swap(Tmp, Other.R);
+    std::swap(R, Tmp);
+    return *this;
+  }
+
+  ~WrapperFunctionResult() {
+    if (R.Destroy)
+      R.Destroy(R.Data, R.Size);
+  }
+
+  /// Relinquish ownership of and return the CWrapperFunctionResult.
+  CWrapperFunctionResult release() {
+    CWrapperFunctionResult Tmp;
+    zeroInit(Tmp);
+    std::swap(R, Tmp);
+    return Tmp;
+  }
+
+  /// Get an ArrayRef covering the data in the result.
+  ArrayRef<uint8_t> getData() const {
+    if (R.Size <= 8)
+      return ArrayRef<uint8_t>(R.Data.Value, R.Size);
+    return ArrayRef<uint8_t>(R.Data.ValuePtr, R.Size);
+  }
+
+  /// Create a WrapperFunctionResult from the given integer, provided its
+  /// size is no greater than 64 bits.
+  template <typename T,
+            typename _ = std::enable_if_t<std::is_integral<T>::value &&
+                                          sizeof(T) <= sizeof(uint64_t)>>
+  static WrapperFunctionResult from(T Value) {
+    CWrapperFunctionResult R;
+    R.Size = sizeof(T);
+    memcpy(&R.Data.Value, Value, R.Size);
+    R.Destroy = nullptr;
+    return R;
+  }
+
+  /// Create a WrapperFunctionResult from the given string.
+  static WrapperFunctionResult from(StringRef S);
+
+  /// Always free Data.ValuePtr by calling free on it.
+  static void destroyWithFree(CWrapperFunctionResultData Data, uint64_t Size);
+
+  /// Always free Data.ValuePtr by calling delete[] on it.
+  static void destroyWithDeleteArray(CWrapperFunctionResultData Data,
+                                     uint64_t Size);
+
+private:
+  static void zeroInit(CWrapperFunctionResult &R) {
+    R.Size = 0;
+    R.Data.ValuePtr = nullptr;
+    R.Destroy = nullptr;
+  }
+
+  CWrapperFunctionResult R;
+};
+
+} // end namespace tpctypes
+} // end namespace orc
+} // end namespace llvm
+
+#endif // LLVM_EXECUTIONENGINE_ORC_SHARED_TARGETPROCESSCONTROLTYPES_H
diff --git a/linux-x64/clang/include/llvm/ExecutionEngine/Orc/SpeculateAnalyses.h b/linux-x64/clang/include/llvm/ExecutionEngine/Orc/SpeculateAnalyses.h
new file mode 100644
index 0000000..cf57b63
--- /dev/null
+++ b/linux-x64/clang/include/llvm/ExecutionEngine/Orc/SpeculateAnalyses.h
@@ -0,0 +1,84 @@
+//===-- SpeculateAnalyses.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
+//
+//===----------------------------------------------------------------------===//
+// \file
+/// Contains the Analyses and Result Interpretation to select likely functions
+/// to Speculatively compile before they are called. [Purely Experimentation]
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_EXECUTIONENGINE_ORC_SPECULATEANALYSES_H
+#define LLVM_EXECUTIONENGINE_ORC_SPECULATEANALYSES_H
+
+#include "llvm/Analysis/BranchProbabilityInfo.h"
+#include "llvm/ExecutionEngine/Orc/Core.h"
+#include "llvm/ExecutionEngine/Orc/Speculation.h"
+
+#include <vector>
+
+namespace llvm {
+
+namespace orc {
+
+// Provides common code.
+class SpeculateQuery {
+protected:
+  void findCalles(const BasicBlock *, DenseSet<StringRef> &);
+  bool isStraightLine(const Function &F);
+
+public:
+  using ResultTy = Optional<DenseMap<StringRef, DenseSet<StringRef>>>;
+};
+
+// Direct calls in high frequency basic blocks are extracted.
+class BlockFreqQuery : public SpeculateQuery {
+  size_t numBBToGet(size_t);
+
+public:
+  // Find likely next executables based on IR Block Frequency
+  ResultTy operator()(Function &F);
+};
+
+// This Query generates a sequence of basic blocks which follows the order of
+// execution.
+// A handful of BB with higher block frequencies are taken, then path to entry
+// and end BB are discovered by traversing up & down the CFG.
+class SequenceBBQuery : public SpeculateQuery {
+  struct WalkDirection {
+    bool Upward = true, Downward = true;
+    // the block associated contain a call
+    bool CallerBlock = false;
+  };
+
+public:
+  using VisitedBlocksInfoTy = DenseMap<const BasicBlock *, WalkDirection>;
+  using BlockListTy = SmallVector<const BasicBlock *, 8>;
+  using BackEdgesInfoTy =
+      SmallVector<std::pair<const BasicBlock *, const BasicBlock *>, 8>;
+  using BlockFreqInfoTy =
+      SmallVector<std::pair<const BasicBlock *, uint64_t>, 8>;
+
+private:
+  std::size_t getHottestBlocks(std::size_t TotalBlocks);
+  BlockListTy rearrangeBB(const Function &, const BlockListTy &);
+  BlockListTy queryCFG(Function &, const BlockListTy &);
+  void traverseToEntryBlock(const BasicBlock *, const BlockListTy &,
+                            const BackEdgesInfoTy &,
+                            const BranchProbabilityInfo *,
+                            VisitedBlocksInfoTy &);
+  void traverseToExitBlock(const BasicBlock *, const BlockListTy &,
+                           const BackEdgesInfoTy &,
+                           const BranchProbabilityInfo *,
+                           VisitedBlocksInfoTy &);
+
+public:
+  ResultTy operator()(Function &F);
+};
+
+} // namespace orc
+} // namespace llvm
+
+#endif // LLVM_EXECUTIONENGINE_ORC_SPECULATEANALYSES_H
diff --git a/linux-x64/clang/include/llvm/ExecutionEngine/Orc/Speculation.h b/linux-x64/clang/include/llvm/ExecutionEngine/Orc/Speculation.h
new file mode 100644
index 0000000..a138f60
--- /dev/null
+++ b/linux-x64/clang/include/llvm/ExecutionEngine/Orc/Speculation.h
@@ -0,0 +1,210 @@
+//===-- Speculation.h - Speculative Compilation --*- 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
+//
+//===----------------------------------------------------------------------===//
+//
+// Contains the definition to support speculative compilation when laziness is
+// enabled.
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_EXECUTIONENGINE_ORC_SPECULATION_H
+#define LLVM_EXECUTIONENGINE_ORC_SPECULATION_H
+
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/Optional.h"
+#include "llvm/ExecutionEngine/Orc/Core.h"
+#include "llvm/ExecutionEngine/Orc/DebugUtils.h"
+#include "llvm/ExecutionEngine/Orc/IRCompileLayer.h"
+#include "llvm/Support/Debug.h"
+#include <mutex>
+#include <type_traits>
+#include <utility>
+
+namespace llvm {
+namespace orc {
+
+class Speculator;
+
+// Track the Impls (JITDylib,Symbols) of Symbols while lazy call through
+// trampolines are created. Operations are guarded by locks tp ensure that Imap
+// stays in consistent state after read/write
+
+class ImplSymbolMap {
+  friend class Speculator;
+
+public:
+  using AliaseeDetails = std::pair<SymbolStringPtr, JITDylib *>;
+  using Alias = SymbolStringPtr;
+  using ImapTy = DenseMap<Alias, AliaseeDetails>;
+  void trackImpls(SymbolAliasMap ImplMaps, JITDylib *SrcJD);
+
+private:
+  // FIX ME: find a right way to distinguish the pre-compile Symbols, and update
+  // the callsite
+  Optional<AliaseeDetails> getImplFor(const SymbolStringPtr &StubSymbol) {
+    std::lock_guard<std::mutex> Lockit(ConcurrentAccess);
+    auto Position = Maps.find(StubSymbol);
+    if (Position != Maps.end())
+      return Position->getSecond();
+    else
+      return None;
+  }
+
+  std::mutex ConcurrentAccess;
+  ImapTy Maps;
+};
+
+// Defines Speculator Concept,
+class Speculator {
+public:
+  using TargetFAddr = JITTargetAddress;
+  using FunctionCandidatesMap = DenseMap<SymbolStringPtr, SymbolNameSet>;
+  using StubAddrLikelies = DenseMap<TargetFAddr, SymbolNameSet>;
+
+private:
+  void registerSymbolsWithAddr(TargetFAddr ImplAddr,
+                               SymbolNameSet likelySymbols) {
+    std::lock_guard<std::mutex> Lockit(ConcurrentAccess);
+    GlobalSpecMap.insert({ImplAddr, std::move(likelySymbols)});
+  }
+
+  void launchCompile(JITTargetAddress FAddr) {
+    SymbolNameSet CandidateSet;
+    // Copy CandidateSet is necessary, to avoid unsynchronized access to
+    // the datastructure.
+    {
+      std::lock_guard<std::mutex> Lockit(ConcurrentAccess);
+      auto It = GlobalSpecMap.find(FAddr);
+      if (It == GlobalSpecMap.end())
+        return;
+      CandidateSet = It->getSecond();
+    }
+
+    SymbolDependenceMap SpeculativeLookUpImpls;
+
+    for (auto &Callee : CandidateSet) {
+      auto ImplSymbol = AliaseeImplTable.getImplFor(Callee);
+      // try to distinguish already compiled & library symbols
+      if (!ImplSymbol.hasValue())
+        continue;
+      const auto &ImplSymbolName = ImplSymbol.getPointer()->first;
+      JITDylib *ImplJD = ImplSymbol.getPointer()->second;
+      auto &SymbolsInJD = SpeculativeLookUpImpls[ImplJD];
+      SymbolsInJD.insert(ImplSymbolName);
+    }
+
+    DEBUG_WITH_TYPE("orc", {
+      for (auto &I : SpeculativeLookUpImpls) {
+        llvm::dbgs() << "\n In " << I.first->getName() << " JITDylib ";
+        for (auto &N : I.second)
+          llvm::dbgs() << "\n Likely Symbol : " << N;
+      }
+    });
+
+    // for a given symbol, there may be no symbol qualified for speculatively
+    // compile try to fix this before jumping to this code if possible.
+    for (auto &LookupPair : SpeculativeLookUpImpls)
+      ES.lookup(
+          LookupKind::Static,
+          makeJITDylibSearchOrder(LookupPair.first,
+                                  JITDylibLookupFlags::MatchAllSymbols),
+          SymbolLookupSet(LookupPair.second), SymbolState::Ready,
+          [this](Expected<SymbolMap> Result) {
+            if (auto Err = Result.takeError())
+              ES.reportError(std::move(Err));
+          },
+          NoDependenciesToRegister);
+  }
+
+public:
+  Speculator(ImplSymbolMap &Impl, ExecutionSession &ref)
+      : AliaseeImplTable(Impl), ES(ref), GlobalSpecMap(0) {}
+  Speculator(const Speculator &) = delete;
+  Speculator(Speculator &&) = delete;
+  Speculator &operator=(const Speculator &) = delete;
+  Speculator &operator=(Speculator &&) = delete;
+
+  /// Define symbols for this Speculator object (__orc_speculator) and the
+  /// speculation runtime entry point symbol (__orc_speculate_for) in the
+  /// given JITDylib.
+  Error addSpeculationRuntime(JITDylib &JD, MangleAndInterner &Mangle);
+
+  // Speculatively compile likely functions for the given Stub Address.
+  // destination of __orc_speculate_for jump
+  void speculateFor(TargetFAddr StubAddr) { launchCompile(StubAddr); }
+
+  // FIXME : Register with Stub Address, after JITLink Fix.
+  void registerSymbols(FunctionCandidatesMap Candidates, JITDylib *JD) {
+    for (auto &SymPair : Candidates) {
+      auto Target = SymPair.first;
+      auto Likely = SymPair.second;
+
+      auto OnReadyFixUp = [Likely, Target,
+                           this](Expected<SymbolMap> ReadySymbol) {
+        if (ReadySymbol) {
+          auto RAddr = (*ReadySymbol)[Target].getAddress();
+          registerSymbolsWithAddr(RAddr, std::move(Likely));
+        } else
+          this->getES().reportError(ReadySymbol.takeError());
+      };
+      // Include non-exported symbols also.
+      ES.lookup(
+          LookupKind::Static,
+          makeJITDylibSearchOrder(JD, JITDylibLookupFlags::MatchAllSymbols),
+          SymbolLookupSet(Target, SymbolLookupFlags::WeaklyReferencedSymbol),
+          SymbolState::Ready, OnReadyFixUp, NoDependenciesToRegister);
+    }
+  }
+
+  ExecutionSession &getES() { return ES; }
+
+private:
+  static void speculateForEntryPoint(Speculator *Ptr, uint64_t StubId);
+  std::mutex ConcurrentAccess;
+  ImplSymbolMap &AliaseeImplTable;
+  ExecutionSession &ES;
+  StubAddrLikelies GlobalSpecMap;
+};
+
+class IRSpeculationLayer : public IRLayer {
+public:
+  using IRlikiesStrRef = Optional<DenseMap<StringRef, DenseSet<StringRef>>>;
+  using ResultEval = std::function<IRlikiesStrRef(Function &)>;
+  using TargetAndLikelies = DenseMap<SymbolStringPtr, SymbolNameSet>;
+
+  IRSpeculationLayer(ExecutionSession &ES, IRCompileLayer &BaseLayer,
+                     Speculator &Spec, MangleAndInterner &Mangle,
+                     ResultEval Interpreter)
+      : IRLayer(ES, BaseLayer.getManglingOptions()), NextLayer(BaseLayer),
+        S(Spec), Mangle(Mangle), QueryAnalysis(Interpreter) {}
+
+  void emit(std::unique_ptr<MaterializationResponsibility> R,
+            ThreadSafeModule TSM) override;
+
+private:
+  TargetAndLikelies
+  internToJITSymbols(DenseMap<StringRef, DenseSet<StringRef>> IRNames) {
+    assert(!IRNames.empty() && "No IRNames received to Intern?");
+    TargetAndLikelies InternedNames;
+    for (auto &NamePair : IRNames) {
+      DenseSet<SymbolStringPtr> TargetJITNames;
+      for (auto &TargetNames : NamePair.second)
+        TargetJITNames.insert(Mangle(TargetNames));
+      InternedNames[Mangle(NamePair.first)] = std::move(TargetJITNames);
+    }
+    return InternedNames;
+  }
+
+  IRCompileLayer &NextLayer;
+  Speculator &S;
+  MangleAndInterner &Mangle;
+  ResultEval QueryAnalysis;
+};
+
+} // namespace orc
+} // namespace llvm
+
+#endif // LLVM_EXECUTIONENGINE_ORC_SPECULATION_H
diff --git a/linux-x64/clang/include/llvm/ExecutionEngine/Orc/SymbolStringPool.h b/linux-x64/clang/include/llvm/ExecutionEngine/Orc/SymbolStringPool.h
index c354f6c..c9fadd7 100644
--- a/linux-x64/clang/include/llvm/ExecutionEngine/Orc/SymbolStringPool.h
+++ b/linux-x64/clang/include/llvm/ExecutionEngine/Orc/SymbolStringPool.h
@@ -48,11 +48,13 @@
 
 /// Pointer to a pooled string representing a symbol name.
 class SymbolStringPtr {
+  friend class OrcV2CAPIHelper;
   friend class SymbolStringPool;
   friend struct DenseMapInfo<SymbolStringPtr>;
 
 public:
   SymbolStringPtr() = default;
+  SymbolStringPtr(std::nullptr_t) {}
   SymbolStringPtr(const SymbolStringPtr &Other)
     : S(Other.S) {
     if (isRealPoolEntry(S))
@@ -85,6 +87,8 @@
       --S->getValue();
   }
 
+  explicit operator bool() const { return S; }
+
   StringRef operator*() const { return S->first(); }
 
   friend bool operator==(const SymbolStringPtr &LHS,
@@ -103,7 +107,8 @@
   }
 
 private:
-  using PoolEntryPtr = SymbolStringPool::PoolMapEntry *;
+  using PoolEntry = SymbolStringPool::PoolMapEntry;
+  using PoolEntryPtr = PoolEntry *;
 
   SymbolStringPtr(SymbolStringPool::PoolMapEntry *S)
       : S(S) {
diff --git a/linux-x64/clang/include/llvm/ExecutionEngine/Orc/TPCDynamicLibrarySearchGenerator.h b/linux-x64/clang/include/llvm/ExecutionEngine/Orc/TPCDynamicLibrarySearchGenerator.h
new file mode 100644
index 0000000..ed4f608
--- /dev/null
+++ b/linux-x64/clang/include/llvm/ExecutionEngine/Orc/TPCDynamicLibrarySearchGenerator.h
@@ -0,0 +1,66 @@
+//===------------ TPCDynamicLibrarySearchGenerator.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
+//
+//===----------------------------------------------------------------------===//
+//
+// Support loading and searching of dynamic libraries in a target process via
+// the TargetProcessControl class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_EXECUTIONENGINE_ORC_TPCDYNAMICLIBRARYSEARCHGENERATOR_H
+#define LLVM_EXECUTIONENGINE_ORC_TPCDYNAMICLIBRARYSEARCHGENERATOR_H
+
+#include "llvm/ADT/FunctionExtras.h"
+#include "llvm/ExecutionEngine/Orc/TargetProcessControl.h"
+
+namespace llvm {
+namespace orc {
+
+class TPCDynamicLibrarySearchGenerator : public DefinitionGenerator {
+public:
+  using SymbolPredicate = unique_function<bool(const SymbolStringPtr &)>;
+
+  /// Create a DynamicLibrarySearchGenerator that searches for symbols in the
+  /// library with the given handle.
+  ///
+  /// If the Allow predicate is given then only symbols matching the predicate
+  /// will be searched for. If the predicate is not given then all symbols will
+  /// be searched for.
+  TPCDynamicLibrarySearchGenerator(TargetProcessControl &TPC,
+                                   tpctypes::DylibHandle H,
+                                   SymbolPredicate Allow = SymbolPredicate())
+      : TPC(TPC), H(H), Allow(std::move(Allow)) {}
+
+  /// Permanently loads the library at the given path and, on success, returns
+  /// a DynamicLibrarySearchGenerator 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<TPCDynamicLibrarySearchGenerator>>
+  Load(TargetProcessControl &TPC, const char *LibraryPath,
+       SymbolPredicate Allow = SymbolPredicate());
+
+  /// Creates a TPCDynamicLibrarySearchGenerator that searches for symbols in
+  /// the target process.
+  static Expected<std::unique_ptr<TPCDynamicLibrarySearchGenerator>>
+  GetForTargetProcess(TargetProcessControl &TPC,
+                      SymbolPredicate Allow = SymbolPredicate()) {
+    return Load(TPC, nullptr, std::move(Allow));
+  }
+
+  Error tryToGenerate(LookupState &LS, LookupKind K, JITDylib &JD,
+                      JITDylibLookupFlags JDLookupFlags,
+                      const SymbolLookupSet &Symbols) override;
+
+private:
+  TargetProcessControl &TPC;
+  tpctypes::DylibHandle H;
+  SymbolPredicate Allow;
+};
+
+} // end namespace orc
+} // end namespace llvm
+
+#endif // LLVM_EXECUTIONENGINE_ORC_TPCDYNAMICLIBRARYSEARCHGENERATOR_H
diff --git a/linux-x64/clang/include/llvm/ExecutionEngine/Orc/TPCEHFrameRegistrar.h b/linux-x64/clang/include/llvm/ExecutionEngine/Orc/TPCEHFrameRegistrar.h
new file mode 100644
index 0000000..519f818
--- /dev/null
+++ b/linux-x64/clang/include/llvm/ExecutionEngine/Orc/TPCEHFrameRegistrar.h
@@ -0,0 +1,54 @@
+//===-- TPCEHFrameRegistrar.h - TPC based eh-frame registration -*- 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
+//
+//===----------------------------------------------------------------------===//
+//
+// TargetProcessControl based eh-frame registration.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_EXECUTIONENGINE_ORC_TPCEHFRAMEREGISTRAR_H
+#define LLVM_EXECUTIONENGINE_ORC_TPCEHFRAMEREGISTRAR_H
+
+#include "llvm/ExecutionEngine/JITLink/EHFrameSupport.h"
+#include "llvm/ExecutionEngine/Orc/TargetProcessControl.h"
+
+namespace llvm {
+namespace orc {
+
+/// Register/Deregisters EH frames in a remote process via a
+/// TargetProcessControl instance.
+class TPCEHFrameRegistrar : public jitlink::EHFrameRegistrar {
+public:
+  /// Create from a TargetProcessControl instance alone. This will use
+  /// the TPC's lookupSymbols method to find the registration/deregistration
+  /// funciton addresses by name.
+  static Expected<std::unique_ptr<TPCEHFrameRegistrar>>
+  Create(TargetProcessControl &TPC);
+
+  /// Create a TPCEHFrameRegistrar with the given TargetProcessControl
+  /// object and registration/deregistration function addresses.
+  TPCEHFrameRegistrar(TargetProcessControl &TPC,
+                      JITTargetAddress RegisterEHFrameWrapperFnAddr,
+                      JITTargetAddress DeregisterEHFRameWrapperFnAddr)
+      : TPC(TPC), RegisterEHFrameWrapperFnAddr(RegisterEHFrameWrapperFnAddr),
+        DeregisterEHFrameWrapperFnAddr(DeregisterEHFRameWrapperFnAddr) {}
+
+  Error registerEHFrames(JITTargetAddress EHFrameSectionAddr,
+                         size_t EHFrameSectionSize) override;
+  Error deregisterEHFrames(JITTargetAddress EHFrameSectionAddr,
+                           size_t EHFrameSectionSize) override;
+
+private:
+  TargetProcessControl &TPC;
+  JITTargetAddress RegisterEHFrameWrapperFnAddr;
+  JITTargetAddress DeregisterEHFrameWrapperFnAddr;
+};
+
+} // end namespace orc
+} // end namespace llvm
+
+#endif // LLVM_EXECUTIONENGINE_ORC_TPCEHFRAMEREGISTRAR_H
diff --git a/linux-x64/clang/include/llvm/ExecutionEngine/Orc/TPCIndirectionUtils.h b/linux-x64/clang/include/llvm/ExecutionEngine/Orc/TPCIndirectionUtils.h
new file mode 100644
index 0000000..e7abd7f
--- /dev/null
+++ b/linux-x64/clang/include/llvm/ExecutionEngine/Orc/TPCIndirectionUtils.h
@@ -0,0 +1,222 @@
+//===--- TPCIndirectionUtils.h - TPC based indirection utils ----*- 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
+//
+//===----------------------------------------------------------------------===//
+//
+// Indirection utilities (stubs, trampolines, lazy call-throughs) that use the
+// TargetProcessControl API to interact with the target process.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_EXECUTIONENGINE_ORC_TPCINDIRECTIONUTILS_H
+#define LLVM_EXECUTIONENGINE_ORC_TPCINDIRECTIONUTILS_H
+
+#include "llvm/ExecutionEngine/JITLink/JITLinkMemoryManager.h"
+#include "llvm/ExecutionEngine/Orc/IndirectionUtils.h"
+#include "llvm/ExecutionEngine/Orc/LazyReexports.h"
+
+#include <mutex>
+
+namespace llvm {
+namespace orc {
+
+class TargetProcessControl;
+
+/// Provides TargetProcessControl based indirect stubs, trampoline pool and
+/// lazy call through manager.
+class TPCIndirectionUtils {
+  friend class TPCIndirectionUtilsAccess;
+
+public:
+  /// ABI support base class. Used to write resolver, stub, and trampoline
+  /// blocks.
+  class ABISupport {
+  protected:
+    ABISupport(unsigned PointerSize, unsigned TrampolineSize, unsigned StubSize,
+               unsigned StubToPointerMaxDisplacement, unsigned ResolverCodeSize)
+        : PointerSize(PointerSize), TrampolineSize(TrampolineSize),
+          StubSize(StubSize),
+          StubToPointerMaxDisplacement(StubToPointerMaxDisplacement),
+          ResolverCodeSize(ResolverCodeSize) {}
+
+  public:
+    virtual ~ABISupport();
+
+    unsigned getPointerSize() const { return PointerSize; }
+    unsigned getTrampolineSize() const { return TrampolineSize; }
+    unsigned getStubSize() const { return StubSize; }
+    unsigned getStubToPointerMaxDisplacement() const {
+      return StubToPointerMaxDisplacement;
+    }
+    unsigned getResolverCodeSize() const { return ResolverCodeSize; }
+
+    virtual void writeResolverCode(char *ResolverWorkingMem,
+                                   JITTargetAddress ResolverTargetAddr,
+                                   JITTargetAddress ReentryFnAddr,
+                                   JITTargetAddress ReentryCtxAddr) const = 0;
+
+    virtual void writeTrampolines(char *TrampolineBlockWorkingMem,
+                                  JITTargetAddress TrampolineBlockTragetAddr,
+                                  JITTargetAddress ResolverAddr,
+                                  unsigned NumTrampolines) const = 0;
+
+    virtual void
+    writeIndirectStubsBlock(char *StubsBlockWorkingMem,
+                            JITTargetAddress StubsBlockTargetAddress,
+                            JITTargetAddress PointersBlockTargetAddress,
+                            unsigned NumStubs) const = 0;
+
+  private:
+    unsigned PointerSize = 0;
+    unsigned TrampolineSize = 0;
+    unsigned StubSize = 0;
+    unsigned StubToPointerMaxDisplacement = 0;
+    unsigned ResolverCodeSize = 0;
+  };
+
+  /// Create using the given ABI class.
+  template <typename ORCABI>
+  static std::unique_ptr<TPCIndirectionUtils>
+  CreateWithABI(TargetProcessControl &TPC);
+
+  /// Create based on the TargetProcessControl triple.
+  static Expected<std::unique_ptr<TPCIndirectionUtils>>
+  Create(TargetProcessControl &TPC);
+
+  /// Return a reference to the TargetProcessControl object.
+  TargetProcessControl &getTargetProcessControl() const { return TPC; }
+
+  /// Return a reference to the ABISupport object for this instance.
+  ABISupport &getABISupport() const { return *ABI; }
+
+  /// Release memory for resources held by this instance. This *must* be called
+  /// prior to destruction of the class.
+  Error cleanup();
+
+  /// Write resolver code to the target process and return its address.
+  /// This must be called before any call to createTrampolinePool or
+  /// createLazyCallThroughManager.
+  Expected<JITTargetAddress>
+  writeResolverBlock(JITTargetAddress ReentryFnAddr,
+                     JITTargetAddress ReentryCtxAddr);
+
+  /// Returns the address of the Resolver block. Returns zero if the
+  /// writeResolverBlock method has not previously been called.
+  JITTargetAddress getResolverBlockAddress() const { return ResolverBlockAddr; }
+
+  /// Create an IndirectStubsManager for the target process.
+  std::unique_ptr<IndirectStubsManager> createIndirectStubsManager();
+
+  /// Create a TrampolinePool for the target process.
+  TrampolinePool &getTrampolinePool();
+
+  /// Create a LazyCallThroughManager.
+  /// This function should only be called once.
+  LazyCallThroughManager &
+  createLazyCallThroughManager(ExecutionSession &ES,
+                               JITTargetAddress ErrorHandlerAddr);
+
+  /// Create a LazyCallThroughManager for the target process.
+  LazyCallThroughManager &getLazyCallThroughManager() {
+    assert(LCTM && "createLazyCallThroughManager must be called first");
+    return *LCTM;
+  }
+
+private:
+  using Allocation = jitlink::JITLinkMemoryManager::Allocation;
+
+  struct IndirectStubInfo {
+    IndirectStubInfo() = default;
+    IndirectStubInfo(JITTargetAddress StubAddress,
+                     JITTargetAddress PointerAddress)
+        : StubAddress(StubAddress), PointerAddress(PointerAddress) {}
+    JITTargetAddress StubAddress = 0;
+    JITTargetAddress PointerAddress = 0;
+  };
+
+  using IndirectStubInfoVector = std::vector<IndirectStubInfo>;
+
+  /// Create a TPCIndirectionUtils instance.
+  TPCIndirectionUtils(TargetProcessControl &TPC,
+                      std::unique_ptr<ABISupport> ABI);
+
+  Expected<IndirectStubInfoVector> getIndirectStubs(unsigned NumStubs);
+
+  std::mutex TPCUIMutex;
+  TargetProcessControl &TPC;
+  std::unique_ptr<ABISupport> ABI;
+  JITTargetAddress ResolverBlockAddr;
+  std::unique_ptr<jitlink::JITLinkMemoryManager::Allocation> ResolverBlock;
+  std::unique_ptr<TrampolinePool> TP;
+  std::unique_ptr<LazyCallThroughManager> LCTM;
+
+  std::vector<IndirectStubInfo> AvailableIndirectStubs;
+  std::vector<std::unique_ptr<Allocation>> IndirectStubAllocs;
+};
+
+/// This will call writeResolver on the given TPCIndirectionUtils instance
+/// to set up re-entry via a function that will directly return the trampoline
+/// landing address.
+///
+/// The TPCIndirectionUtils' LazyCallThroughManager must have been previously
+/// created via TPCIndirectionUtils::createLazyCallThroughManager.
+///
+/// The TPCIndirectionUtils' writeResolver method must not have been previously
+/// called.
+///
+/// This function is experimental and likely subject to revision.
+Error setUpInProcessLCTMReentryViaTPCIU(TPCIndirectionUtils &TPCIU);
+
+namespace detail {
+
+template <typename ORCABI>
+class ABISupportImpl : public TPCIndirectionUtils::ABISupport {
+public:
+  ABISupportImpl()
+      : ABISupport(ORCABI::PointerSize, ORCABI::TrampolineSize,
+                   ORCABI::StubSize, ORCABI::StubToPointerMaxDisplacement,
+                   ORCABI::ResolverCodeSize) {}
+
+  void writeResolverCode(char *ResolverWorkingMem,
+                         JITTargetAddress ResolverTargetAddr,
+                         JITTargetAddress ReentryFnAddr,
+                         JITTargetAddress ReentryCtxAddr) const override {
+    ORCABI::writeResolverCode(ResolverWorkingMem, ResolverTargetAddr,
+                              ReentryFnAddr, ReentryCtxAddr);
+  }
+
+  void writeTrampolines(char *TrampolineBlockWorkingMem,
+                        JITTargetAddress TrampolineBlockTargetAddr,
+                        JITTargetAddress ResolverAddr,
+                        unsigned NumTrampolines) const override {
+    ORCABI::writeTrampolines(TrampolineBlockWorkingMem,
+                             TrampolineBlockTargetAddr, ResolverAddr,
+                             NumTrampolines);
+  }
+
+  void writeIndirectStubsBlock(char *StubsBlockWorkingMem,
+                               JITTargetAddress StubsBlockTargetAddress,
+                               JITTargetAddress PointersBlockTargetAddress,
+                               unsigned NumStubs) const override {
+    ORCABI::writeIndirectStubsBlock(StubsBlockWorkingMem,
+                                    StubsBlockTargetAddress,
+                                    PointersBlockTargetAddress, NumStubs);
+  }
+};
+
+} // end namespace detail
+
+template <typename ORCABI>
+std::unique_ptr<TPCIndirectionUtils>
+TPCIndirectionUtils::CreateWithABI(TargetProcessControl &TPC) {
+  return std::unique_ptr<TPCIndirectionUtils>(new TPCIndirectionUtils(
+      TPC, std::make_unique<detail::ABISupportImpl<ORCABI>>()));
+}
+
+} // end namespace orc
+} // end namespace llvm
+
+#endif // LLVM_EXECUTIONENGINE_ORC_TPCINDIRECTIONUTILS_H
diff --git a/linux-x64/clang/include/llvm/ExecutionEngine/Orc/TargetProcess/OrcRPCTPCServer.h b/linux-x64/clang/include/llvm/ExecutionEngine/Orc/TargetProcess/OrcRPCTPCServer.h
new file mode 100644
index 0000000..253e06b
--- /dev/null
+++ b/linux-x64/clang/include/llvm/ExecutionEngine/Orc/TargetProcess/OrcRPCTPCServer.h
@@ -0,0 +1,620 @@
+//===-- OrcRPCTPCServer.h -- OrcRPCTargetProcessControl Server --*- 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
+//
+//===----------------------------------------------------------------------===//
+//
+// OrcRPCTargetProcessControl server class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_EXECUTIONENGINE_ORC_TARGETPROCESS_ORCRPCTPCSERVER_H
+#define LLVM_EXECUTIONENGINE_ORC_TARGETPROCESS_ORCRPCTPCSERVER_H
+
+#include "llvm/ADT/BitmaskEnum.h"
+#include "llvm/ExecutionEngine/Orc/Shared/RPCUtils.h"
+#include "llvm/ExecutionEngine/Orc/Shared/RawByteChannel.h"
+#include "llvm/ExecutionEngine/Orc/Shared/TargetProcessControlTypes.h"
+#include "llvm/ExecutionEngine/Orc/TargetProcess/TargetExecutionUtils.h"
+#include "llvm/ExecutionEngine/Orc/TargetProcessControl.h"
+#include "llvm/Support/DynamicLibrary.h"
+#include "llvm/Support/FormatVariadic.h"
+#include "llvm/Support/Host.h"
+#include "llvm/Support/MathExtras.h"
+#include "llvm/Support/Memory.h"
+#include "llvm/Support/Process.h"
+
+#include <atomic>
+
+namespace llvm {
+namespace orc {
+
+namespace orcrpctpc {
+
+enum WireProtectionFlags : uint8_t {
+  WPF_None = 0,
+  WPF_Read = 1U << 0,
+  WPF_Write = 1U << 1,
+  WPF_Exec = 1U << 2,
+  LLVM_MARK_AS_BITMASK_ENUM(WPF_Exec)
+};
+
+/// Convert from sys::Memory::ProtectionFlags
+inline WireProtectionFlags
+toWireProtectionFlags(sys::Memory::ProtectionFlags PF) {
+  WireProtectionFlags WPF = WPF_None;
+  if (PF & sys::Memory::MF_READ)
+    WPF |= WPF_Read;
+  if (PF & sys::Memory::MF_WRITE)
+    WPF |= WPF_Write;
+  if (PF & sys::Memory::MF_EXEC)
+    WPF |= WPF_Exec;
+  return WPF;
+}
+
+inline sys::Memory::ProtectionFlags
+fromWireProtectionFlags(WireProtectionFlags WPF) {
+  int PF = 0;
+  if (WPF & WPF_Read)
+    PF |= sys::Memory::MF_READ;
+  if (WPF & WPF_Write)
+    PF |= sys::Memory::MF_WRITE;
+  if (WPF & WPF_Exec)
+    PF |= sys::Memory::MF_EXEC;
+  return static_cast<sys::Memory::ProtectionFlags>(PF);
+}
+
+struct ReserveMemRequestElement {
+  WireProtectionFlags Prot = WPF_None;
+  uint64_t Size = 0;
+  uint64_t Alignment = 0;
+};
+
+using ReserveMemRequest = std::vector<ReserveMemRequestElement>;
+
+struct ReserveMemResultElement {
+  WireProtectionFlags Prot = WPF_None;
+  JITTargetAddress Address = 0;
+  uint64_t AllocatedSize = 0;
+};
+
+using ReserveMemResult = std::vector<ReserveMemResultElement>;
+
+struct ReleaseOrFinalizeMemRequestElement {
+  WireProtectionFlags Prot = WPF_None;
+  JITTargetAddress Address = 0;
+  uint64_t Size = 0;
+};
+
+using ReleaseOrFinalizeMemRequest =
+    std::vector<ReleaseOrFinalizeMemRequestElement>;
+
+} // end namespace orcrpctpc
+
+namespace shared {
+
+template <> class SerializationTypeName<tpctypes::UInt8Write> {
+public:
+  static const char *getName() { return "UInt8Write"; }
+};
+
+template <> class SerializationTypeName<tpctypes::UInt16Write> {
+public:
+  static const char *getName() { return "UInt16Write"; }
+};
+
+template <> class SerializationTypeName<tpctypes::UInt32Write> {
+public:
+  static const char *getName() { return "UInt32Write"; }
+};
+
+template <> class SerializationTypeName<tpctypes::UInt64Write> {
+public:
+  static const char *getName() { return "UInt64Write"; }
+};
+
+template <> class SerializationTypeName<tpctypes::BufferWrite> {
+public:
+  static const char *getName() { return "BufferWrite"; }
+};
+
+template <> class SerializationTypeName<orcrpctpc::ReserveMemRequestElement> {
+public:
+  static const char *getName() { return "ReserveMemRequestElement"; }
+};
+
+template <> class SerializationTypeName<orcrpctpc::ReserveMemResultElement> {
+public:
+  static const char *getName() { return "ReserveMemResultElement"; }
+};
+
+template <>
+class SerializationTypeName<orcrpctpc::ReleaseOrFinalizeMemRequestElement> {
+public:
+  static const char *getName() { return "ReleaseOrFinalizeMemRequestElement"; }
+};
+
+template <> class SerializationTypeName<tpctypes::WrapperFunctionResult> {
+public:
+  static const char *getName() { return "WrapperFunctionResult"; }
+};
+
+template <typename ChannelT, typename WriteT>
+class SerializationTraits<
+    ChannelT, WriteT, WriteT,
+    std::enable_if_t<std::is_same<WriteT, tpctypes::UInt8Write>::value ||
+                     std::is_same<WriteT, tpctypes::UInt16Write>::value ||
+                     std::is_same<WriteT, tpctypes::UInt32Write>::value ||
+                     std::is_same<WriteT, tpctypes::UInt64Write>::value>> {
+public:
+  static Error serialize(ChannelT &C, const WriteT &W) {
+    return serializeSeq(C, W.Address, W.Value);
+  }
+  static Error deserialize(ChannelT &C, WriteT &W) {
+    return deserializeSeq(C, W.Address, W.Value);
+  }
+};
+
+template <typename ChannelT>
+class SerializationTraits<
+    ChannelT, tpctypes::BufferWrite, tpctypes::BufferWrite,
+    std::enable_if_t<std::is_base_of<RawByteChannel, ChannelT>::value>> {
+public:
+  static Error serialize(ChannelT &C, const tpctypes::BufferWrite &W) {
+    uint64_t Size = W.Buffer.size();
+    if (auto Err = serializeSeq(C, W.Address, Size))
+      return Err;
+
+    return C.appendBytes(W.Buffer.data(), Size);
+  }
+  static Error deserialize(ChannelT &C, tpctypes::BufferWrite &W) {
+    JITTargetAddress Address;
+    uint64_t Size;
+
+    if (auto Err = deserializeSeq(C, Address, Size))
+      return Err;
+
+    char *Buffer = jitTargetAddressToPointer<char *>(Address);
+
+    if (auto Err = C.readBytes(Buffer, Size))
+      return Err;
+
+    W = {Address, StringRef(Buffer, Size)};
+    return Error::success();
+  }
+};
+
+template <typename ChannelT>
+class SerializationTraits<ChannelT, orcrpctpc::ReserveMemRequestElement> {
+public:
+  static Error serialize(ChannelT &C,
+                         const orcrpctpc::ReserveMemRequestElement &E) {
+    return serializeSeq(C, static_cast<uint8_t>(E.Prot), E.Size, E.Alignment);
+  }
+
+  static Error deserialize(ChannelT &C,
+                           orcrpctpc::ReserveMemRequestElement &E) {
+    return deserializeSeq(C, *reinterpret_cast<uint8_t *>(&E.Prot), E.Size,
+                          E.Alignment);
+  }
+};
+
+template <typename ChannelT>
+class SerializationTraits<ChannelT, orcrpctpc::ReserveMemResultElement> {
+public:
+  static Error serialize(ChannelT &C,
+                         const orcrpctpc::ReserveMemResultElement &E) {
+    return serializeSeq(C, static_cast<uint8_t>(E.Prot), E.Address,
+                        E.AllocatedSize);
+  }
+
+  static Error deserialize(ChannelT &C, orcrpctpc::ReserveMemResultElement &E) {
+    return deserializeSeq(C, *reinterpret_cast<uint8_t *>(&E.Prot), E.Address,
+                          E.AllocatedSize);
+  }
+};
+
+template <typename ChannelT>
+class SerializationTraits<ChannelT,
+                          orcrpctpc::ReleaseOrFinalizeMemRequestElement> {
+public:
+  static Error
+  serialize(ChannelT &C,
+            const orcrpctpc::ReleaseOrFinalizeMemRequestElement &E) {
+    return serializeSeq(C, static_cast<uint8_t>(E.Prot), E.Address, E.Size);
+  }
+
+  static Error deserialize(ChannelT &C,
+                           orcrpctpc::ReleaseOrFinalizeMemRequestElement &E) {
+    return deserializeSeq(C, *reinterpret_cast<uint8_t *>(&E.Prot), E.Address,
+                          E.Size);
+  }
+};
+
+template <typename ChannelT>
+class SerializationTraits<
+    ChannelT, tpctypes::WrapperFunctionResult, tpctypes::WrapperFunctionResult,
+    std::enable_if_t<std::is_base_of<RawByteChannel, ChannelT>::value>> {
+public:
+  static Error serialize(ChannelT &C,
+                         const tpctypes::WrapperFunctionResult &E) {
+    auto Data = E.getData();
+    if (auto Err = serializeSeq(C, static_cast<uint64_t>(Data.size())))
+      return Err;
+    if (Data.size() == 0)
+      return Error::success();
+    return C.appendBytes(reinterpret_cast<const char *>(Data.data()),
+                         Data.size());
+  }
+
+  static Error deserialize(ChannelT &C, tpctypes::WrapperFunctionResult &E) {
+    tpctypes::CWrapperFunctionResult R;
+
+    R.Size = 0;
+    R.Data.ValuePtr = nullptr;
+    R.Destroy = nullptr;
+
+    if (auto Err = deserializeSeq(C, R.Size))
+      return Err;
+    if (R.Size == 0)
+      return Error::success();
+    R.Data.ValuePtr = new uint8_t[R.Size];
+    if (auto Err =
+            C.readBytes(reinterpret_cast<char *>(R.Data.ValuePtr), R.Size)) {
+      R.Destroy = tpctypes::WrapperFunctionResult::destroyWithDeleteArray;
+      return Err;
+    }
+
+    E = tpctypes::WrapperFunctionResult(R);
+    return Error::success();
+  }
+};
+
+} // end namespace shared
+
+namespace orcrpctpc {
+
+using RemoteSymbolLookupSet = std::vector<std::pair<std::string, bool>>;
+using RemoteLookupRequest =
+    std::pair<tpctypes::DylibHandle, RemoteSymbolLookupSet>;
+
+class GetTargetTriple
+    : public shared::RPCFunction<GetTargetTriple, std::string()> {
+public:
+  static const char *getName() { return "GetTargetTriple"; }
+};
+
+class GetPageSize : public shared::RPCFunction<GetPageSize, uint64_t()> {
+public:
+  static const char *getName() { return "GetPageSize"; }
+};
+
+class ReserveMem
+    : public shared::RPCFunction<ReserveMem, Expected<ReserveMemResult>(
+                                                 ReserveMemRequest)> {
+public:
+  static const char *getName() { return "ReserveMem"; }
+};
+
+class FinalizeMem
+    : public shared::RPCFunction<FinalizeMem,
+                                 Error(ReleaseOrFinalizeMemRequest)> {
+public:
+  static const char *getName() { return "FinalizeMem"; }
+};
+
+class ReleaseMem
+    : public shared::RPCFunction<ReleaseMem,
+                                 Error(ReleaseOrFinalizeMemRequest)> {
+public:
+  static const char *getName() { return "ReleaseMem"; }
+};
+
+class WriteUInt8s
+    : public shared::RPCFunction<WriteUInt8s,
+                                 Error(std::vector<tpctypes::UInt8Write>)> {
+public:
+  static const char *getName() { return "WriteUInt8s"; }
+};
+
+class WriteUInt16s
+    : public shared::RPCFunction<WriteUInt16s,
+                                 Error(std::vector<tpctypes::UInt16Write>)> {
+public:
+  static const char *getName() { return "WriteUInt16s"; }
+};
+
+class WriteUInt32s
+    : public shared::RPCFunction<WriteUInt32s,
+                                 Error(std::vector<tpctypes::UInt32Write>)> {
+public:
+  static const char *getName() { return "WriteUInt32s"; }
+};
+
+class WriteUInt64s
+    : public shared::RPCFunction<WriteUInt64s,
+                                 Error(std::vector<tpctypes::UInt64Write>)> {
+public:
+  static const char *getName() { return "WriteUInt64s"; }
+};
+
+class WriteBuffers
+    : public shared::RPCFunction<WriteBuffers,
+                                 Error(std::vector<tpctypes::BufferWrite>)> {
+public:
+  static const char *getName() { return "WriteBuffers"; }
+};
+
+class LoadDylib
+    : public shared::RPCFunction<LoadDylib, Expected<tpctypes::DylibHandle>(
+                                                std::string DylibPath)> {
+public:
+  static const char *getName() { return "LoadDylib"; }
+};
+
+class LookupSymbols
+    : public shared::RPCFunction<LookupSymbols,
+                                 Expected<std::vector<tpctypes::LookupResult>>(
+                                     std::vector<RemoteLookupRequest>)> {
+public:
+  static const char *getName() { return "LookupSymbols"; }
+};
+
+class RunMain
+    : public shared::RPCFunction<RunMain,
+                                 int32_t(JITTargetAddress MainAddr,
+                                         std::vector<std::string> Args)> {
+public:
+  static const char *getName() { return "RunMain"; }
+};
+
+class RunWrapper
+    : public shared::RPCFunction<RunWrapper,
+                                 tpctypes::WrapperFunctionResult(
+                                     JITTargetAddress, std::vector<uint8_t>)> {
+public:
+  static const char *getName() { return "RunWrapper"; }
+};
+
+class CloseConnection : public shared::RPCFunction<CloseConnection, void()> {
+public:
+  static const char *getName() { return "CloseConnection"; }
+};
+
+} // end namespace orcrpctpc
+
+/// TargetProcessControl for a process connected via an ORC RPC Endpoint.
+template <typename RPCEndpointT> class OrcRPCTPCServer {
+public:
+  /// Create an OrcRPCTPCServer from the given endpoint.
+  OrcRPCTPCServer(RPCEndpointT &EP) : EP(EP) {
+    using ThisT = OrcRPCTPCServer<RPCEndpointT>;
+
+    TripleStr = sys::getProcessTriple();
+    PageSize = sys::Process::getPageSizeEstimate();
+
+    EP.template addHandler<orcrpctpc::GetTargetTriple>(*this,
+                                                       &ThisT::getTargetTriple);
+    EP.template addHandler<orcrpctpc::GetPageSize>(*this, &ThisT::getPageSize);
+
+    EP.template addHandler<orcrpctpc::ReserveMem>(*this, &ThisT::reserveMemory);
+    EP.template addHandler<orcrpctpc::FinalizeMem>(*this,
+                                                   &ThisT::finalizeMemory);
+    EP.template addHandler<orcrpctpc::ReleaseMem>(*this, &ThisT::releaseMemory);
+
+    EP.template addHandler<orcrpctpc::WriteUInt8s>(
+        handleWriteUInt<tpctypes::UInt8Write>);
+    EP.template addHandler<orcrpctpc::WriteUInt16s>(
+        handleWriteUInt<tpctypes::UInt16Write>);
+    EP.template addHandler<orcrpctpc::WriteUInt32s>(
+        handleWriteUInt<tpctypes::UInt32Write>);
+    EP.template addHandler<orcrpctpc::WriteUInt64s>(
+        handleWriteUInt<tpctypes::UInt64Write>);
+    EP.template addHandler<orcrpctpc::WriteBuffers>(handleWriteBuffer);
+
+    EP.template addHandler<orcrpctpc::LoadDylib>(*this, &ThisT::loadDylib);
+    EP.template addHandler<orcrpctpc::LookupSymbols>(*this,
+                                                     &ThisT::lookupSymbols);
+
+    EP.template addHandler<orcrpctpc::RunMain>(*this, &ThisT::runMain);
+    EP.template addHandler<orcrpctpc::RunWrapper>(*this, &ThisT::runWrapper);
+
+    EP.template addHandler<orcrpctpc::CloseConnection>(*this,
+                                                       &ThisT::closeConnection);
+  }
+
+  /// Set the ProgramName to be used as the first argv element when running
+  /// functions via runAsMain.
+  void setProgramName(Optional<std::string> ProgramName = None) {
+    this->ProgramName = std::move(ProgramName);
+  }
+
+  /// Get the RPC endpoint for this server.
+  RPCEndpointT &getEndpoint() { return EP; }
+
+  /// Run the server loop.
+  Error run() {
+    while (!Finished) {
+      if (auto Err = EP.handleOne())
+        return Err;
+    }
+    return Error::success();
+  }
+
+private:
+  std::string getTargetTriple() { return TripleStr; }
+  uint64_t getPageSize() { return PageSize; }
+
+  template <typename WriteT>
+  static void handleWriteUInt(const std::vector<WriteT> &Ws) {
+    using ValueT = decltype(std::declval<WriteT>().Value);
+    for (auto &W : Ws)
+      *jitTargetAddressToPointer<ValueT *>(W.Address) = W.Value;
+  }
+
+  std::string getProtStr(orcrpctpc::WireProtectionFlags WPF) {
+    std::string Result;
+    Result += (WPF & orcrpctpc::WPF_Read) ? 'R' : '-';
+    Result += (WPF & orcrpctpc::WPF_Write) ? 'W' : '-';
+    Result += (WPF & orcrpctpc::WPF_Exec) ? 'X' : '-';
+    return Result;
+  }
+
+  static void handleWriteBuffer(const std::vector<tpctypes::BufferWrite> &Ws) {
+    for (auto &W : Ws) {
+      memcpy(jitTargetAddressToPointer<char *>(W.Address), W.Buffer.data(),
+             W.Buffer.size());
+    }
+  }
+
+  Expected<orcrpctpc::ReserveMemResult>
+  reserveMemory(const orcrpctpc::ReserveMemRequest &Request) {
+    orcrpctpc::ReserveMemResult Allocs;
+    auto PF = sys::Memory::MF_READ | sys::Memory::MF_WRITE;
+
+    uint64_t TotalSize = 0;
+
+    for (const auto &E : Request) {
+      uint64_t Size = alignTo(E.Size, PageSize);
+      uint16_t Align = E.Alignment;
+
+      if ((Align > PageSize) || (PageSize % Align))
+        return make_error<StringError>(
+            "Page alignmen does not satisfy requested alignment",
+            inconvertibleErrorCode());
+
+      TotalSize += Size;
+    }
+
+    // Allocate memory slab.
+    std::error_code EC;
+    auto MB = sys::Memory::allocateMappedMemory(TotalSize, nullptr, PF, EC);
+    if (EC)
+      return make_error<StringError>("Unable to allocate memory: " +
+                                         EC.message(),
+                                     inconvertibleErrorCode());
+
+    // Zero-fill the whole thing.
+    memset(MB.base(), 0, MB.allocatedSize());
+
+    // Carve up sections to return.
+    uint64_t SectionBase = 0;
+    for (const auto &E : Request) {
+      uint64_t SectionSize = alignTo(E.Size, PageSize);
+      Allocs.push_back({E.Prot,
+                        pointerToJITTargetAddress(MB.base()) + SectionBase,
+                        SectionSize});
+      SectionBase += SectionSize;
+    }
+
+    return Allocs;
+  }
+
+  Error finalizeMemory(const orcrpctpc::ReleaseOrFinalizeMemRequest &FMR) {
+    for (const auto &E : FMR) {
+      sys::MemoryBlock MB(jitTargetAddressToPointer<void *>(E.Address), E.Size);
+
+      auto PF = orcrpctpc::fromWireProtectionFlags(E.Prot);
+      if (auto EC =
+              sys::Memory::protectMappedMemory(MB, static_cast<unsigned>(PF)))
+        return make_error<StringError>("error protecting memory: " +
+                                           EC.message(),
+                                       inconvertibleErrorCode());
+    }
+    return Error::success();
+  }
+
+  Error releaseMemory(const orcrpctpc::ReleaseOrFinalizeMemRequest &RMR) {
+    for (const auto &E : RMR) {
+      sys::MemoryBlock MB(jitTargetAddressToPointer<void *>(E.Address), E.Size);
+
+      if (auto EC = sys::Memory::releaseMappedMemory(MB))
+        return make_error<StringError>("error release memory: " + EC.message(),
+                                       inconvertibleErrorCode());
+    }
+    return Error::success();
+  }
+
+  Expected<tpctypes::DylibHandle> loadDylib(const std::string &Path) {
+    std::string ErrMsg;
+    const char *DLPath = !Path.empty() ? Path.c_str() : nullptr;
+    auto DL = sys::DynamicLibrary::getPermanentLibrary(DLPath, &ErrMsg);
+    if (!DL.isValid())
+      return make_error<StringError>(std::move(ErrMsg),
+                                     inconvertibleErrorCode());
+
+    tpctypes::DylibHandle H = Dylibs.size();
+    Dylibs[H] = std::move(DL);
+    return H;
+  }
+
+  Expected<std::vector<tpctypes::LookupResult>>
+  lookupSymbols(const std::vector<orcrpctpc::RemoteLookupRequest> &Request) {
+    std::vector<tpctypes::LookupResult> Result;
+
+    for (const auto &E : Request) {
+      auto I = Dylibs.find(E.first);
+      if (I == Dylibs.end())
+        return make_error<StringError>("Unrecognized handle",
+                                       inconvertibleErrorCode());
+      auto &DL = I->second;
+      Result.push_back({});
+
+      for (const auto &KV : E.second) {
+        auto &SymString = KV.first;
+        bool WeakReference = KV.second;
+
+        const char *Sym = SymString.c_str();
+#ifdef __APPLE__
+        if (*Sym == '_')
+          ++Sym;
+#endif
+
+        void *Addr = DL.getAddressOfSymbol(Sym);
+        if (!Addr && !WeakReference)
+          return make_error<StringError>(Twine("Missing definition for ") + Sym,
+                                         inconvertibleErrorCode());
+
+        Result.back().push_back(pointerToJITTargetAddress(Addr));
+      }
+    }
+
+    return Result;
+  }
+
+  int32_t runMain(JITTargetAddress MainFnAddr,
+                  const std::vector<std::string> &Args) {
+    Optional<StringRef> ProgramNameOverride;
+    if (ProgramName)
+      ProgramNameOverride = *ProgramName;
+
+    return runAsMain(
+        jitTargetAddressToFunction<int (*)(int, char *[])>(MainFnAddr), Args,
+        ProgramNameOverride);
+  }
+
+  tpctypes::WrapperFunctionResult
+  runWrapper(JITTargetAddress WrapperFnAddr,
+             const std::vector<uint8_t> &ArgBuffer) {
+    using WrapperFnTy = tpctypes::CWrapperFunctionResult (*)(
+        const uint8_t *Data, uint64_t Size);
+    auto *WrapperFn = jitTargetAddressToFunction<WrapperFnTy>(WrapperFnAddr);
+    return WrapperFn(ArgBuffer.data(), ArgBuffer.size());
+  }
+
+  void closeConnection() { Finished = true; }
+
+  std::string TripleStr;
+  uint64_t PageSize = 0;
+  Optional<std::string> ProgramName;
+  RPCEndpointT &EP;
+  std::atomic<bool> Finished{false};
+  DenseMap<tpctypes::DylibHandle, sys::DynamicLibrary> Dylibs;
+};
+
+} // end namespace orc
+} // end namespace llvm
+
+#endif // LLVM_EXECUTIONENGINE_ORC_TARGETPROCESS_ORCRPCTPCSERVER_H
diff --git a/linux-x64/clang/include/llvm/ExecutionEngine/Orc/TargetProcess/RegisterEHFrames.h b/linux-x64/clang/include/llvm/ExecutionEngine/Orc/TargetProcess/RegisterEHFrames.h
new file mode 100644
index 0000000..811c50e
--- /dev/null
+++ b/linux-x64/clang/include/llvm/ExecutionEngine/Orc/TargetProcess/RegisterEHFrames.h
@@ -0,0 +1,41 @@
+//===----- RegisterEHFrames.h -- Register EH frame sections -----*- 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
+//
+//===----------------------------------------------------------------------===//
+//
+// Support for dynamically registering and deregistering eh-frame sections
+// in-process via libunwind.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_EXECUTIONENGINE_ORC_TARGETPROCESS_REGISTEREHFRAMES_H
+#define LLVM_EXECUTIONENGINE_ORC_TARGETPROCESS_REGISTEREHFRAMES_H
+
+#include "llvm/ExecutionEngine/Orc/Shared/TargetProcessControlTypes.h"
+#include "llvm/Support/Error.h"
+#include <vector>
+
+namespace llvm {
+namespace orc {
+
+/// Register frames in the given eh-frame section with libunwind.
+Error registerEHFrameSection(const void *EHFrameSectionAddr,
+                             size_t EHFrameSectionSize);
+
+/// Unregister frames in the given eh-frame section with libunwind.
+Error deregisterEHFrameSection(const void *EHFrameSectionAddr,
+                               size_t EHFrameSectionSize);
+
+} // end namespace orc
+} // end namespace llvm
+
+extern "C" llvm::orc::tpctypes::CWrapperFunctionResult
+llvm_orc_registerEHFrameSectionWrapper(uint8_t *Data, uint64_t Size);
+
+extern "C" llvm::orc::tpctypes::CWrapperFunctionResult
+llvm_orc_deregisterEHFrameSectionWrapper(uint8_t *Data, uint64_t Size);
+
+#endif // LLVM_EXECUTIONENGINE_ORC_TARGETPROCESS_REGISTEREHFRAMES_H
diff --git a/linux-x64/clang/include/llvm/ExecutionEngine/Orc/TargetProcess/TargetExecutionUtils.h b/linux-x64/clang/include/llvm/ExecutionEngine/Orc/TargetProcess/TargetExecutionUtils.h
new file mode 100644
index 0000000..1d2f6d2
--- /dev/null
+++ b/linux-x64/clang/include/llvm/ExecutionEngine/Orc/TargetProcess/TargetExecutionUtils.h
@@ -0,0 +1,38 @@
+//===-- TargetExecutionUtils.h - Utils for execution in target --*- 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
+//
+//===----------------------------------------------------------------------===//
+//
+// Utilities for execution in the target process.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_EXECUTIONENGINE_ORC_TARGETPROCESS_TARGETEXECUTIONUTILS_H
+#define LLVM_EXECUTIONENGINE_ORC_TARGETPROCESS_TARGETEXECUTIONUTILS_H
+
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/Optional.h"
+#include "llvm/ADT/StringRef.h"
+#include <string>
+
+namespace llvm {
+namespace orc {
+
+/// Run a main function, returning the result.
+///
+/// If the optional ProgramName argument is given then it will be inserted
+/// before the strings in Args as the first argument to the called function.
+///
+/// It is legal to have an empty argument list and no program name, however
+/// many main functions will expect a name argument at least, and will fail
+/// if none is provided.
+int runAsMain(int (*Main)(int, char *[]), ArrayRef<std::string> Args,
+              Optional<StringRef> ProgramName = None);
+
+} // end namespace orc
+} // end namespace llvm
+
+#endif // LLVM_EXECUTIONENGINE_ORC_TARGETPROCESS_TARGETEXECUTIONUTILS_H
diff --git a/linux-x64/clang/include/llvm/ExecutionEngine/Orc/TargetProcessControl.h b/linux-x64/clang/include/llvm/ExecutionEngine/Orc/TargetProcessControl.h
new file mode 100644
index 0000000..504a5ea
--- /dev/null
+++ b/linux-x64/clang/include/llvm/ExecutionEngine/Orc/TargetProcessControl.h
@@ -0,0 +1,210 @@
+//===--- TargetProcessControl.h - Target process control APIs ---*- 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
+//
+//===----------------------------------------------------------------------===//
+//
+// Utilities for interacting with target processes.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_EXECUTIONENGINE_ORC_TARGETPROCESSCONTROL_H
+#define LLVM_EXECUTIONENGINE_ORC_TARGETPROCESSCONTROL_H
+
+#include "llvm/ADT/Optional.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/Triple.h"
+#include "llvm/ExecutionEngine/JITLink/JITLinkMemoryManager.h"
+#include "llvm/ExecutionEngine/Orc/Core.h"
+#include "llvm/ExecutionEngine/Orc/Shared/TargetProcessControlTypes.h"
+#include "llvm/Support/DynamicLibrary.h"
+#include "llvm/Support/MSVCErrorWorkarounds.h"
+
+#include <future>
+#include <vector>
+
+namespace llvm {
+namespace orc {
+
+/// TargetProcessControl supports interaction with a JIT target process.
+class TargetProcessControl {
+public:
+  /// APIs for manipulating memory in the target process.
+  class MemoryAccess {
+  public:
+    /// Callback function for asynchronous writes.
+    using WriteResultFn = unique_function<void(Error)>;
+
+    virtual ~MemoryAccess();
+
+    virtual void writeUInt8s(ArrayRef<tpctypes::UInt8Write> Ws,
+                             WriteResultFn OnWriteComplete) = 0;
+
+    virtual void writeUInt16s(ArrayRef<tpctypes::UInt16Write> Ws,
+                              WriteResultFn OnWriteComplete) = 0;
+
+    virtual void writeUInt32s(ArrayRef<tpctypes::UInt32Write> Ws,
+                              WriteResultFn OnWriteComplete) = 0;
+
+    virtual void writeUInt64s(ArrayRef<tpctypes::UInt64Write> Ws,
+                              WriteResultFn OnWriteComplete) = 0;
+
+    virtual void writeBuffers(ArrayRef<tpctypes::BufferWrite> Ws,
+                              WriteResultFn OnWriteComplete) = 0;
+
+    Error writeUInt8s(ArrayRef<tpctypes::UInt8Write> Ws) {
+      std::promise<MSVCPError> ResultP;
+      auto ResultF = ResultP.get_future();
+      writeUInt8s(Ws, [&](Error Err) { ResultP.set_value(std::move(Err)); });
+      return ResultF.get();
+    }
+
+    Error writeUInt16s(ArrayRef<tpctypes::UInt16Write> Ws) {
+      std::promise<MSVCPError> ResultP;
+      auto ResultF = ResultP.get_future();
+      writeUInt16s(Ws, [&](Error Err) { ResultP.set_value(std::move(Err)); });
+      return ResultF.get();
+    }
+
+    Error writeUInt32s(ArrayRef<tpctypes::UInt32Write> Ws) {
+      std::promise<MSVCPError> ResultP;
+      auto ResultF = ResultP.get_future();
+      writeUInt32s(Ws, [&](Error Err) { ResultP.set_value(std::move(Err)); });
+      return ResultF.get();
+    }
+
+    Error writeUInt64s(ArrayRef<tpctypes::UInt64Write> Ws) {
+      std::promise<MSVCPError> ResultP;
+      auto ResultF = ResultP.get_future();
+      writeUInt64s(Ws, [&](Error Err) { ResultP.set_value(std::move(Err)); });
+      return ResultF.get();
+    }
+
+    Error writeBuffers(ArrayRef<tpctypes::BufferWrite> Ws) {
+      std::promise<MSVCPError> ResultP;
+      auto ResultF = ResultP.get_future();
+      writeBuffers(Ws, [&](Error Err) { ResultP.set_value(std::move(Err)); });
+      return ResultF.get();
+    }
+  };
+
+  virtual ~TargetProcessControl();
+
+  /// Intern a symbol name in the SymbolStringPool.
+  SymbolStringPtr intern(StringRef SymName) { return SSP->intern(SymName); }
+
+  /// Return a shared pointer to the SymbolStringPool for this instance.
+  std::shared_ptr<SymbolStringPool> getSymbolStringPool() const { return SSP; }
+
+  /// Return the Triple for the target process.
+  const Triple &getTargetTriple() const { return TargetTriple; }
+
+  /// Get the page size for the target process.
+  unsigned getPageSize() const { return PageSize; }
+
+  /// Return a MemoryAccess object for the target process.
+  MemoryAccess &getMemoryAccess() const { return *MemAccess; }
+
+  /// Return a JITLinkMemoryManager for the target process.
+  jitlink::JITLinkMemoryManager &getMemMgr() const { return *MemMgr; }
+
+  /// Load the dynamic library at the given path and return a handle to it.
+  /// If LibraryPath is null this function will return the global handle for
+  /// the target process.
+  virtual Expected<tpctypes::DylibHandle> loadDylib(const char *DylibPath) = 0;
+
+  /// Search for symbols in the target process.
+  ///
+  /// The result of the lookup is a 2-dimentional array of target addresses
+  /// that correspond to the lookup order. If a required symbol is not
+  /// found then this method will return an error. If a weakly referenced
+  /// symbol is not found then it be assigned a '0' value in the result.
+  /// that correspond to the lookup order.
+  virtual Expected<std::vector<tpctypes::LookupResult>>
+  lookupSymbols(ArrayRef<tpctypes::LookupRequest> Request) = 0;
+
+  /// Run function with a main-like signature.
+  virtual Expected<int32_t> runAsMain(JITTargetAddress MainFnAddr,
+                                      ArrayRef<std::string> Args) = 0;
+
+  /// Run a wrapper function with signature:
+  ///
+  /// \code{.cpp}
+  ///   CWrapperFunctionResult fn(uint8_t *Data, uint64_t Size);
+  /// \endcode{.cpp}
+  ///
+  virtual Expected<tpctypes::WrapperFunctionResult>
+  runWrapper(JITTargetAddress WrapperFnAddr, ArrayRef<uint8_t> ArgBuffer) = 0;
+
+  /// Disconnect from the target process.
+  ///
+  /// This should be called after the JIT session is shut down.
+  virtual Error disconnect() = 0;
+
+protected:
+  TargetProcessControl(std::shared_ptr<SymbolStringPool> SSP)
+      : SSP(std::move(SSP)) {}
+
+  std::shared_ptr<SymbolStringPool> SSP;
+  Triple TargetTriple;
+  unsigned PageSize = 0;
+  MemoryAccess *MemAccess = nullptr;
+  jitlink::JITLinkMemoryManager *MemMgr = nullptr;
+};
+
+/// A TargetProcessControl implementation targeting the current process.
+class SelfTargetProcessControl : public TargetProcessControl,
+                                 private TargetProcessControl::MemoryAccess {
+public:
+  SelfTargetProcessControl(
+      std::shared_ptr<SymbolStringPool> SSP, Triple TargetTriple,
+      unsigned PageSize, std::unique_ptr<jitlink::JITLinkMemoryManager> MemMgr);
+
+  /// Create a SelfTargetProcessControl with the given memory manager.
+  /// If no memory manager is given a jitlink::InProcessMemoryManager will
+  /// be used by default.
+  static Expected<std::unique_ptr<SelfTargetProcessControl>>
+  Create(std::shared_ptr<SymbolStringPool> SSP,
+         std::unique_ptr<jitlink::JITLinkMemoryManager> MemMgr = nullptr);
+
+  Expected<tpctypes::DylibHandle> loadDylib(const char *DylibPath) override;
+
+  Expected<std::vector<tpctypes::LookupResult>>
+  lookupSymbols(ArrayRef<tpctypes::LookupRequest> Request) override;
+
+  Expected<int32_t> runAsMain(JITTargetAddress MainFnAddr,
+                              ArrayRef<std::string> Args) override;
+
+  Expected<tpctypes::WrapperFunctionResult>
+  runWrapper(JITTargetAddress WrapperFnAddr,
+             ArrayRef<uint8_t> ArgBuffer) override;
+
+  Error disconnect() override;
+
+private:
+  void writeUInt8s(ArrayRef<tpctypes::UInt8Write> Ws,
+                   WriteResultFn OnWriteComplete) override;
+
+  void writeUInt16s(ArrayRef<tpctypes::UInt16Write> Ws,
+                    WriteResultFn OnWriteComplete) override;
+
+  void writeUInt32s(ArrayRef<tpctypes::UInt32Write> Ws,
+                    WriteResultFn OnWriteComplete) override;
+
+  void writeUInt64s(ArrayRef<tpctypes::UInt64Write> Ws,
+                    WriteResultFn OnWriteComplete) override;
+
+  void writeBuffers(ArrayRef<tpctypes::BufferWrite> Ws,
+                    WriteResultFn OnWriteComplete) override;
+
+  std::unique_ptr<jitlink::JITLinkMemoryManager> OwnedMemMgr;
+  char GlobalManglingPrefix = 0;
+  std::vector<std::unique_ptr<sys::DynamicLibrary>> DynamicLibraries;
+};
+
+} // end namespace orc
+} // end namespace llvm
+
+#endif // LLVM_EXECUTIONENGINE_ORC_TARGETPROCESSCONTROL_H
diff --git a/linux-x64/clang/include/llvm/ExecutionEngine/Orc/ThreadSafeModule.h b/linux-x64/clang/include/llvm/ExecutionEngine/Orc/ThreadSafeModule.h
index 5787500..82f2b74 100644
--- a/linux-x64/clang/include/llvm/ExecutionEngine/Orc/ThreadSafeModule.h
+++ b/linux-x64/clang/include/llvm/ExecutionEngine/Orc/ThreadSafeModule.h
@@ -38,17 +38,12 @@
 public:
   // RAII based lock for ThreadSafeContext.
   class LLVM_NODISCARD Lock {
-  private:
-    using UnderlyingLock = std::lock_guard<std::recursive_mutex>;
-
   public:
-    Lock(std::shared_ptr<State> S)
-        : S(std::move(S)),
-          L(llvm::make_unique<UnderlyingLock>(this->S->Mutex)) {}
+    Lock(std::shared_ptr<State> S) : S(std::move(S)), L(this->S->Mutex) {}
 
   private:
     std::shared_ptr<State> S;
-    std::unique_ptr<UnderlyingLock> L;
+    std::unique_lock<std::recursive_mutex> L;
   };
 
   /// Construct a null context.
@@ -69,7 +64,7 @@
   /// instance, or null if the instance was default constructed.
   const LLVMContext *getContext() const { return S ? S->Ctx.get() : nullptr; }
 
-  Lock getLock() {
+  Lock getLock() const {
     assert(S && "Can not lock an empty ThreadSafeContext");
     return Lock(S);
   }
@@ -95,7 +90,7 @@
     // We also need to lock the context to make sure the module tear-down
     // does not overlap any other work on the context.
     if (M) {
-      auto L = getContextLock();
+      auto L = TSCtx.getLock();
       M = nullptr;
     }
     M = std::move(Other.M);
@@ -117,23 +112,14 @@
   ~ThreadSafeModule() {
     // We need to lock the context while we destruct the module.
     if (M) {
-      auto L = getContextLock();
+      auto L = TSCtx.getLock();
       M = nullptr;
     }
   }
 
-  /// Get the module wrapped by this ThreadSafeModule.
-  Module *getModule() { return M.get(); }
-
-  /// Get the module wrapped by this ThreadSafeModule.
-  const Module *getModule() const { return M.get(); }
-
-  /// Take out a lock on the ThreadSafeContext for this module.
-  ThreadSafeContext::Lock getContextLock() { return TSCtx.getLock(); }
-
   /// Boolean conversion: This ThreadSafeModule will evaluate to true if it
   /// wraps a non-null module.
-  explicit operator bool() {
+  explicit operator bool() const {
     if (M) {
       assert(TSCtx.getContext() &&
              "Non-null module must have non-null context");
@@ -142,6 +128,30 @@
     return false;
   }
 
+  /// Locks the associated ThreadSafeContext and calls the given function
+  /// on the contained Module.
+  template <typename Func> decltype(auto) withModuleDo(Func &&F) {
+    assert(M && "Can not call on null module");
+    auto Lock = TSCtx.getLock();
+    return F(*M);
+  }
+
+  /// Locks the associated ThreadSafeContext and calls the given function
+  /// on the contained Module.
+  template <typename Func> decltype(auto) withModuleDo(Func &&F) const {
+    auto Lock = TSCtx.getLock();
+    return F(*M);
+  }
+
+  /// Get a raw pointer to the contained module without locking the context.
+  Module *getModuleUnlocked() { return M.get(); }
+
+  /// Get a raw pointer to the contained module without locking the context.
+  const Module *getModuleUnlocked() const { return M.get(); }
+
+  /// Returns the context for this ThreadSafeModule.
+  ThreadSafeContext getContext() const { return TSCtx; }
+
 private:
   std::unique_ptr<Module> M;
   ThreadSafeContext TSCtx;
@@ -152,7 +162,7 @@
 
 /// Clones the given module on to a new context.
 ThreadSafeModule
-cloneToNewContext(ThreadSafeModule &TSMW,
+cloneToNewContext(const ThreadSafeModule &TSMW,
                   GVPredicate ShouldCloneDef = GVPredicate(),
                   GVModifier UpdateClonedDefSource = GVModifier());