//===- llvm-jitlink.cpp -- Command line interface/tester for llvm-jitlink -===//
//
// 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
//
//===----------------------------------------------------------------------===//
//
// This utility provides a simple command line interface to the llvm jitlink
// library, which makes relocatable object files executable in memory. Its
// primary function is as a testing utility for the jitlink library.
//
//===----------------------------------------------------------------------===//

#include "llvm-jitlink.h"
#include "llvm/BinaryFormat/Magic.h"
#include "llvm/Config/llvm-config.h" // for LLVM_ON_UNIX, LLVM_ENABLE_THREADS
#include "llvm/ExecutionEngine/Orc/AbsoluteSymbols.h"
#include "llvm/ExecutionEngine/Orc/COFFPlatform.h"
#include "llvm/ExecutionEngine/Orc/DebugObjectManagerPlugin.h"
#include "llvm/ExecutionEngine/Orc/Debugging/DebugInfoSupport.h"
#include "llvm/ExecutionEngine/Orc/Debugging/DebuggerSupportPlugin.h"
#include "llvm/ExecutionEngine/Orc/Debugging/PerfSupportPlugin.h"
#include "llvm/ExecutionEngine/Orc/Debugging/VTuneSupportPlugin.h"
#include "llvm/ExecutionEngine/Orc/EHFrameRegistrationPlugin.h"
#include "llvm/ExecutionEngine/Orc/ELFNixPlatform.h"
#include "llvm/ExecutionEngine/Orc/EPCDebugObjectRegistrar.h"
#include "llvm/ExecutionEngine/Orc/EPCDynamicLibrarySearchGenerator.h"
#include "llvm/ExecutionEngine/Orc/ExecutionUtils.h"
#include "llvm/ExecutionEngine/Orc/GetDylibInterface.h"
#include "llvm/ExecutionEngine/Orc/IndirectionUtils.h"
#include "llvm/ExecutionEngine/Orc/JITLinkRedirectableSymbolManager.h"
#include "llvm/ExecutionEngine/Orc/JITLinkReentryTrampolines.h"
#include "llvm/ExecutionEngine/Orc/JITTargetMachineBuilder.h"
#include "llvm/ExecutionEngine/Orc/LoadLinkableFile.h"
#include "llvm/ExecutionEngine/Orc/MachO.h"
#include "llvm/ExecutionEngine/Orc/MachOPlatform.h"
#include "llvm/ExecutionEngine/Orc/MapperJITLinkMemoryManager.h"
#include "llvm/ExecutionEngine/Orc/ObjectFileInterface.h"
#include "llvm/ExecutionEngine/Orc/SectCreate.h"
#include "llvm/ExecutionEngine/Orc/SelfExecutorProcessControl.h"
#include "llvm/ExecutionEngine/Orc/Shared/OrcRTBridge.h"
#include "llvm/ExecutionEngine/Orc/SimpleRemoteMemoryMapper.h"
#include "llvm/ExecutionEngine/Orc/TargetProcess/JITLoaderGDB.h"
#include "llvm/ExecutionEngine/Orc/TargetProcess/JITLoaderPerf.h"
#include "llvm/ExecutionEngine/Orc/TargetProcess/JITLoaderVTune.h"
#include "llvm/ExecutionEngine/Orc/TargetProcess/RegisterEHFrames.h"
#include "llvm/ExecutionEngine/Orc/UnwindInfoRegistrationPlugin.h"
#include "llvm/MC/MCAsmInfo.h"
#include "llvm/MC/MCContext.h"
#include "llvm/MC/MCDisassembler/MCDisassembler.h"
#include "llvm/MC/MCInstPrinter.h"
#include "llvm/MC/MCInstrAnalysis.h"
#include "llvm/MC/MCInstrInfo.h"
#include "llvm/MC/MCRegisterInfo.h"
#include "llvm/MC/MCSubtargetInfo.h"
#include "llvm/MC/MCTargetOptions.h"
#include "llvm/MC/TargetRegistry.h"
#include "llvm/Object/COFF.h"
#include "llvm/Object/MachO.h"
#include "llvm/Object/ObjectFile.h"
#include "llvm/Object/TapiUniversal.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/InitLLVM.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/Process.h"
#include "llvm/Support/TargetSelect.h"
#include "llvm/Support/Timer.h"
#include <cstring>
#include <deque>
#include <string>

#ifdef LLVM_ON_UNIX
#include <netdb.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <unistd.h>
#endif // LLVM_ON_UNIX

#define DEBUG_TYPE "llvm_jitlink"

using namespace llvm;
using namespace llvm::jitlink;
using namespace llvm::orc;

static cl::OptionCategory JITLinkCategory("JITLink Options");

static cl::list<std::string> InputFiles(cl::Positional, cl::OneOrMore,
                                        cl::desc("input files"),
                                        cl::cat(JITLinkCategory));

static cl::list<bool> LazyLink("lazy",
                               cl::desc("Link the following file lazily"),
                               cl::cat(JITLinkCategory));

enum class SpeculateKind { None, Simple };

static cl::opt<SpeculateKind> Speculate(
    "speculate", cl::desc("Choose speculation scheme"),
    cl::init(SpeculateKind::None),
    cl::values(clEnumValN(SpeculateKind::None, "none", "No speculation"),
               clEnumValN(SpeculateKind::Simple, "simple",
                          "Simple speculation")),
    cl::cat(JITLinkCategory));

static cl::opt<std::string> SpeculateOrder(
    "speculate-order",
    cl::desc("A CSV file containing (JITDylib, Function) pairs to"
             "speculatively look up"),
    cl::cat(JITLinkCategory));

static cl::opt<std::string> RecordLazyExecs(
    "record-lazy-execs",
    cl::desc("Write lazy-function executions to a CSV file as (JITDylib, "
             "function) pairs"),
    cl::cat(JITLinkCategory));

static cl::opt<size_t> MaterializationThreads(
    "num-threads", cl::desc("Number of materialization threads to use"),
    cl::init(std::numeric_limits<size_t>::max()), cl::cat(JITLinkCategory));

static cl::list<std::string>
    LibrarySearchPaths("L",
                       cl::desc("Add dir to the list of library search paths"),
                       cl::Prefix, cl::cat(JITLinkCategory));

static cl::list<std::string>
    Libraries("l",
              cl::desc("Link against library X in the library search paths"),
              cl::Prefix, cl::cat(JITLinkCategory));

static cl::list<std::string>
    LibrariesHidden("hidden-l",
                    cl::desc("Link against library X in the library search "
                             "paths with hidden visibility"),
                    cl::Prefix, cl::cat(JITLinkCategory));

static cl::list<std::string>
    LoadHidden("load_hidden",
               cl::desc("Link against library X with hidden visibility"),
               cl::cat(JITLinkCategory));

static cl::list<std::string>
    LibrariesWeak("weak-l",
                  cl::desc("Emulate weak link against library X. Must resolve "
                           "to a TextAPI file, and all symbols in the "
                           "interface will resolve to null."),
                  cl::Prefix, cl::cat(JITLinkCategory));

static cl::list<std::string> WeakLibraries(
    "weak_library",
    cl::desc("Emulate weak link against library X. X must point to a "
             "TextAPI file, and all symbols in the interface will "
             "resolve to null"),
    cl::cat(JITLinkCategory));

static cl::opt<bool> SearchSystemLibrary(
    "search-sys-lib",
    cl::desc("Add system library paths to library search paths"),
    cl::init(false), cl::cat(JITLinkCategory));

static cl::opt<bool> NoExec("noexec", cl::desc("Do not execute loaded code"),
                            cl::init(false), cl::cat(JITLinkCategory));

static cl::list<std::string>
    CheckFiles("check", cl::desc("File containing verifier checks"),
               cl::cat(JITLinkCategory));

static cl::opt<std::string>
    CheckName("check-name", cl::desc("Name of checks to match against"),
              cl::init("jitlink-check"), cl::cat(JITLinkCategory));

static cl::opt<std::string>
    EntryPointName("entry", cl::desc("Symbol to call as main entry point"),
                   cl::init(""), cl::cat(JITLinkCategory));

static cl::list<std::string> JITDylibs(
    "jd",
    cl::desc("Specifies the JITDylib to be used for any subsequent "
             "input file, -L<seacrh-path>, and -l<library> arguments"),
    cl::cat(JITLinkCategory));

static cl::list<std::string>
    Dylibs("preload",
           cl::desc("Pre-load dynamic libraries (e.g. language runtimes "
                    "required by the ORC runtime)"),
           cl::cat(JITLinkCategory));

static cl::list<std::string> InputArgv("args", cl::Positional,
                                       cl::desc("<program arguments>..."),
                                       cl::PositionalEatsArgs,
                                       cl::cat(JITLinkCategory));

static cl::opt<bool>
    DebuggerSupport("debugger-support",
                    cl::desc("Enable debugger suppport (default = !-noexec)"),
                    cl::init(true), cl::Hidden, cl::cat(JITLinkCategory));

static cl::opt<bool> PerfSupport("perf-support",
                                 cl::desc("Enable perf profiling support"),
                                 cl::init(false), cl::Hidden,
                                 cl::cat(JITLinkCategory));

static cl::opt<bool> VTuneSupport("vtune-support",
                                  cl::desc("Enable vtune profiling support"),
                                  cl::init(false), cl::Hidden,
                                  cl::cat(JITLinkCategory));
static cl::opt<bool>
    NoProcessSymbols("no-process-syms",
                     cl::desc("Do not resolve to llvm-jitlink process symbols"),
                     cl::init(false), cl::cat(JITLinkCategory));

static cl::list<std::string> AbsoluteDefs(
    "abs",
    cl::desc("Inject absolute symbol definitions (syntax: <name>=<addr>)"),
    cl::cat(JITLinkCategory));

static cl::list<std::string>
    Aliases("alias",
            cl::desc("Inject symbol aliases (syntax: <alias-name>=<aliasee>)"),
            cl::cat(JITLinkCategory));

static cl::list<std::string>
    SectCreate("sectcreate",
               cl::desc("given <sectname>,<filename>[@<sym>=<offset>,...]  "
                        "add the content of <filename> to <sectname>"),
               cl::cat(JITLinkCategory));

static cl::list<std::string> TestHarnesses("harness", cl::Positional,
                                           cl::desc("Test harness files"),
                                           cl::PositionalEatsArgs,
                                           cl::cat(JITLinkCategory));

static cl::opt<bool>
    ShowLinkedFiles("show-linked-files",
                    cl::desc("List each file/graph name if/when it is linked"),
                    cl::init(false), cl::cat(JITLinkCategory));

static cl::opt<bool> ShowInitialExecutionSessionState(
    "show-init-es",
    cl::desc("Print ExecutionSession state before resolving entry point"),
    cl::init(false), cl::cat(JITLinkCategory));

static cl::opt<bool> ShowEntryExecutionSessionState(
    "show-entry-es",
    cl::desc("Print ExecutionSession state after resolving entry point"),
    cl::init(false), cl::cat(JITLinkCategory));

static cl::opt<bool> ShowAddrs(
    "show-addrs",
    cl::desc("Print registered symbol, section, got and stub addresses"),
    cl::init(false), cl::cat(JITLinkCategory));

static cl::opt<std::string> ShowLinkGraphs(
    "show-graphs",
    cl::desc("Takes a posix regex and prints the link graphs of all files "
             "matching that regex after fixups have been applied"),
    cl::Optional, cl::cat(JITLinkCategory));

static cl::opt<bool> ShowTimes("show-times",
                               cl::desc("Show times for llvm-jitlink phases"),
                               cl::init(false), cl::cat(JITLinkCategory));

static cl::opt<std::string> SlabAllocateSizeString(
    "slab-allocate",
    cl::desc("Allocate from a slab of the given size "
             "(allowable suffixes: Kb, Mb, Gb. default = "
             "Kb)"),
    cl::init(""), cl::cat(JITLinkCategory));

static cl::opt<uint64_t> SlabAddress(
    "slab-address",
    cl::desc("Set slab target address (requires -slab-allocate and -noexec)"),
    cl::init(~0ULL), cl::cat(JITLinkCategory));

static cl::opt<uint64_t> SlabPageSize(
    "slab-page-size",
    cl::desc("Set page size for slab (requires -slab-allocate and -noexec)"),
    cl::init(0), cl::cat(JITLinkCategory));

static cl::opt<bool> ShowRelocatedSectionContents(
    "show-relocated-section-contents",
    cl::desc("show section contents after fixups have been applied"),
    cl::init(false), cl::cat(JITLinkCategory));

static cl::opt<bool> PhonyExternals(
    "phony-externals",
    cl::desc("resolve all otherwise unresolved externals to null"),
    cl::init(false), cl::cat(JITLinkCategory));

static cl::opt<std::string> OutOfProcessExecutor(
    "oop-executor", cl::desc("Launch an out-of-process executor to run code"),
    cl::ValueOptional, cl::cat(JITLinkCategory));

static cl::opt<std::string> OutOfProcessExecutorConnect(
    "oop-executor-connect",
    cl::desc("Connect to an out-of-process executor via TCP"),
    cl::cat(JITLinkCategory));

static cl::opt<std::string>
    OrcRuntime("orc-runtime", cl::desc("Use ORC runtime from given path"),
               cl::init(""), cl::cat(JITLinkCategory));

static cl::opt<bool> AddSelfRelocations(
    "add-self-relocations",
    cl::desc("Add relocations to function pointers to the current function"),
    cl::init(false), cl::cat(JITLinkCategory));

static cl::opt<bool>
    ShowErrFailedToMaterialize("show-err-failed-to-materialize",
                               cl::desc("Show FailedToMaterialize errors"),
                               cl::init(false), cl::cat(JITLinkCategory));

enum class MemMgr { Default, Generic, SimpleRemote, Shared };

static cl::opt<MemMgr> UseMemMgr(
    "use-memmgr", cl::desc("Choose memory manager"), cl::init(MemMgr::Generic),
    cl::values(clEnumValN(MemMgr::Default, "default",
                          "Use setup default (InProcess or EPCGeneric)"),
               clEnumValN(MemMgr::Generic, "generic",
                          "Generic remote memory manager"),
               clEnumValN(MemMgr::SimpleRemote, "simple-remote",
                          "Mapper memory manager with simple-remote backend"),
               clEnumValN(MemMgr::Shared, "shared",
                          "Mapper memory manager with shared-memory manager")),
    cl::cat(JITLinkCategory));

