//===--------- LLJIT.cpp - An ORC-based JIT for compiling LLVM IR ---------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#include "llvm/ExecutionEngine/Orc/LLJIT.h"

#include "llvm/Analysis/TargetLibraryInfo.h"
#include "llvm/Config/llvm-config.h" // for LLVM_ENABLE_THREADS
#include "llvm/ExecutionEngine/Orc/COFFPlatform.h"
#include "llvm/ExecutionEngine/Orc/EHFrameRegistrationPlugin.h"
#include "llvm/ExecutionEngine/Orc/ELFNixPlatform.h"
#include "llvm/ExecutionEngine/Orc/EPCDynamicLibrarySearchGenerator.h"
#include "llvm/ExecutionEngine/Orc/ExecutorProcessControl.h"
#include "llvm/ExecutionEngine/Orc/MachOPlatform.h"
#include "llvm/ExecutionEngine/Orc/ObjectLinkingLayer.h"
#include "llvm/ExecutionEngine/Orc/ObjectTransformLayer.h"
#include "llvm/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.h"
#include "llvm/ExecutionEngine/Orc/SelfExecutorProcessControl.h"
#include "llvm/ExecutionEngine/Orc/TargetProcess/RegisterEHFrames.h"
#include "llvm/ExecutionEngine/Orc/UnwindInfoRegistrationPlugin.h"
#include "llvm/ExecutionEngine/SectionMemoryManager.h"
#include "llvm/IR/GlobalVariable.h"
#include "llvm/IR/IRBuilder.h"
#include "llvm/IR/Mangler.h"
#include "llvm/IR/Module.h"
#include "llvm/Support/DynamicLibrary.h"

#define DEBUG_TYPE "orc"

using namespace llvm;
using namespace llvm::orc;

namespace {

/// Adds helper function decls and wrapper functions that call the helper with
/// some additional prefix arguments.
///
/// E.g. For wrapper "foo" with type i8(i8, i64), helper "bar", and prefix
/// args i32 4 and i16 12345, this function will add:
///
/// declare i8 @bar(i32, i16, i8, i64)
///
/// define i8 @foo(i8, i64) {
/// entry:
///   %2 = call i8 @bar(i32 4, i16 12345, i8 %0, i64 %1)
///   ret i8 %2
/// }
///
Function *addHelperAndWrapper(Module &M, StringRef WrapperName,
                              FunctionType *WrapperFnType,
                              GlobalValue::VisibilityTypes WrapperVisibility,
                              StringRef HelperName,
                              ArrayRef<Value *> HelperPrefixArgs) {
  std::vector<Type *> HelperArgTypes;
  for (auto *Arg : HelperPrefixArgs)
    HelperArgTypes.push_back(Arg->getType());
  llvm::append_range(HelperArgTypes, WrapperFnType->params());
  auto *HelperFnType =
      FunctionType::get(WrapperFnType->getReturnType(), HelperArgTypes, false);
  auto *HelperFn = Function::Create(HelperFnType, GlobalValue::ExternalLinkage,
                                    HelperName, M);

  auto *WrapperFn = Function::Create(
      WrapperFnType, GlobalValue::ExternalLinkage, WrapperName, M);
  WrapperFn->setVisibility(WrapperVisibility);

  auto *EntryBlock = BasicBlock::Create(M.getContext(), "entry", WrapperFn);
  IRBuilder<> IB(EntryBlock);

  std::vector<Value *> HelperArgs;
  llvm::append_range(HelperArgs, HelperPrefixArgs);
  for (auto &Arg : WrapperFn->args())
    HelperArgs.push_back(&Arg);
  auto *HelperResult = IB.CreateCall(HelperFn, HelperArgs);
  if (HelperFn->getReturnType()->isVoidTy())
    IB.CreateRetVoid();
  else
    IB.CreateRet(HelperResult);

  return WrapperFn;
}

class GenericLLVMIRPlatformSupport;

/// orc::Platform component of Generic LLVM IR Platform support.
/// Just forwards calls to the GenericLLVMIRPlatformSupport class below.
class GenericLLVMIRPlatform : public Platform {
public:
  GenericLLVMIRPlatform(GenericLLVMIRPlatformSupport &S) : S(S) {}
  Error setupJITDylib(JITDylib &JD) override;
  Error teardownJITDylib(JITDylib &JD) override;
  Error notifyAdding(ResourceTracker &RT,
                     const MaterializationUnit &MU) override;
  Error notifyRemoving(ResourceTracker &RT) override {
    // Noop -- Nothing to do (yet).
    return Error::success();
  }

private:
  GenericLLVMIRPlatformSupport &S;
};

/// This transform parses llvm.global_ctors to produce a single initialization
/// function for the module, records the function, then deletes
/// llvm.global_ctors.
class GlobalCtorDtorScraper {
public:
  GlobalCtorDtorScraper(GenericLLVMIRPlatformSupport &PS,
                        StringRef InitFunctionPrefix,
                        StringRef DeInitFunctionPrefix)
      : PS(PS), InitFunctionPrefix(InitFunctionPrefix),
        DeInitFunctionPrefix(DeInitFunctionPrefix) {}
  Expected<ThreadSafeModule> operator()(ThreadSafeModule TSM,
                                        MaterializationResponsibility &R);

private:
  GenericLLVMIRPlatformSupport &PS;
  StringRef InitFunctionPrefix;
  StringRef DeInitFunctionPrefix;
};

/// Generic IR Platform Support
///
/// Scrapes llvm.global_ctors and llvm.global_dtors and replaces them with
/// specially named 'init' and 'deinit'. Injects definitions / interposes for
/// some runtime API, including __cxa_atexit, dlopen, and dlclose.
class GenericLLVMIRPlatformSupport : public LLJIT::PlatformSupport {
public:
  GenericLLVMIRPlatformSupport(LLJIT &J, JITDylib &PlatformJD)
      : J(J), InitFunctionPrefix(J.mangle("__orc_init_func.")),
        DeInitFunctionPrefix(J.mangle("__orc_deinit_func.")) {

    getExecutionSession().setPlatform(
        std::make_unique<GenericLLVMIRPlatform>(*this));

    setInitTransform(J, GlobalCtorDtorScraper(*this, InitFunctionPrefix,
                                              DeInitFunctionPrefix));

    SymbolMap StdInterposes;

    StdInterposes[J.mangleAndIntern("__lljit.platform_support_instance")] = {
        ExecutorAddr::fromPtr(this), JITSymbolFlags::Exported};
    StdInterposes[J.mangleAndIntern("__lljit.cxa_atexit_helper")] = {
        ExecutorAddr::fromPtr(registerCxaAtExitHelper), JITSymbolFlags()};

    cantFail(PlatformJD.define(absoluteSymbols(std::move(StdInterposes))));
    cantFail(setupJITDylib(PlatformJD));
    cantFail(J.addIRModule(PlatformJD, createPlatformRuntimeModule()));
  }

  ExecutionSession &getExecutionSession() { return J.getExecutionSession(); }

  /// Adds a module that defines the __dso_handle global.
  Error setupJITDylib(JITDylib &JD) {

    // Add per-jitdylib standard interposes.
    SymbolMap PerJDInterposes;
    PerJDInterposes[J.mangleAndIntern("__lljit.run_atexits_helper")] = {
        ExecutorAddr::fromPtr(runAtExitsHelper), JITSymbolFlags()};
    PerJDInterposes[J.mangleAndIntern("__lljit.atexit_helper")] = {
        ExecutorAddr::fromPtr(registerAtExitHelper), JITSymbolFlags()};
    cantFail(JD.define(absoluteSymbols(std::move(PerJDInterposes))));

    auto Ctx = std::make_unique<LLVMContext>();
    auto M = std::make_unique<Module>("__standard_lib", *Ctx);
    M->setDataLayout(J.getDataLayout());

    auto *Int64Ty = Type::getInt64Ty(*Ctx);
    auto *DSOHandle = new GlobalVariable(
        *M, Int64Ty, true, GlobalValue::ExternalLinkage,
        ConstantInt::get(Int64Ty, reinterpret_cast<uintptr_t>(&JD)),
        "__dso_handle");
    DSOHandle->setVisibility(GlobalValue::DefaultVisibility);
    DSOHandle->setInitializer(
        ConstantInt::get(Int64Ty, ExecutorAddr::fromPtr(&JD).getValue()));

    auto *GenericIRPlatformSupportTy =
        StructType::create(*Ctx, "lljit.GenericLLJITIRPlatformSupport");

    auto *PlatformInstanceDecl = new GlobalVariable(
        *M, GenericIRPlatformSupportTy, true, GlobalValue::ExternalLinkage,
        nullptr, "__lljit.platform_support_instance");

    auto *VoidTy = Type::getVoidTy(*Ctx);
    addHelperAndWrapper(
        *M, "__lljit_run_atexits", FunctionType::get(VoidTy, {}, false),
        GlobalValue::HiddenVisibility, "__lljit.run_atexits_helper",
        {PlatformInstanceDecl, DSOHandle});

    auto *IntTy = Type::getIntNTy(*Ctx, sizeof(int) * CHAR_BIT);
    auto *AtExitCallbackPtrTy = PointerType::getUnqual(*Ctx);
    auto *AtExit = addHelperAndWrapper(
        *M, "atexit", FunctionType::get(IntTy, {AtExitCallbackPtrTy}, false),
        GlobalValue::HiddenVisibility, "__lljit.atexit_helper",
        {PlatformInstanceDecl, DSOHandle});
    Attribute::AttrKind AtExitExtAttr =
        TargetLibraryInfo::getExtAttrForI32Return(J.getTargetTriple());
    if (AtExitExtAttr != Attribute::None)
      AtExit->addRetAttr(AtExitExtAttr);

    return J.addIRModule(JD, ThreadSafeModule(std::move(M), std::move(Ctx)));
  }

  Error notifyAdding(ResourceTracker &RT, const MaterializationUnit &MU) {
    auto &JD = RT.getJITDylib();
    if (auto &InitSym = MU.getInitializerSymbol())
      InitSymbols[&JD].add(InitSym, SymbolLookupFlags::WeaklyReferencedSymbol);
    else {
      // If there's no identified init symbol attached, but there is a symbol
      // with the GenericIRPlatform::InitFunctionPrefix, then treat that as
      // an init function. Add the symbol to both the InitSymbols map (which
      // will trigger a lookup to materialize the module) and the InitFunctions
      // map (which holds the names of the symbols to execute).
      for (auto &KV : MU.getSymbols())
        if ((*KV.first).starts_with(InitFunctionPrefix)) {
          InitSymbols[&JD].add(KV.first,
                               SymbolLookupFlags::WeaklyReferencedSymbol);
          InitFunctions[&JD].add(KV.first);
        } else if ((*KV.first).starts_with(DeInitFunctionPrefix)) {
          DeInitFunctions[&JD].add(KV.first);
        }
    }
    return Error::success();
  }

  Error initialize(JITDylib &JD) override {
    LLVM_DEBUG({
      dbgs() << "GenericLLVMIRPlatformSupport getting initializers to run\n";
    });
    if (auto Initializers = getInitializers(JD)) {
      LLVM_DEBUG(
          { dbgs() << "GenericLLVMIRPlatformSupport running initializers\n"; });
      for (auto InitFnAddr : *Initializers) {
        LLVM_DEBUG({
          dbgs() << "  Running init " << formatv("{0:x16}", InitFnAddr)
                 << "...\n";
        });
        auto *InitFn = InitFnAddr.toPtr<void (*)()>();
        InitFn();
      }
    } else
      return Initializers.takeError();
    return Error::success();
  }

  Error deinitialize(JITDylib &JD) override {
    LLVM_DEBUG({
      dbgs() << "GenericLLVMIRPlatformSupport getting deinitializers to run\n";
    });
    if (auto Deinitializers = getDeinitializers(JD)) {
      LLVM_DEBUG({
        dbgs() << "GenericLLVMIRPlatformSupport running deinitializers\n";
      });
      for (auto DeinitFnAddr : *Deinitializers) {
        LLVM_DEBUG({
          dbgs() << "  Running deinit " << formatv("{0:x16}", DeinitFnAddr)
                 << "...\n";
        });
        auto *DeinitFn = DeinitFnAddr.toPtr<void (*)()>();
        DeinitFn();
      }
    } else
      return Deinitializers.takeError();

    return Error::success();
  }

  void registerInitFunc(JITDylib &JD, SymbolStringPtr InitName) {
    getExecutionSession().runSessionLocked(
        [&]() { InitFunctions[&JD].add(InitName); });
  }