static cl::opt<std::string>
    OverrideTriple("triple", cl::desc("Override target triple detection"),
                   cl::init(""), cl::cat(JITLinkCategory));

static cl::opt<bool> AllLoad("all_load",
                             cl::desc("Load all members of static archives"),
                             cl::init(false), cl::cat(JITLinkCategory));

static cl::opt<bool> ForceLoadObjC(
    "ObjC",
    cl::desc("Load all members of static archives that implement "
             "Objective-C classes or categories, or Swift structs, "
             "classes or extensions"),
    cl::init(false), cl::cat(JITLinkCategory));

static ExitOnError ExitOnErr;

static LLVM_ATTRIBUTE_USED void linkComponents() {
  errs() << "Linking in runtime functions\n"
         << (void *)&llvm_orc_registerEHFrameSectionAllocAction << '\n'
         << (void *)&llvm_orc_deregisterEHFrameSectionAllocAction << '\n'
         << (void *)&llvm_orc_registerJITLoaderGDBWrapper << '\n'
         << (void *)&llvm_orc_registerJITLoaderGDBAllocAction << '\n'
         << (void *)&llvm_orc_registerJITLoaderPerfStart << '\n'
         << (void *)&llvm_orc_registerJITLoaderPerfEnd << '\n'
         << (void *)&llvm_orc_registerJITLoaderPerfImpl << '\n'
         << (void *)&llvm_orc_registerVTuneImpl << '\n'
         << (void *)&llvm_orc_unregisterVTuneImpl << '\n'
         << (void *)&llvm_orc_test_registerVTuneImpl << '\n';
}

static bool UseTestResultOverride = false;
static int64_t TestResultOverride = 0;

extern "C" LLVM_ATTRIBUTE_USED void
llvm_jitlink_setTestResultOverride(int64_t Value) {
  TestResultOverride = Value;
  UseTestResultOverride = true;
}

static Error addSelfRelocations(LinkGraph &G);

namespace {

template <typename ErrT>

class ConditionalPrintErr {
public:
  ConditionalPrintErr(bool C) : C(C) {}
  void operator()(ErrT &EI) {
    if (C) {
      errs() << "llvm-jitlink error: ";
      EI.log(errs());
      errs() << "\n";
    }
  }

private:
  bool C;
};

Expected<std::unique_ptr<MemoryBuffer>> getFile(const Twine &FileName) {
  if (auto F = MemoryBuffer::getFile(FileName))
    return std::move(*F);
  else
    return createFileError(FileName, F.getError());
}

void reportLLVMJITLinkError(Error Err) {
  handleAllErrors(
      std::move(Err),
      ConditionalPrintErr<orc::FailedToMaterialize>(ShowErrFailedToMaterialize),
      ConditionalPrintErr<ErrorInfoBase>(true));
}

} // end anonymous namespace

namespace llvm {

static raw_ostream &
operator<<(raw_ostream &OS, const Session::MemoryRegionInfo &MRI) {
  return OS << "target addr = "
            << format("0x%016" PRIx64, MRI.getTargetAddress())
            << ", content: " << (const void *)MRI.getContent().data() << " -- "
            << (const void *)(MRI.getContent().data() + MRI.getContent().size())
            << " (" << MRI.getContent().size() << " bytes)";
}

static raw_ostream &
operator<<(raw_ostream &OS, const Session::SymbolInfoMap &SIM) {
  OS << "Symbols:\n";
  for (auto &SKV : SIM)
    OS << "  \"" << SKV.first << "\" " << SKV.second << "\n";
  return OS;
}

static raw_ostream &
operator<<(raw_ostream &OS, const Session::FileInfo &FI) {
  for (auto &SIKV : FI.SectionInfos)
    OS << "  Section \"" << SIKV.first() << "\": " << SIKV.second << "\n";
  for (auto &GOTKV : FI.GOTEntryInfos)
    OS << "  GOT \"" << GOTKV.first() << "\": " << GOTKV.second << "\n";
  for (auto &StubKVs : FI.StubInfos) {
    OS << "  Stubs \"" << StubKVs.first() << "\":";
    for (auto MemRegion : StubKVs.second)
      OS << " " << MemRegion;
    OS << "\n";
  }
  return OS;
}

static raw_ostream &
operator<<(raw_ostream &OS, const Session::FileInfoMap &FIM) {
  for (auto &FIKV : FIM)
    OS << "File \"" << FIKV.first() << "\":\n" << FIKV.second;
  return OS;
}

bool lazyLinkingRequested() {
  for (auto LL : LazyLink)
    if (LL)
      return true;
  return false;
}

static Error applyLibraryLinkModifiers(Session &S, LinkGraph &G) {
  // If there are hidden archives and this graph is an archive
  // member then apply hidden modifier.
  if (!S.HiddenArchives.empty()) {
    StringRef ObjName(G.getName());
    if (ObjName.ends_with(')')) {
      auto LibName = ObjName.split('[').first;
      if (S.HiddenArchives.count(LibName)) {
        for (auto *Sym : G.defined_symbols())
          Sym->setScope(std::max(Sym->getScope(), Scope::Hidden));
      }
    }
  }

  return Error::success();
}

static Error applyHarnessPromotions(Session &S, LinkGraph &G) {
  std::lock_guard<std::mutex> Lock(S.M);

  // If this graph is part of the test harness there's nothing to do.
  if (S.HarnessFiles.empty() || S.HarnessFiles.count(G.getName()))
    return Error::success();

  LLVM_DEBUG(dbgs() << "Applying promotions to graph " << G.getName() << "\n");

  // If this graph is part of the test then promote any symbols referenced by
  // the harness to default scope, remove all symbols that clash with harness
  // definitions.
  std::vector<Symbol *> DefinitionsToRemove;
  for (auto *Sym : G.defined_symbols()) {

    if (!Sym->hasName())
      continue;

    if (Sym->getLinkage() == Linkage::Weak) {
      auto It = S.CanonicalWeakDefs.find(*Sym->getName());
      if (It == S.CanonicalWeakDefs.end() || It->second != G.getName()) {
        LLVM_DEBUG({
          dbgs() << "  Externalizing weak symbol " << Sym->getName() << "\n";
        });
        DefinitionsToRemove.push_back(Sym);
      } else {
        LLVM_DEBUG({
          dbgs() << "  Making weak symbol " << Sym->getName() << " strong\n";
        });
        if (S.HarnessExternals.count(*Sym->getName()))
          Sym->setScope(Scope::Default);
        else
          Sym->setScope(Scope::Hidden);
        Sym->setLinkage(Linkage::Strong);
      }
    } else if (S.HarnessExternals.count(*Sym->getName())) {
      LLVM_DEBUG(dbgs() << "  Promoting " << Sym->getName() << "\n");
      Sym->setScope(Scope::Default);
      Sym->setLive(true);
      continue;
    } else if (S.HarnessDefinitions.count(*Sym->getName())) {
      LLVM_DEBUG(dbgs() << "  Externalizing " << Sym->getName() << "\n");
      DefinitionsToRemove.push_back(Sym);
    }
  }

  for (auto *Sym : DefinitionsToRemove)
    G.makeExternal(*Sym);

  return Error::success();
}

static void dumpSectionContents(raw_ostream &OS, Session &S, LinkGraph &G) {
  std::lock_guard<std::mutex> Lock(S.M);

  outs() << "Relocated section contents for " << G.getName() << ":\n";

  constexpr orc::ExecutorAddrDiff DumpWidth = 16;
  static_assert(isPowerOf2_64(DumpWidth), "DumpWidth must be a power of two");

  // Put sections in address order.
  std::vector<Section *> Sections;
  for (auto &S : G.sections())
    Sections.push_back(&S);

  llvm::sort(Sections, [](const Section *LHS, const Section *RHS) {
    if (LHS->symbols().empty() && RHS->symbols().empty())
      return false;
    if (LHS->symbols().empty())
      return false;
    if (RHS->symbols().empty())
      return true;
    SectionRange LHSRange(*LHS);
    SectionRange RHSRange(*RHS);
    return LHSRange.getStart() < RHSRange.getStart();
  });

  for (auto *S : Sections) {
    OS << S->getName() << " content:";
    if (S->symbols().empty()) {
      OS << "\n  section empty\n";
      continue;
    }

    // Sort symbols into order, then render.
    std::vector<Symbol *> Syms(S->symbols().begin(), S->symbols().end());
    llvm::sort(Syms, [](const Symbol *LHS, const Symbol *RHS) {
      return LHS->getAddress() < RHS->getAddress();
    });

    orc::ExecutorAddr NextAddr(Syms.front()->getAddress().getValue() &
                               ~(DumpWidth - 1));
    for (auto *Sym : Syms) {
      bool IsZeroFill = Sym->getBlock().isZeroFill();
      auto SymStart = Sym->getAddress();
      auto SymSize = Sym->getSize();
      auto SymEnd = SymStart + SymSize;
      const uint8_t *SymData = IsZeroFill ? nullptr
                                          : reinterpret_cast<const uint8_t *>(
                                                Sym->getSymbolContent().data());

      // Pad any space before the symbol starts.
      while (NextAddr != SymStart) {
        if (NextAddr % DumpWidth == 0)
          OS << formatv("\n{0:x16}:", NextAddr);
        OS << "   ";
        ++NextAddr;
      }

      // Render the symbol content.
      while (NextAddr != SymEnd) {
        if (NextAddr % DumpWidth == 0)
          OS << formatv("\n{0:x16}:", NextAddr);
        if (IsZeroFill)
          OS << " 00";
        else
          OS << formatv(" {0:x-2}", SymData[NextAddr - SymStart]);
        ++NextAddr;
      }
    }
    OS << "\n";
  }
}

// A memory mapper with a fake offset applied only used for -noexec testing
class InProcessDeltaMapper final : public InProcessMemoryMapper {
public:
  InProcessDeltaMapper(size_t PageSize, uint64_t TargetAddr)
      : InProcessMemoryMapper(PageSize), TargetMapAddr(TargetAddr),
        DeltaAddr(0) {}

  static Expected<std::unique_ptr<InProcessDeltaMapper>> Create() {
    size_t PageSize = SlabPageSize;
    if (!PageSize) {
      if (auto PageSizeOrErr = sys::Process::getPageSize())
        PageSize = *PageSizeOrErr;
      else
        return PageSizeOrErr.takeError();
    }

    if (PageSize == 0)
      return make_error<StringError>("Page size is zero",
                                     inconvertibleErrorCode());

    return std::make_unique<InProcessDeltaMapper>(PageSize, SlabAddress);
  }

  void reserve(size_t NumBytes, OnReservedFunction OnReserved) override {
    InProcessMemoryMapper::reserve(
        NumBytes, [this, OnReserved = std::move(OnReserved)](
                      Expected<ExecutorAddrRange> Result) mutable {
          if (!Result)
            return OnReserved(Result.takeError());

          assert(DeltaAddr == 0 && "Overwriting previous offset");
          if (TargetMapAddr != ~0ULL)
            DeltaAddr = TargetMapAddr - Result->Start.getValue();
          auto OffsetRange = ExecutorAddrRange(Result->Start + DeltaAddr,
                                               Result->End + DeltaAddr);

          OnReserved(OffsetRange);
        });
  }

  char *prepare(jitlink::LinkGraph &G, ExecutorAddr Addr,
                size_t ContentSize) override {
    return InProcessMemoryMapper::prepare(G, Addr - DeltaAddr, ContentSize);
  }

  void initialize(AllocInfo &AI, OnInitializedFunction OnInitialized) override {
    // Slide mapping based on delta, make all segments read-writable, and
    // discard allocation actions.
    auto FixedAI = std::move(AI);
    FixedAI.MappingBase -= DeltaAddr;
    for (auto &Seg : FixedAI.Segments)
      Seg.AG = {MemProt::Read | MemProt::Write, Seg.AG.getMemLifetime()};
    FixedAI.Actions.clear();
    InProcessMemoryMapper::initialize(
        FixedAI, [this, OnInitialized = std::move(OnInitialized)](
                     Expected<ExecutorAddr> Result) mutable {
          if (!Result)
            return OnInitialized(Result.takeError());

          OnInitialized(ExecutorAddr(Result->getValue() + DeltaAddr));
        });
  }

  void deinitialize(ArrayRef<ExecutorAddr> Allocations,
                    OnDeinitializedFunction OnDeInitialized) override {
    std::vector<ExecutorAddr> Addrs(Allocations.size());
    for (const auto Base : Allocations) {
      Addrs.push_back(Base - DeltaAddr);
    }

    InProcessMemoryMapper::deinitialize(Addrs, std::move(OnDeInitialized));
  }

  void release(ArrayRef<ExecutorAddr> Reservations,
               OnReleasedFunction OnRelease) override {
    std::vector<ExecutorAddr> Addrs(Reservations.size());
    for (const auto Base : Reservations) {
      Addrs.push_back(Base - DeltaAddr);
    }
    InProcessMemoryMapper::release(Addrs, std::move(OnRelease));
  }

private:
  uint64_t TargetMapAddr;
  uint64_t DeltaAddr;
};

Expected<uint64_t> getSlabAllocSize(StringRef SizeString) {
  SizeString = SizeString.trim();

  uint64_t Units = 1024;

  if (SizeString.ends_with_insensitive("kb"))
    SizeString = SizeString.drop_back(2).rtrim();
  else if (SizeString.ends_with_insensitive("mb")) {
    Units = 1024 * 1024;
    SizeString = SizeString.drop_back(2).rtrim();
  } else if (SizeString.ends_with_insensitive("gb")) {
    Units = 1024 * 1024 * 1024;
    SizeString = SizeString.drop_back(2).rtrim();
  }

  uint64_t SlabSize = 0;
  if (SizeString.getAsInteger(10, SlabSize))
    return make_error<StringError>("Invalid numeric format for slab size",
                                   inconvertibleErrorCode());

  return SlabSize * Units;
}

static std::unique_ptr<JITLinkMemoryManager> createInProcessMemoryManager() {
  uint64_t SlabSize;
#ifdef _WIN32
  SlabSize = 1024 * 1024;
#else
  SlabSize = 1024 * 1024 * 1024;
#endif

  if (!SlabAllocateSizeString.empty())
    SlabSize = ExitOnErr(getSlabAllocSize(SlabAllocateSizeString));

  // If this is a -no-exec case and we're tweaking the slab address or size then
  // use the delta mapper.
  if (NoExec && (SlabAddress || SlabPageSize))
    return ExitOnErr(
        MapperJITLinkMemoryManager::CreateWithMapper<InProcessDeltaMapper>(
            SlabSize));

  // Otherwise use the standard in-process mapper.
  return ExitOnErr(
      MapperJITLinkMemoryManager::CreateWithMapper<InProcessMemoryMapper>(
          SlabSize));
}

Expected<std::unique_ptr<jitlink::JITLinkMemoryManager>>
createSimpleRemoteMemoryManager(SimpleRemoteEPC &SREPC) {
  SimpleRemoteMemoryMapper::SymbolAddrs SAs;
  if (auto Err = SREPC.getBootstrapSymbols(
          {{SAs.Instance, rt::SimpleExecutorMemoryManagerInstanceName},
           {SAs.Reserve, rt::SimpleExecutorMemoryManagerReserveWrapperName},
           {SAs.Initialize,
            rt::SimpleExecutorMemoryManagerInitializeWrapperName},
           {SAs.Deinitialize,
            rt::SimpleExecutorMemoryManagerDeinitializeWrapperName},
           {SAs.Release, rt::SimpleExecutorMemoryManagerReleaseWrapperName}}))
    return std::move(Err);
#ifdef _WIN32
  size_t SlabSize = 1024 * 1024;
#else
  size_t SlabSize = 1024 * 1024 * 1024;
#endif
  return MapperJITLinkMemoryManager::CreateWithMapper<SimpleRemoteMemoryMapper>(
      SlabSize, SREPC, SAs);
}

Expected<std::unique_ptr<jitlink::JITLinkMemoryManager>>
createSharedMemoryManager(SimpleRemoteEPC &SREPC) {
  SharedMemoryMapper::SymbolAddrs SAs;
  if (auto Err = SREPC.getBootstrapSymbols(
          {{SAs.Instance, rt::ExecutorSharedMemoryMapperServiceInstanceName},
           {SAs.Reserve,
            rt::ExecutorSharedMemoryMapperServiceReserveWrapperName},
           {SAs.Initialize,
            rt::ExecutorSharedMemoryMapperServiceInitializeWrapperName},
           {SAs.Deinitialize,
            rt::ExecutorSharedMemoryMapperServiceDeinitializeWrapperName},
           {SAs.Release,
            rt::ExecutorSharedMemoryMapperServiceReleaseWrapperName}}))
    return std::move(Err);

#ifdef _WIN32
  size_t SlabSize = 1024 * 1024;
#else
  size_t SlabSize = 1024 * 1024 * 1024;
#endif

  if (!SlabAllocateSizeString.empty())
    SlabSize = ExitOnErr(getSlabAllocSize(SlabAllocateSizeString));

  return MapperJITLinkMemoryManager::CreateWithMapper<SharedMemoryMapper>(
      SlabSize, SREPC, SAs);
}

static void setupEPCRemoteMemoryManager(SimpleRemoteEPC::Setup &S) {
  switch (UseMemMgr) {
  case MemMgr::Default:
  case MemMgr::Generic:
    break;
  case MemMgr::SimpleRemote:
    S.CreateMemoryManager = createSimpleRemoteMemoryManager;
    break;
  case MemMgr::Shared:
    S.CreateMemoryManager = createSharedMemoryManager;
    break;
  }
}

static Expected<MaterializationUnit::Interface>
getTestObjectFileInterface(Session &S, MemoryBufferRef O) {

  // Get the standard interface for this object, but ignore the symbols field.
  // We'll handle that manually to include promotion.
  auto I = getObjectFileInterface(S.ES, O);
  if (!I)
    return I.takeError();
  I->SymbolFlags.clear();

  // If creating an object file was going to fail it would have happened above,
  // so we can 'cantFail' this.
  auto Obj = cantFail(object::ObjectFile::createObjectFile(O));

  // The init symbol must be included in the SymbolFlags map if present.
  if (I->InitSymbol)
    I->SymbolFlags[I->InitSymbol] =
        JITSymbolFlags::MaterializationSideEffectsOnly;

  for (auto &Sym : Obj->symbols()) {
    Expected<uint32_t> SymFlagsOrErr = Sym.getFlags();
    if (!SymFlagsOrErr)
      // TODO: Test this error.
      return SymFlagsOrErr.takeError();

    // Skip symbols not defined in this object file.
    if ((*SymFlagsOrErr & object::BasicSymbolRef::SF_Undefined))
      continue;

    auto Name = Sym.getName();
    if (!Name)
      return Name.takeError();

    // Skip symbols that have type SF_File.
    if (auto SymType = Sym.getType()) {
      if (*SymType == object::SymbolRef::ST_File)
        continue;
    } else
      return SymType.takeError();

    auto SymFlags = JITSymbolFlags::fromObjectSymbol(Sym);
    if (!SymFlags)
      return SymFlags.takeError();

    if (SymFlags->isWeak()) {
      // If this is a weak symbol that's not defined in the harness then we
      // need to either mark it as strong (if this is the first definition
      // that we've seen) or discard it.
      if (S.HarnessDefinitions.count(*Name) || S.CanonicalWeakDefs.count(*Name))
        continue;
      S.CanonicalWeakDefs[*Name] = O.getBufferIdentifier();
      *SymFlags &= ~JITSymbolFlags::Weak;
      if (!S.HarnessExternals.count(*Name))
        *SymFlags &= ~JITSymbolFlags::Exported;
    } else if (S.HarnessExternals.count(*Name)) {
      *SymFlags |= JITSymbolFlags::Exported;
    } else if (S.HarnessDefinitions.count(*Name) ||
               !(*SymFlagsOrErr & object::BasicSymbolRef::SF_Global))
      continue;

    I->SymbolFlags[S.ES.intern(*Name)] = std::move(*SymFlags);
  }

  return I;
}

static Error loadProcessSymbols(Session &S) {
  S.ProcessSymsJD = &S.ES.createBareJITDylib("Process");
  auto FilterMainEntryPoint =
      [EPName = S.ES.intern(EntryPointName)](SymbolStringPtr Name) {
        return Name != EPName;
      };
  S.ProcessSymsJD->addGenerator(
      ExitOnErr(orc::EPCDynamicLibrarySearchGenerator::GetForTargetProcess(
          S.ES, std::move(FilterMainEntryPoint))));

  return Error::success();
}

static Error loadDylibs(Session &S) {
  LLVM_DEBUG(dbgs() << "Loading dylibs...\n");
  for (const auto &Dylib : Dylibs) {
    LLVM_DEBUG(dbgs() << "  " << Dylib << "\n");
    auto DL = S.getOrLoadDynamicLibrary(Dylib);
    if (!DL)
      return DL.takeError();
  }

  return Error::success();
}

static Expected<std::unique_ptr<ExecutorProcessControl>> launchExecutor() {
#ifndef LLVM_ON_UNIX
  // FIXME: Add support for Windows.
  return make_error<StringError>("-" + OutOfProcessExecutor.ArgStr +
                                     " not supported on non-unix platforms",
                                 inconvertibleErrorCode());
#elif !LLVM_ENABLE_THREADS
  // Out of process mode using SimpleRemoteEPC depends on threads.
  return make_error<StringError>(
      "-" + OutOfProcessExecutor.ArgStr +
          " requires threads, but LLVM was built with "
          "LLVM_ENABLE_THREADS=Off",
      inconvertibleErrorCode());
#else

  constexpr int ReadEnd = 0;
  constexpr int WriteEnd = 1;

  // Pipe FDs.
  int ToExecutor[2];
  int FromExecutor[2];

  pid_t ChildPID;

  // Create pipes to/from the executor..
  if (pipe(ToExecutor) != 0 || pipe(FromExecutor) != 0)
    return make_error<StringError>("Unable to create pipe for executor",
                                   inconvertibleErrorCode());

  ChildPID = fork();

  if (ChildPID == 0) {
    // In the child...

    // Close the parent ends of the pipes
    close(ToExecutor[WriteEnd]);
    close(FromExecutor[ReadEnd]);

    // Execute the child process.
    std::unique_ptr<char[]> ExecutorPath, FDSpecifier;
    {
      ExecutorPath = std::make_unique<char[]>(OutOfProcessExecutor.size() + 1);
      strcpy(ExecutorPath.get(), OutOfProcessExecutor.data());

      std::string FDSpecifierStr("filedescs=");
      FDSpecifierStr += utostr(ToExecutor[ReadEnd]);
      FDSpecifierStr += ',';
      FDSpecifierStr += utostr(FromExecutor[WriteEnd]);
      FDSpecifier = std::make_unique<char[]>(FDSpecifierStr.size() + 1);
      strcpy(FDSpecifier.get(), FDSpecifierStr.c_str());
    }

    char *const Args[] = {ExecutorPath.get(), FDSpecifier.get(), nullptr};
    int RC = execvp(ExecutorPath.get(), Args);
    if (RC != 0) {
      errs() << "unable to launch out-of-process executor \""
             << ExecutorPath.get() << "\"\n";
      exit(1);
    }
  }
  // else we're the parent...

  // Close the child ends of the pipes
  close(ToExecutor[ReadEnd]);
  close(FromExecutor[WriteEnd]);

  auto S = SimpleRemoteEPC::Setup();
  setupEPCRemoteMemoryManager(S);

  return SimpleRemoteEPC::Create<FDSimpleRemoteEPCTransport>(
      std::make_unique<DynamicThreadPoolTaskDispatcher>(MaterializationThreads),
      std::move(S), FromExecutor[ReadEnd], ToExecutor[WriteEnd]);
#endif
}

#if LLVM_ON_UNIX && LLVM_ENABLE_THREADS
static Error createTCPSocketError(Twine Details) {
  return make_error<StringError>(
      formatv("Failed to connect TCP socket '{0}': {1}",
              OutOfProcessExecutorConnect, Details),
      inconvertibleErrorCode());
}

static Expected<int> connectTCPSocket(std::string Host, std::string PortStr) {
  addrinfo *AI;
  addrinfo Hints{};
  Hints.ai_family = AF_INET;
  Hints.ai_socktype = SOCK_STREAM;
  Hints.ai_flags = AI_NUMERICSERV;

  if (int EC = getaddrinfo(Host.c_str(), PortStr.c_str(), &Hints, &AI))
    return createTCPSocketError("Address resolution failed (" +
                                StringRef(gai_strerror(EC)) + ")");

  // Cycle through the returned addrinfo structures and connect to the first
  // reachable endpoint.
  int SockFD;
  addrinfo *Server;
  for (Server = AI; Server != nullptr; Server = Server->ai_next) {
    // socket might fail, e.g. if the address family is not supported. Skip to
    // the next addrinfo structure in such a case.
    if ((SockFD = socket(AI->ai_family, AI->ai_socktype, AI->ai_protocol)) < 0)
      continue;

    // If connect returns null, we exit the loop with a working socket.
    if (connect(SockFD, Server->ai_addr, Server->ai_addrlen) == 0)
      break;

    close(SockFD);
  }
  freeaddrinfo(AI);

  // If we reached the end of the loop without connecting to a valid endpoint,
  // dump the last error that was logged in socket() or connect().
  if (Server == nullptr)
    return createTCPSocketError(std::strerror(errno));

  return SockFD;
}
#endif

static Expected<std::unique_ptr<ExecutorProcessControl>> connectToExecutor() {
#ifndef LLVM_ON_UNIX
  // FIXME: Add TCP support for Windows.
  return make_error<StringError>("-" + OutOfProcessExecutorConnect.ArgStr +
                                     " not supported on non-unix platforms",
                                 inconvertibleErrorCode());
#elif !LLVM_ENABLE_THREADS
  // Out of process mode using SimpleRemoteEPC depends on threads.
  return make_error<StringError>(
      "-" + OutOfProcessExecutorConnect.ArgStr +
          " requires threads, but LLVM was built with "
          "LLVM_ENABLE_THREADS=Off",
      inconvertibleErrorCode());
#else

  StringRef Host, PortStr;
  std::tie(Host, PortStr) = StringRef(OutOfProcessExecutorConnect).split(':');
  if (Host.empty())
    return createTCPSocketError("Host name for -" +
                                OutOfProcessExecutorConnect.ArgStr +
                                " can not be empty");
  if (PortStr.empty())
    return createTCPSocketError("Port number in -" +
                                OutOfProcessExecutorConnect.ArgStr +
                                " can not be empty");
  int Port = 0;
  if (PortStr.getAsInteger(10, Port))
    return createTCPSocketError("Port number '" + PortStr +
                                "' is not a valid integer");

  Expected<int> SockFD = connectTCPSocket(Host.str(), PortStr.str());
  if (!SockFD)
    return SockFD.takeError();

  auto S = SimpleRemoteEPC::Setup();
  setupEPCRemoteMemoryManager(S);

  return SimpleRemoteEPC::Create<FDSimpleRemoteEPCTransport>(
      std::make_unique<DynamicThreadPoolTaskDispatcher>(std::nullopt),
      std::move(S), *SockFD, *SockFD);
#endif
}

class PhonyExternalsGenerator : public DefinitionGenerator {
public:
  Error tryToGenerate(LookupState &LS, LookupKind K, JITDylib &JD,
                      JITDylibLookupFlags JDLookupFlags,
                      const SymbolLookupSet &LookupSet) override {
    SymbolMap PhonySymbols;
    for (auto &KV : LookupSet)
      PhonySymbols[KV.first] = {ExecutorAddr(), JITSymbolFlags::Exported};
    return JD.define(absoluteSymbols(std::move(PhonySymbols)));
  }
};

Expected<std::unique_ptr<Session::LazyLinkingSupport>>
createLazyLinkingSupport(Session &S) {
  auto RSMgr = JITLinkRedirectableSymbolManager::Create(S.ObjLayer);
  if (!RSMgr)
    return RSMgr.takeError();

  std::shared_ptr<SimpleLazyReexportsSpeculator> Speculator;
  switch (Speculate) {
  case SpeculateKind::None:
    break;
  case SpeculateKind::Simple:
    SimpleLazyReexportsSpeculator::RecordExecutionFunction RecordExecs;

    if (!RecordLazyExecs.empty())
      RecordExecs = [&S](const LazyReexportsManager::CallThroughInfo &CTI) {
        S.LazyFnExecOrder.push_back({CTI.JD->getName(), CTI.BodyName});
      };

    Speculator =
        SimpleLazyReexportsSpeculator::Create(S.ES, std::move(RecordExecs));
    break;
  }

  auto LRMgr = createJITLinkLazyReexportsManager(
      S.ObjLayer, **RSMgr, *S.PlatformJD, Speculator.get());
  if (!LRMgr)
    return LRMgr.takeError();

  return std::make_unique<Session::LazyLinkingSupport>(
      std::move(*RSMgr), std::move(Speculator), std::move(*LRMgr), S.ObjLayer);
}

static Error writeLazyExecOrder(Session &S) {
  if (RecordLazyExecs.empty())
    return Error::success();

  std::error_code EC;
  raw_fd_ostream ExecOrderOut(RecordLazyExecs, EC);
  if (EC)
    return createFileError(RecordLazyExecs, EC);

  for (auto &[JDName, FunctionName] : S.LazyFnExecOrder)
    ExecOrderOut << JDName << ", " << FunctionName << "\n";

  return Error::success();
}

Expected<std::unique_ptr<Session>> Session::Create(Triple TT,
                                                   SubtargetFeatures Features) {

  std::unique_ptr<ExecutorProcessControl> EPC;
  if (OutOfProcessExecutor.getNumOccurrences()) {
    /// If -oop-executor is passed then launch the executor.
    if (auto REPC = launchExecutor())
      EPC = std::move(*REPC);
    else
      return REPC.takeError();
  } else if (OutOfProcessExecutorConnect.getNumOccurrences()) {
    /// If -oop-executor-connect is passed then connect to the executor.
    if (auto REPC = connectToExecutor())
      EPC = std::move(*REPC);
    else
      return REPC.takeError();
  } else {
    /// Otherwise use SelfExecutorProcessControl to target the current process.
    auto PageSize = sys::Process::getPageSize();
    if (!PageSize)
      return PageSize.takeError();
    std::unique_ptr<TaskDispatcher> Dispatcher;
    if (MaterializationThreads == 0)
      Dispatcher = std::make_unique<InPlaceTaskDispatcher>();
    else {
#if LLVM_ENABLE_THREADS
      Dispatcher = std::make_unique<DynamicThreadPoolTaskDispatcher>(
          MaterializationThreads);
#else
      llvm_unreachable("MaterializationThreads should be 0");
#endif
    }

    EPC = std::make_unique<SelfExecutorProcessControl>(
        std::make_shared<SymbolStringPool>(), std::move(Dispatcher),
        std::move(TT), *PageSize, createInProcessMemoryManager());
  }

  Error Err = Error::success();
  std::unique_ptr<Session> S(new Session(std::move(EPC), Err));
  if (Err)
    return std::move(Err);
  S->Features = std::move(Features);

  if (lazyLinkingRequested()) {
    if (auto LazyLinking = createLazyLinkingSupport(*S))
      S->LazyLinking = std::move(*LazyLinking);
    else
      return LazyLinking.takeError();
  }

  return std::move(S);
}

Session::~Session() {
  if (auto Err = writeLazyExecOrder(*this))
    ES.reportError(std::move(Err));

  if (auto Err = ES.endSession())
    ES.reportError(std::move(Err));
}

Session::Session(std::unique_ptr<ExecutorProcessControl> EPC, Error &Err)
    : ES(std::move(EPC)),
      ObjLayer(ES, ES.getExecutorProcessControl().getMemMgr()) {

  /// Local ObjectLinkingLayer::Plugin class to forward modifyPassConfig to the
  /// Session.
  class JITLinkSessionPlugin : public ObjectLinkingLayer::Plugin {
  public:
    JITLinkSessionPlugin(Session &S) : S(S) {}
    void modifyPassConfig(MaterializationResponsibility &MR, LinkGraph &G,
                          PassConfiguration &PassConfig) override {
      S.modifyPassConfig(G, PassConfig);
    }

    Error notifyFailed(MaterializationResponsibility &MR) override {
      return Error::success();
    }
    Error notifyRemovingResources(JITDylib &JD, ResourceKey K) override {
      return Error::success();
    }
    void notifyTransferringResources(JITDylib &JD, ResourceKey DstKey,
                                     ResourceKey SrcKey) override {}

  private:
    Session &S;
  };

  ErrorAsOutParameter _(&Err);

  ES.setErrorReporter(reportLLVMJITLinkError);

  if (!NoProcessSymbols)
    ExitOnErr(loadProcessSymbols(*this));

  ExitOnErr(loadDylibs(*this));

  auto &TT = ES.getTargetTriple();

  if (DebuggerSupport && TT.isOSBinFormatMachO()) {
    if (!ProcessSymsJD) {
      Err = make_error<StringError>("MachO debugging requires process symbols",
                                    inconvertibleErrorCode());
      return;
    }
    ObjLayer.addPlugin(ExitOnErr(GDBJITDebugInfoRegistrationPlugin::Create(
        this->ES, *ProcessSymsJD, TT)));
  }

  if (PerfSupport && TT.isOSBinFormatELF()) {
    if (!ProcessSymsJD) {
      Err = make_error<StringError>("MachO debugging requires process symbols",
                                    inconvertibleErrorCode());
      return;
    }
    ObjLayer.addPlugin(ExitOnErr(DebugInfoPreservationPlugin::Create()));
    ObjLayer.addPlugin(ExitOnErr(PerfSupportPlugin::Create(
        this->ES.getExecutorProcessControl(), *ProcessSymsJD, true, true)));
  }

  if (VTuneSupport && TT.isOSBinFormatELF()) {
    ObjLayer.addPlugin(ExitOnErr(DebugInfoPreservationPlugin::Create()));
    ObjLayer.addPlugin(ExitOnErr(
        VTuneSupportPlugin::Create(this->ES.getExecutorProcessControl(),
                                   *ProcessSymsJD, /*EmitDebugInfo=*/true,
                                   /*TestMode=*/true)));
  }

  // Set up the platform.
  if (!OrcRuntime.empty()) {
    assert(ProcessSymsJD && "ProcessSymsJD should have been set");
    PlatformJD = &ES.createBareJITDylib("Platform");
    PlatformJD->addToLinkOrder(*ProcessSymsJD);

    if (TT.isOSBinFormatMachO()) {
      if (auto P =
              MachOPlatform::Create(ObjLayer, *PlatformJD, OrcRuntime.c_str()))
        ES.setPlatform(std::move(*P));
      else {
        Err = P.takeError();
        return;
      }
    } else if (TT.isOSBinFormatELF()) {
      if (auto P =
              ELFNixPlatform::Create(ObjLayer, *PlatformJD, OrcRuntime.c_str()))
        ES.setPlatform(std::move(*P));
      else {
        Err = P.takeError();
        return;
      }
    } else if (TT.isOSBinFormatCOFF()) {
      auto LoadDynLibrary = [&, this](JITDylib &JD,
                                      StringRef DLLName) -> Error {
        if (!DLLName.ends_with_insensitive(".dll"))
          return make_error<StringError>("DLLName not ending with .dll",
                                         inconvertibleErrorCode());
        return loadAndLinkDynamicLibrary(JD, DLLName);
      };

      if (auto P =
              COFFPlatform::Create(ObjLayer, *PlatformJD, OrcRuntime.c_str(),
                                   std::move(LoadDynLibrary)))
        ES.setPlatform(std::move(*P));
      else {
        Err = P.takeError();
        return;
      }
    } else {
      Err = make_error<StringError>(
          "-" + OrcRuntime.ArgStr + " specified, but format " +
              Triple::getObjectFormatTypeName(TT.getObjectFormat()) +
              " not supported",
          inconvertibleErrorCode());
      return;
    }
  } else if (TT.isOSBinFormatMachO()) {
    if (!NoExec) {
      std::optional<bool> ForceEHFrames;
      if ((Err = ES.getBootstrapMapValue<bool, bool>("darwin-use-ehframes-only",
                                                     ForceEHFrames)))
        return;
      bool UseEHFrames = ForceEHFrames.value_or(false);
      if (!UseEHFrames)
        ObjLayer.addPlugin(ExitOnErr(UnwindInfoRegistrationPlugin::Create(ES)));
      else
        ObjLayer.addPlugin(ExitOnErr(EHFrameRegistrationPlugin::Create(ES)));
    }
  } else if (TT.isOSBinFormatELF()) {
    if (!NoExec)
      ObjLayer.addPlugin(ExitOnErr(EHFrameRegistrationPlugin::Create(ES)));
    if (DebuggerSupport)
      ObjLayer.addPlugin(std::make_unique<DebugObjectManagerPlugin>(
          ES, ExitOnErr(createJITLoaderGDBRegistrar(this->ES)), true, true));
  }

  if (auto MainJDOrErr = ES.createJITDylib("main"))
    MainJD = &*MainJDOrErr;
  else {
    Err = MainJDOrErr.takeError();
    return;
  }

  if (NoProcessSymbols) {
    // This symbol is used in testcases, but we're not reflecting process
    // symbols so we'll need to make it available some other way.
    auto &TestResultJD = ES.createBareJITDylib("<TestResultJD>");
    ExitOnErr(TestResultJD.define(absoluteSymbols(
        {{ES.intern("llvm_jitlink_setTestResultOverride"),
          {ExecutorAddr::fromPtr(llvm_jitlink_setTestResultOverride),
           JITSymbolFlags::Exported}}})));
    MainJD->addToLinkOrder(TestResultJD);
  }

  ObjLayer.addPlugin(std::make_unique<JITLinkSessionPlugin>(*this));

  // Process any harness files.
  for (auto &HarnessFile : TestHarnesses) {
    HarnessFiles.insert(HarnessFile);

    auto ObjBuffer =
        ExitOnErr(loadLinkableFile(HarnessFile, ES.getTargetTriple(),
                                   LoadArchives::Never))
            .first;

    auto ObjInterface =
        ExitOnErr(getObjectFileInterface(ES, ObjBuffer->getMemBufferRef()));

    for (auto &KV : ObjInterface.SymbolFlags)
      HarnessDefinitions.insert(*KV.first);

    auto Obj = ExitOnErr(
        object::ObjectFile::createObjectFile(ObjBuffer->getMemBufferRef()));

    for (auto &Sym : Obj->symbols()) {
      uint32_t SymFlags = ExitOnErr(Sym.getFlags());
      auto Name = ExitOnErr(Sym.getName());

      if (Name.empty())
        continue;

      if (SymFlags & object::BasicSymbolRef::SF_Undefined)
        HarnessExternals.insert(Name);
    }
  }

  // If a name is defined by some harness file then it's a definition, not an
  // external.
  for (auto &DefName : HarnessDefinitions)
    HarnessExternals.erase(DefName.getKey());

  if (!ShowLinkGraphs.empty())
    ShowGraphsRegex = Regex(ShowLinkGraphs);
}

void Session::dumpSessionInfo(raw_ostream &OS) {
  OS << "Registered addresses:\n" << SymbolInfos << FileInfos;
}

void Session::modifyPassConfig(LinkGraph &G, PassConfiguration &PassConfig) {

  if (ShowLinkedFiles)
    outs() << "Linking " << G.getName() << "\n";

  if (!CheckFiles.empty())
    PassConfig.PostFixupPasses.push_back([this](LinkGraph &G) {
      if (ES.getTargetTriple().getObjectFormat() == Triple::ELF)
        return registerELFGraphInfo(*this, G);

      if (ES.getTargetTriple().getObjectFormat() == Triple::MachO)
        return registerMachOGraphInfo(*this, G);

      if (ES.getTargetTriple().getObjectFormat() == Triple::COFF)
        return registerCOFFGraphInfo(*this, G);

      return make_error<StringError>("Unsupported object format for GOT/stub "
                                     "registration",
                                     inconvertibleErrorCode());
    });

  if (ShowGraphsRegex)
    PassConfig.PostFixupPasses.push_back([this](LinkGraph &G) -> Error {
      std::lock_guard<std::mutex> Lock(M);
      // Print graph if ShowLinkGraphs is specified-but-empty, or if
      // it contains the given graph.
      if (ShowGraphsRegex->match(G.getName())) {
        outs() << "Link graph \"" << G.getName() << "\" post-fixup:\n";
        G.dump(outs());
      }
      return Error::success();
    });

  PassConfig.PrePrunePasses.push_back([this](LinkGraph &G) {
    std::lock_guard<std::mutex> Lock(M);
    ++ActiveLinks;
    return Error::success();
  });
  PassConfig.PrePrunePasses.push_back(
      [this](LinkGraph &G) { return applyLibraryLinkModifiers(*this, G); });
  PassConfig.PrePrunePasses.push_back(
      [this](LinkGraph &G) { return applyHarnessPromotions(*this, G); });

  if (ShowRelocatedSectionContents)
    PassConfig.PostFixupPasses.push_back([this](LinkGraph &G) -> Error {
      dumpSectionContents(outs(), *this, G);
      return Error::success();
    });

  if (AddSelfRelocations)
    PassConfig.PostPrunePasses.push_back(addSelfRelocations);

  PassConfig.PostFixupPasses.push_back([this](LinkGraph &G) {
    std::lock_guard<std::mutex> Lock(M);
    if (--ActiveLinks == 0)
      ActiveLinksCV.notify_all();
    return Error::success();
  });
}

Expected<JITDylib *> Session::getOrLoadDynamicLibrary(StringRef LibPath) {
  auto It = DynLibJDs.find(LibPath);
  if (It != DynLibJDs.end()) {
    return It->second;
  }
  auto G = EPCDynamicLibrarySearchGenerator::Load(ES, LibPath.data());
  if (!G)
    return G.takeError();
  auto JD = &ES.createBareJITDylib(LibPath.str());

  JD->addGenerator(std::move(*G));
  DynLibJDs.emplace(LibPath.str(), JD);
  LLVM_DEBUG({
    dbgs() << "Loaded dynamic library " << LibPath.data() << " for " << LibPath
           << "\n";
  });
  return JD;
}

Error Session::loadAndLinkDynamicLibrary(JITDylib &JD, StringRef LibPath) {
  auto DL = getOrLoadDynamicLibrary(LibPath);
  if (!DL)
    return DL.takeError();
  JD.addToLinkOrder(**DL);
  LLVM_DEBUG({
    dbgs() << "Linking dynamic library " << LibPath << " to " << JD.getName()
           << "\n";
  });
  return Error::success();
}

Error Session::FileInfo::registerGOTEntry(
    LinkGraph &G, Symbol &Sym, GetSymbolTargetFunction GetSymbolTarget) {
  if (Sym.isSymbolZeroFill())
    return make_error<StringError>("Unexpected zero-fill symbol in section " +
                                       Sym.getBlock().getSection().getName(),
                                   inconvertibleErrorCode());
  auto TS = GetSymbolTarget(G, Sym.getBlock());
  if (!TS)
    return TS.takeError();
  GOTEntryInfos[*TS->getName()] = {Sym.getSymbolContent(),
                                   Sym.getAddress().getValue(),
                                   Sym.getTargetFlags()};
  return Error::success();
}

Error Session::FileInfo::registerStubEntry(
    LinkGraph &G, Symbol &Sym, GetSymbolTargetFunction GetSymbolTarget) {
  if (Sym.isSymbolZeroFill())
    return make_error<StringError>("Unexpected zero-fill symbol in section " +
                                       Sym.getBlock().getSection().getName(),
                                   inconvertibleErrorCode());
  auto TS = GetSymbolTarget(G, Sym.getBlock());
  if (!TS)
    return TS.takeError();

  SmallVectorImpl<MemoryRegionInfo> &Entry = StubInfos[*TS->getName()];
  Entry.insert(Entry.begin(),
               {Sym.getSymbolContent(), Sym.getAddress().getValue(),
                Sym.getTargetFlags()});
  return Error::success();
}

Error Session::FileInfo::registerMultiStubEntry(
    LinkGraph &G, Symbol &Sym, GetSymbolTargetFunction GetSymbolTarget) {
  if (Sym.isSymbolZeroFill())
    return make_error<StringError>("Unexpected zero-fill symbol in section " +
                                       Sym.getBlock().getSection().getName(),
                                   inconvertibleErrorCode());

  auto Target = GetSymbolTarget(G, Sym.getBlock());
  if (!Target)
    return Target.takeError();

  SmallVectorImpl<MemoryRegionInfo> &Entry = StubInfos[*Target->getName()];
  Entry.emplace_back(Sym.getSymbolContent(), Sym.getAddress().getValue(),
                     Sym.getTargetFlags());

  // Let's keep stubs ordered by ascending address.
  std::sort(Entry.begin(), Entry.end(),
            [](const MemoryRegionInfo &L, const MemoryRegionInfo &R) {
              return L.getTargetAddress() < R.getTargetAddress();
            });

  return Error::success();
}

Expected<Session::FileInfo &> Session::findFileInfo(StringRef FileName) {
  auto FileInfoItr = FileInfos.find(FileName);
  if (FileInfoItr == FileInfos.end())
    return make_error<StringError>("file \"" + FileName + "\" not recognized",
                                   inconvertibleErrorCode());
  return FileInfoItr->second;
}

Expected<Session::MemoryRegionInfo &>
Session::findSectionInfo(StringRef FileName, StringRef SectionName) {
  auto FI = findFileInfo(FileName);
  if (!FI)
    return FI.takeError();
  auto SecInfoItr = FI->SectionInfos.find(SectionName);
  if (SecInfoItr == FI->SectionInfos.end())
    return make_error<StringError>("no section \"" + SectionName +
                                       "\" registered for file \"" + FileName +
                                       "\"",
                                   inconvertibleErrorCode());
  return SecInfoItr->second;
}

class MemoryMatcher {
public:
  MemoryMatcher(ArrayRef<char> Content)
      : Pos(Content.data()), End(Pos + Content.size()) {}