  void registerDeInitFunc(JITDylib &JD, SymbolStringPtr DeInitName) {
    getExecutionSession().runSessionLocked(
        [&]() { DeInitFunctions[&JD].add(DeInitName); });
  }

private:
  Expected<std::vector<ExecutorAddr>> getInitializers(JITDylib &JD) {
    if (auto Err = issueInitLookups(JD))
      return std::move(Err);

    DenseMap<JITDylib *, SymbolLookupSet> LookupSymbols;
    std::vector<JITDylibSP> DFSLinkOrder;

    if (auto Err = getExecutionSession().runSessionLocked([&]() -> Error {
          if (auto DFSLinkOrderOrErr = JD.getDFSLinkOrder())
            DFSLinkOrder = std::move(*DFSLinkOrderOrErr);
          else
            return DFSLinkOrderOrErr.takeError();

          for (auto &NextJD : DFSLinkOrder) {
            auto IFItr = InitFunctions.find(NextJD.get());
            if (IFItr != InitFunctions.end()) {
              LookupSymbols[NextJD.get()] = std::move(IFItr->second);
              InitFunctions.erase(IFItr);
            }
          }
          return Error::success();
        }))
      return std::move(Err);

    LLVM_DEBUG({
      dbgs() << "JITDylib init order is [ ";
      for (auto &JD : llvm::reverse(DFSLinkOrder))
        dbgs() << "\"" << JD->getName() << "\" ";
      dbgs() << "]\n";
      dbgs() << "Looking up init functions:\n";
      for (auto &KV : LookupSymbols)
        dbgs() << "  \"" << KV.first->getName() << "\": " << KV.second << "\n";
    });

    auto &ES = getExecutionSession();
    auto LookupResult = Platform::lookupInitSymbols(ES, LookupSymbols);

    if (!LookupResult)
      return LookupResult.takeError();

    std::vector<ExecutorAddr> Initializers;
    while (!DFSLinkOrder.empty()) {
      auto &NextJD = *DFSLinkOrder.back();
      DFSLinkOrder.pop_back();
      auto InitsItr = LookupResult->find(&NextJD);
      if (InitsItr == LookupResult->end())
        continue;
      for (auto &KV : InitsItr->second)
        Initializers.push_back(KV.second.getAddress());
    }

    return Initializers;
  }

  Expected<std::vector<ExecutorAddr>> getDeinitializers(JITDylib &JD) {
    auto &ES = getExecutionSession();

    auto LLJITRunAtExits = J.mangleAndIntern("__lljit_run_atexits");

    DenseMap<JITDylib *, SymbolLookupSet> LookupSymbols;
    std::vector<JITDylibSP> DFSLinkOrder;

    if (auto Err = ES.runSessionLocked([&]() -> Error {
          if (auto DFSLinkOrderOrErr = JD.getDFSLinkOrder())
            DFSLinkOrder = std::move(*DFSLinkOrderOrErr);
          else
            return DFSLinkOrderOrErr.takeError();

          for (auto &NextJD : DFSLinkOrder) {
            auto &JDLookupSymbols = LookupSymbols[NextJD.get()];
            auto DIFItr = DeInitFunctions.find(NextJD.get());
            if (DIFItr != DeInitFunctions.end()) {
              LookupSymbols[NextJD.get()] = std::move(DIFItr->second);
              DeInitFunctions.erase(DIFItr);
            }
            JDLookupSymbols.add(LLJITRunAtExits,
                                SymbolLookupFlags::WeaklyReferencedSymbol);
          }
          return Error::success();
        }))
      return std::move(Err);

    LLVM_DEBUG({
      dbgs() << "JITDylib deinit order is [ ";
      for (auto &JD : DFSLinkOrder)
        dbgs() << "\"" << JD->getName() << "\" ";
      dbgs() << "]\n";
      dbgs() << "Looking up deinit functions:\n";
      for (auto &KV : LookupSymbols)
        dbgs() << "  \"" << KV.first->getName() << "\": " << KV.second << "\n";
    });

    auto LookupResult = Platform::lookupInitSymbols(ES, LookupSymbols);

    if (!LookupResult)
      return LookupResult.takeError();

    std::vector<ExecutorAddr> DeInitializers;
    for (auto &NextJD : DFSLinkOrder) {
      auto DeInitsItr = LookupResult->find(NextJD.get());
      assert(DeInitsItr != LookupResult->end() &&
             "Every JD should have at least __lljit_run_atexits");

      auto RunAtExitsItr = DeInitsItr->second.find(LLJITRunAtExits);
      if (RunAtExitsItr != DeInitsItr->second.end())
        DeInitializers.push_back(RunAtExitsItr->second.getAddress());

      for (auto &KV : DeInitsItr->second)
        if (KV.first != LLJITRunAtExits)
          DeInitializers.push_back(KV.second.getAddress());
    }

    return DeInitializers;
  }

  /// Issue lookups for all init symbols required to initialize JD (and any
  /// JITDylibs that it depends on).
  Error issueInitLookups(JITDylib &JD) {
    DenseMap<JITDylib *, SymbolLookupSet> RequiredInitSymbols;
    std::vector<JITDylibSP> DFSLinkOrder;

    if (auto Err = getExecutionSession().runSessionLocked([&]() -> Error {
          if (auto DFSLinkOrderOrErr = JD.getDFSLinkOrder())
            DFSLinkOrder = std::move(*DFSLinkOrderOrErr);
          else
            return DFSLinkOrderOrErr.takeError();

          for (auto &NextJD : DFSLinkOrder) {
            auto ISItr = InitSymbols.find(NextJD.get());
            if (ISItr != InitSymbols.end()) {
              RequiredInitSymbols[NextJD.get()] = std::move(ISItr->second);
              InitSymbols.erase(ISItr);
            }
          }
          return Error::success();
        }))
      return Err;

    return Platform::lookupInitSymbols(getExecutionSession(),
                                       RequiredInitSymbols)
        .takeError();
  }

  static void registerCxaAtExitHelper(void *Self, void (*F)(void *), void *Ctx,
                                      void *DSOHandle) {
    LLVM_DEBUG({
      dbgs() << "Registering cxa atexit function " << (void *)F << " for JD "
             << (*static_cast<JITDylib **>(DSOHandle))->getName() << "\n";
    });
    static_cast<GenericLLVMIRPlatformSupport *>(Self)->AtExitMgr.registerAtExit(
        F, Ctx, DSOHandle);
  }

  static void registerAtExitHelper(void *Self, void *DSOHandle, void (*F)()) {
    LLVM_DEBUG({
      dbgs() << "Registering atexit function " << (void *)F << " for JD "
             << (*static_cast<JITDylib **>(DSOHandle))->getName() << "\n";
    });
    static_cast<GenericLLVMIRPlatformSupport *>(Self)->AtExitMgr.registerAtExit(
        reinterpret_cast<void (*)(void *)>(F), nullptr, DSOHandle);
  }

  static void runAtExitsHelper(void *Self, void *DSOHandle) {
    LLVM_DEBUG({
      dbgs() << "Running atexit functions for JD "
             << (*static_cast<JITDylib **>(DSOHandle))->getName() << "\n";
    });
    static_cast<GenericLLVMIRPlatformSupport *>(Self)->AtExitMgr.runAtExits(
        DSOHandle);
  }