  template <typename MaskType> bool matchMask(MaskType Mask) {
    if (Mask == (Mask & *reinterpret_cast<const MaskType *>(Pos))) {
      Pos += sizeof(MaskType);
      return true;
    }
    return false;
  }

  template <typename ValueType> bool matchEqual(ValueType Value) {
    if (Value == *reinterpret_cast<const ValueType *>(Pos)) {
      Pos += sizeof(ValueType);
      return true;
    }
    return false;
  }

  bool done() const { return Pos == End; }

private:
  const char *Pos;
  const char *End;
};

static StringRef detectStubKind(const Session::MemoryRegionInfo &Stub) {
  using namespace support::endian;
  auto Armv7MovWTle = byte_swap<uint32_t>(0xe300c000, endianness::little);
  auto Armv7BxR12le = byte_swap<uint32_t>(0xe12fff1c, endianness::little);
  auto Thumbv7MovWTle = byte_swap<uint32_t>(0x0c00f240, endianness::little);
  auto Thumbv7BxR12le = byte_swap<uint16_t>(0x4760, endianness::little);

  MemoryMatcher M(Stub.getContent());
  if (M.matchMask(Thumbv7MovWTle)) {
    if (M.matchMask(Thumbv7MovWTle))
      if (M.matchEqual(Thumbv7BxR12le))
        if (M.done())
          return "thumbv7_abs_le";
  } else if (M.matchMask(Armv7MovWTle)) {
    if (M.matchMask(Armv7MovWTle))
      if (M.matchEqual(Armv7BxR12le))
        if (M.done())
          return "armv7_abs_le";
  }
  return "";
}

Expected<Session::MemoryRegionInfo &>
Session::findStubInfo(StringRef FileName, StringRef TargetName,
                      StringRef KindNameFilter) {
  auto FI = findFileInfo(FileName);
  if (!FI)
    return FI.takeError();
  auto StubInfoItr = FI->StubInfos.find(TargetName);
  if (StubInfoItr == FI->StubInfos.end())
    return make_error<StringError>("no stub for \"" + TargetName +
                                       "\" registered for file \"" + FileName +
                                       "\"",
                                   inconvertibleErrorCode());
  auto &StubsForTarget = StubInfoItr->second;
  assert(!StubsForTarget.empty() && "At least 1 stub in each entry");
  if (KindNameFilter.empty() && StubsForTarget.size() == 1)
    return StubsForTarget[0]; // Regular single-stub match

  std::string KindsStr;
  SmallVector<MemoryRegionInfo *, 1> Matches;
  Regex KindNameMatcher(KindNameFilter.empty() ? ".*" : KindNameFilter);
  for (MemoryRegionInfo &Stub : StubsForTarget) {
    StringRef Kind = detectStubKind(Stub);
    if (KindNameMatcher.match(Kind))
      Matches.push_back(&Stub);
    KindsStr += "\"" + (Kind.empty() ? "<unknown>" : Kind.str()) + "\", ";
  }
  if (Matches.empty())
    return make_error<StringError>(
        "\"" + TargetName + "\" has " + Twine(StubsForTarget.size()) +
            " stubs in file \"" + FileName +
            "\", but none of them matches the stub-kind filter \"" +
            KindNameFilter + "\" (all encountered kinds are " +
            StringRef(KindsStr.data(), KindsStr.size() - 2) + ").",
        inconvertibleErrorCode());
  if (Matches.size() > 1)
    return make_error<StringError>(
        "\"" + TargetName + "\" has " + Twine(Matches.size()) +
            " candidate stubs in file \"" + FileName +
            "\". Please refine stub-kind filter \"" + KindNameFilter +
            "\" for disambiguation (encountered kinds are " +
            StringRef(KindsStr.data(), KindsStr.size() - 2) + ").",
        inconvertibleErrorCode());

  return *Matches[0];
}

Expected<Session::MemoryRegionInfo &>
Session::findGOTEntryInfo(StringRef FileName, StringRef TargetName) {
  auto FI = findFileInfo(FileName);
  if (!FI)
    return FI.takeError();
  auto GOTInfoItr = FI->GOTEntryInfos.find(TargetName);
  if (GOTInfoItr == FI->GOTEntryInfos.end())
    return make_error<StringError>("no GOT entry for \"" + TargetName +
                                       "\" registered for file \"" + FileName +
                                       "\"",
                                   inconvertibleErrorCode());
  return GOTInfoItr->second;
}

bool Session::isSymbolRegistered(const orc::SymbolStringPtr &SymbolName) {
  return SymbolInfos.count(SymbolName);
}

Expected<Session::MemoryRegionInfo &>
Session::findSymbolInfo(const orc::SymbolStringPtr &SymbolName,
                        Twine ErrorMsgStem) {
  auto SymInfoItr = SymbolInfos.find(SymbolName);
  if (SymInfoItr == SymbolInfos.end())
    return make_error<StringError>(ErrorMsgStem + ": symbol " + *SymbolName +
                                       " not found",
                                   inconvertibleErrorCode());
  return SymInfoItr->second;
}

} // end namespace llvm

static std::pair<Triple, SubtargetFeatures> getFirstFileTripleAndFeatures() {
  static std::pair<Triple, SubtargetFeatures> FirstTTAndFeatures = []() {
    assert(!InputFiles.empty() && "InputFiles can not be empty");

    if (!OverrideTriple.empty()) {
      LLVM_DEBUG({
        dbgs() << "Triple from -triple override: " << OverrideTriple << "\n";
      });
      return std::make_pair(Triple(OverrideTriple), SubtargetFeatures());
    }

    for (auto InputFile : InputFiles) {
      auto ObjBuffer = ExitOnErr(getFile(InputFile));
      file_magic Magic = identify_magic(ObjBuffer->getBuffer());
      switch (Magic) {
      case file_magic::coff_object:
      case file_magic::elf_relocatable:
      case file_magic::macho_object: {
        auto Obj = ExitOnErr(
            object::ObjectFile::createObjectFile(ObjBuffer->getMemBufferRef()));
        Triple TT;
        if (auto *MachOObj = dyn_cast<object::MachOObjectFile>(Obj.get()))
          TT = MachOObj->getArchTriple();
        else
          TT = Obj->makeTriple();
        if (Magic == file_magic::coff_object) {
          // TODO: Move this to makeTriple() if possible.
          TT.setObjectFormat(Triple::COFF);
          TT.setOS(Triple::OSType::Win32);
        }
        SubtargetFeatures Features;
        if (auto ObjFeatures = Obj->getFeatures())
          Features = std::move(*ObjFeatures);

        LLVM_DEBUG({
          dbgs() << "Triple from " << InputFile << ": " << TT.str() << "\n";
        });
        return std::make_pair(TT, Features);
      }
      default:
        break;
      }
    }

    // If no plain object file inputs exist to pin down the triple then detect
    // the host triple and default to that.
    auto JTMB = ExitOnErr(JITTargetMachineBuilder::detectHost());
    LLVM_DEBUG({
      dbgs() << "Triple from host-detection: " << JTMB.getTargetTriple().str()
             << "\n";
    });
    return std::make_pair(JTMB.getTargetTriple(), JTMB.getFeatures());
  }();

  return FirstTTAndFeatures;
}

static Error sanitizeArguments(const Triple &TT, const char *ArgV0) {

  // -noexec and --args should not be used together.
  if (NoExec && !InputArgv.empty())
    errs() << "Warning: --args passed to -noexec run will be ignored.\n";

  // Set the entry point name if not specified.
  if (EntryPointName.empty())
    EntryPointName = TT.getObjectFormat() == Triple::MachO ? "_main" : "main";

  // Disable debugger support by default in noexec tests.
  if (DebuggerSupport.getNumOccurrences() == 0 && NoExec)
    DebuggerSupport = false;

  if (!OrcRuntime.empty() && NoProcessSymbols)
    return make_error<StringError>("-orc-runtime requires process symbols",
                                   inconvertibleErrorCode());

  // If -slab-allocate is passed, check that we're not trying to use it in
  // -oop-executor or -oop-executor-connect mode.
  //
  // FIXME: Remove once we enable remote slab allocation.
  if (SlabAllocateSizeString != "") {
    if (OutOfProcessExecutor.getNumOccurrences() ||
        OutOfProcessExecutorConnect.getNumOccurrences())
      return make_error<StringError>(
          "-slab-allocate cannot be used with -oop-executor or "
          "-oop-executor-connect",
          inconvertibleErrorCode());
  }

  // If -slab-address is passed, require -slab-allocate and -noexec
  if (SlabAddress != ~0ULL) {
    if (SlabAllocateSizeString == "" || !NoExec)
      return make_error<StringError>(
          "-slab-address requires -slab-allocate and -noexec",
          inconvertibleErrorCode());

    if (SlabPageSize == 0)
      errs() << "Warning: -slab-address used without -slab-page-size.\n";
  }

  if (SlabPageSize != 0) {
    // -slab-page-size requires slab alloc.
    if (SlabAllocateSizeString == "")
      return make_error<StringError>("-slab-page-size requires -slab-allocate",
                                     inconvertibleErrorCode());

    // Check -slab-page-size / -noexec interactions.
    if (!NoExec) {
      if (auto RealPageSize = sys::Process::getPageSize()) {
        if (SlabPageSize % *RealPageSize)
          return make_error<StringError>(
              "-slab-page-size must be a multiple of real page size for exec "
              "tests (did you mean to use -noexec ?)\n",
              inconvertibleErrorCode());
      } else {
        errs() << "Could not retrieve process page size:\n";
        logAllUnhandledErrors(RealPageSize.takeError(), errs(), "");
        errs() << "Executing with slab page size = "
               << formatv("{0:x}", SlabPageSize) << ".\n"
               << "Tool may crash if " << formatv("{0:x}", SlabPageSize)
               << " is not a multiple of the real process page size.\n"
               << "(did you mean to use -noexec ?)";
      }
    }
  }

#if LLVM_ENABLE_THREADS
  if (MaterializationThreads == std::numeric_limits<size_t>::max()) {
    if (auto HC = std::thread::hardware_concurrency())
      MaterializationThreads = HC;
    else {
      errs() << "Warning: std::thread::hardware_concurrency() returned 0, "
                "defaulting to -num-threads=1.\n";
      MaterializationThreads = 1;
    }
  }
#else
  if (MaterializationThreads.getNumOccurrences() &&
      MaterializationThreads != 0) {
    errs() << "Warning: -num-threads was set, but LLVM was built with threads "
              "disabled. Resetting to -num-threads=0\n";
  }
  MaterializationThreads = 0;
#endif

  if (!!OutOfProcessExecutor.getNumOccurrences() ||
      !!OutOfProcessExecutorConnect.getNumOccurrences()) {
    if (NoExec)
      return make_error<StringError>("-noexec cannot be used with " +
                                         OutOfProcessExecutor.ArgStr + " or " +
                                         OutOfProcessExecutorConnect.ArgStr,
                                     inconvertibleErrorCode());

    if (MaterializationThreads == 0)
      return make_error<StringError>("-threads=0 cannot be used with " +
                                         OutOfProcessExecutor.ArgStr + " or " +
                                         OutOfProcessExecutorConnect.ArgStr,
                                     inconvertibleErrorCode());
  }

#ifndef NDEBUG
  if (DebugFlag && MaterializationThreads != 0)
    errs() << "Warning: debugging output is not thread safe. "
              "Use -num-threads=0 to stabilize output.\n";
#endif // NDEBUG

  // Only one of -oop-executor and -oop-executor-connect can be used.
  if (!!OutOfProcessExecutor.getNumOccurrences() &&
      !!OutOfProcessExecutorConnect.getNumOccurrences())
    return make_error<StringError>(
        "Only one of -" + OutOfProcessExecutor.ArgStr + " and -" +
            OutOfProcessExecutorConnect.ArgStr + " can be specified",
        inconvertibleErrorCode());

  // If -oop-executor was used but no value was specified then use a sensible
  // default.
  if (!!OutOfProcessExecutor.getNumOccurrences() &&
      OutOfProcessExecutor.empty()) {
    SmallString<256> OOPExecutorPath(sys::fs::getMainExecutable(
        ArgV0, reinterpret_cast<void *>(&sanitizeArguments)));
    sys::path::remove_filename(OOPExecutorPath);
    sys::path::append(OOPExecutorPath, "llvm-jitlink-executor");
    OutOfProcessExecutor = OOPExecutorPath.str().str();
  }

  // If lazy linking is requested then check compatibility with other options.
  if (lazyLinkingRequested()) {
    if (OrcRuntime.empty())
      return make_error<StringError>("Lazy linking requries the ORC runtime",
                                     inconvertibleErrorCode());

    if (!TestHarnesses.empty())
      return make_error<StringError>(
          "Lazy linking cannot be used with -harness mode",
          inconvertibleErrorCode());
  } else if (Speculate != SpeculateKind::None) {
    errs() << "Warning: -speculate ignored as there are no -lazy inputs\n";
    Speculate = SpeculateKind::None;
  }

  if (Speculate == SpeculateKind::None) {
    if (!SpeculateOrder.empty()) {
      errs() << "Warning: -speculate-order ignored because speculation is "
                "disabled\n";
      SpeculateOrder = "";
    }

    if (!RecordLazyExecs.empty()) {
      errs() << "Warning: -record-lazy-execs ignored because speculation is "
                "disabled\n";
      RecordLazyExecs = "";
    }
  }

  return Error::success();
}