  // Constructs an LLVM IR module containing platform runtime globals,
  // functions, and interposes.
  ThreadSafeModule createPlatformRuntimeModule() {
    auto Ctx = std::make_unique<LLVMContext>();
    auto M = std::make_unique<Module>("__standard_lib", *Ctx);
    M->setDataLayout(J.getDataLayout());

    auto *GenericIRPlatformSupportTy =
        StructType::create(*Ctx, "lljit.GenericLLJITIRPlatformSupport");

    auto *PlatformInstanceDecl = new GlobalVariable(
        *M, GenericIRPlatformSupportTy, true, GlobalValue::ExternalLinkage,
        nullptr, "__lljit.platform_support_instance");

    auto *IntTy = Type::getIntNTy(*Ctx, sizeof(int) * CHAR_BIT);
    auto *BytePtrTy = PointerType::getUnqual(*Ctx);
    auto *CxaAtExitCallbackPtrTy = PointerType::getUnqual(*Ctx);

    auto *CxaAtExit = addHelperAndWrapper(
        *M, "__cxa_atexit",
        FunctionType::get(IntTy, {CxaAtExitCallbackPtrTy, BytePtrTy, BytePtrTy},
                          false),
        GlobalValue::DefaultVisibility, "__lljit.cxa_atexit_helper",
        {PlatformInstanceDecl});
    Attribute::AttrKind CxaAtExitExtAttr =
        TargetLibraryInfo::getExtAttrForI32Return(J.getTargetTriple());
    if (CxaAtExitExtAttr != Attribute::None)
      CxaAtExit->addRetAttr(CxaAtExitExtAttr);

    return ThreadSafeModule(std::move(M), std::move(Ctx));
  }

  LLJIT &J;
  std::string InitFunctionPrefix;
  std::string DeInitFunctionPrefix;
  DenseMap<JITDylib *, SymbolLookupSet> InitSymbols;
  DenseMap<JITDylib *, SymbolLookupSet> InitFunctions;
  DenseMap<JITDylib *, SymbolLookupSet> DeInitFunctions;
  ItaniumCXAAtExitSupport AtExitMgr;
};

Error GenericLLVMIRPlatform::setupJITDylib(JITDylib &JD) {
  return S.setupJITDylib(JD);
}

Error GenericLLVMIRPlatform::teardownJITDylib(JITDylib &JD) {
  return Error::success();
}

Error GenericLLVMIRPlatform::notifyAdding(ResourceTracker &RT,
                                          const MaterializationUnit &MU) {
  return S.notifyAdding(RT, MU);
}

Expected<ThreadSafeModule>
GlobalCtorDtorScraper::operator()(ThreadSafeModule TSM,
                                  MaterializationResponsibility &R) {
  auto Err = TSM.withModuleDo([&](Module &M) -> Error {
    auto &Ctx = M.getContext();
    auto *GlobalCtors = M.getNamedGlobal("llvm.global_ctors");
    auto *GlobalDtors = M.getNamedGlobal("llvm.global_dtors");

    auto RegisterCOrDtors = [&](GlobalVariable *GlobalCOrDtors,
                                bool isCtor) -> Error {
      // If there's no llvm.global_c/dtor or it's just a decl then skip.
      if (!GlobalCOrDtors || GlobalCOrDtors->isDeclaration())
        return Error::success();
      std::string InitOrDeInitFunctionName;
      if (isCtor)
        raw_string_ostream(InitOrDeInitFunctionName)
            << InitFunctionPrefix << M.getModuleIdentifier();
      else
        raw_string_ostream(InitOrDeInitFunctionName)
            << DeInitFunctionPrefix << M.getModuleIdentifier();

      MangleAndInterner Mangle(PS.getExecutionSession(), M.getDataLayout());
      auto InternedInitOrDeInitName = Mangle(InitOrDeInitFunctionName);
      if (auto Err = R.defineMaterializing(
              {{InternedInitOrDeInitName, JITSymbolFlags::Callable}}))
        return Err;

      auto *InitOrDeInitFunc = Function::Create(
          FunctionType::get(Type::getVoidTy(Ctx), {}, false),
          GlobalValue::ExternalLinkage, InitOrDeInitFunctionName, &M);
      InitOrDeInitFunc->setVisibility(GlobalValue::HiddenVisibility);
      std::vector<std::pair<Function *, unsigned>> InitsOrDeInits;
      auto COrDtors = isCtor ? getConstructors(M) : getDestructors(M);

      for (auto E : COrDtors)
        InitsOrDeInits.push_back(std::make_pair(E.Func, E.Priority));
      llvm::stable_sort(InitsOrDeInits, llvm::less_second());

      auto *InitOrDeInitFuncEntryBlock =
          BasicBlock::Create(Ctx, "entry", InitOrDeInitFunc);
      IRBuilder<> IB(InitOrDeInitFuncEntryBlock);
      for (auto &KV : InitsOrDeInits)
        IB.CreateCall(KV.first);
      IB.CreateRetVoid();

      if (isCtor)
        PS.registerInitFunc(R.getTargetJITDylib(), InternedInitOrDeInitName);
      else
        PS.registerDeInitFunc(R.getTargetJITDylib(), InternedInitOrDeInitName);

      GlobalCOrDtors->eraseFromParent();
      return Error::success();
    };

    if (auto Err = RegisterCOrDtors(GlobalCtors, true))
      return Err;
    if (auto Err = RegisterCOrDtors(GlobalDtors, false))
      return Err;

    return Error::success();
  });

  if (Err)
    return std::move(Err);

  return std::move(TSM);
}

/// Inactive Platform Support
///
/// Explicitly disables platform support. JITDylibs are not scanned for special
/// init/deinit symbols. No runtime API interposes are injected.
class InactivePlatformSupport : public LLJIT::PlatformSupport {
public:
  InactivePlatformSupport() = default;

  Error initialize(JITDylib &JD) override {
    LLVM_DEBUG(dbgs() << "InactivePlatformSupport: no initializers running for "
                      << JD.getName() << "\n");
    return Error::success();
  }

  Error deinitialize(JITDylib &JD) override {
    LLVM_DEBUG(
        dbgs() << "InactivePlatformSupport: no deinitializers running for "
               << JD.getName() << "\n");
    return Error::success();
  }
};

} // end anonymous namespace