static void addPhonyExternalsGenerator(Session &S) {
  S.MainJD->addGenerator(std::make_unique<PhonyExternalsGenerator>());
}

static Error createJITDylibs(Session &S,
                             std::map<unsigned, JITDylib *> &IdxToJD) {
  // First, set up JITDylibs.
  LLVM_DEBUG(dbgs() << "Creating JITDylibs...\n");
  {
    // Create a "main" JITLinkDylib.
    IdxToJD[0] = S.MainJD;
    S.JDSearchOrder.push_back({S.MainJD, JITDylibLookupFlags::MatchAllSymbols});
    LLVM_DEBUG(dbgs() << "  0: " << S.MainJD->getName() << "\n");

    // Add any extra JITDylibs from the command line.
    for (auto JDItr = JITDylibs.begin(), JDEnd = JITDylibs.end();
         JDItr != JDEnd; ++JDItr) {
      auto JD = S.ES.createJITDylib(*JDItr);
      if (!JD)
        return JD.takeError();
      unsigned JDIdx = JITDylibs.getPosition(JDItr - JITDylibs.begin());
      IdxToJD[JDIdx] = &*JD;
      S.JDSearchOrder.push_back({&*JD, JITDylibLookupFlags::MatchAllSymbols});
      LLVM_DEBUG(dbgs() << "  " << JDIdx << ": " << JD->getName() << "\n");
    }
  }

  if (S.PlatformJD)
    S.JDSearchOrder.push_back(
        {S.PlatformJD, JITDylibLookupFlags::MatchExportedSymbolsOnly});
  if (S.ProcessSymsJD)
    S.JDSearchOrder.push_back(
        {S.ProcessSymsJD, JITDylibLookupFlags::MatchExportedSymbolsOnly});

  LLVM_DEBUG({
    dbgs() << "Dylib search order is [ ";
    for (auto &KV : S.JDSearchOrder)
      dbgs() << KV.first->getName() << " ";
    dbgs() << "]\n";
  });

  return Error::success();
}

static Error addAbsoluteSymbols(Session &S,
                                const std::map<unsigned, JITDylib *> &IdxToJD) {
  // Define absolute symbols.
  LLVM_DEBUG(dbgs() << "Defining absolute symbols...\n");
  for (auto AbsDefItr = AbsoluteDefs.begin(), AbsDefEnd = AbsoluteDefs.end();
       AbsDefItr != AbsDefEnd; ++AbsDefItr) {
    unsigned AbsDefArgIdx =
      AbsoluteDefs.getPosition(AbsDefItr - AbsoluteDefs.begin());
    auto &JD = *std::prev(IdxToJD.lower_bound(AbsDefArgIdx))->second;

    StringRef AbsDefStmt = *AbsDefItr;
    size_t EqIdx = AbsDefStmt.find_first_of('=');
    if (EqIdx == StringRef::npos)
      return make_error<StringError>("Invalid absolute define \"" + AbsDefStmt +
                                     "\". Syntax: <name>=<addr>",
                                     inconvertibleErrorCode());
    StringRef Name = AbsDefStmt.substr(0, EqIdx).trim();
    StringRef AddrStr = AbsDefStmt.substr(EqIdx + 1).trim();

    uint64_t Addr;
    if (AddrStr.getAsInteger(0, Addr))
      return make_error<StringError>("Invalid address expression \"" + AddrStr +
                                         "\" in absolute symbol definition \"" +
                                         AbsDefStmt + "\"",
                                     inconvertibleErrorCode());
    ExecutorSymbolDef AbsDef(ExecutorAddr(Addr), JITSymbolFlags::Exported);
    auto InternedName = S.ES.intern(Name);
    if (auto Err = JD.define(absoluteSymbols({{InternedName, AbsDef}})))
      return Err;

    // Register the absolute symbol with the session symbol infos.
    S.SymbolInfos[std::move(InternedName)] =
      {ArrayRef<char>(), Addr, AbsDef.getFlags().getTargetFlags()};
  }

  return Error::success();
}

static Error addAliases(Session &S,
                        const std::map<unsigned, JITDylib *> &IdxToJD) {
  // Define absolute symbols.
  LLVM_DEBUG(dbgs() << "Defining aliases...\n");

  DenseMap<std::pair<JITDylib *, JITDylib *>, SymbolAliasMap> Reexports;
  for (auto AliasItr = Aliases.begin(), AliasEnd = Aliases.end();
       AliasItr != AliasEnd; ++AliasItr) {

    auto BadExpr = [&]() {
      return make_error<StringError>(
          "Invalid alias definition \"" + *AliasItr +
              "\". Syntax: [<dst-jd>:]<alias>=[<src-jd>:]<aliasee>",
          inconvertibleErrorCode());
    };

    auto GetJD = [&](StringRef JDName) -> Expected<JITDylib *> {
      if (JDName.empty()) {
        unsigned AliasArgIdx = Aliases.getPosition(AliasItr - Aliases.begin());
        return std::prev(IdxToJD.lower_bound(AliasArgIdx))->second;
      }

      auto *JD = S.ES.getJITDylibByName(JDName);
      if (!JD)
        return make_error<StringError>(StringRef("In alias definition \"") +
                                           *AliasItr + "\" no dylib named " +
                                           JDName,
                                       inconvertibleErrorCode());

      return JD;
    };

    {
      // First split on '=' to get alias and aliasee.
      StringRef AliasStmt = *AliasItr;
      auto [AliasExpr, AliaseeExpr] = AliasStmt.split('=');
      if (AliaseeExpr.empty())
        return BadExpr();

      auto [AliasJDName, Alias] = AliasExpr.split(':');
      if (Alias.empty())
        std::swap(AliasJDName, Alias);

      auto AliasJD = GetJD(AliasJDName);
      if (!AliasJD)
        return AliasJD.takeError();

      auto [AliaseeJDName, Aliasee] = AliaseeExpr.split(':');
      if (Aliasee.empty())
        std::swap(AliaseeJDName, Aliasee);

      if (AliaseeJDName.empty() && !AliasJDName.empty())
        AliaseeJDName = AliasJDName;
      auto AliaseeJD = GetJD(AliaseeJDName);
      if (!AliaseeJD)
        return AliaseeJD.takeError();

      Reexports[{*AliasJD, *AliaseeJD}][S.ES.intern(Alias)] = {
          S.ES.intern(Aliasee), JITSymbolFlags::Exported};
    }
  }

  for (auto &[JDs, AliasMap] : Reexports) {
    auto [DstJD, SrcJD] = JDs;
    if (auto Err = DstJD->define(reexports(*SrcJD, std::move(AliasMap))))
      return Err;
  }

  return Error::success();
}

static Error addSectCreates(Session &S,
                            const std::map<unsigned, JITDylib *> &IdxToJD) {
  for (auto SCItr = SectCreate.begin(), SCEnd = SectCreate.end();
       SCItr != SCEnd; ++SCItr) {

    unsigned SCArgIdx = SectCreate.getPosition(SCItr - SectCreate.begin());
    auto &JD = *std::prev(IdxToJD.lower_bound(SCArgIdx))->second;

    StringRef SCArg(*SCItr);

    auto [SectAndFileName, ExtraSymbolsString] = SCArg.rsplit('@');
    auto [SectName, FileName] = SectAndFileName.rsplit(',');
    if (SectName.empty())
      return make_error<StringError>("In -sectcreate=" + SCArg +
                                         ", filename component cannot be empty",
                                     inconvertibleErrorCode());
    if (FileName.empty())
      return make_error<StringError>("In -sectcreate=" + SCArg +
                                         ", filename component cannot be empty",
                                     inconvertibleErrorCode());

    auto Content = getFile(FileName);
    if (!Content)
      return Content.takeError();

    SectCreateMaterializationUnit::ExtraSymbolsMap ExtraSymbols;
    while (!ExtraSymbolsString.empty()) {
      StringRef NextSymPair;
      std::tie(NextSymPair, ExtraSymbolsString) = ExtraSymbolsString.split(',');

      auto [Sym, OffsetString] = NextSymPair.split('=');
      size_t Offset;

      if (OffsetString.getAsInteger(0, Offset))
        return make_error<StringError>("In -sectcreate=" + SCArg + ", " +
                                           OffsetString +
                                           " is not a valid integer",
                                       inconvertibleErrorCode());

      ExtraSymbols[S.ES.intern(Sym)] = {JITSymbolFlags::Exported, Offset};
    }

    if (auto Err = JD.define(std::make_unique<SectCreateMaterializationUnit>(
            S.ObjLayer, SectName.str(), MemProt::Read, 16, std::move(*Content),
            std::move(ExtraSymbols))))
      return Err;
  }

  return Error::success();
}

static Error addTestHarnesses(Session &S) {
  LLVM_DEBUG(dbgs() << "Adding test harness objects...\n");
  for (auto HarnessFile : TestHarnesses) {
    LLVM_DEBUG(dbgs() << "  " << HarnessFile << "\n");
    auto Linkable = loadLinkableFile(HarnessFile, S.ES.getTargetTriple(),
                                     LoadArchives::Never);
    if (!Linkable)
      return Linkable.takeError();
    if (auto Err = S.ObjLayer.add(*S.MainJD, std::move(Linkable->first)))
      return Err;
  }
  return Error::success();
}

static Error addObjects(Session &S,
                        const std::map<unsigned, JITDylib *> &IdxToJD,
                        const DenseSet<unsigned> &LazyLinkIdxs) {

  // Load each object into the corresponding JITDylib..
  LLVM_DEBUG(dbgs() << "Adding objects...\n");
  for (auto InputFileItr = InputFiles.begin(), InputFileEnd = InputFiles.end();
       InputFileItr != InputFileEnd; ++InputFileItr) {
    unsigned InputFileArgIdx =
        InputFiles.getPosition(InputFileItr - InputFiles.begin());
    const std::string &InputFile = *InputFileItr;
    if (StringRef(InputFile).ends_with(".a") ||
        StringRef(InputFile).ends_with(".lib"))
      continue;
    auto &JD = *std::prev(IdxToJD.lower_bound(InputFileArgIdx))->second;
    bool AddLazy = LazyLinkIdxs.count(InputFileArgIdx);
    LLVM_DEBUG(dbgs() << "  " << InputFileArgIdx << ": \"" << InputFile << "\" "
                      << (AddLazy ? " (lazy-linked)" : "") << " to "
                      << JD.getName() << "\n";);
    auto ObjBuffer = loadLinkableFile(InputFile, S.ES.getTargetTriple(),
                                      LoadArchives::Never);
    if (!ObjBuffer)
      return ObjBuffer.takeError();

    if (S.HarnessFiles.empty()) {
      if (auto Err =
              S.getLinkLayer(AddLazy).add(JD, std::move(ObjBuffer->first)))
        return Err;
    } else {
      // We're in -harness mode. Use a custom interface for this
      // test object.
      auto ObjInterface =
          getTestObjectFileInterface(S, ObjBuffer->first->getMemBufferRef());
      if (!ObjInterface)
        return ObjInterface.takeError();

      if (auto Err = S.ObjLayer.add(JD, std::move(ObjBuffer->first),
                                    std::move(*ObjInterface)))
        return Err;
    }
  }

  return Error::success();
}

static Expected<MaterializationUnit::Interface>
getObjectFileInterfaceHidden(ExecutionSession &ES, MemoryBufferRef ObjBuffer) {
  auto I = getObjectFileInterface(ES, ObjBuffer);
  if (I) {
    for (auto &KV : I->SymbolFlags)
      KV.second &= ~JITSymbolFlags::Exported;
  }
  return I;
}

static SmallVector<StringRef, 5> getSearchPathsFromEnvVar(Session &S) {
  // FIXME: Handle EPC environment.
  SmallVector<StringRef, 5> PathVec;
  auto TT = S.ES.getTargetTriple();
  if (TT.isOSBinFormatCOFF())
    StringRef(getenv("PATH")).split(PathVec, ";");
  else if (TT.isOSBinFormatELF())
    StringRef(getenv("LD_LIBRARY_PATH")).split(PathVec, ":");

  return PathVec;
}

static Expected<std::unique_ptr<DefinitionGenerator>>
LoadLibraryWeak(Session &S, StringRef Path) {
  auto Symbols = getDylibInterface(S.ES, Path);
  if (!Symbols)
    return Symbols.takeError();

  return std::make_unique<EPCDynamicLibrarySearchGenerator>(
      S.ES, [Symbols = std::move(*Symbols)](const SymbolStringPtr &Sym) {
        return Symbols.count(Sym);
      });
}

static Error addLibraries(Session &S,
                          const std::map<unsigned, JITDylib *> &IdxToJD,
                          const DenseSet<unsigned> &LazyLinkIdxs) {

  // 1. Collect search paths for each JITDylib.
  DenseMap<const JITDylib *, SmallVector<StringRef, 2>> JDSearchPaths;

  for (auto LSPItr = LibrarySearchPaths.begin(),
            LSPEnd = LibrarySearchPaths.end();
       LSPItr != LSPEnd; ++LSPItr) {
    unsigned LibrarySearchPathIdx =
        LibrarySearchPaths.getPosition(LSPItr - LibrarySearchPaths.begin());
    auto &JD = *std::prev(IdxToJD.lower_bound(LibrarySearchPathIdx))->second;

    StringRef LibrarySearchPath = *LSPItr;
    if (sys::fs::get_file_type(LibrarySearchPath) !=
        sys::fs::file_type::directory_file)
      return make_error<StringError>("While linking " + JD.getName() + ", -L" +
                                         LibrarySearchPath +
                                         " does not point to a directory",
                                     inconvertibleErrorCode());

    JDSearchPaths[&JD].push_back(*LSPItr);
  }

  LLVM_DEBUG({
    if (!JDSearchPaths.empty())
      dbgs() << "Search paths:\n";
    for (auto &KV : JDSearchPaths) {
      dbgs() << "  " << KV.first->getName() << ": [";
      for (auto &LibSearchPath : KV.second)
        dbgs() << " \"" << LibSearchPath << "\"";
      dbgs() << " ]\n";
    }
  });

  // 2. Collect library loads
  struct LibraryLoad {
    std::string LibName;
    bool IsPath = false;
    unsigned Position;
    ArrayRef<StringRef> CandidateExtensions;
    enum { Standard, Hidden, Weak } Modifier;
  };

  // Queue to load library as in the order as it appears in the argument list.
  std::deque<LibraryLoad> LibraryLoadQueue;

  // Add archive files from the inputs to LibraryLoads.
  for (auto InputFileItr = InputFiles.begin(), InputFileEnd = InputFiles.end();
       InputFileItr != InputFileEnd; ++InputFileItr) {
    StringRef InputFile = *InputFileItr;
    if (!InputFile.ends_with(".a") && !InputFile.ends_with(".lib"))
      continue;
    LibraryLoad LL;
    LL.LibName = InputFile.str();
    LL.IsPath = true;
    LL.Position = InputFiles.getPosition(InputFileItr - InputFiles.begin());
    LL.CandidateExtensions = {};
    LL.Modifier = LibraryLoad::Standard;
    LibraryLoadQueue.push_back(std::move(LL));
  }

  // Add -load_hidden arguments to LibraryLoads.
  for (auto LibItr = LoadHidden.begin(), LibEnd = LoadHidden.end();
       LibItr != LibEnd; ++LibItr) {
    LibraryLoad LL;
    LL.LibName = *LibItr;
    LL.IsPath = true;
    LL.Position = LoadHidden.getPosition(LibItr - LoadHidden.begin());
    LL.CandidateExtensions = {};
    LL.Modifier = LibraryLoad::Hidden;
    LibraryLoadQueue.push_back(std::move(LL));
  }

  // Add -weak_library arguments to LibraryLoads.
  for (auto LibItr = WeakLibraries.begin(), LibEnd = WeakLibraries.end();
       LibItr != LibEnd; ++LibItr) {
    LibraryLoad LL;
    LL.LibName = *LibItr;
    LL.IsPath = true;
    LL.Position = WeakLibraries.getPosition(LibItr - WeakLibraries.begin());
    LL.CandidateExtensions = {};
    LL.Modifier = LibraryLoad::Weak;
    LibraryLoadQueue.push_back(std::move(LL));
  }

  StringRef StandardExtensions[] = {".so", ".dylib", ".dll", ".a", ".lib"};
  StringRef DynLibExtensionsOnly[] = {".so", ".dylib", ".dll"};
  StringRef ArchiveExtensionsOnly[] = {".a", ".lib"};
  StringRef WeakLinkExtensionsOnly[] = {".dylib", ".tbd"};

  // Add -lx arguments to LibraryLoads.
  for (auto LibItr = Libraries.begin(), LibEnd = Libraries.end();
       LibItr != LibEnd; ++LibItr) {
    LibraryLoad LL;
    LL.LibName = *LibItr;
    LL.Position = Libraries.getPosition(LibItr - Libraries.begin());
    LL.CandidateExtensions = StandardExtensions;
    LL.Modifier = LibraryLoad::Standard;
    LibraryLoadQueue.push_back(std::move(LL));
  }

  // Add -hidden-lx arguments to LibraryLoads.
  for (auto LibHiddenItr = LibrariesHidden.begin(),
            LibHiddenEnd = LibrariesHidden.end();
       LibHiddenItr != LibHiddenEnd; ++LibHiddenItr) {
    LibraryLoad LL;
    LL.LibName = *LibHiddenItr;
    LL.Position =
        LibrariesHidden.getPosition(LibHiddenItr - LibrariesHidden.begin());
    LL.CandidateExtensions = ArchiveExtensionsOnly;
    LL.Modifier = LibraryLoad::Hidden;
    LibraryLoadQueue.push_back(std::move(LL));
  }

  // Add -weak-lx arguments to LibraryLoads.
  for (auto LibWeakItr = LibrariesWeak.begin(),
            LibWeakEnd = LibrariesWeak.end();
       LibWeakItr != LibWeakEnd; ++LibWeakItr) {
    LibraryLoad LL;
    LL.LibName = *LibWeakItr;
    LL.Position = LibrariesWeak.getPosition(LibWeakItr - LibrariesWeak.begin());
    LL.CandidateExtensions = WeakLinkExtensionsOnly;
    LL.Modifier = LibraryLoad::Weak;
    LibraryLoadQueue.push_back(std::move(LL));
  }

  // Sort library loads by position in the argument list.
  llvm::sort(LibraryLoadQueue,
             [](const LibraryLoad &LHS, const LibraryLoad &RHS) {
               return LHS.Position < RHS.Position;
             });

  // 3. Process library loads.
  auto AddArchive = [&](JITDylib &JD, const char *Path, const LibraryLoad &LL)
      -> Expected<std::unique_ptr<StaticLibraryDefinitionGenerator>> {
    StaticLibraryDefinitionGenerator::GetObjectFileInterface
        GetObjFileInterface;
    switch (LL.Modifier) {
    case LibraryLoad::Standard:
      GetObjFileInterface = getObjectFileInterface;
      break;
    case LibraryLoad::Hidden:
      GetObjFileInterface = getObjectFileInterfaceHidden;
      S.HiddenArchives.insert(Path);
      break;
    case LibraryLoad::Weak:
      llvm_unreachable("Unsupported");
      break;
    }

    auto &LinkLayer = S.getLinkLayer(LazyLinkIdxs.count(LL.Position));

    std::set<std::string> ImportedDynamicLibraries;
    StaticLibraryDefinitionGenerator::VisitMembersFunction VisitMembers;

    // COFF gets special handling due to import libraries.
    if (S.ES.getTargetTriple().isOSBinFormatCOFF()) {
      if (AllLoad) {
        VisitMembers =
            [ImportScanner = COFFImportFileScanner(ImportedDynamicLibraries),
             LoadAll =
                 StaticLibraryDefinitionGenerator::loadAllObjectFileMembers(
                     LinkLayer, JD)](object::Archive &A,
                                     MemoryBufferRef MemberBuf,
                                     size_t Index) mutable -> Expected<bool> {
          if (!ImportScanner(A, MemberBuf, Index))
            return false;
          return LoadAll(A, MemberBuf, Index);
        };
      } else
        VisitMembers = COFFImportFileScanner(ImportedDynamicLibraries);
    } else if (AllLoad)
      VisitMembers = StaticLibraryDefinitionGenerator::loadAllObjectFileMembers(
          LinkLayer, JD);
    else if (S.ES.getTargetTriple().isOSBinFormatMachO() && ForceLoadObjC)
      VisitMembers = ForceLoadMachOArchiveMembers(LinkLayer, JD, true);

    auto G = StaticLibraryDefinitionGenerator::Load(
        LinkLayer, Path, std::move(VisitMembers),
        std::move(GetObjFileInterface));
    if (!G)
      return G.takeError();

    // Push additional dynamic libraries to search.
    // Note that this mechanism only happens in COFF.
    for (auto FileName : ImportedDynamicLibraries) {
      LibraryLoad NewLL;
      auto FileNameRef = StringRef(FileName);
      if (!FileNameRef.ends_with_insensitive(".dll"))
        return make_error<StringError>(
            "COFF Imported library not ending with dll extension?",
            inconvertibleErrorCode());
      NewLL.LibName = FileNameRef.drop_back(strlen(".dll")).str();
      NewLL.Position = LL.Position;
      NewLL.CandidateExtensions = DynLibExtensionsOnly;
      NewLL.Modifier = LibraryLoad::Standard;
      LibraryLoadQueue.push_front(std::move(NewLL));
    }
    return G;
  };

  SmallVector<StringRef, 5> SystemSearchPaths;
  if (SearchSystemLibrary.getValue())
    SystemSearchPaths = getSearchPathsFromEnvVar(S);
  while (!LibraryLoadQueue.empty()) {
    bool LibFound = false;
    auto LL = LibraryLoadQueue.front();
    LibraryLoadQueue.pop_front();
    auto &JD = *std::prev(IdxToJD.lower_bound(LL.Position))->second;

    // If this is the name of a JITDylib then link against that.
    if (auto *LJD = S.ES.getJITDylibByName(LL.LibName)) {
      if (LL.Modifier == LibraryLoad::Weak)
        return make_error<StringError>(
            "Can't use -weak-lx or -weak_library to load JITDylib " +
                LL.LibName,
            inconvertibleErrorCode());
      JD.addToLinkOrder(*LJD);
      continue;
    }

    if (LL.IsPath) {
      // Must be -weak_library.
      if (LL.Modifier == LibraryLoad::Weak) {
        if (auto G = LoadLibraryWeak(S, LL.LibName)) {
          JD.addGenerator(std::move(*G));
          continue;
        } else
          return G.takeError();
      }

      // Otherwise handle archive.
      auto G = AddArchive(JD, LL.LibName.c_str(), LL);
      if (!G)
        return createFileError(LL.LibName, G.takeError());
      JD.addGenerator(std::move(*G));
      LLVM_DEBUG({
        dbgs() << "Adding generator for static library " << LL.LibName << " to "
               << JD.getName() << "\n";
      });
      continue;
    }

    // Otherwise look through the search paths.
    auto CurJDSearchPaths = JDSearchPaths[&JD];
    for (StringRef SearchPath :
         concat<StringRef>(CurJDSearchPaths, SystemSearchPaths)) {
      for (auto LibExt : LL.CandidateExtensions) {
        SmallVector<char, 256> LibPath;
        LibPath.reserve(SearchPath.size() + strlen("lib") + LL.LibName.size() +
                        LibExt.size() + 2); // +2 for pathsep, null term.
        llvm::append_range(LibPath, SearchPath);
        if (LibExt != ".lib" && LibExt != ".dll")
          sys::path::append(LibPath, "lib" + LL.LibName + LibExt);
        else
          sys::path::append(LibPath, LL.LibName + LibExt);
        LibPath.push_back('\0');

        // Skip missing or non-regular paths.
        if (sys::fs::get_file_type(LibPath.data()) !=
            sys::fs::file_type::regular_file) {
          continue;
        }

        file_magic Magic;
        if (auto EC = identify_magic(LibPath, Magic)) {
          // If there was an error loading the file then skip it.
          LLVM_DEBUG({
            dbgs() << "Library search found \"" << LibPath
                   << "\", but could not identify file type (" << EC.message()
                   << "). Skipping.\n";
          });
          continue;
        }

        // We identified the magic. Assume that we can load it -- we'll reset
        // in the default case.
        LibFound = true;
        switch (Magic) {
        case file_magic::pecoff_executable:
        case file_magic::elf_shared_object:
        case file_magic::macho_dynamically_linked_shared_lib: {
          if (LL.Modifier == LibraryLoad::Weak) {
            if (auto G = LoadLibraryWeak(S, LibPath.data()))
              JD.addGenerator(std::move(*G));
            else
              return G.takeError();
          } else {
            if (auto Err = S.loadAndLinkDynamicLibrary(JD, LibPath.data()))
              return Err;
          }
          break;
        }
        case file_magic::archive:
        case file_magic::macho_universal_binary: {
          auto G = AddArchive(JD, LibPath.data(), LL);
          if (!G)
            return G.takeError();
          JD.addGenerator(std::move(*G));
          LLVM_DEBUG({
            dbgs() << "Adding generator for static library " << LibPath.data()
                   << " to " << JD.getName() << "\n";
          });
          break;
        }
        case file_magic::tapi_file:
          assert(LL.Modifier == LibraryLoad::Weak &&
                 "TextAPI file not being loaded as weak?");
          if (auto G = LoadLibraryWeak(S, LibPath.data()))
            JD.addGenerator(std::move(*G));
          else
            return G.takeError();
          break;
        default:
          // This file isn't a recognized library kind.
          LLVM_DEBUG({
            dbgs() << "Library search found \"" << LibPath
                   << "\", but file type is not supported. Skipping.\n";
          });
          LibFound = false;
          break;
        }
        if (LibFound)
          break;
      }
      if (LibFound)
        break;
    }

    if (!LibFound)
      return make_error<StringError>("While linking " + JD.getName() +
                                         ", could not find library for -l" +
                                         LL.LibName,
                                     inconvertibleErrorCode());
  }

  // Add platform and process symbols if available.
  for (auto &[Idx, JD] : IdxToJD) {
    if (S.PlatformJD)
      JD->addToLinkOrder(*S.PlatformJD);
    if (S.ProcessSymsJD)
      JD->addToLinkOrder(*S.ProcessSymsJD);
  }

  return Error::success();
}