namespace llvm {
namespace orc {

Error ORCPlatformSupport::initialize(orc::JITDylib &JD) {
  using llvm::orc::shared::SPSExecutorAddr;
  using llvm::orc::shared::SPSString;
  using SPSDLOpenSig = SPSExecutorAddr(SPSString, int32_t);
  using SPSDLUpdateSig = int32_t(SPSExecutorAddr);
  enum dlopen_mode : int32_t {
    ORC_RT_RTLD_LAZY = 0x1,
    ORC_RT_RTLD_NOW = 0x2,
    ORC_RT_RTLD_LOCAL = 0x4,
    ORC_RT_RTLD_GLOBAL = 0x8
  };

  auto &ES = J.getExecutionSession();
  auto MainSearchOrder = J.getMainJITDylib().withLinkOrderDo(
      [](const JITDylibSearchOrder &SO) { return SO; });
  StringRef WrapperToCall = "__orc_rt_jit_dlopen_wrapper";
  bool dlupdate = false;
  const Triple &TT = ES.getTargetTriple();
  if (TT.isOSBinFormatMachO() || TT.isOSBinFormatELF()) {
    if (InitializedDylib.contains(&JD)) {
      WrapperToCall = "__orc_rt_jit_dlupdate_wrapper";
      dlupdate = true;
    } else
      InitializedDylib.insert(&JD);
  }

  if (auto WrapperAddr =
          ES.lookup(MainSearchOrder, J.mangleAndIntern(WrapperToCall))) {
    if (dlupdate) {
      int32_t result;
      auto E = ES.callSPSWrapper<SPSDLUpdateSig>(WrapperAddr->getAddress(),
                                                 result, DSOHandles[&JD]);
      if (E)
        return E;
      else if (result)
        return make_error<StringError>("dlupdate failed",
                                       inconvertibleErrorCode());
    } else
      return ES.callSPSWrapper<SPSDLOpenSig>(WrapperAddr->getAddress(),
                                             DSOHandles[&JD], JD.getName(),
                                             int32_t(ORC_RT_RTLD_LAZY));
  } else
    return WrapperAddr.takeError();

  return Error::success();
}

Error ORCPlatformSupport::deinitialize(orc::JITDylib &JD) {
  using llvm::orc::shared::SPSExecutorAddr;
  using SPSDLCloseSig = int32_t(SPSExecutorAddr);

  auto &ES = J.getExecutionSession();
  auto MainSearchOrder = J.getMainJITDylib().withLinkOrderDo(
      [](const JITDylibSearchOrder &SO) { return SO; });

  if (auto WrapperAddr = ES.lookup(
          MainSearchOrder, J.mangleAndIntern("__orc_rt_jit_dlclose_wrapper"))) {
    int32_t result;
    auto E = J.getExecutionSession().callSPSWrapper<SPSDLCloseSig>(
        WrapperAddr->getAddress(), result, DSOHandles[&JD]);
    if (E)
      return E;
    else if (result)
      return make_error<StringError>("dlclose failed",
                                     inconvertibleErrorCode());
    DSOHandles.erase(&JD);
    InitializedDylib.erase(&JD);
  } else
    return WrapperAddr.takeError();
  return Error::success();
}

void LLJIT::PlatformSupport::setInitTransform(
    LLJIT &J, IRTransformLayer::TransformFunction T) {
  J.InitHelperTransformLayer->setTransform(std::move(T));
}

LLJIT::PlatformSupport::~PlatformSupport() = default;

Error LLJITBuilderState::prepareForConstruction() {

  LLVM_DEBUG(dbgs() << "Preparing to create LLJIT instance...\n");

  if (!JTMB) {
    LLVM_DEBUG({
      dbgs() << "  No explicitly set JITTargetMachineBuilder. "
                "Detecting host...\n";
    });
    if (auto JTMBOrErr = JITTargetMachineBuilder::detectHost())
      JTMB = std::move(*JTMBOrErr);
    else
      return JTMBOrErr.takeError();
  }

  if ((ES || EPC) && NumCompileThreads)
    return make_error<StringError>(
        "NumCompileThreads cannot be used with a custom ExecutionSession or "
        "ExecutorProcessControl",
        inconvertibleErrorCode());

#if !LLVM_ENABLE_THREADS
  if (NumCompileThreads)
    return make_error<StringError>(
        "LLJIT num-compile-threads is " + Twine(NumCompileThreads) +
            " but LLVM was compiled with LLVM_ENABLE_THREADS=Off",
        inconvertibleErrorCode());
#endif // !LLVM_ENABLE_THREADS

  // Only used in debug builds.
  [[maybe_unused]] bool ConcurrentCompilationSettingDefaulted =
      !SupportConcurrentCompilation;

  if (!SupportConcurrentCompilation) {
#if LLVM_ENABLE_THREADS
    SupportConcurrentCompilation = NumCompileThreads || ES || EPC;
#else
    SupportConcurrentCompilation = false;
#endif // LLVM_ENABLE_THREADS
  } else {
#if !LLVM_ENABLE_THREADS
    if (*SupportConcurrentCompilation)
      return make_error<StringError>(
          "LLJIT concurrent compilation support requested, but LLVM was built "
          "with LLVM_ENABLE_THREADS=Off",
          inconvertibleErrorCode());
#endif // !LLVM_ENABLE_THREADS
  }

  LLVM_DEBUG({
    dbgs() << "  JITTargetMachineBuilder is "
           << JITTargetMachineBuilderPrinter(*JTMB, "  ")
           << "  Pre-constructed ExecutionSession: " << (ES ? "Yes" : "No")
           << "\n"
           << "  DataLayout: ";
    if (DL)
      dbgs() << DL->getStringRepresentation() << "\n";
    else
      dbgs() << "None (will be created by JITTargetMachineBuilder)\n";

    dbgs() << "  Custom object-linking-layer creator: "
           << (CreateObjectLinkingLayer ? "Yes" : "No") << "\n"
           << "  Custom compile-function creator: "
           << (CreateCompileFunction ? "Yes" : "No") << "\n"
           << "  Custom platform-setup function: "
           << (SetUpPlatform ? "Yes" : "No") << "\n"
           << "  Support concurrent compilation: "
           << (*SupportConcurrentCompilation ? "Yes" : "No");
    if (ConcurrentCompilationSettingDefaulted)
      dbgs() << " (defaulted based on ES / EPC / NumCompileThreads)\n";
    else
      dbgs() << "\n";
    dbgs() << "  Number of compile threads: " << NumCompileThreads << "\n";
  });

  // Create DL if not specified.
  if (!DL) {
    if (auto DLOrErr = JTMB->getDefaultDataLayoutForTarget())
      DL = std::move(*DLOrErr);
    else
      return DLOrErr.takeError();
  }

  // If neither ES nor EPC has been set then create an EPC instance.
  if (!ES && !EPC) {
    LLVM_DEBUG({
      dbgs() << "ExecutorProcessControl not specified, "
                "Creating SelfExecutorProcessControl instance\n";
    });

    std::unique_ptr<TaskDispatcher> D = nullptr;
#if LLVM_ENABLE_THREADS
    if (*SupportConcurrentCompilation) {
      std::optional<size_t> NumThreads = std ::nullopt;
      if (NumCompileThreads)
        NumThreads = NumCompileThreads;
      D = std::make_unique<DynamicThreadPoolTaskDispatcher>(NumThreads);
    } else
      D = std::make_unique<InPlaceTaskDispatcher>();
#endif // LLVM_ENABLE_THREADS
    if (auto EPCOrErr =
            SelfExecutorProcessControl::Create(nullptr, std::move(D), nullptr))
      EPC = std::move(*EPCOrErr);
    else
      return EPCOrErr.takeError();
  } else if (EPC) {
    LLVM_DEBUG({
      dbgs() << "Using explicitly specified ExecutorProcessControl instance "
             << EPC.get() << "\n";
    });
  } else {
    LLVM_DEBUG({
      dbgs() << "Using explicitly specified ExecutionSession instance "
             << ES.get() << "\n";
    });
  }

  // If the client didn't configure any linker options then auto-configure the
  // JIT linker.
  if (!CreateObjectLinkingLayer) {
    auto &TT = JTMB->getTargetTriple();
    bool UseJITLink = false;
    switch (TT.getArch()) {
    case Triple::riscv64:
    case Triple::loongarch64:
      UseJITLink = true;
      break;
    case Triple::aarch64:
      UseJITLink = !TT.isOSBinFormatCOFF();
      break;
    case Triple::arm:
    case Triple::armeb:
    case Triple::thumb:
    case Triple::thumbeb:
      UseJITLink = TT.isOSBinFormatELF();
      break;
    case Triple::x86_64:
      UseJITLink = !TT.isOSBinFormatCOFF();
      break;
    case Triple::ppc64:
      UseJITLink = TT.isPPC64ELFv2ABI();
      break;
    case Triple::ppc64le:
      UseJITLink = TT.isOSBinFormatELF();
      break;
    default:
      break;
    }
    if (UseJITLink) {
      if (!JTMB->getCodeModel())
        JTMB->setCodeModel(CodeModel::Small);
      JTMB->setRelocationModel(Reloc::PIC_);
      CreateObjectLinkingLayer =
          [](ExecutionSession &ES) -> Expected<std::unique_ptr<ObjectLayer>> {
        return std::make_unique<ObjectLinkingLayer>(ES);
      };
    }
  }

  // If we need a process JITDylib but no setup function has been given then
  // create a default one.
  if (!SetupProcessSymbolsJITDylib && LinkProcessSymbolsByDefault) {
    LLVM_DEBUG(dbgs() << "Creating default Process JD setup function\n");
    SetupProcessSymbolsJITDylib = [](LLJIT &J) -> Expected<JITDylibSP> {
      auto &JD =
          J.getExecutionSession().createBareJITDylib("<Process Symbols>");
      auto G = EPCDynamicLibrarySearchGenerator::GetForTargetProcess(
          J.getExecutionSession());
      if (!G)
        return G.takeError();
      JD.addGenerator(std::move(*G));
      return &JD;
    };
  }

  return Error::success();
}

LLJIT::~LLJIT() {
  if (auto Err = ES->endSession())
    ES->reportError(std::move(Err));
}

JITDylibSP LLJIT::getProcessSymbolsJITDylib() { return ProcessSymbols; }

JITDylibSP LLJIT::getPlatformJITDylib() { return Platform; }

Expected<JITDylib &> LLJIT::createJITDylib(std::string Name) {
  auto JD = ES->createJITDylib(std::move(Name));
  if (!JD)
    return JD.takeError();

  JD->addToLinkOrder(DefaultLinks);
  return JD;
}

Expected<JITDylib &> LLJIT::loadPlatformDynamicLibrary(const char *Path) {
  auto G = EPCDynamicLibrarySearchGenerator::Load(*ES, Path);
  if (!G)
    return G.takeError();

  if (auto *ExistingJD = ES->getJITDylibByName(Path))
    return *ExistingJD;

  auto &JD = ES->createBareJITDylib(Path);
  JD.addGenerator(std::move(*G));
  return JD;
}

Error LLJIT::linkStaticLibraryInto(JITDylib &JD,
                                   std::unique_ptr<MemoryBuffer> LibBuffer) {
  auto G = StaticLibraryDefinitionGenerator::Create(*ObjLinkingLayer,
                                                    std::move(LibBuffer));
  if (!G)
    return G.takeError();

  JD.addGenerator(std::move(*G));

  return Error::success();
}

Error LLJIT::linkStaticLibraryInto(JITDylib &JD, const char *Path) {
  auto G = StaticLibraryDefinitionGenerator::Load(*ObjLinkingLayer, Path);
  if (!G)
    return G.takeError();

  JD.addGenerator(std::move(*G));

  return Error::success();
}

Error LLJIT::addIRModule(ResourceTrackerSP RT, ThreadSafeModule TSM) {
  assert(TSM && "Can not add null module");

  if (auto Err =
          TSM.withModuleDo([&](Module &M) { return applyDataLayout(M); }))
    return Err;

  return InitHelperTransformLayer->add(std::move(RT), std::move(TSM));
}

Error LLJIT::addIRModule(JITDylib &JD, ThreadSafeModule TSM) {
  return addIRModule(JD.getDefaultResourceTracker(), std::move(TSM));
}

Error LLJIT::addObjectFile(ResourceTrackerSP RT,
                           std::unique_ptr<MemoryBuffer> Obj) {
  assert(Obj && "Can not add null object");

  return ObjTransformLayer->add(std::move(RT), std::move(Obj));
}

Error LLJIT::addObjectFile(JITDylib &JD, std::unique_ptr<MemoryBuffer> Obj) {
  return addObjectFile(JD.getDefaultResourceTracker(), std::move(Obj));
}

Expected<ExecutorAddr> LLJIT::lookupLinkerMangled(JITDylib &JD,
                                                  SymbolStringPtr Name) {
  if (auto Sym = ES->lookup(
          makeJITDylibSearchOrder(&JD, JITDylibLookupFlags::MatchAllSymbols),
          Name))
    return Sym->getAddress();
  else
    return Sym.takeError();
}

Expected<std::unique_ptr<ObjectLayer>>
LLJIT::createObjectLinkingLayer(LLJITBuilderState &S, ExecutionSession &ES) {

  // If the config state provided an ObjectLinkingLayer factory then use it.
  if (S.CreateObjectLinkingLayer)
    return S.CreateObjectLinkingLayer(ES);

  // Otherwise default to creating an RTDyldObjectLinkingLayer that constructs
  // a new SectionMemoryManager for each object.
  auto GetMemMgr = [](const MemoryBuffer &) {
    return std::make_unique<SectionMemoryManager>();
  };
  auto Layer =
      std::make_unique<RTDyldObjectLinkingLayer>(ES, std::move(GetMemMgr));

  if (S.JTMB->getTargetTriple().isOSBinFormatCOFF()) {
    Layer->setOverrideObjectFlagsWithResponsibilityFlags(true);
    Layer->setAutoClaimResponsibilityForObjectSymbols(true);
  }

  if (S.JTMB->getTargetTriple().isOSBinFormatELF() &&
      (S.JTMB->getTargetTriple().getArch() == Triple::ArchType::ppc64 ||
       S.JTMB->getTargetTriple().getArch() == Triple::ArchType::ppc64le))
    Layer->setAutoClaimResponsibilityForObjectSymbols(true);

  // FIXME: Explicit conversion to std::unique_ptr<ObjectLayer> added to silence
  //        errors from some GCC / libstdc++ bots. Remove this conversion (i.e.
  //        just return ObjLinkingLayer) once those bots are upgraded.
  return std::unique_ptr<ObjectLayer>(std::move(Layer));
}

Expected<std::unique_ptr<IRCompileLayer::IRCompiler>>
LLJIT::createCompileFunction(LLJITBuilderState &S,
                             JITTargetMachineBuilder JTMB) {

  /// If there is a custom compile function creator set then use it.
  if (S.CreateCompileFunction)
    return S.CreateCompileFunction(std::move(JTMB));

  // If using a custom EPC then use a ConcurrentIRCompiler by default.
  if (*S.SupportConcurrentCompilation)
    return std::make_unique<ConcurrentIRCompiler>(std::move(JTMB));

  auto TM = JTMB.createTargetMachine();
  if (!TM)
    return TM.takeError();

  return std::make_unique<TMOwningSimpleCompiler>(std::move(*TM));
}

LLJIT::LLJIT(LLJITBuilderState &S, Error &Err)
    : DL(std::move(*S.DL)), TT(S.JTMB->getTargetTriple()) {

  ErrorAsOutParameter _(Err);

  assert(!(S.EPC && S.ES) && "EPC and ES should not both be set");

  if (S.EPC) {
    ES = std::make_unique<ExecutionSession>(std::move(S.EPC));
  } else if (S.ES)
    ES = std::move(S.ES);
  else {
    if (auto EPC = SelfExecutorProcessControl::Create()) {
      ES = std::make_unique<ExecutionSession>(std::move(*EPC));
    } else {
      Err = EPC.takeError();
      return;
    }
  }

  auto ObjLayer = createObjectLinkingLayer(S, *ES);
  if (!ObjLayer) {
    Err = ObjLayer.takeError();
    return;
  }
  ObjLinkingLayer = std::move(*ObjLayer);
  ObjTransformLayer =
      std::make_unique<ObjectTransformLayer>(*ES, *ObjLinkingLayer);

  {
    auto CompileFunction = createCompileFunction(S, std::move(*S.JTMB));
    if (!CompileFunction) {
      Err = CompileFunction.takeError();
      return;
    }
    CompileLayer = std::make_unique<IRCompileLayer>(
        *ES, *ObjTransformLayer, std::move(*CompileFunction));
    TransformLayer = std::make_unique<IRTransformLayer>(*ES, *CompileLayer);
    InitHelperTransformLayer =
        std::make_unique<IRTransformLayer>(*ES, *TransformLayer);
  }

  if (*S.SupportConcurrentCompilation)
    InitHelperTransformLayer->setCloneToNewContextOnEmit(true);

  if (S.SetupProcessSymbolsJITDylib) {
    if (auto ProcSymsJD = S.SetupProcessSymbolsJITDylib(*this)) {
      ProcessSymbols = ProcSymsJD->get();
    } else {
      Err = ProcSymsJD.takeError();
      return;
    }
  }

  if (S.PrePlatformSetup)
    if ((Err = S.PrePlatformSetup(*this)))
      return;

  if (!S.SetUpPlatform)
    S.SetUpPlatform = setUpGenericLLVMIRPlatform;

  if (auto PlatformJDOrErr = S.SetUpPlatform(*this)) {
    Platform = PlatformJDOrErr->get();
    if (Platform)
      DefaultLinks.push_back(
          {Platform, JITDylibLookupFlags::MatchExportedSymbolsOnly});
  } else {
    Err = PlatformJDOrErr.takeError();
    return;
  }

  if (S.LinkProcessSymbolsByDefault)
    DefaultLinks.push_back(
        {ProcessSymbols, JITDylibLookupFlags::MatchExportedSymbolsOnly});

  if (auto MainOrErr = createJITDylib("main"))
    Main = &*MainOrErr;
  else {
    Err = MainOrErr.takeError();
    return;
  }
}

std::string LLJIT::mangle(StringRef UnmangledName) const {
  std::string MangledName;
  {
    raw_string_ostream MangledNameStream(MangledName);
    Mangler::getNameWithPrefix(MangledNameStream, UnmangledName, DL);
  }
  return MangledName;
}

Error LLJIT::applyDataLayout(Module &M) {
  if (M.getDataLayout().isDefault())
    M.setDataLayout(DL);

  if (M.getDataLayout() != DL)
    return make_error<StringError>(
        "Added modules have incompatible data layouts: " +
            M.getDataLayout().getStringRepresentation() + " (module) vs " +
            DL.getStringRepresentation() + " (jit)",
        inconvertibleErrorCode());

  return Error::success();
}

Error setUpOrcPlatformManually(LLJIT &J) {
  LLVM_DEBUG({ dbgs() << "Setting up orc platform support for LLJIT\n"; });
  J.setPlatformSupport(std::make_unique<ORCPlatformSupport>(J));
  return Error::success();
}

class LoadAndLinkDynLibrary {
public:
  LoadAndLinkDynLibrary(LLJIT &J) : J(J) {}
  Error operator()(JITDylib &JD, StringRef DLLName) {
    if (!DLLName.ends_with_insensitive(".dll"))
      return make_error<StringError>("DLLName not ending with .dll",
                                     inconvertibleErrorCode());
    auto DLLNameStr = DLLName.str(); // Guarantees null-termination.
    auto DLLJD = J.loadPlatformDynamicLibrary(DLLNameStr.c_str());
    if (!DLLJD)
      return DLLJD.takeError();
    JD.addToLinkOrder(*DLLJD);
    return Error::success();
  }

private:
  LLJIT &J;
};

Expected<JITDylibSP> ExecutorNativePlatform::operator()(LLJIT &J) {
  auto ProcessSymbolsJD = J.getProcessSymbolsJITDylib();
  if (!ProcessSymbolsJD)
    return make_error<StringError>(
        "Native platforms require a process symbols JITDylib",
        inconvertibleErrorCode());

  const Triple &TT = J.getTargetTriple();
  ObjectLinkingLayer *ObjLinkingLayer =
      dyn_cast<ObjectLinkingLayer>(&J.getObjLinkingLayer());

  if (!ObjLinkingLayer)
    return make_error<StringError>(
        "ExecutorNativePlatform requires ObjectLinkingLayer",
        inconvertibleErrorCode());

  std::unique_ptr<MemoryBuffer> RuntimeArchiveBuffer;
  if (OrcRuntime.index() == 0) {
    auto A = errorOrToExpected(MemoryBuffer::getFile(std::get<0>(OrcRuntime)));
    if (!A)
      return A.takeError();
    RuntimeArchiveBuffer = std::move(*A);
  } else
    RuntimeArchiveBuffer = std::move(std::get<1>(OrcRuntime));

  auto &ES = J.getExecutionSession();
  auto &PlatformJD = ES.createBareJITDylib("<Platform>");
  PlatformJD.addToLinkOrder(*ProcessSymbolsJD);

  J.setPlatformSupport(std::make_unique<ORCPlatformSupport>(J));

  switch (TT.getObjectFormat()) {
  case Triple::COFF: {
    const char *VCRuntimePath = nullptr;
    bool StaticVCRuntime = false;
    if (VCRuntime) {
      VCRuntimePath = VCRuntime->first.c_str();
      StaticVCRuntime = VCRuntime->second;
    }
    if (auto P = COFFPlatform::Create(
            *ObjLinkingLayer, PlatformJD, std::move(RuntimeArchiveBuffer),
            LoadAndLinkDynLibrary(J), StaticVCRuntime, VCRuntimePath))
      J.getExecutionSession().setPlatform(std::move(*P));
    else
      return P.takeError();
    break;
  }
  case Triple::ELF: {
    auto G = StaticLibraryDefinitionGenerator::Create(
        *ObjLinkingLayer, std::move(RuntimeArchiveBuffer));
    if (!G)
      return G.takeError();

    if (auto P =
            ELFNixPlatform::Create(*ObjLinkingLayer, PlatformJD, std::move(*G)))
      J.getExecutionSession().setPlatform(std::move(*P));
    else
      return P.takeError();
    break;
  }
  case Triple::MachO: {
    auto G = StaticLibraryDefinitionGenerator::Create(
        *ObjLinkingLayer, std::move(RuntimeArchiveBuffer));
    if (!G)
      return G.takeError();

    if (auto P =
            MachOPlatform::Create(*ObjLinkingLayer, PlatformJD, std::move(*G)))
      ES.setPlatform(std::move(*P));
    else
      return P.takeError();
    break;
  }
  default:
    return make_error<StringError>("Unsupported object format in triple " +
                                       TT.str(),
                                   inconvertibleErrorCode());
  }

  return &PlatformJD;
}

Expected<JITDylibSP> setUpGenericLLVMIRPlatform(LLJIT &J) {
  LLVM_DEBUG(
      { dbgs() << "Setting up GenericLLVMIRPlatform support for LLJIT\n"; });
  auto ProcessSymbolsJD = J.getProcessSymbolsJITDylib();
  if (!ProcessSymbolsJD)
    return make_error<StringError>(
        "Native platforms require a process symbols JITDylib",
        inconvertibleErrorCode());

  auto &PlatformJD = J.getExecutionSession().createBareJITDylib("<Platform>");
  PlatformJD.addToLinkOrder(*ProcessSymbolsJD);

  if (auto *OLL = dyn_cast<ObjectLinkingLayer>(&J.getObjLinkingLayer())) {

    bool UseEHFrames = true;

    // Enable compact-unwind support if possible.
    if (J.getTargetTriple().isOSDarwin() ||
        J.getTargetTriple().isOSBinFormatMachO()) {

      // Check if the bootstrap map says that we should force eh-frames:
      // Older libunwinds require this as they don't have a dynamic
      // registration API for compact-unwind.
      std::optional<bool> ForceEHFrames;
      if (auto Err = J.getExecutionSession().getBootstrapMapValue<bool, bool>(
              "darwin-use-ehframes-only", ForceEHFrames))
        return Err;
      if (ForceEHFrames.has_value())
        UseEHFrames = *ForceEHFrames;
      else
        UseEHFrames = false;

      // If UseEHFrames hasn't been set then we're good to use compact-unwind.
      if (!UseEHFrames) {
        if (auto UIRP =
                UnwindInfoRegistrationPlugin::Create(J.getExecutionSession())) {
          OLL->addPlugin(std::move(*UIRP));
          LLVM_DEBUG(dbgs() << "Enabled compact-unwind support.\n");
        } else
          return UIRP.takeError();
      }
    }

    // Otherwise fall back to standard unwind registration.
    if (UseEHFrames) {
      auto &ES = J.getExecutionSession();
      if (auto EHFP = EHFrameRegistrationPlugin::Create(ES)) {
        OLL->addPlugin(std::move(*EHFP));
        LLVM_DEBUG(dbgs() << "Enabled eh-frame support.\n");
      } else
        return EHFP.takeError();
    }
  }

  J.setPlatformSupport(
      std::make_unique<GenericLLVMIRPlatformSupport>(J, PlatformJD));

  return &PlatformJD;
}

Expected<JITDylibSP> setUpInactivePlatform(LLJIT &J) {
  LLVM_DEBUG(
      { dbgs() << "Explicitly deactivated platform support for LLJIT\n"; });
  J.setPlatformSupport(std::make_unique<InactivePlatformSupport>());
  return nullptr;
}

Error LLLazyJITBuilderState::prepareForConstruction() {
  if (auto Err = LLJITBuilderState::prepareForConstruction())
    return Err;
  TT = JTMB->getTargetTriple();
  return Error::success();
}

Error LLLazyJIT::addLazyIRModule(JITDylib &JD, ThreadSafeModule TSM) {
  assert(TSM && "Can not add null module");

  if (auto Err = TSM.withModuleDo(
          [&](Module &M) -> Error { return applyDataLayout(M); }))
    return Err;

  return CODLayer->add(JD, std::move(TSM));
}

LLLazyJIT::LLLazyJIT(LLLazyJITBuilderState &S, Error &Err) : LLJIT(S, Err) {

  // If LLJIT construction failed then bail out.
  if (Err)
    return;

  ErrorAsOutParameter _(&Err);

  /// Take/Create the lazy-compile callthrough manager.
  if (S.LCTMgr)
    LCTMgr = std::move(S.LCTMgr);
  else {
    if (auto LCTMgrOrErr = createLocalLazyCallThroughManager(
            S.TT, *ES, S.LazyCompileFailureAddr))
      LCTMgr = std::move(*LCTMgrOrErr);
    else {
      Err = LCTMgrOrErr.takeError();
      return;
    }
  }

  // Take/Create the indirect stubs manager builder.
  auto ISMBuilder = std::move(S.ISMBuilder);

  // If none was provided, try to build one.
  if (!ISMBuilder)
    ISMBuilder = createLocalIndirectStubsManagerBuilder(S.TT);

  // No luck. Bail out.
  if (!ISMBuilder) {
    Err = make_error<StringError>("Could not construct "
                                  "IndirectStubsManagerBuilder for target " +
                                      S.TT.str(),
                                  inconvertibleErrorCode());
    return;
  }

  // Create the IP Layer.
  IPLayer = std::make_unique<IRPartitionLayer>(*ES, *InitHelperTransformLayer);

  // Create the COD layer.
  CODLayer = std::make_unique<CompileOnDemandLayer>(*ES, *IPLayer, *LCTMgr,
                                                    std::move(ISMBuilder));

  if (*S.SupportConcurrentCompilation)
    CODLayer->setCloneToNewContextOnEmit(true);
}

// In-process LLJIT uses eh-frame section wrappers via EPC, so we need to force
// them to be linked in.
LLVM_ATTRIBUTE_USED void linkComponents() {
  errs() << (void *)&llvm_orc_registerEHFrameSectionAllocAction
         << (void *)&llvm_orc_deregisterEHFrameSectionAllocAction;
}

} // End namespace orc.
} // End namespace llvm.