static Error addSpeculationOrder(Session &S) {

  if (SpeculateOrder.empty())
    return Error::success();

  assert(S.LazyLinking && "SpeculateOrder set, but lazy linking not enabled");
  assert(S.LazyLinking->Speculator && "SpeculatoOrder set, but no speculator");

  auto SpecOrderBuffer = getFile(SpeculateOrder);
  if (!SpecOrderBuffer)
    return SpecOrderBuffer.takeError();

  StringRef LineStream((*SpecOrderBuffer)->getBuffer());
  std::vector<std::pair<std::string, SymbolStringPtr>> SpecOrder;

  size_t LineNumber = 0;
  while (!LineStream.empty()) {
    ++LineNumber;

    auto MakeSpecOrderErr = [&](StringRef Reason) {
      return make_error<StringError>("Error in speculation order file \"" +
                                         SpeculateOrder + "\" on line " +
                                         Twine(LineNumber) + ": " + Reason,
                                     inconvertibleErrorCode());
    };

    StringRef CurLine;
    std::tie(CurLine, LineStream) = LineStream.split('\n');
    CurLine = CurLine.trim();
    if (CurLine.empty())
      continue;

    auto [JDName, FuncName] = CurLine.split(',');

    if (FuncName.empty())
      return MakeSpecOrderErr("missing ',' separator");

    JDName = JDName.trim();
    if (JDName.empty())
      return MakeSpecOrderErr("no value for column 1 (JIT Dylib name)");

    FuncName = FuncName.trim();
    if (FuncName.empty())
      return MakeSpecOrderErr("no value for column 2 (function name)");

    SpecOrder.push_back({JDName.str(), S.ES.intern(FuncName)});
  }

  S.LazyLinking->Speculator->addSpeculationSuggestions(std::move(SpecOrder));

  return Error::success();
}

static Error addSessionInputs(Session &S) {
  std::map<unsigned, JITDylib *> IdxToJD;
  DenseSet<unsigned> LazyLinkIdxs;

  for (auto LLItr = LazyLink.begin(), LLEnd = LazyLink.end(); LLItr != LLEnd;
       ++LLItr) {
    if (*LLItr)
      LazyLinkIdxs.insert(LazyLink.getPosition(LLItr - LazyLink.begin()) + 1);
  }

  if (auto Err = createJITDylibs(S, IdxToJD))
    return Err;

  if (auto Err = addAbsoluteSymbols(S, IdxToJD))
    return Err;

  if (auto Err = addAliases(S, IdxToJD))
    return Err;

  if (auto Err = addSectCreates(S, IdxToJD))
    return Err;

  if (!TestHarnesses.empty())
    if (auto Err = addTestHarnesses(S))
      return Err;

  if (auto Err = addObjects(S, IdxToJD, LazyLinkIdxs))
    return Err;

  if (auto Err = addLibraries(S, IdxToJD, LazyLinkIdxs))
    return Err;

  if (auto Err = addSpeculationOrder(S))
    return Err;

  return Error::success();
}

namespace {
struct TargetInfo {
  const Target *TheTarget;
  std::unique_ptr<MCSubtargetInfo> STI;
  std::unique_ptr<MCRegisterInfo> MRI;
  std::unique_ptr<MCAsmInfo> MAI;
  std::unique_ptr<MCContext> Ctx;
  std::unique_ptr<MCDisassembler> Disassembler;
  std::unique_ptr<MCInstrInfo> MII;
  std::unique_ptr<MCInstrAnalysis> MIA;
  std::unique_ptr<MCInstPrinter> InstPrinter;
};
} // anonymous namespace

static TargetInfo
getTargetInfo(const Triple &TT,
              const SubtargetFeatures &TF = SubtargetFeatures()) {
  std::string ErrorStr;
  const Target *TheTarget = TargetRegistry::lookupTarget(TT, ErrorStr);
  if (!TheTarget)
    ExitOnErr(make_error<StringError>("Error accessing target '" + TT.str() +
                                          "': " + ErrorStr,
                                      inconvertibleErrorCode()));

  std::unique_ptr<MCSubtargetInfo> STI(
      TheTarget->createMCSubtargetInfo(TT, "", TF.getString()));
  if (!STI)
    ExitOnErr(
        make_error<StringError>("Unable to create subtarget for " + TT.str(),
                                inconvertibleErrorCode()));

  std::unique_ptr<MCRegisterInfo> MRI(TheTarget->createMCRegInfo(TT));
  if (!MRI)
    ExitOnErr(make_error<StringError>("Unable to create target register info "
                                      "for " +
                                          TT.str(),
                                      inconvertibleErrorCode()));

  MCTargetOptions MCOptions;
  std::unique_ptr<MCAsmInfo> MAI(
      TheTarget->createMCAsmInfo(*MRI, TT, MCOptions));
  if (!MAI)
    ExitOnErr(
        make_error<StringError>("Unable to create target asm info " + TT.str(),
                                inconvertibleErrorCode()));

  auto Ctx = std::make_unique<MCContext>(Triple(TT.str()), MAI.get(), MRI.get(),
                                         STI.get());

  std::unique_ptr<MCDisassembler> Disassembler(
      TheTarget->createMCDisassembler(*STI, *Ctx));
  if (!Disassembler)
    ExitOnErr(
        make_error<StringError>("Unable to create disassembler for " + TT.str(),
                                inconvertibleErrorCode()));

  std::unique_ptr<MCInstrInfo> MII(TheTarget->createMCInstrInfo());
  if (!MII)
    ExitOnErr(make_error<StringError>("Unable to create instruction info for" +
                                          TT.str(),
                                      inconvertibleErrorCode()));

  std::unique_ptr<MCInstrAnalysis> MIA(
      TheTarget->createMCInstrAnalysis(MII.get()));
  if (!MIA)
    ExitOnErr(make_error<StringError>(
        "Unable to create instruction analysis for" + TT.str(),
        inconvertibleErrorCode()));

  std::unique_ptr<MCInstPrinter> InstPrinter(
      TheTarget->createMCInstPrinter(Triple(TT.str()), 0, *MAI, *MII, *MRI));
  if (!InstPrinter)
    ExitOnErr(make_error<StringError>(
        "Unable to create instruction printer for" + TT.str(),
        inconvertibleErrorCode()));
  return {TheTarget,      std::move(STI), std::move(MRI),
          std::move(MAI), std::move(Ctx), std::move(Disassembler),
          std::move(MII), std::move(MIA), std::move(InstPrinter)};
}
static Error runChecks(Session &S, Triple TT, SubtargetFeatures Features) {
  if (CheckFiles.empty())
    return Error::success();

  S.waitForFilesLinkedFromEntryPointFile();

  LLVM_DEBUG(dbgs() << "Running checks...\n");

  auto IsSymbolValid = [&S](StringRef Symbol) {
    auto InternedSymbol = S.ES.getSymbolStringPool()->intern(Symbol);
    return S.isSymbolRegistered(InternedSymbol);
  };

  auto GetSymbolInfo = [&S](StringRef Symbol) {
    auto InternedSymbol = S.ES.getSymbolStringPool()->intern(Symbol);
    return S.findSymbolInfo(InternedSymbol, "Can not get symbol info");
  };

  auto GetSectionInfo = [&S](StringRef FileName, StringRef SectionName) {
    return S.findSectionInfo(FileName, SectionName);
  };

  auto GetStubInfo = [&S](StringRef FileName, StringRef SectionName,
                          StringRef KindNameFilter) {
    return S.findStubInfo(FileName, SectionName, KindNameFilter);
  };

  auto GetGOTInfo = [&S](StringRef FileName, StringRef SectionName) {
    return S.findGOTEntryInfo(FileName, SectionName);
  };

  RuntimeDyldChecker Checker(
      IsSymbolValid, GetSymbolInfo, GetSectionInfo, GetStubInfo, GetGOTInfo,
      S.ES.getTargetTriple().isLittleEndian() ? llvm::endianness::little
                                              : llvm::endianness::big,
      TT, StringRef(), Features, dbgs());

  std::string CheckLineStart = "# " + CheckName + ":";
  for (auto &CheckFile : CheckFiles) {
    auto CheckerFileBuf = ExitOnErr(getFile(CheckFile));
    if (!Checker.checkAllRulesInBuffer(CheckLineStart, &*CheckerFileBuf))
      ExitOnErr(make_error<StringError>(
          "Some checks in " + CheckFile + " failed", inconvertibleErrorCode()));
  }

  return Error::success();
}

static Error addSelfRelocations(LinkGraph &G) {
  auto TI = getTargetInfo(G.getTargetTriple());
  for (auto *Sym : G.defined_symbols())
    if (Sym->isCallable())
      if (auto Err = addFunctionPointerRelocationsToCurrentSymbol(
              *Sym, G, *TI.Disassembler, *TI.MIA))
        return Err;
  return Error::success();
}

static Expected<ExecutorSymbolDef> getMainEntryPoint(Session &S) {
  return S.ES.lookup(S.JDSearchOrder, S.ES.intern(EntryPointName));
}

static Expected<ExecutorSymbolDef> getOrcRuntimeEntryPoint(Session &S) {
  std::string RuntimeEntryPoint = "__orc_rt_run_program_wrapper";
  if (S.ES.getTargetTriple().getObjectFormat() == Triple::MachO)
    RuntimeEntryPoint = '_' + RuntimeEntryPoint;
  return S.ES.lookup(S.JDSearchOrder, S.ES.intern(RuntimeEntryPoint));
}

static Expected<ExecutorSymbolDef> getEntryPoint(Session &S) {
  ExecutorSymbolDef EntryPoint;

  // Find the entry-point function unconditionally, since we want to force
  // it to be materialized to collect stats.
  if (auto EP = getMainEntryPoint(S))
    EntryPoint = *EP;
  else
    return EP.takeError();
  LLVM_DEBUG({
    dbgs() << "Using entry point \"" << EntryPointName
           << "\": " << formatv("{0:x16}", EntryPoint.getAddress()) << "\n";
  });

  // If we're running with the ORC runtime then replace the entry-point
  // with the __orc_rt_run_program symbol.
  if (!OrcRuntime.empty()) {
    if (auto EP = getOrcRuntimeEntryPoint(S))
      EntryPoint = *EP;
    else
      return EP.takeError();
    LLVM_DEBUG({
      dbgs() << "(called via __orc_rt_run_program_wrapper at "
             << formatv("{0:x16}", EntryPoint.getAddress()) << ")\n";
    });
  }

  return EntryPoint;
}

static Expected<int> runWithRuntime(Session &S, ExecutorAddr EntryPointAddr) {
  StringRef DemangledEntryPoint = EntryPointName;
  if (S.ES.getTargetTriple().getObjectFormat() == Triple::MachO &&
      DemangledEntryPoint.front() == '_')
    DemangledEntryPoint = DemangledEntryPoint.drop_front();
  using llvm::orc::shared::SPSString;
  using SPSRunProgramSig =
      int64_t(SPSString, SPSString, shared::SPSSequence<SPSString>);
  int64_t Result;
  if (auto Err = S.ES.callSPSWrapper<SPSRunProgramSig>(
          EntryPointAddr, Result, S.MainJD->getName(), DemangledEntryPoint,
          static_cast<std::vector<std::string> &>(InputArgv)))
    return std::move(Err);
  return Result;
}

static Expected<int> runWithoutRuntime(Session &S,
                                       ExecutorAddr EntryPointAddr) {
  return S.ES.getExecutorProcessControl().runAsMain(EntryPointAddr, InputArgv);
}

namespace {
struct JITLinkTimers {
  TimerGroup JITLinkTG{"llvm-jitlink timers", "timers for llvm-jitlink phases"};
  Timer LoadObjectsTimer{"load", "time to load/add object files", JITLinkTG};
  Timer LinkTimer{"link", "time to link object files", JITLinkTG};
  Timer RunTimer{"run", "time to execute jitlink'd code", JITLinkTG};
};
} // namespace

int main(int argc, char *argv[]) {
  InitLLVM X(argc, argv);

  InitializeAllTargetInfos();
  InitializeAllTargetMCs();
  InitializeAllDisassemblers();

  cl::HideUnrelatedOptions({&JITLinkCategory, &getColorCategory()});
  cl::ParseCommandLineOptions(argc, argv, "llvm jitlink tool");
  ExitOnErr.setBanner(std::string(argv[0]) + ": ");

  /// If timers are enabled, create a JITLinkTimers instance.
  std::unique_ptr<JITLinkTimers> Timers =
      ShowTimes ? std::make_unique<JITLinkTimers>() : nullptr;

  auto [TT, Features] = getFirstFileTripleAndFeatures();
  ExitOnErr(sanitizeArguments(TT, argv[0]));

  auto S = ExitOnErr(Session::Create(TT, Features));

  enableStatistics(*S, !OrcRuntime.empty());

  {
    TimeRegion TR(Timers ? &Timers->LoadObjectsTimer : nullptr);
    ExitOnErr(addSessionInputs(*S));
  }

  if (PhonyExternals)
    addPhonyExternalsGenerator(*S);

  if (ShowInitialExecutionSessionState)
    S->ES.dump(outs());

  Expected<ExecutorSymbolDef> EntryPoint((ExecutorSymbolDef()));
  {
    ExpectedAsOutParameter<ExecutorSymbolDef> _(&EntryPoint);
    TimeRegion TR(Timers ? &Timers->LinkTimer : nullptr);
    EntryPoint = getEntryPoint(*S);
  }

  // Print any reports regardless of whether we succeeded or failed.
  if (ShowEntryExecutionSessionState)
    S->ES.dump(outs());

  if (ShowAddrs)
    S->dumpSessionInfo(outs());

  if (!EntryPoint) {
    if (Timers)
      Timers->JITLinkTG.printAll(errs());
    reportLLVMJITLinkError(EntryPoint.takeError());
    ExitOnErr(S->ES.endSession());
    exit(1);
  }

  ExitOnErr(runChecks(*S, std::move(TT), std::move(Features)));

  int Result = 0;
  if (!NoExec) {
    LLVM_DEBUG(dbgs() << "Running \"" << EntryPointName << "\"...\n");
    TimeRegion TR(Timers ? &Timers->RunTimer : nullptr);
    if (!OrcRuntime.empty())
      Result =
          ExitOnErr(runWithRuntime(*S, ExecutorAddr(EntryPoint->getAddress())));
    else
      Result = ExitOnErr(
          runWithoutRuntime(*S, ExecutorAddr(EntryPoint->getAddress())));
  }

  // Destroy the session.
  ExitOnErr(S->ES.endSession());
  S.reset();

  if (Timers)
    Timers->JITLinkTG.printAll(errs());

  // If the executing code set a test result override then use that.
  if (UseTestResultOverride)
    Result = TestResultOverride;

  return Result;
}
