brintos

brintos / llvm-project-archived public Read only

0
0
Text · 101.9 KiB · b8de817 Raw
2911 lines · cpp
1//===- llvm-jitlink.cpp -- Command line interface/tester for llvm-jitlink -===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8//9// This utility provides a simple command line interface to the llvm jitlink10// library, which makes relocatable object files executable in memory. Its11// primary function is as a testing utility for the jitlink library.12//13//===----------------------------------------------------------------------===//14 15#include "llvm-jitlink.h"16#include "llvm/BinaryFormat/Magic.h"17#include "llvm/Config/llvm-config.h" // for LLVM_ON_UNIX, LLVM_ENABLE_THREADS18#include "llvm/ExecutionEngine/Orc/AbsoluteSymbols.h"19#include "llvm/ExecutionEngine/Orc/COFFPlatform.h"20#include "llvm/ExecutionEngine/Orc/Debugging/DebugInfoSupport.h"21#include "llvm/ExecutionEngine/Orc/Debugging/DebuggerSupportPlugin.h"22#include "llvm/ExecutionEngine/Orc/Debugging/ELFDebugObjectPlugin.h"23#include "llvm/ExecutionEngine/Orc/Debugging/PerfSupportPlugin.h"24#include "llvm/ExecutionEngine/Orc/Debugging/VTuneSupportPlugin.h"25#include "llvm/ExecutionEngine/Orc/EHFrameRegistrationPlugin.h"26#include "llvm/ExecutionEngine/Orc/ELFNixPlatform.h"27#include "llvm/ExecutionEngine/Orc/EPCDynamicLibrarySearchGenerator.h"28#include "llvm/ExecutionEngine/Orc/ExecutionUtils.h"29#include "llvm/ExecutionEngine/Orc/IndirectionUtils.h"30#include "llvm/ExecutionEngine/Orc/JITLinkRedirectableSymbolManager.h"31#include "llvm/ExecutionEngine/Orc/JITLinkReentryTrampolines.h"32#include "llvm/ExecutionEngine/Orc/JITTargetMachineBuilder.h"33#include "llvm/ExecutionEngine/Orc/LoadLinkableFile.h"34#include "llvm/ExecutionEngine/Orc/MachO.h"35#include "llvm/ExecutionEngine/Orc/MachOPlatform.h"36#include "llvm/ExecutionEngine/Orc/MapperJITLinkMemoryManager.h"37#include "llvm/ExecutionEngine/Orc/ObjectFileInterface.h"38#include "llvm/ExecutionEngine/Orc/SectCreate.h"39#include "llvm/ExecutionEngine/Orc/SelfExecutorProcessControl.h"40#include "llvm/ExecutionEngine/Orc/Shared/OrcRTBridge.h"41#include "llvm/ExecutionEngine/Orc/SimpleRemoteMemoryMapper.h"42#include "llvm/ExecutionEngine/Orc/TargetProcess/JITLoaderGDB.h"43#include "llvm/ExecutionEngine/Orc/TargetProcess/JITLoaderPerf.h"44#include "llvm/ExecutionEngine/Orc/TargetProcess/JITLoaderVTune.h"45#include "llvm/ExecutionEngine/Orc/TargetProcess/RegisterEHFrames.h"46#include "llvm/ExecutionEngine/Orc/UnwindInfoRegistrationPlugin.h"47#include "llvm/MC/MCAsmInfo.h"48#include "llvm/MC/MCContext.h"49#include "llvm/MC/MCDisassembler/MCDisassembler.h"50#include "llvm/MC/MCInstPrinter.h"51#include "llvm/MC/MCInstrAnalysis.h"52#include "llvm/MC/MCInstrInfo.h"53#include "llvm/MC/MCRegisterInfo.h"54#include "llvm/MC/MCSubtargetInfo.h"55#include "llvm/MC/MCTargetOptions.h"56#include "llvm/MC/TargetRegistry.h"57#include "llvm/Object/COFF.h"58#include "llvm/Object/MachO.h"59#include "llvm/Object/ObjectFile.h"60#include "llvm/Object/TapiUniversal.h"61#include "llvm/Support/CommandLine.h"62#include "llvm/Support/Debug.h"63#include "llvm/Support/InitLLVM.h"64#include "llvm/Support/MemoryBuffer.h"65#include "llvm/Support/Path.h"66#include "llvm/Support/Process.h"67#include "llvm/Support/TargetSelect.h"68#include "llvm/Support/Timer.h"69#include <cstring>70#include <deque>71#include <string>72 73#ifdef LLVM_ON_UNIX74#include <netdb.h>75#include <netinet/in.h>76#include <sys/socket.h>77#include <unistd.h>78#endif // LLVM_ON_UNIX79 80#define DEBUG_TYPE "llvm_jitlink"81 82using namespace llvm;83using namespace llvm::jitlink;84using namespace llvm::orc;85 86static cl::OptionCategory JITLinkCategory("JITLink Options");87 88static cl::list<std::string> InputFiles(cl::Positional, cl::OneOrMore,89                                        cl::desc("input files"),90                                        cl::cat(JITLinkCategory));91 92static cl::list<bool> LazyLink("lazy",93                               cl::desc("Link the following file lazily"),94                               cl::cat(JITLinkCategory));95 96enum class SpeculateKind { None, Simple };97 98static cl::opt<SpeculateKind> Speculate(99    "speculate", cl::desc("Choose speculation scheme"),100    cl::init(SpeculateKind::None),101    cl::values(clEnumValN(SpeculateKind::None, "none", "No speculation"),102               clEnumValN(SpeculateKind::Simple, "simple",103                          "Simple speculation")),104    cl::cat(JITLinkCategory));105 106static cl::opt<std::string> SpeculateOrder(107    "speculate-order",108    cl::desc("A CSV file containing (JITDylib, Function) pairs to"109             "speculatively look up"),110    cl::cat(JITLinkCategory));111 112static cl::opt<std::string> RecordLazyExecs(113    "record-lazy-execs",114    cl::desc("Write lazy-function executions to a CSV file as (JITDylib, "115             "function) pairs"),116    cl::cat(JITLinkCategory));117 118static cl::opt<size_t> MaterializationThreads(119    "num-threads", cl::desc("Number of materialization threads to use"),120    cl::init(std::numeric_limits<size_t>::max()), cl::cat(JITLinkCategory));121 122static cl::list<std::string>123    LibrarySearchPaths("L",124                       cl::desc("Add dir to the list of library search paths"),125                       cl::Prefix, cl::cat(JITLinkCategory));126 127static cl::list<std::string>128    Libraries("l",129              cl::desc("Link against library X in the library search paths"),130              cl::Prefix, cl::cat(JITLinkCategory));131 132static cl::list<std::string>133    LibrariesHidden("hidden-l",134                    cl::desc("Link against library X in the library search "135                             "paths with hidden visibility"),136                    cl::Prefix, cl::cat(JITLinkCategory));137 138static cl::list<std::string>139    LoadHidden("load_hidden",140               cl::desc("Link against library X with hidden visibility"),141               cl::cat(JITLinkCategory));142 143static cl::list<std::string>144    LibrariesWeak("weak-l",145                  cl::desc("Emulate weak link against library X. Must resolve "146                           "to a TextAPI file, and all symbols in the "147                           "interface will resolve to null."),148                  cl::Prefix, cl::cat(JITLinkCategory));149 150static cl::list<std::string> WeakLibraries(151    "weak_library",152    cl::desc("Emulate weak link against library X. X must point to a "153             "TextAPI file, and all symbols in the interface will "154             "resolve to null"),155    cl::cat(JITLinkCategory));156 157static cl::opt<bool> SearchSystemLibrary(158    "search-sys-lib",159    cl::desc("Add system library paths to library search paths"),160    cl::init(false), cl::cat(JITLinkCategory));161 162static cl::opt<bool> NoExec("noexec", cl::desc("Do not execute loaded code"),163                            cl::init(false), cl::cat(JITLinkCategory));164 165static cl::list<std::string>166    CheckFiles("check", cl::desc("File containing verifier checks"),167               cl::cat(JITLinkCategory));168 169static cl::opt<std::string>170    CheckName("check-name", cl::desc("Name of checks to match against"),171              cl::init("jitlink-check"), cl::cat(JITLinkCategory));172 173static cl::opt<std::string>174    EntryPointName("entry", cl::desc("Symbol to call as main entry point"),175                   cl::init(""), cl::cat(JITLinkCategory));176 177static cl::list<std::string> JITDylibs(178    "jd",179    cl::desc("Specifies the JITDylib to be used for any subsequent "180             "input file, -L<seacrh-path>, and -l<library> arguments"),181    cl::cat(JITLinkCategory));182 183static cl::list<std::string>184    Dylibs("preload",185           cl::desc("Pre-load dynamic libraries (e.g. language runtimes "186                    "required by the ORC runtime)"),187           cl::cat(JITLinkCategory));188 189static cl::list<std::string> InputArgv("args", cl::Positional,190                                       cl::desc("<program arguments>..."),191                                       cl::PositionalEatsArgs,192                                       cl::cat(JITLinkCategory));193 194static cl::opt<bool>195    DebuggerSupport("debugger-support",196                    cl::desc("Enable debugger suppport (default = !-noexec)"),197                    cl::init(true), cl::Hidden, cl::cat(JITLinkCategory));198 199static cl::opt<bool> PerfSupport("perf-support",200                                 cl::desc("Enable perf profiling support"),201                                 cl::init(false), cl::Hidden,202                                 cl::cat(JITLinkCategory));203 204static cl::opt<bool> VTuneSupport("vtune-support",205                                  cl::desc("Enable vtune profiling support"),206                                  cl::init(false), cl::Hidden,207                                  cl::cat(JITLinkCategory));208static cl::opt<bool>209    NoProcessSymbols("no-process-syms",210                     cl::desc("Do not resolve to llvm-jitlink process symbols"),211                     cl::init(false), cl::cat(JITLinkCategory));212 213static cl::list<std::string> AbsoluteDefs(214    "abs",215    cl::desc("Inject absolute symbol definitions (syntax: <name>=<addr>)"),216    cl::cat(JITLinkCategory));217 218static cl::list<std::string>219    Aliases("alias",220            cl::desc("Inject symbol aliases (syntax: <alias-name>=<aliasee>)"),221            cl::cat(JITLinkCategory));222 223static cl::list<std::string>224    SectCreate("sectcreate",225               cl::desc("given <sectname>,<filename>[@<sym>=<offset>,...]  "226                        "add the content of <filename> to <sectname>"),227               cl::cat(JITLinkCategory));228 229static cl::list<std::string> TestHarnesses("harness", cl::Positional,230                                           cl::desc("Test harness files"),231                                           cl::PositionalEatsArgs,232                                           cl::cat(JITLinkCategory));233 234static cl::opt<bool>235    ShowLinkedFiles("show-linked-files",236                    cl::desc("List each file/graph name if/when it is linked"),237                    cl::init(false), cl::cat(JITLinkCategory));238 239static cl::opt<bool> ShowInitialExecutionSessionState(240    "show-init-es",241    cl::desc("Print ExecutionSession state before resolving entry point"),242    cl::init(false), cl::cat(JITLinkCategory));243 244static cl::opt<bool> ShowEntryExecutionSessionState(245    "show-entry-es",246    cl::desc("Print ExecutionSession state after resolving entry point"),247    cl::init(false), cl::cat(JITLinkCategory));248 249static cl::opt<bool> ShowAddrs(250    "show-addrs",251    cl::desc("Print registered symbol, section, got and stub addresses"),252    cl::init(false), cl::cat(JITLinkCategory));253 254static cl::opt<std::string> ShowLinkGraphs(255    "show-graphs",256    cl::desc("Takes a posix regex and prints the link graphs of all files "257             "matching that regex after fixups have been applied"),258    cl::Optional, cl::cat(JITLinkCategory));259 260static cl::opt<bool> ShowTimes("show-times",261                               cl::desc("Show times for llvm-jitlink phases"),262                               cl::init(false), cl::cat(JITLinkCategory));263 264static cl::opt<std::string> SlabAllocateSizeString(265    "slab-allocate",266    cl::desc("Allocate from a slab of the given size "267             "(allowable suffixes: Kb, Mb, Gb. default = "268             "Kb)"),269    cl::init(""), cl::cat(JITLinkCategory));270 271static cl::opt<uint64_t> SlabAddress(272    "slab-address",273    cl::desc("Set slab target address (requires -slab-allocate and -noexec)"),274    cl::init(~0ULL), cl::cat(JITLinkCategory));275 276static cl::opt<uint64_t> SlabPageSize(277    "slab-page-size",278    cl::desc("Set page size for slab (requires -slab-allocate and -noexec)"),279    cl::init(0), cl::cat(JITLinkCategory));280 281static cl::opt<bool> ShowRelocatedSectionContents(282    "show-relocated-section-contents",283    cl::desc("show section contents after fixups have been applied"),284    cl::init(false), cl::cat(JITLinkCategory));285 286static cl::opt<bool> PhonyExternals(287    "phony-externals",288    cl::desc("resolve all otherwise unresolved externals to null"),289    cl::init(false), cl::cat(JITLinkCategory));290 291static cl::opt<std::string> OutOfProcessExecutor(292    "oop-executor", cl::desc("Launch an out-of-process executor to run code"),293    cl::ValueOptional, cl::cat(JITLinkCategory));294 295static cl::opt<std::string> OutOfProcessExecutorConnect(296    "oop-executor-connect",297    cl::desc("Connect to an out-of-process executor via TCP"),298    cl::cat(JITLinkCategory));299 300static cl::opt<std::string>301    OrcRuntime("orc-runtime", cl::desc("Use ORC runtime from given path"),302               cl::init(""), cl::cat(JITLinkCategory));303 304static cl::opt<bool> AddSelfRelocations(305    "add-self-relocations",306    cl::desc("Add relocations to function pointers to the current function"),307    cl::init(false), cl::cat(JITLinkCategory));308 309static cl::opt<bool>310    ShowErrFailedToMaterialize("show-err-failed-to-materialize",311                               cl::desc("Show FailedToMaterialize errors"),312                               cl::init(false), cl::cat(JITLinkCategory));313 314enum class MemMgr { Default, Generic, SimpleRemote, Shared };315 316static cl::opt<MemMgr> UseMemMgr(317    "use-memmgr", cl::desc("Choose memory manager"), cl::init(MemMgr::Generic),318    cl::values(clEnumValN(MemMgr::Default, "default",319                          "Use setup default (InProcess or EPCGeneric)"),320               clEnumValN(MemMgr::Generic, "generic",321                          "Generic remote memory manager"),322               clEnumValN(MemMgr::SimpleRemote, "simple-remote",323                          "Mapper memory manager with simple-remote backend"),324               clEnumValN(MemMgr::Shared, "shared",325                          "Mapper memory manager with shared-memory manager")),326    cl::cat(JITLinkCategory));327 328static cl::opt<std::string>329    OverrideTriple("triple", cl::desc("Override target triple detection"),330                   cl::init(""), cl::cat(JITLinkCategory));331 332static cl::opt<bool> AllLoad("all_load",333                             cl::desc("Load all members of static archives"),334                             cl::init(false), cl::cat(JITLinkCategory));335 336static cl::opt<bool> ForceLoadObjC(337    "ObjC",338    cl::desc("Load all members of static archives that implement "339             "Objective-C classes or categories, or Swift structs, "340             "classes or extensions"),341    cl::init(false), cl::cat(JITLinkCategory));342 343static ExitOnError ExitOnErr;344 345static LLVM_ATTRIBUTE_USED void linkComponents() {346  errs() << "Linking in runtime functions\n"347         << (void *)&llvm_orc_registerEHFrameSectionAllocAction << '\n'348         << (void *)&llvm_orc_deregisterEHFrameSectionAllocAction << '\n'349         << (void *)&llvm_orc_registerJITLoaderGDBAllocAction << '\n'350         << (void *)&llvm_orc_registerJITLoaderPerfStart << '\n'351         << (void *)&llvm_orc_registerJITLoaderPerfEnd << '\n'352         << (void *)&llvm_orc_registerJITLoaderPerfImpl << '\n'353         << (void *)&llvm_orc_registerVTuneImpl << '\n'354         << (void *)&llvm_orc_unregisterVTuneImpl << '\n'355         << (void *)&llvm_orc_test_registerVTuneImpl << '\n';356}357 358static bool UseTestResultOverride = false;359static int64_t TestResultOverride = 0;360 361extern "C" LLVM_ATTRIBUTE_USED void362llvm_jitlink_setTestResultOverride(int64_t Value) {363  TestResultOverride = Value;364  UseTestResultOverride = true;365}366 367static Error addSelfRelocations(LinkGraph &G);368 369namespace {370 371template <typename ErrT>372 373class ConditionalPrintErr {374public:375  ConditionalPrintErr(bool C) : C(C) {}376  void operator()(ErrT &EI) {377    if (C) {378      errs() << "llvm-jitlink error: ";379      EI.log(errs());380      errs() << "\n";381    }382  }383 384private:385  bool C;386};387 388Expected<std::unique_ptr<MemoryBuffer>> getFile(const Twine &FileName) {389  if (auto F = MemoryBuffer::getFile(FileName))390    return std::move(*F);391  else392    return createFileError(FileName, F.getError());393}394 395void reportLLVMJITLinkError(Error Err) {396  handleAllErrors(397      std::move(Err),398      ConditionalPrintErr<orc::FailedToMaterialize>(ShowErrFailedToMaterialize),399      ConditionalPrintErr<ErrorInfoBase>(true));400}401 402} // end anonymous namespace403 404namespace llvm {405 406static raw_ostream &407operator<<(raw_ostream &OS, const Session::MemoryRegionInfo &MRI) {408  return OS << "target addr = "409            << format("0x%016" PRIx64, MRI.getTargetAddress())410            << ", content: " << (const void *)MRI.getContent().data() << " -- "411            << (const void *)(MRI.getContent().data() + MRI.getContent().size())412            << " (" << MRI.getContent().size() << " bytes)";413}414 415static raw_ostream &416operator<<(raw_ostream &OS, const Session::SymbolInfoMap &SIM) {417  OS << "Symbols:\n";418  for (auto &SKV : SIM)419    OS << "  \"" << SKV.first << "\" " << SKV.second << "\n";420  return OS;421}422 423static raw_ostream &424operator<<(raw_ostream &OS, const Session::FileInfo &FI) {425  for (auto &SIKV : FI.SectionInfos)426    OS << "  Section \"" << SIKV.first() << "\": " << SIKV.second << "\n";427  for (auto &GOTKV : FI.GOTEntryInfos)428    OS << "  GOT \"" << GOTKV.first() << "\": " << GOTKV.second << "\n";429  for (auto &StubKVs : FI.StubInfos) {430    OS << "  Stubs \"" << StubKVs.first() << "\":";431    for (auto MemRegion : StubKVs.second)432      OS << " " << MemRegion;433    OS << "\n";434  }435  return OS;436}437 438static raw_ostream &439operator<<(raw_ostream &OS, const Session::FileInfoMap &FIM) {440  for (auto &FIKV : FIM)441    OS << "File \"" << FIKV.first() << "\":\n" << FIKV.second;442  return OS;443}444 445bool lazyLinkingRequested() {446  for (auto LL : LazyLink)447    if (LL)448      return true;449  return false;450}451 452static Error applyLibraryLinkModifiers(Session &S, LinkGraph &G) {453  // If there are hidden archives and this graph is an archive454  // member then apply hidden modifier.455  if (!S.HiddenArchives.empty()) {456    StringRef ObjName(G.getName());457    if (ObjName.ends_with(')')) {458      auto LibName = ObjName.split('[').first;459      if (S.HiddenArchives.count(LibName)) {460        for (auto *Sym : G.defined_symbols())461          Sym->setScope(std::max(Sym->getScope(), Scope::Hidden));462      }463    }464  }465 466  return Error::success();467}468 469static Error applyHarnessPromotions(Session &S, LinkGraph &G) {470  std::lock_guard<std::mutex> Lock(S.M);471 472  // If this graph is part of the test harness there's nothing to do.473  if (S.HarnessFiles.empty() || S.HarnessFiles.count(G.getName()))474    return Error::success();475 476  LLVM_DEBUG(dbgs() << "Applying promotions to graph " << G.getName() << "\n");477 478  // If this graph is part of the test then promote any symbols referenced by479  // the harness to default scope, remove all symbols that clash with harness480  // definitions.481  std::vector<Symbol *> DefinitionsToRemove;482  for (auto *Sym : G.defined_symbols()) {483 484    if (!Sym->hasName())485      continue;486 487    if (Sym->getLinkage() == Linkage::Weak) {488      auto It = S.CanonicalWeakDefs.find(*Sym->getName());489      if (It == S.CanonicalWeakDefs.end() || It->second != G.getName()) {490        LLVM_DEBUG({491          dbgs() << "  Externalizing weak symbol " << Sym->getName() << "\n";492        });493        DefinitionsToRemove.push_back(Sym);494      } else {495        LLVM_DEBUG({496          dbgs() << "  Making weak symbol " << Sym->getName() << " strong\n";497        });498        if (S.HarnessExternals.count(*Sym->getName()))499          Sym->setScope(Scope::Default);500        else501          Sym->setScope(Scope::Hidden);502        Sym->setLinkage(Linkage::Strong);503      }504    } else if (S.HarnessExternals.count(*Sym->getName())) {505      LLVM_DEBUG(dbgs() << "  Promoting " << Sym->getName() << "\n");506      Sym->setScope(Scope::Default);507      Sym->setLive(true);508      continue;509    } else if (S.HarnessDefinitions.count(*Sym->getName())) {510      LLVM_DEBUG(dbgs() << "  Externalizing " << Sym->getName() << "\n");511      DefinitionsToRemove.push_back(Sym);512    }513  }514 515  for (auto *Sym : DefinitionsToRemove)516    G.makeExternal(*Sym);517 518  return Error::success();519}520 521static void dumpSectionContents(raw_ostream &OS, Session &S, LinkGraph &G) {522  std::lock_guard<std::mutex> Lock(S.M);523 524  outs() << "Relocated section contents for " << G.getName() << ":\n";525 526  constexpr orc::ExecutorAddrDiff DumpWidth = 16;527  static_assert(isPowerOf2_64(DumpWidth), "DumpWidth must be a power of two");528 529  // Put sections in address order.530  std::vector<Section *> Sections;531  for (auto &S : G.sections())532    Sections.push_back(&S);533 534  llvm::sort(Sections, [](const Section *LHS, const Section *RHS) {535    if (LHS->symbols().empty() && RHS->symbols().empty())536      return false;537    if (LHS->symbols().empty())538      return false;539    if (RHS->symbols().empty())540      return true;541    SectionRange LHSRange(*LHS);542    SectionRange RHSRange(*RHS);543    return LHSRange.getStart() < RHSRange.getStart();544  });545 546  for (auto *S : Sections) {547    OS << S->getName() << " content:";548    if (S->symbols().empty()) {549      OS << "\n  section empty\n";550      continue;551    }552 553    // Sort symbols into order, then render.554    std::vector<Symbol *> Syms(S->symbols().begin(), S->symbols().end());555    llvm::sort(Syms, [](const Symbol *LHS, const Symbol *RHS) {556      return LHS->getAddress() < RHS->getAddress();557    });558 559    orc::ExecutorAddr NextAddr(Syms.front()->getAddress().getValue() &560                               ~(DumpWidth - 1));561    for (auto *Sym : Syms) {562      bool IsZeroFill = Sym->getBlock().isZeroFill();563      auto SymStart = Sym->getAddress();564      auto SymSize = Sym->getSize();565      auto SymEnd = SymStart + SymSize;566      const uint8_t *SymData = IsZeroFill ? nullptr567                                          : reinterpret_cast<const uint8_t *>(568                                                Sym->getSymbolContent().data());569 570      // Pad any space before the symbol starts.571      while (NextAddr != SymStart) {572        if (NextAddr % DumpWidth == 0)573          OS << formatv("\n{0:x16}:", NextAddr);574        OS << "   ";575        ++NextAddr;576      }577 578      // Render the symbol content.579      while (NextAddr != SymEnd) {580        if (NextAddr % DumpWidth == 0)581          OS << formatv("\n{0:x16}:", NextAddr);582        if (IsZeroFill)583          OS << " 00";584        else585          OS << formatv(" {0:x-2}", SymData[NextAddr - SymStart]);586        ++NextAddr;587      }588    }589    OS << "\n";590  }591}592 593// A memory mapper with a fake offset applied only used for -noexec testing594class InProcessDeltaMapper final : public InProcessMemoryMapper {595public:596  InProcessDeltaMapper(size_t PageSize, uint64_t TargetAddr)597      : InProcessMemoryMapper(PageSize), TargetMapAddr(TargetAddr),598        DeltaAddr(0) {}599 600  static Expected<std::unique_ptr<InProcessDeltaMapper>> Create() {601    size_t PageSize = SlabPageSize;602    if (!PageSize) {603      if (auto PageSizeOrErr = sys::Process::getPageSize())604        PageSize = *PageSizeOrErr;605      else606        return PageSizeOrErr.takeError();607    }608 609    if (PageSize == 0)610      return make_error<StringError>("Page size is zero",611                                     inconvertibleErrorCode());612 613    return std::make_unique<InProcessDeltaMapper>(PageSize, SlabAddress);614  }615 616  void reserve(size_t NumBytes, OnReservedFunction OnReserved) override {617    InProcessMemoryMapper::reserve(618        NumBytes, [this, OnReserved = std::move(OnReserved)](619                      Expected<ExecutorAddrRange> Result) mutable {620          if (!Result)621            return OnReserved(Result.takeError());622 623          assert(DeltaAddr == 0 && "Overwriting previous offset");624          if (TargetMapAddr != ~0ULL)625            DeltaAddr = TargetMapAddr - Result->Start.getValue();626          auto OffsetRange = ExecutorAddrRange(Result->Start + DeltaAddr,627                                               Result->End + DeltaAddr);628 629          OnReserved(OffsetRange);630        });631  }632 633  char *prepare(jitlink::LinkGraph &G, ExecutorAddr Addr,634                size_t ContentSize) override {635    return InProcessMemoryMapper::prepare(G, Addr - DeltaAddr, ContentSize);636  }637 638  void initialize(AllocInfo &AI, OnInitializedFunction OnInitialized) override {639    // Slide mapping based on delta, make all segments read-writable, and640    // discard allocation actions.641    auto FixedAI = std::move(AI);642    FixedAI.MappingBase -= DeltaAddr;643    for (auto &Seg : FixedAI.Segments)644      Seg.AG = {MemProt::Read | MemProt::Write, Seg.AG.getMemLifetime()};645    FixedAI.Actions.clear();646    InProcessMemoryMapper::initialize(647        FixedAI, [this, OnInitialized = std::move(OnInitialized)](648                     Expected<ExecutorAddr> Result) mutable {649          if (!Result)650            return OnInitialized(Result.takeError());651 652          OnInitialized(ExecutorAddr(Result->getValue() + DeltaAddr));653        });654  }655 656  void deinitialize(ArrayRef<ExecutorAddr> Allocations,657                    OnDeinitializedFunction OnDeInitialized) override {658    std::vector<ExecutorAddr> Addrs(Allocations.size());659    for (const auto Base : Allocations) {660      Addrs.push_back(Base - DeltaAddr);661    }662 663    InProcessMemoryMapper::deinitialize(Addrs, std::move(OnDeInitialized));664  }665 666  void release(ArrayRef<ExecutorAddr> Reservations,667               OnReleasedFunction OnRelease) override {668    std::vector<ExecutorAddr> Addrs(Reservations.size());669    for (const auto Base : Reservations) {670      Addrs.push_back(Base - DeltaAddr);671    }672    InProcessMemoryMapper::release(Addrs, std::move(OnRelease));673  }674 675private:676  uint64_t TargetMapAddr;677  uint64_t DeltaAddr;678};679 680Expected<uint64_t> getSlabAllocSize(StringRef SizeString) {681  SizeString = SizeString.trim();682 683  uint64_t Units = 1024;684 685  if (SizeString.ends_with_insensitive("kb"))686    SizeString = SizeString.drop_back(2).rtrim();687  else if (SizeString.ends_with_insensitive("mb")) {688    Units = 1024 * 1024;689    SizeString = SizeString.drop_back(2).rtrim();690  } else if (SizeString.ends_with_insensitive("gb")) {691    Units = 1024 * 1024 * 1024;692    SizeString = SizeString.drop_back(2).rtrim();693  }694 695  uint64_t SlabSize = 0;696  if (SizeString.getAsInteger(10, SlabSize))697    return make_error<StringError>("Invalid numeric format for slab size",698                                   inconvertibleErrorCode());699 700  return SlabSize * Units;701}702 703static std::unique_ptr<JITLinkMemoryManager> createInProcessMemoryManager() {704  uint64_t SlabSize;705#ifdef _WIN32706  SlabSize = 1024 * 1024;707#else708  SlabSize = 1024 * 1024 * 1024;709#endif710 711  if (!SlabAllocateSizeString.empty())712    SlabSize = ExitOnErr(getSlabAllocSize(SlabAllocateSizeString));713 714  // If this is a -no-exec case and we're tweaking the slab address or size then715  // use the delta mapper.716  if (NoExec && (SlabAddress || SlabPageSize))717    return ExitOnErr(718        MapperJITLinkMemoryManager::CreateWithMapper<InProcessDeltaMapper>(719            SlabSize));720 721  // Otherwise use the standard in-process mapper.722  return ExitOnErr(723      MapperJITLinkMemoryManager::CreateWithMapper<InProcessMemoryMapper>(724          SlabSize));725}726 727Expected<std::unique_ptr<jitlink::JITLinkMemoryManager>>728createSimpleRemoteMemoryManager(SimpleRemoteEPC &SREPC) {729  SimpleRemoteMemoryMapper::SymbolAddrs SAs;730  if (auto Err = SREPC.getBootstrapSymbols(731          {{SAs.Instance, rt::SimpleExecutorMemoryManagerInstanceName},732           {SAs.Reserve, rt::SimpleExecutorMemoryManagerReserveWrapperName},733           {SAs.Initialize,734            rt::SimpleExecutorMemoryManagerInitializeWrapperName},735           {SAs.Deinitialize,736            rt::SimpleExecutorMemoryManagerDeinitializeWrapperName},737           {SAs.Release, rt::SimpleExecutorMemoryManagerReleaseWrapperName}}))738    return std::move(Err);739#ifdef _WIN32740  size_t SlabSize = 1024 * 1024;741#else742  size_t SlabSize = 1024 * 1024 * 1024;743#endif744  return MapperJITLinkMemoryManager::CreateWithMapper<SimpleRemoteMemoryMapper>(745      SlabSize, SREPC, SAs);746}747 748Expected<std::unique_ptr<jitlink::JITLinkMemoryManager>>749createSharedMemoryManager(SimpleRemoteEPC &SREPC) {750  SharedMemoryMapper::SymbolAddrs SAs;751  if (auto Err = SREPC.getBootstrapSymbols(752          {{SAs.Instance, rt::ExecutorSharedMemoryMapperServiceInstanceName},753           {SAs.Reserve,754            rt::ExecutorSharedMemoryMapperServiceReserveWrapperName},755           {SAs.Initialize,756            rt::ExecutorSharedMemoryMapperServiceInitializeWrapperName},757           {SAs.Deinitialize,758            rt::ExecutorSharedMemoryMapperServiceDeinitializeWrapperName},759           {SAs.Release,760            rt::ExecutorSharedMemoryMapperServiceReleaseWrapperName}}))761    return std::move(Err);762 763#ifdef _WIN32764  size_t SlabSize = 1024 * 1024;765#else766  size_t SlabSize = 1024 * 1024 * 1024;767#endif768 769  if (!SlabAllocateSizeString.empty())770    SlabSize = ExitOnErr(getSlabAllocSize(SlabAllocateSizeString));771 772  return MapperJITLinkMemoryManager::CreateWithMapper<SharedMemoryMapper>(773      SlabSize, SREPC, SAs);774}775 776#if LLVM_ON_UNIX && LLVM_ENABLE_THREADS777static void setupEPCRemoteMemoryManager(SimpleRemoteEPC::Setup &S) {778  switch (UseMemMgr) {779  case MemMgr::Default:780  case MemMgr::Generic:781    break;782  case MemMgr::SimpleRemote:783    S.CreateMemoryManager = createSimpleRemoteMemoryManager;784    break;785  case MemMgr::Shared:786    S.CreateMemoryManager = createSharedMemoryManager;787    break;788  }789}790#endif791 792static Expected<MaterializationUnit::Interface>793getTestObjectFileInterface(Session &S, MemoryBufferRef O) {794 795  // Get the standard interface for this object, but ignore the symbols field.796  // We'll handle that manually to include promotion.797  auto I = getObjectFileInterface(S.ES, O);798  if (!I)799    return I.takeError();800  I->SymbolFlags.clear();801 802  // If creating an object file was going to fail it would have happened above,803  // so we can 'cantFail' this.804  auto Obj = cantFail(object::ObjectFile::createObjectFile(O));805 806  // The init symbol must be included in the SymbolFlags map if present.807  if (I->InitSymbol)808    I->SymbolFlags[I->InitSymbol] =809        JITSymbolFlags::MaterializationSideEffectsOnly;810 811  for (auto &Sym : Obj->symbols()) {812    Expected<uint32_t> SymFlagsOrErr = Sym.getFlags();813    if (!SymFlagsOrErr)814      // TODO: Test this error.815      return SymFlagsOrErr.takeError();816 817    // Skip symbols not defined in this object file.818    if ((*SymFlagsOrErr & object::BasicSymbolRef::SF_Undefined))819      continue;820 821    auto Name = Sym.getName();822    if (!Name)823      return Name.takeError();824 825    // Skip symbols that have type SF_File.826    if (auto SymType = Sym.getType()) {827      if (*SymType == object::SymbolRef::ST_File)828        continue;829    } else830      return SymType.takeError();831 832    auto SymFlags = JITSymbolFlags::fromObjectSymbol(Sym);833    if (!SymFlags)834      return SymFlags.takeError();835 836    if (SymFlags->isWeak()) {837      // If this is a weak symbol that's not defined in the harness then we838      // need to either mark it as strong (if this is the first definition839      // that we've seen) or discard it.840      if (S.HarnessDefinitions.count(*Name) || S.CanonicalWeakDefs.count(*Name))841        continue;842      S.CanonicalWeakDefs[*Name] = O.getBufferIdentifier();843      *SymFlags &= ~JITSymbolFlags::Weak;844      if (!S.HarnessExternals.count(*Name))845        *SymFlags &= ~JITSymbolFlags::Exported;846    } else if (S.HarnessExternals.count(*Name)) {847      *SymFlags |= JITSymbolFlags::Exported;848    } else if (S.HarnessDefinitions.count(*Name) ||849               !(*SymFlagsOrErr & object::BasicSymbolRef::SF_Global))850      continue;851 852    I->SymbolFlags[S.ES.intern(*Name)] = std::move(*SymFlags);853  }854 855  return I;856}857 858static Error loadProcessSymbols(Session &S) {859  S.ProcessSymsJD = &S.ES.createBareJITDylib("Process");860  auto FilterMainEntryPoint =861      [EPName = S.ES.intern(EntryPointName)](SymbolStringPtr Name) {862        return Name != EPName;863      };864  S.ProcessSymsJD->addGenerator(865      ExitOnErr(orc::EPCDynamicLibrarySearchGenerator::GetForTargetProcess(866          S.ES, std::move(FilterMainEntryPoint))));867 868  return Error::success();869}870 871static Error loadDylibs(Session &S) {872  LLVM_DEBUG(dbgs() << "Loading dylibs...\n");873  for (const auto &Dylib : Dylibs) {874    LLVM_DEBUG(dbgs() << "  " << Dylib << "\n");875    auto DL = S.getOrLoadDynamicLibrary(Dylib);876    if (!DL)877      return DL.takeError();878  }879 880  return Error::success();881}882 883static Expected<std::unique_ptr<ExecutorProcessControl>> launchExecutor() {884#ifndef LLVM_ON_UNIX885  // FIXME: Add support for Windows.886  return make_error<StringError>("-" + OutOfProcessExecutor.ArgStr +887                                     " not supported on non-unix platforms",888                                 inconvertibleErrorCode());889#elif !LLVM_ENABLE_THREADS890  // Out of process mode using SimpleRemoteEPC depends on threads.891  return make_error<StringError>(892      "-" + OutOfProcessExecutor.ArgStr +893          " requires threads, but LLVM was built with "894          "LLVM_ENABLE_THREADS=Off",895      inconvertibleErrorCode());896#else897 898  constexpr int ReadEnd = 0;899  constexpr int WriteEnd = 1;900 901  // Pipe FDs.902  int ToExecutor[2];903  int FromExecutor[2];904 905  pid_t ChildPID;906 907  // Create pipes to/from the executor..908  if (pipe(ToExecutor) != 0 || pipe(FromExecutor) != 0)909    return make_error<StringError>("Unable to create pipe for executor",910                                   inconvertibleErrorCode());911 912  ChildPID = fork();913 914  if (ChildPID == 0) {915    // In the child...916 917    // Close the parent ends of the pipes918    close(ToExecutor[WriteEnd]);919    close(FromExecutor[ReadEnd]);920 921    // Execute the child process.922    std::unique_ptr<char[]> ExecutorPath, FDSpecifier;923    {924      ExecutorPath = std::make_unique<char[]>(OutOfProcessExecutor.size() + 1);925      strcpy(ExecutorPath.get(), OutOfProcessExecutor.data());926 927      std::string FDSpecifierStr("filedescs=");928      FDSpecifierStr += utostr(ToExecutor[ReadEnd]);929      FDSpecifierStr += ',';930      FDSpecifierStr += utostr(FromExecutor[WriteEnd]);931      FDSpecifier = std::make_unique<char[]>(FDSpecifierStr.size() + 1);932      strcpy(FDSpecifier.get(), FDSpecifierStr.c_str());933    }934 935    char *const Args[] = {ExecutorPath.get(), FDSpecifier.get(), nullptr};936    int RC = execvp(ExecutorPath.get(), Args);937    if (RC != 0) {938      errs() << "unable to launch out-of-process executor \""939             << ExecutorPath.get() << "\"\n";940      exit(1);941    }942  }943  // else we're the parent...944 945  // Close the child ends of the pipes946  close(ToExecutor[ReadEnd]);947  close(FromExecutor[WriteEnd]);948 949  auto S = SimpleRemoteEPC::Setup();950  setupEPCRemoteMemoryManager(S);951 952  return SimpleRemoteEPC::Create<FDSimpleRemoteEPCTransport>(953      std::make_unique<DynamicThreadPoolTaskDispatcher>(MaterializationThreads),954      std::move(S), FromExecutor[ReadEnd], ToExecutor[WriteEnd]);955#endif956}957 958#if LLVM_ON_UNIX && LLVM_ENABLE_THREADS959static Error createTCPSocketError(Twine Details) {960  return make_error<StringError>(961      formatv("Failed to connect TCP socket '{0}': {1}",962              OutOfProcessExecutorConnect, Details),963      inconvertibleErrorCode());964}965 966static Expected<int> connectTCPSocket(std::string Host, std::string PortStr) {967  addrinfo *AI;968  addrinfo Hints{};969  Hints.ai_family = AF_INET;970  Hints.ai_socktype = SOCK_STREAM;971  Hints.ai_flags = AI_NUMERICSERV;972 973  if (int EC = getaddrinfo(Host.c_str(), PortStr.c_str(), &Hints, &AI))974    return createTCPSocketError("Address resolution failed (" +975                                StringRef(gai_strerror(EC)) + ")");976 977  // Cycle through the returned addrinfo structures and connect to the first978  // reachable endpoint.979  int SockFD;980  addrinfo *Server;981  for (Server = AI; Server != nullptr; Server = Server->ai_next) {982    // socket might fail, e.g. if the address family is not supported. Skip to983    // the next addrinfo structure in such a case.984    if ((SockFD = socket(AI->ai_family, AI->ai_socktype, AI->ai_protocol)) < 0)985      continue;986 987    // If connect returns null, we exit the loop with a working socket.988    if (connect(SockFD, Server->ai_addr, Server->ai_addrlen) == 0)989      break;990 991    close(SockFD);992  }993  freeaddrinfo(AI);994 995  // If we reached the end of the loop without connecting to a valid endpoint,996  // dump the last error that was logged in socket() or connect().997  if (Server == nullptr)998    return createTCPSocketError(std::strerror(errno));999 1000  return SockFD;1001}1002#endif1003 1004static Expected<std::unique_ptr<ExecutorProcessControl>> connectToExecutor() {1005#ifndef LLVM_ON_UNIX1006  // FIXME: Add TCP support for Windows.1007  return make_error<StringError>("-" + OutOfProcessExecutorConnect.ArgStr +1008                                     " not supported on non-unix platforms",1009                                 inconvertibleErrorCode());1010#elif !LLVM_ENABLE_THREADS1011  // Out of process mode using SimpleRemoteEPC depends on threads.1012  return make_error<StringError>(1013      "-" + OutOfProcessExecutorConnect.ArgStr +1014          " requires threads, but LLVM was built with "1015          "LLVM_ENABLE_THREADS=Off",1016      inconvertibleErrorCode());1017#else1018 1019  StringRef Host, PortStr;1020  std::tie(Host, PortStr) = StringRef(OutOfProcessExecutorConnect).split(':');1021  if (Host.empty())1022    return createTCPSocketError("Host name for -" +1023                                OutOfProcessExecutorConnect.ArgStr +1024                                " can not be empty");1025  if (PortStr.empty())1026    return createTCPSocketError("Port number in -" +1027                                OutOfProcessExecutorConnect.ArgStr +1028                                " can not be empty");1029  int Port = 0;1030  if (PortStr.getAsInteger(10, Port))1031    return createTCPSocketError("Port number '" + PortStr +1032                                "' is not a valid integer");1033 1034  Expected<int> SockFD = connectTCPSocket(Host.str(), PortStr.str());1035  if (!SockFD)1036    return SockFD.takeError();1037 1038  auto S = SimpleRemoteEPC::Setup();1039  setupEPCRemoteMemoryManager(S);1040 1041  return SimpleRemoteEPC::Create<FDSimpleRemoteEPCTransport>(1042      std::make_unique<DynamicThreadPoolTaskDispatcher>(std::nullopt),1043      std::move(S), *SockFD, *SockFD);1044#endif1045}1046 1047class PhonyExternalsGenerator : public DefinitionGenerator {1048public:1049  Error tryToGenerate(LookupState &LS, LookupKind K, JITDylib &JD,1050                      JITDylibLookupFlags JDLookupFlags,1051                      const SymbolLookupSet &LookupSet) override {1052    SymbolMap PhonySymbols;1053    for (auto &KV : LookupSet)1054      PhonySymbols[KV.first] = {ExecutorAddr(), JITSymbolFlags::Exported};1055    return JD.define(absoluteSymbols(std::move(PhonySymbols)));1056  }1057};1058 1059Expected<std::unique_ptr<Session::LazyLinkingSupport>>1060createLazyLinkingSupport(Session &S) {1061  auto RSMgr = JITLinkRedirectableSymbolManager::Create(S.ObjLayer);1062  if (!RSMgr)1063    return RSMgr.takeError();1064 1065  std::shared_ptr<SimpleLazyReexportsSpeculator> Speculator;1066  switch (Speculate) {1067  case SpeculateKind::None:1068    break;1069  case SpeculateKind::Simple:1070    SimpleLazyReexportsSpeculator::RecordExecutionFunction RecordExecs;1071 1072    if (!RecordLazyExecs.empty())1073      RecordExecs = [&S](const LazyReexportsManager::CallThroughInfo &CTI) {1074        S.LazyFnExecOrder.push_back({CTI.JD->getName(), CTI.BodyName});1075      };1076 1077    Speculator =1078        SimpleLazyReexportsSpeculator::Create(S.ES, std::move(RecordExecs));1079    break;1080  }1081 1082  auto LRMgr = createJITLinkLazyReexportsManager(1083      S.ObjLayer, **RSMgr, *S.PlatformJD, Speculator.get());1084  if (!LRMgr)1085    return LRMgr.takeError();1086 1087  return std::make_unique<Session::LazyLinkingSupport>(1088      std::move(*RSMgr), std::move(Speculator), std::move(*LRMgr), S.ObjLayer);1089}1090 1091static Error writeLazyExecOrder(Session &S) {1092  if (RecordLazyExecs.empty())1093    return Error::success();1094 1095  std::error_code EC;1096  raw_fd_ostream ExecOrderOut(RecordLazyExecs, EC);1097  if (EC)1098    return createFileError(RecordLazyExecs, EC);1099 1100  for (auto &[JDName, FunctionName] : S.LazyFnExecOrder)1101    ExecOrderOut << JDName << ", " << FunctionName << "\n";1102 1103  return Error::success();1104}1105 1106Expected<std::unique_ptr<Session>> Session::Create(Triple TT,1107                                                   SubtargetFeatures Features) {1108 1109  std::unique_ptr<ExecutorProcessControl> EPC;1110  if (OutOfProcessExecutor.getNumOccurrences()) {1111    /// If -oop-executor is passed then launch the executor.1112    if (auto REPC = launchExecutor())1113      EPC = std::move(*REPC);1114    else1115      return REPC.takeError();1116  } else if (OutOfProcessExecutorConnect.getNumOccurrences()) {1117    /// If -oop-executor-connect is passed then connect to the executor.1118    if (auto REPC = connectToExecutor())1119      EPC = std::move(*REPC);1120    else1121      return REPC.takeError();1122  } else {1123    /// Otherwise use SelfExecutorProcessControl to target the current process.1124    auto PageSize = sys::Process::getPageSize();1125    if (!PageSize)1126      return PageSize.takeError();1127    std::unique_ptr<TaskDispatcher> Dispatcher;1128    if (MaterializationThreads == 0)1129      Dispatcher = std::make_unique<InPlaceTaskDispatcher>();1130    else {1131#if LLVM_ENABLE_THREADS1132      Dispatcher = std::make_unique<DynamicThreadPoolTaskDispatcher>(1133          MaterializationThreads);1134#else1135      llvm_unreachable("MaterializationThreads should be 0");1136#endif1137    }1138 1139    EPC = std::make_unique<SelfExecutorProcessControl>(1140        std::make_shared<SymbolStringPool>(), std::move(Dispatcher),1141        std::move(TT), *PageSize, createInProcessMemoryManager());1142  }1143 1144  Error Err = Error::success();1145  std::unique_ptr<Session> S(new Session(std::move(EPC), Err));1146  if (Err)1147    return std::move(Err);1148  S->Features = std::move(Features);1149 1150  if (lazyLinkingRequested()) {1151    if (auto LazyLinking = createLazyLinkingSupport(*S))1152      S->LazyLinking = std::move(*LazyLinking);1153    else1154      return LazyLinking.takeError();1155  }1156 1157  return std::move(S);1158}1159 1160Session::~Session() {1161  if (auto Err = writeLazyExecOrder(*this))1162    ES.reportError(std::move(Err));1163 1164  if (auto Err = ES.endSession())1165    ES.reportError(std::move(Err));1166}1167 1168Session::Session(std::unique_ptr<ExecutorProcessControl> EPC, Error &Err)1169    : ES(std::move(EPC)),1170      ObjLayer(ES, ES.getExecutorProcessControl().getMemMgr()) {1171 1172  /// Local ObjectLinkingLayer::Plugin class to forward modifyPassConfig to the1173  /// Session.1174  class JITLinkSessionPlugin : public ObjectLinkingLayer::Plugin {1175  public:1176    JITLinkSessionPlugin(Session &S) : S(S) {}1177    void modifyPassConfig(MaterializationResponsibility &MR, LinkGraph &G,1178                          PassConfiguration &PassConfig) override {1179      S.modifyPassConfig(G, PassConfig);1180    }1181 1182    Error notifyFailed(MaterializationResponsibility &MR) override {1183      return Error::success();1184    }1185    Error notifyRemovingResources(JITDylib &JD, ResourceKey K) override {1186      return Error::success();1187    }1188    void notifyTransferringResources(JITDylib &JD, ResourceKey DstKey,1189                                     ResourceKey SrcKey) override {}1190 1191  private:1192    Session &S;1193  };1194 1195  ErrorAsOutParameter _(&Err);1196 1197  ES.setErrorReporter(reportLLVMJITLinkError);1198 1199  if (!NoProcessSymbols)1200    ExitOnErr(loadProcessSymbols(*this));1201 1202  ExitOnErr(loadDylibs(*this));1203 1204  auto &TT = ES.getTargetTriple();1205 1206  if (DebuggerSupport && TT.isOSBinFormatMachO()) {1207    if (!ProcessSymsJD) {1208      Err = make_error<StringError>("MachO debugging requires process symbols",1209                                    inconvertibleErrorCode());1210      return;1211    }1212    ObjLayer.addPlugin(ExitOnErr(GDBJITDebugInfoRegistrationPlugin::Create(1213        this->ES, *ProcessSymsJD, TT)));1214  }1215 1216  if (PerfSupport && TT.isOSBinFormatELF()) {1217    if (!ProcessSymsJD) {1218      Err = make_error<StringError>("MachO debugging requires process symbols",1219                                    inconvertibleErrorCode());1220      return;1221    }1222    ObjLayer.addPlugin(ExitOnErr(DebugInfoPreservationPlugin::Create()));1223    ObjLayer.addPlugin(ExitOnErr(PerfSupportPlugin::Create(1224        this->ES.getExecutorProcessControl(), *ProcessSymsJD, true, true)));1225  }1226 1227  if (VTuneSupport && TT.isOSBinFormatELF()) {1228    ObjLayer.addPlugin(ExitOnErr(DebugInfoPreservationPlugin::Create()));1229    ObjLayer.addPlugin(ExitOnErr(1230        VTuneSupportPlugin::Create(this->ES.getExecutorProcessControl(),1231                                   *ProcessSymsJD, /*EmitDebugInfo=*/true,1232                                   /*TestMode=*/true)));1233  }1234 1235  // Set up the platform.1236  if (!OrcRuntime.empty()) {1237    assert(ProcessSymsJD && "ProcessSymsJD should have been set");1238    PlatformJD = &ES.createBareJITDylib("Platform");1239    PlatformJD->addToLinkOrder(*ProcessSymsJD);1240 1241    if (TT.isOSBinFormatMachO()) {1242      if (auto P =1243              MachOPlatform::Create(ObjLayer, *PlatformJD, OrcRuntime.c_str()))1244        ES.setPlatform(std::move(*P));1245      else {1246        Err = P.takeError();1247        return;1248      }1249    } else if (TT.isOSBinFormatELF()) {1250      if (auto P =1251              ELFNixPlatform::Create(ObjLayer, *PlatformJD, OrcRuntime.c_str()))1252        ES.setPlatform(std::move(*P));1253      else {1254        Err = P.takeError();1255        return;1256      }1257    } else if (TT.isOSBinFormatCOFF()) {1258      auto LoadDynLibrary = [&, this](JITDylib &JD,1259                                      StringRef DLLName) -> Error {1260        if (!DLLName.ends_with_insensitive(".dll"))1261          return make_error<StringError>("DLLName not ending with .dll",1262                                         inconvertibleErrorCode());1263        return loadAndLinkDynamicLibrary(JD, DLLName);1264      };1265 1266      if (auto P =1267              COFFPlatform::Create(ObjLayer, *PlatformJD, OrcRuntime.c_str(),1268                                   std::move(LoadDynLibrary)))1269        ES.setPlatform(std::move(*P));1270      else {1271        Err = P.takeError();1272        return;1273      }1274    } else {1275      Err = make_error<StringError>(1276          "-" + OrcRuntime.ArgStr + " specified, but format " +1277              Triple::getObjectFormatTypeName(TT.getObjectFormat()) +1278              " not supported",1279          inconvertibleErrorCode());1280      return;1281    }1282  } else if (TT.isOSBinFormatMachO()) {1283    if (!NoExec) {1284      std::optional<bool> ForceEHFrames;1285      if ((Err = ES.getBootstrapMapValue<bool, bool>("darwin-use-ehframes-only",1286                                                     ForceEHFrames)))1287        return;1288      bool UseEHFrames = ForceEHFrames.value_or(false);1289      if (!UseEHFrames)1290        ObjLayer.addPlugin(ExitOnErr(UnwindInfoRegistrationPlugin::Create(ES)));1291      else1292        ObjLayer.addPlugin(ExitOnErr(EHFrameRegistrationPlugin::Create(ES)));1293    }1294  } else if (TT.isOSBinFormatELF()) {1295    if (!NoExec)1296      ObjLayer.addPlugin(ExitOnErr(EHFrameRegistrationPlugin::Create(ES)));1297    if (DebuggerSupport) {1298      Error TargetSymErr = Error::success();1299      auto Plugin =1300          std::make_unique<ELFDebugObjectPlugin>(ES, true, true, TargetSymErr);1301      if (!TargetSymErr)1302        ObjLayer.addPlugin(std::move(Plugin));1303      else1304        logAllUnhandledErrors(std::move(TargetSymErr), errs(),1305                              "Debugger support not available: ");1306    }1307  }1308 1309  if (auto MainJDOrErr = ES.createJITDylib("main"))1310    MainJD = &*MainJDOrErr;1311  else {1312    Err = MainJDOrErr.takeError();1313    return;1314  }1315 1316  if (NoProcessSymbols) {1317    // This symbol is used in testcases, but we're not reflecting process1318    // symbols so we'll need to make it available some other way.1319    auto &TestResultJD = ES.createBareJITDylib("<TestResultJD>");1320    ExitOnErr(TestResultJD.define(absoluteSymbols(1321        {{ES.intern("llvm_jitlink_setTestResultOverride"),1322          {ExecutorAddr::fromPtr(llvm_jitlink_setTestResultOverride),1323           JITSymbolFlags::Exported}}})));1324    MainJD->addToLinkOrder(TestResultJD);1325  }1326 1327  ObjLayer.addPlugin(std::make_unique<JITLinkSessionPlugin>(*this));1328 1329  // Process any harness files.1330  for (auto &HarnessFile : TestHarnesses) {1331    HarnessFiles.insert(HarnessFile);1332 1333    auto ObjBuffer =1334        ExitOnErr(loadLinkableFile(HarnessFile, ES.getTargetTriple(),1335                                   LoadArchives::Never))1336            .first;1337 1338    auto ObjInterface =1339        ExitOnErr(getObjectFileInterface(ES, ObjBuffer->getMemBufferRef()));1340 1341    for (auto &KV : ObjInterface.SymbolFlags)1342      HarnessDefinitions.insert(*KV.first);1343 1344    auto Obj = ExitOnErr(1345        object::ObjectFile::createObjectFile(ObjBuffer->getMemBufferRef()));1346 1347    for (auto &Sym : Obj->symbols()) {1348      uint32_t SymFlags = ExitOnErr(Sym.getFlags());1349      auto Name = ExitOnErr(Sym.getName());1350 1351      if (Name.empty())1352        continue;1353 1354      if (SymFlags & object::BasicSymbolRef::SF_Undefined)1355        HarnessExternals.insert(Name);1356    }1357  }1358 1359  // If a name is defined by some harness file then it's a definition, not an1360  // external.1361  for (auto &DefName : HarnessDefinitions)1362    HarnessExternals.erase(DefName.getKey());1363 1364  if (!ShowLinkGraphs.empty())1365    ShowGraphsRegex = Regex(ShowLinkGraphs);1366}1367 1368void Session::dumpSessionInfo(raw_ostream &OS) {1369  OS << "Registered addresses:\n" << SymbolInfos << FileInfos;1370}1371 1372void Session::modifyPassConfig(LinkGraph &G, PassConfiguration &PassConfig) {1373 1374  if (ShowLinkedFiles)1375    outs() << "Linking " << G.getName() << "\n";1376 1377  if (!CheckFiles.empty())1378    PassConfig.PostFixupPasses.push_back([this](LinkGraph &G) {1379      if (ES.getTargetTriple().getObjectFormat() == Triple::ELF)1380        return registerELFGraphInfo(*this, G);1381 1382      if (ES.getTargetTriple().getObjectFormat() == Triple::MachO)1383        return registerMachOGraphInfo(*this, G);1384 1385      if (ES.getTargetTriple().getObjectFormat() == Triple::COFF)1386        return registerCOFFGraphInfo(*this, G);1387 1388      return make_error<StringError>("Unsupported object format for GOT/stub "1389                                     "registration",1390                                     inconvertibleErrorCode());1391    });1392 1393  if (ShowGraphsRegex)1394    PassConfig.PostFixupPasses.push_back([this](LinkGraph &G) -> Error {1395      std::lock_guard<std::mutex> Lock(M);1396      // Print graph if ShowLinkGraphs is specified-but-empty, or if1397      // it contains the given graph.1398      if (ShowGraphsRegex->match(G.getName())) {1399        outs() << "Link graph \"" << G.getName() << "\" post-fixup:\n";1400        G.dump(outs());1401      }1402      return Error::success();1403    });1404 1405  PassConfig.PrePrunePasses.push_back([this](LinkGraph &G) {1406    std::lock_guard<std::mutex> Lock(M);1407    ++ActiveLinks;1408    return Error::success();1409  });1410  PassConfig.PrePrunePasses.push_back(1411      [this](LinkGraph &G) { return applyLibraryLinkModifiers(*this, G); });1412  PassConfig.PrePrunePasses.push_back(1413      [this](LinkGraph &G) { return applyHarnessPromotions(*this, G); });1414 1415  if (ShowRelocatedSectionContents)1416    PassConfig.PostFixupPasses.push_back([this](LinkGraph &G) -> Error {1417      dumpSectionContents(outs(), *this, G);1418      return Error::success();1419    });1420 1421  if (AddSelfRelocations)1422    PassConfig.PostPrunePasses.push_back(addSelfRelocations);1423 1424  PassConfig.PostFixupPasses.push_back([this](LinkGraph &G) {1425    std::lock_guard<std::mutex> Lock(M);1426    if (--ActiveLinks == 0)1427      ActiveLinksCV.notify_all();1428    return Error::success();1429  });1430}1431 1432Expected<JITDylib *> Session::getOrLoadDynamicLibrary(StringRef LibPath) {1433  auto It = DynLibJDs.find(LibPath);1434  if (It != DynLibJDs.end()) {1435    return It->second;1436  }1437  auto G = EPCDynamicLibrarySearchGenerator::Load(ES, LibPath.data());1438  if (!G)1439    return G.takeError();1440  auto JD = &ES.createBareJITDylib(LibPath.str());1441 1442  JD->addGenerator(std::move(*G));1443  DynLibJDs.emplace(LibPath.str(), JD);1444  LLVM_DEBUG({1445    dbgs() << "Loaded dynamic library " << LibPath.data() << " for " << LibPath1446           << "\n";1447  });1448  return JD;1449}1450 1451Error Session::loadAndLinkDynamicLibrary(JITDylib &JD, StringRef LibPath) {1452  auto DL = getOrLoadDynamicLibrary(LibPath);1453  if (!DL)1454    return DL.takeError();1455  JD.addToLinkOrder(**DL);1456  LLVM_DEBUG({1457    dbgs() << "Linking dynamic library " << LibPath << " to " << JD.getName()1458           << "\n";1459  });1460  return Error::success();1461}1462 1463Error Session::FileInfo::registerGOTEntry(1464    LinkGraph &G, Symbol &Sym, GetSymbolTargetFunction GetSymbolTarget) {1465  if (Sym.isSymbolZeroFill())1466    return make_error<StringError>("Unexpected zero-fill symbol in section " +1467                                       Sym.getBlock().getSection().getName(),1468                                   inconvertibleErrorCode());1469  auto TS = GetSymbolTarget(G, Sym.getBlock());1470  if (!TS)1471    return TS.takeError();1472  GOTEntryInfos[*TS->getName()] = {Sym.getSymbolContent(),1473                                   Sym.getAddress().getValue(),1474                                   Sym.getTargetFlags()};1475  return Error::success();1476}1477 1478Error Session::FileInfo::registerStubEntry(1479    LinkGraph &G, Symbol &Sym, GetSymbolTargetFunction GetSymbolTarget) {1480  if (Sym.isSymbolZeroFill())1481    return make_error<StringError>("Unexpected zero-fill symbol in section " +1482                                       Sym.getBlock().getSection().getName(),1483                                   inconvertibleErrorCode());1484  auto TS = GetSymbolTarget(G, Sym.getBlock());1485  if (!TS)1486    return TS.takeError();1487 1488  SmallVectorImpl<MemoryRegionInfo> &Entry = StubInfos[*TS->getName()];1489  Entry.insert(Entry.begin(),1490               {Sym.getSymbolContent(), Sym.getAddress().getValue(),1491                Sym.getTargetFlags()});1492  return Error::success();1493}1494 1495Error Session::FileInfo::registerMultiStubEntry(1496    LinkGraph &G, Symbol &Sym, GetSymbolTargetFunction GetSymbolTarget) {1497  if (Sym.isSymbolZeroFill())1498    return make_error<StringError>("Unexpected zero-fill symbol in section " +1499                                       Sym.getBlock().getSection().getName(),1500                                   inconvertibleErrorCode());1501 1502  auto Target = GetSymbolTarget(G, Sym.getBlock());1503  if (!Target)1504    return Target.takeError();1505 1506  SmallVectorImpl<MemoryRegionInfo> &Entry = StubInfos[*Target->getName()];1507  Entry.emplace_back(Sym.getSymbolContent(), Sym.getAddress().getValue(),1508                     Sym.getTargetFlags());1509 1510  // Let's keep stubs ordered by ascending address.1511  std::sort(Entry.begin(), Entry.end(),1512            [](const MemoryRegionInfo &L, const MemoryRegionInfo &R) {1513              return L.getTargetAddress() < R.getTargetAddress();1514            });1515 1516  return Error::success();1517}1518 1519Expected<Session::FileInfo &> Session::findFileInfo(StringRef FileName) {1520  auto FileInfoItr = FileInfos.find(FileName);1521  if (FileInfoItr == FileInfos.end())1522    return make_error<StringError>("file \"" + FileName + "\" not recognized",1523                                   inconvertibleErrorCode());1524  return FileInfoItr->second;1525}1526 1527Expected<Session::MemoryRegionInfo &>1528Session::findSectionInfo(StringRef FileName, StringRef SectionName) {1529  auto FI = findFileInfo(FileName);1530  if (!FI)1531    return FI.takeError();1532  auto SecInfoItr = FI->SectionInfos.find(SectionName);1533  if (SecInfoItr == FI->SectionInfos.end())1534    return make_error<StringError>("no section \"" + SectionName +1535                                       "\" registered for file \"" + FileName +1536                                       "\"",1537                                   inconvertibleErrorCode());1538  return SecInfoItr->second;1539}1540 1541class MemoryMatcher {1542public:1543  MemoryMatcher(ArrayRef<char> Content)1544      : Pos(Content.data()), End(Pos + Content.size()) {}1545 1546  template <typename MaskType> bool matchMask(MaskType Mask) {1547    if (Mask == (Mask & *reinterpret_cast<const MaskType *>(Pos))) {1548      Pos += sizeof(MaskType);1549      return true;1550    }1551    return false;1552  }1553 1554  template <typename ValueType> bool matchEqual(ValueType Value) {1555    if (Value == *reinterpret_cast<const ValueType *>(Pos)) {1556      Pos += sizeof(ValueType);1557      return true;1558    }1559    return false;1560  }1561 1562  bool done() const { return Pos == End; }1563 1564private:1565  const char *Pos;1566  const char *End;1567};1568 1569static StringRef detectStubKind(const Session::MemoryRegionInfo &Stub) {1570  using namespace support::endian;1571  auto Armv7MovWTle = byte_swap<uint32_t>(0xe300c000, endianness::little);1572  auto Armv7BxR12le = byte_swap<uint32_t>(0xe12fff1c, endianness::little);1573  auto Thumbv7MovWTle = byte_swap<uint32_t>(0x0c00f240, endianness::little);1574  auto Thumbv7BxR12le = byte_swap<uint16_t>(0x4760, endianness::little);1575 1576  MemoryMatcher M(Stub.getContent());1577  if (M.matchMask(Thumbv7MovWTle)) {1578    if (M.matchMask(Thumbv7MovWTle))1579      if (M.matchEqual(Thumbv7BxR12le))1580        if (M.done())1581          return "thumbv7_abs_le";1582  } else if (M.matchMask(Armv7MovWTle)) {1583    if (M.matchMask(Armv7MovWTle))1584      if (M.matchEqual(Armv7BxR12le))1585        if (M.done())1586          return "armv7_abs_le";1587  }1588  return "";1589}1590 1591Expected<Session::MemoryRegionInfo &>1592Session::findStubInfo(StringRef FileName, StringRef TargetName,1593                      StringRef KindNameFilter) {1594  auto FI = findFileInfo(FileName);1595  if (!FI)1596    return FI.takeError();1597  auto StubInfoItr = FI->StubInfos.find(TargetName);1598  if (StubInfoItr == FI->StubInfos.end())1599    return make_error<StringError>("no stub for \"" + TargetName +1600                                       "\" registered for file \"" + FileName +1601                                       "\"",1602                                   inconvertibleErrorCode());1603  auto &StubsForTarget = StubInfoItr->second;1604  assert(!StubsForTarget.empty() && "At least 1 stub in each entry");1605  if (KindNameFilter.empty() && StubsForTarget.size() == 1)1606    return StubsForTarget[0]; // Regular single-stub match1607 1608  std::string KindsStr;1609  SmallVector<MemoryRegionInfo *, 1> Matches;1610  Regex KindNameMatcher(KindNameFilter.empty() ? ".*" : KindNameFilter);1611  for (MemoryRegionInfo &Stub : StubsForTarget) {1612    StringRef Kind = detectStubKind(Stub);1613    if (KindNameMatcher.match(Kind))1614      Matches.push_back(&Stub);1615    KindsStr += "\"" + (Kind.empty() ? "<unknown>" : Kind.str()) + "\", ";1616  }1617  if (Matches.empty())1618    return make_error<StringError>(1619        "\"" + TargetName + "\" has " + Twine(StubsForTarget.size()) +1620            " stubs in file \"" + FileName +1621            "\", but none of them matches the stub-kind filter \"" +1622            KindNameFilter + "\" (all encountered kinds are " +1623            StringRef(KindsStr.data(), KindsStr.size() - 2) + ").",1624        inconvertibleErrorCode());1625  if (Matches.size() > 1)1626    return make_error<StringError>(1627        "\"" + TargetName + "\" has " + Twine(Matches.size()) +1628            " candidate stubs in file \"" + FileName +1629            "\". Please refine stub-kind filter \"" + KindNameFilter +1630            "\" for disambiguation (encountered kinds are " +1631            StringRef(KindsStr.data(), KindsStr.size() - 2) + ").",1632        inconvertibleErrorCode());1633 1634  return *Matches[0];1635}1636 1637Expected<Session::MemoryRegionInfo &>1638Session::findGOTEntryInfo(StringRef FileName, StringRef TargetName) {1639  auto FI = findFileInfo(FileName);1640  if (!FI)1641    return FI.takeError();1642  auto GOTInfoItr = FI->GOTEntryInfos.find(TargetName);1643  if (GOTInfoItr == FI->GOTEntryInfos.end())1644    return make_error<StringError>("no GOT entry for \"" + TargetName +1645                                       "\" registered for file \"" + FileName +1646                                       "\"",1647                                   inconvertibleErrorCode());1648  return GOTInfoItr->second;1649}1650 1651bool Session::isSymbolRegistered(const orc::SymbolStringPtr &SymbolName) {1652  return SymbolInfos.count(SymbolName);1653}1654 1655Expected<Session::MemoryRegionInfo &>1656Session::findSymbolInfo(const orc::SymbolStringPtr &SymbolName,1657                        Twine ErrorMsgStem) {1658  auto SymInfoItr = SymbolInfos.find(SymbolName);1659  if (SymInfoItr == SymbolInfos.end())1660    return make_error<StringError>(ErrorMsgStem + ": symbol " + *SymbolName +1661                                       " not found",1662                                   inconvertibleErrorCode());1663  return SymInfoItr->second;1664}1665 1666} // end namespace llvm1667 1668static std::pair<Triple, SubtargetFeatures> getFirstFileTripleAndFeatures() {1669  static std::pair<Triple, SubtargetFeatures> FirstTTAndFeatures = []() {1670    assert(!InputFiles.empty() && "InputFiles can not be empty");1671 1672    if (!OverrideTriple.empty()) {1673      LLVM_DEBUG({1674        dbgs() << "Triple from -triple override: " << OverrideTriple << "\n";1675      });1676      return std::make_pair(Triple(OverrideTriple), SubtargetFeatures());1677    }1678 1679    for (auto InputFile : InputFiles) {1680      auto ObjBuffer = ExitOnErr(getFile(InputFile));1681      file_magic Magic = identify_magic(ObjBuffer->getBuffer());1682      switch (Magic) {1683      case file_magic::coff_object:1684      case file_magic::elf_relocatable:1685      case file_magic::macho_object: {1686        auto Obj = ExitOnErr(1687            object::ObjectFile::createObjectFile(ObjBuffer->getMemBufferRef()));1688        Triple TT;1689        if (auto *MachOObj = dyn_cast<object::MachOObjectFile>(Obj.get()))1690          TT = MachOObj->getArchTriple();1691        else1692          TT = Obj->makeTriple();1693        if (Magic == file_magic::coff_object) {1694          // TODO: Move this to makeTriple() if possible.1695          TT.setObjectFormat(Triple::COFF);1696          TT.setOS(Triple::OSType::Win32);1697        }1698        SubtargetFeatures Features;1699        if (auto ObjFeatures = Obj->getFeatures())1700          Features = std::move(*ObjFeatures);1701 1702        LLVM_DEBUG({1703          dbgs() << "Triple from " << InputFile << ": " << TT.str() << "\n";1704        });1705        return std::make_pair(TT, Features);1706      }1707      default:1708        break;1709      }1710    }1711 1712    // If no plain object file inputs exist to pin down the triple then detect1713    // the host triple and default to that.1714    auto JTMB = ExitOnErr(JITTargetMachineBuilder::detectHost());1715    LLVM_DEBUG({1716      dbgs() << "Triple from host-detection: " << JTMB.getTargetTriple().str()1717             << "\n";1718    });1719    return std::make_pair(JTMB.getTargetTriple(), JTMB.getFeatures());1720  }();1721 1722  return FirstTTAndFeatures;1723}1724 1725static Error sanitizeArguments(const Triple &TT, const char *ArgV0) {1726 1727  // -noexec and --args should not be used together.1728  if (NoExec && !InputArgv.empty())1729    errs() << "Warning: --args passed to -noexec run will be ignored.\n";1730 1731  // Set the entry point name if not specified.1732  if (EntryPointName.empty())1733    EntryPointName = TT.getObjectFormat() == Triple::MachO ? "_main" : "main";1734 1735  // Disable debugger support by default in noexec tests.1736  if (DebuggerSupport.getNumOccurrences() == 0 && NoExec)1737    DebuggerSupport = false;1738 1739  if (!OrcRuntime.empty() && NoProcessSymbols)1740    return make_error<StringError>("-orc-runtime requires process symbols",1741                                   inconvertibleErrorCode());1742 1743  // If -slab-allocate is passed, check that we're not trying to use it in1744  // -oop-executor or -oop-executor-connect mode.1745  //1746  // FIXME: Remove once we enable remote slab allocation.1747  if (SlabAllocateSizeString != "") {1748    if (OutOfProcessExecutor.getNumOccurrences() ||1749        OutOfProcessExecutorConnect.getNumOccurrences())1750      return make_error<StringError>(1751          "-slab-allocate cannot be used with -oop-executor or "1752          "-oop-executor-connect",1753          inconvertibleErrorCode());1754  }1755 1756  // If -slab-address is passed, require -slab-allocate and -noexec1757  if (SlabAddress != ~0ULL) {1758    if (SlabAllocateSizeString == "" || !NoExec)1759      return make_error<StringError>(1760          "-slab-address requires -slab-allocate and -noexec",1761          inconvertibleErrorCode());1762 1763    if (SlabPageSize == 0)1764      errs() << "Warning: -slab-address used without -slab-page-size.\n";1765  }1766 1767  if (SlabPageSize != 0) {1768    // -slab-page-size requires slab alloc.1769    if (SlabAllocateSizeString == "")1770      return make_error<StringError>("-slab-page-size requires -slab-allocate",1771                                     inconvertibleErrorCode());1772 1773    // Check -slab-page-size / -noexec interactions.1774    if (!NoExec) {1775      if (auto RealPageSize = sys::Process::getPageSize()) {1776        if (SlabPageSize % *RealPageSize)1777          return make_error<StringError>(1778              "-slab-page-size must be a multiple of real page size for exec "1779              "tests (did you mean to use -noexec ?)\n",1780              inconvertibleErrorCode());1781      } else {1782        errs() << "Could not retrieve process page size:\n";1783        logAllUnhandledErrors(RealPageSize.takeError(), errs(), "");1784        errs() << "Executing with slab page size = "1785               << formatv("{0:x}", SlabPageSize) << ".\n"1786               << "Tool may crash if " << formatv("{0:x}", SlabPageSize)1787               << " is not a multiple of the real process page size.\n"1788               << "(did you mean to use -noexec ?)";1789      }1790    }1791  }1792 1793#if LLVM_ENABLE_THREADS1794  if (MaterializationThreads == std::numeric_limits<size_t>::max()) {1795    if (auto HC = std::thread::hardware_concurrency())1796      MaterializationThreads = HC;1797    else {1798      errs() << "Warning: std::thread::hardware_concurrency() returned 0, "1799                "defaulting to -num-threads=1.\n";1800      MaterializationThreads = 1;1801    }1802  }1803#else1804  if (MaterializationThreads.getNumOccurrences() &&1805      MaterializationThreads != 0) {1806    errs() << "Warning: -num-threads was set, but LLVM was built with threads "1807              "disabled. Resetting to -num-threads=0\n";1808  }1809  MaterializationThreads = 0;1810#endif1811 1812  if (!!OutOfProcessExecutor.getNumOccurrences() ||1813      !!OutOfProcessExecutorConnect.getNumOccurrences()) {1814    if (NoExec)1815      return make_error<StringError>("-noexec cannot be used with " +1816                                         OutOfProcessExecutor.ArgStr + " or " +1817                                         OutOfProcessExecutorConnect.ArgStr,1818                                     inconvertibleErrorCode());1819 1820    if (MaterializationThreads == 0)1821      return make_error<StringError>("-threads=0 cannot be used with " +1822                                         OutOfProcessExecutor.ArgStr + " or " +1823                                         OutOfProcessExecutorConnect.ArgStr,1824                                     inconvertibleErrorCode());1825  }1826 1827#ifndef NDEBUG1828  if (DebugFlag && MaterializationThreads != 0)1829    errs() << "Warning: debugging output is not thread safe. "1830              "Use -num-threads=0 to stabilize output.\n";1831#endif // NDEBUG1832 1833  // Only one of -oop-executor and -oop-executor-connect can be used.1834  if (!!OutOfProcessExecutor.getNumOccurrences() &&1835      !!OutOfProcessExecutorConnect.getNumOccurrences())1836    return make_error<StringError>(1837        "Only one of -" + OutOfProcessExecutor.ArgStr + " and -" +1838            OutOfProcessExecutorConnect.ArgStr + " can be specified",1839        inconvertibleErrorCode());1840 1841  // If -oop-executor was used but no value was specified then use a sensible1842  // default.1843  if (!!OutOfProcessExecutor.getNumOccurrences() &&1844      OutOfProcessExecutor.empty()) {1845    SmallString<256> OOPExecutorPath(sys::fs::getMainExecutable(1846        ArgV0, reinterpret_cast<void *>(&sanitizeArguments)));1847    sys::path::remove_filename(OOPExecutorPath);1848    sys::path::append(OOPExecutorPath, "llvm-jitlink-executor");1849    OutOfProcessExecutor = OOPExecutorPath.str().str();1850  }1851 1852  // If lazy linking is requested then check compatibility with other options.1853  if (lazyLinkingRequested()) {1854    if (OrcRuntime.empty())1855      return make_error<StringError>("Lazy linking requries the ORC runtime",1856                                     inconvertibleErrorCode());1857 1858    if (!TestHarnesses.empty())1859      return make_error<StringError>(1860          "Lazy linking cannot be used with -harness mode",1861          inconvertibleErrorCode());1862  } else if (Speculate != SpeculateKind::None) {1863    errs() << "Warning: -speculate ignored as there are no -lazy inputs\n";1864    Speculate = SpeculateKind::None;1865  }1866 1867  if (Speculate == SpeculateKind::None) {1868    if (!SpeculateOrder.empty()) {1869      errs() << "Warning: -speculate-order ignored because speculation is "1870                "disabled\n";1871      SpeculateOrder = "";1872    }1873 1874    if (!RecordLazyExecs.empty()) {1875      errs() << "Warning: -record-lazy-execs ignored because speculation is "1876                "disabled\n";1877      RecordLazyExecs = "";1878    }1879  }1880 1881  return Error::success();1882}1883 1884static void addPhonyExternalsGenerator(Session &S) {1885  S.MainJD->addGenerator(std::make_unique<PhonyExternalsGenerator>());1886}1887 1888static Error createJITDylibs(Session &S,1889                             std::map<unsigned, JITDylib *> &IdxToJD) {1890  // First, set up JITDylibs.1891  LLVM_DEBUG(dbgs() << "Creating JITDylibs...\n");1892  {1893    // Create a "main" JITLinkDylib.1894    IdxToJD[0] = S.MainJD;1895    S.JDSearchOrder.push_back({S.MainJD, JITDylibLookupFlags::MatchAllSymbols});1896    LLVM_DEBUG(dbgs() << "  0: " << S.MainJD->getName() << "\n");1897 1898    // Add any extra JITDylibs from the command line.1899    for (auto JDItr = JITDylibs.begin(), JDEnd = JITDylibs.end();1900         JDItr != JDEnd; ++JDItr) {1901      auto JD = S.ES.createJITDylib(*JDItr);1902      if (!JD)1903        return JD.takeError();1904      unsigned JDIdx = JITDylibs.getPosition(JDItr - JITDylibs.begin());1905      IdxToJD[JDIdx] = &*JD;1906      S.JDSearchOrder.push_back({&*JD, JITDylibLookupFlags::MatchAllSymbols});1907      LLVM_DEBUG(dbgs() << "  " << JDIdx << ": " << JD->getName() << "\n");1908    }1909  }1910 1911  if (S.PlatformJD)1912    S.JDSearchOrder.push_back(1913        {S.PlatformJD, JITDylibLookupFlags::MatchExportedSymbolsOnly});1914  if (S.ProcessSymsJD)1915    S.JDSearchOrder.push_back(1916        {S.ProcessSymsJD, JITDylibLookupFlags::MatchExportedSymbolsOnly});1917 1918  LLVM_DEBUG({1919    dbgs() << "Dylib search order is [ ";1920    for (auto &KV : S.JDSearchOrder)1921      dbgs() << KV.first->getName() << " ";1922    dbgs() << "]\n";1923  });1924 1925  return Error::success();1926}1927 1928static Error addAbsoluteSymbols(Session &S,1929                                const std::map<unsigned, JITDylib *> &IdxToJD) {1930  // Define absolute symbols.1931  LLVM_DEBUG(dbgs() << "Defining absolute symbols...\n");1932  for (auto AbsDefItr = AbsoluteDefs.begin(), AbsDefEnd = AbsoluteDefs.end();1933       AbsDefItr != AbsDefEnd; ++AbsDefItr) {1934    unsigned AbsDefArgIdx =1935      AbsoluteDefs.getPosition(AbsDefItr - AbsoluteDefs.begin());1936    auto &JD = *std::prev(IdxToJD.lower_bound(AbsDefArgIdx))->second;1937 1938    StringRef AbsDefStmt = *AbsDefItr;1939    size_t EqIdx = AbsDefStmt.find_first_of('=');1940    if (EqIdx == StringRef::npos)1941      return make_error<StringError>("Invalid absolute define \"" + AbsDefStmt +1942                                     "\". Syntax: <name>=<addr>",1943                                     inconvertibleErrorCode());1944    StringRef Name = AbsDefStmt.substr(0, EqIdx).trim();1945    StringRef AddrStr = AbsDefStmt.substr(EqIdx + 1).trim();1946 1947    uint64_t Addr;1948    if (AddrStr.getAsInteger(0, Addr))1949      return make_error<StringError>("Invalid address expression \"" + AddrStr +1950                                         "\" in absolute symbol definition \"" +1951                                         AbsDefStmt + "\"",1952                                     inconvertibleErrorCode());1953    ExecutorSymbolDef AbsDef(ExecutorAddr(Addr), JITSymbolFlags::Exported);1954    auto InternedName = S.ES.intern(Name);1955    if (auto Err = JD.define(absoluteSymbols({{InternedName, AbsDef}})))1956      return Err;1957 1958    // Register the absolute symbol with the session symbol infos.1959    S.SymbolInfos[std::move(InternedName)] =1960      {ArrayRef<char>(), Addr, AbsDef.getFlags().getTargetFlags()};1961  }1962 1963  return Error::success();1964}1965 1966static Error addAliases(Session &S,1967                        const std::map<unsigned, JITDylib *> &IdxToJD) {1968  // Define absolute symbols.1969  LLVM_DEBUG(dbgs() << "Defining aliases...\n");1970 1971  DenseMap<std::pair<JITDylib *, JITDylib *>, SymbolAliasMap> Reexports;1972  for (auto AliasItr = Aliases.begin(), AliasEnd = Aliases.end();1973       AliasItr != AliasEnd; ++AliasItr) {1974 1975    auto BadExpr = [&]() {1976      return make_error<StringError>(1977          "Invalid alias definition \"" + *AliasItr +1978              "\". Syntax: [<dst-jd>:]<alias>=[<src-jd>:]<aliasee>",1979          inconvertibleErrorCode());1980    };1981 1982    auto GetJD = [&](StringRef JDName) -> Expected<JITDylib *> {1983      if (JDName.empty()) {1984        unsigned AliasArgIdx = Aliases.getPosition(AliasItr - Aliases.begin());1985        return std::prev(IdxToJD.lower_bound(AliasArgIdx))->second;1986      }1987 1988      auto *JD = S.ES.getJITDylibByName(JDName);1989      if (!JD)1990        return make_error<StringError>(StringRef("In alias definition \"") +1991                                           *AliasItr + "\" no dylib named " +1992                                           JDName,1993                                       inconvertibleErrorCode());1994 1995      return JD;1996    };1997 1998    {1999      // First split on '=' to get alias and aliasee.2000      StringRef AliasStmt = *AliasItr;2001      auto [AliasExpr, AliaseeExpr] = AliasStmt.split('=');2002      if (AliaseeExpr.empty())2003        return BadExpr();2004 2005      auto [AliasJDName, Alias] = AliasExpr.split(':');2006      if (Alias.empty())2007        std::swap(AliasJDName, Alias);2008 2009      auto AliasJD = GetJD(AliasJDName);2010      if (!AliasJD)2011        return AliasJD.takeError();2012 2013      auto [AliaseeJDName, Aliasee] = AliaseeExpr.split(':');2014      if (Aliasee.empty())2015        std::swap(AliaseeJDName, Aliasee);2016 2017      if (AliaseeJDName.empty() && !AliasJDName.empty())2018        AliaseeJDName = AliasJDName;2019      auto AliaseeJD = GetJD(AliaseeJDName);2020      if (!AliaseeJD)2021        return AliaseeJD.takeError();2022 2023      Reexports[{*AliasJD, *AliaseeJD}][S.ES.intern(Alias)] = {2024          S.ES.intern(Aliasee), JITSymbolFlags::Exported};2025    }2026  }2027 2028  for (auto &[JDs, AliasMap] : Reexports) {2029    auto [DstJD, SrcJD] = JDs;2030    if (auto Err = DstJD->define(reexports(*SrcJD, std::move(AliasMap))))2031      return Err;2032  }2033 2034  return Error::success();2035}2036 2037static Error addSectCreates(Session &S,2038                            const std::map<unsigned, JITDylib *> &IdxToJD) {2039  for (auto SCItr = SectCreate.begin(), SCEnd = SectCreate.end();2040       SCItr != SCEnd; ++SCItr) {2041 2042    unsigned SCArgIdx = SectCreate.getPosition(SCItr - SectCreate.begin());2043    auto &JD = *std::prev(IdxToJD.lower_bound(SCArgIdx))->second;2044 2045    StringRef SCArg(*SCItr);2046 2047    auto [SectAndFileName, ExtraSymbolsString] = SCArg.rsplit('@');2048    auto [SectName, FileName] = SectAndFileName.rsplit(',');2049    if (SectName.empty())2050      return make_error<StringError>("In -sectcreate=" + SCArg +2051                                         ", filename component cannot be empty",2052                                     inconvertibleErrorCode());2053    if (FileName.empty())2054      return make_error<StringError>("In -sectcreate=" + SCArg +2055                                         ", filename component cannot be empty",2056                                     inconvertibleErrorCode());2057 2058    auto Content = getFile(FileName);2059    if (!Content)2060      return Content.takeError();2061 2062    SectCreateMaterializationUnit::ExtraSymbolsMap ExtraSymbols;2063    while (!ExtraSymbolsString.empty()) {2064      StringRef NextSymPair;2065      std::tie(NextSymPair, ExtraSymbolsString) = ExtraSymbolsString.split(',');2066 2067      auto [Sym, OffsetString] = NextSymPair.split('=');2068      size_t Offset;2069 2070      if (OffsetString.getAsInteger(0, Offset))2071        return make_error<StringError>("In -sectcreate=" + SCArg + ", " +2072                                           OffsetString +2073                                           " is not a valid integer",2074                                       inconvertibleErrorCode());2075 2076      ExtraSymbols[S.ES.intern(Sym)] = {JITSymbolFlags::Exported, Offset};2077    }2078 2079    if (auto Err = JD.define(std::make_unique<SectCreateMaterializationUnit>(2080            S.ObjLayer, SectName.str(), MemProt::Read, 16, std::move(*Content),2081            std::move(ExtraSymbols))))2082      return Err;2083  }2084 2085  return Error::success();2086}2087 2088static Error addTestHarnesses(Session &S) {2089  LLVM_DEBUG(dbgs() << "Adding test harness objects...\n");2090  for (auto HarnessFile : TestHarnesses) {2091    LLVM_DEBUG(dbgs() << "  " << HarnessFile << "\n");2092    auto Linkable = loadLinkableFile(HarnessFile, S.ES.getTargetTriple(),2093                                     LoadArchives::Never);2094    if (!Linkable)2095      return Linkable.takeError();2096    if (auto Err = S.ObjLayer.add(*S.MainJD, std::move(Linkable->first)))2097      return Err;2098  }2099  return Error::success();2100}2101 2102static Error addObjects(Session &S,2103                        const std::map<unsigned, JITDylib *> &IdxToJD,2104                        const DenseSet<unsigned> &LazyLinkIdxs) {2105 2106  // Load each object into the corresponding JITDylib..2107  LLVM_DEBUG(dbgs() << "Adding objects...\n");2108  for (auto InputFileItr = InputFiles.begin(), InputFileEnd = InputFiles.end();2109       InputFileItr != InputFileEnd; ++InputFileItr) {2110    unsigned InputFileArgIdx =2111        InputFiles.getPosition(InputFileItr - InputFiles.begin());2112    const std::string &InputFile = *InputFileItr;2113    if (StringRef(InputFile).ends_with(".a") ||2114        StringRef(InputFile).ends_with(".lib"))2115      continue;2116    auto &JD = *std::prev(IdxToJD.lower_bound(InputFileArgIdx))->second;2117    bool AddLazy = LazyLinkIdxs.count(InputFileArgIdx);2118    LLVM_DEBUG(dbgs() << "  " << InputFileArgIdx << ": \"" << InputFile << "\" "2119                      << (AddLazy ? " (lazy-linked)" : "") << " to "2120                      << JD.getName() << "\n";);2121    auto ObjBuffer = loadLinkableFile(InputFile, S.ES.getTargetTriple(),2122                                      LoadArchives::Never);2123    if (!ObjBuffer)2124      return ObjBuffer.takeError();2125 2126    if (S.HarnessFiles.empty()) {2127      if (auto Err =2128              S.getLinkLayer(AddLazy).add(JD, std::move(ObjBuffer->first)))2129        return Err;2130    } else {2131      // We're in -harness mode. Use a custom interface for this2132      // test object.2133      auto ObjInterface =2134          getTestObjectFileInterface(S, ObjBuffer->first->getMemBufferRef());2135      if (!ObjInterface)2136        return ObjInterface.takeError();2137 2138      if (auto Err = S.ObjLayer.add(JD, std::move(ObjBuffer->first),2139                                    std::move(*ObjInterface)))2140        return Err;2141    }2142  }2143 2144  return Error::success();2145}2146 2147static Expected<MaterializationUnit::Interface>2148getObjectFileInterfaceHidden(ExecutionSession &ES, MemoryBufferRef ObjBuffer) {2149  auto I = getObjectFileInterface(ES, ObjBuffer);2150  if (I) {2151    for (auto &KV : I->SymbolFlags)2152      KV.second &= ~JITSymbolFlags::Exported;2153  }2154  return I;2155}2156 2157static SmallVector<StringRef, 5> getSearchPathsFromEnvVar(Session &S) {2158  // FIXME: Handle EPC environment.2159  SmallVector<StringRef, 5> PathVec;2160  auto TT = S.ES.getTargetTriple();2161  if (TT.isOSBinFormatCOFF())2162    StringRef(getenv("PATH")).split(PathVec, ";");2163  else if (TT.isOSBinFormatELF())2164    StringRef(getenv("LD_LIBRARY_PATH")).split(PathVec, ":");2165 2166  return PathVec;2167}2168 2169static Expected<std::unique_ptr<DefinitionGenerator>>2170LoadLibraryWeak(Session &S, StringRef Path) {2171  auto Symbols = getDylibInterface(S.ES, Path);2172  if (!Symbols)2173    return Symbols.takeError();2174 2175  return std::make_unique<EPCDynamicLibrarySearchGenerator>(2176      S.ES, [Symbols = std::move(*Symbols)](const SymbolStringPtr &Sym) {2177        return Symbols.count(Sym);2178      });2179}2180 2181static Error addLibraries(Session &S,2182                          const std::map<unsigned, JITDylib *> &IdxToJD,2183                          const DenseSet<unsigned> &LazyLinkIdxs) {2184 2185  // 1. Collect search paths for each JITDylib.2186  DenseMap<const JITDylib *, SmallVector<StringRef, 2>> JDSearchPaths;2187 2188  for (auto LSPItr = LibrarySearchPaths.begin(),2189            LSPEnd = LibrarySearchPaths.end();2190       LSPItr != LSPEnd; ++LSPItr) {2191    unsigned LibrarySearchPathIdx =2192        LibrarySearchPaths.getPosition(LSPItr - LibrarySearchPaths.begin());2193    auto &JD = *std::prev(IdxToJD.lower_bound(LibrarySearchPathIdx))->second;2194 2195    StringRef LibrarySearchPath = *LSPItr;2196    if (sys::fs::get_file_type(LibrarySearchPath) !=2197        sys::fs::file_type::directory_file)2198      return make_error<StringError>("While linking " + JD.getName() + ", -L" +2199                                         LibrarySearchPath +2200                                         " does not point to a directory",2201                                     inconvertibleErrorCode());2202 2203    JDSearchPaths[&JD].push_back(*LSPItr);2204  }2205 2206  LLVM_DEBUG({2207    if (!JDSearchPaths.empty())2208      dbgs() << "Search paths:\n";2209    for (auto &KV : JDSearchPaths) {2210      dbgs() << "  " << KV.first->getName() << ": [";2211      for (auto &LibSearchPath : KV.second)2212        dbgs() << " \"" << LibSearchPath << "\"";2213      dbgs() << " ]\n";2214    }2215  });2216 2217  // 2. Collect library loads2218  struct LibraryLoad {2219    std::string LibName;2220    bool IsPath = false;2221    unsigned Position;2222    ArrayRef<StringRef> CandidateExtensions;2223    enum { Standard, Hidden, Weak } Modifier;2224  };2225 2226  // Queue to load library as in the order as it appears in the argument list.2227  std::deque<LibraryLoad> LibraryLoadQueue;2228 2229  // Add archive files from the inputs to LibraryLoads.2230  for (auto InputFileItr = InputFiles.begin(), InputFileEnd = InputFiles.end();2231       InputFileItr != InputFileEnd; ++InputFileItr) {2232    StringRef InputFile = *InputFileItr;2233    if (!InputFile.ends_with(".a") && !InputFile.ends_with(".lib"))2234      continue;2235    LibraryLoad LL;2236    LL.LibName = InputFile.str();2237    LL.IsPath = true;2238    LL.Position = InputFiles.getPosition(InputFileItr - InputFiles.begin());2239    LL.CandidateExtensions = {};2240    LL.Modifier = LibraryLoad::Standard;2241    LibraryLoadQueue.push_back(std::move(LL));2242  }2243 2244  // Add -load_hidden arguments to LibraryLoads.2245  for (auto LibItr = LoadHidden.begin(), LibEnd = LoadHidden.end();2246       LibItr != LibEnd; ++LibItr) {2247    LibraryLoad LL;2248    LL.LibName = *LibItr;2249    LL.IsPath = true;2250    LL.Position = LoadHidden.getPosition(LibItr - LoadHidden.begin());2251    LL.CandidateExtensions = {};2252    LL.Modifier = LibraryLoad::Hidden;2253    LibraryLoadQueue.push_back(std::move(LL));2254  }2255 2256  // Add -weak_library arguments to LibraryLoads.2257  for (auto LibItr = WeakLibraries.begin(), LibEnd = WeakLibraries.end();2258       LibItr != LibEnd; ++LibItr) {2259    LibraryLoad LL;2260    LL.LibName = *LibItr;2261    LL.IsPath = true;2262    LL.Position = WeakLibraries.getPosition(LibItr - WeakLibraries.begin());2263    LL.CandidateExtensions = {};2264    LL.Modifier = LibraryLoad::Weak;2265    LibraryLoadQueue.push_back(std::move(LL));2266  }2267 2268  StringRef StandardExtensions[] = {".so", ".dylib", ".dll", ".a", ".lib"};2269  StringRef DynLibExtensionsOnly[] = {".so", ".dylib", ".dll"};2270  StringRef ArchiveExtensionsOnly[] = {".a", ".lib"};2271  StringRef WeakLinkExtensionsOnly[] = {".dylib", ".tbd"};2272 2273  // Add -lx arguments to LibraryLoads.2274  for (auto LibItr = Libraries.begin(), LibEnd = Libraries.end();2275       LibItr != LibEnd; ++LibItr) {2276    LibraryLoad LL;2277    LL.LibName = *LibItr;2278    LL.Position = Libraries.getPosition(LibItr - Libraries.begin());2279    LL.CandidateExtensions = StandardExtensions;2280    LL.Modifier = LibraryLoad::Standard;2281    LibraryLoadQueue.push_back(std::move(LL));2282  }2283 2284  // Add -hidden-lx arguments to LibraryLoads.2285  for (auto LibHiddenItr = LibrariesHidden.begin(),2286            LibHiddenEnd = LibrariesHidden.end();2287       LibHiddenItr != LibHiddenEnd; ++LibHiddenItr) {2288    LibraryLoad LL;2289    LL.LibName = *LibHiddenItr;2290    LL.Position =2291        LibrariesHidden.getPosition(LibHiddenItr - LibrariesHidden.begin());2292    LL.CandidateExtensions = ArchiveExtensionsOnly;2293    LL.Modifier = LibraryLoad::Hidden;2294    LibraryLoadQueue.push_back(std::move(LL));2295  }2296 2297  // Add -weak-lx arguments to LibraryLoads.2298  for (auto LibWeakItr = LibrariesWeak.begin(),2299            LibWeakEnd = LibrariesWeak.end();2300       LibWeakItr != LibWeakEnd; ++LibWeakItr) {2301    LibraryLoad LL;2302    LL.LibName = *LibWeakItr;2303    LL.Position = LibrariesWeak.getPosition(LibWeakItr - LibrariesWeak.begin());2304    LL.CandidateExtensions = WeakLinkExtensionsOnly;2305    LL.Modifier = LibraryLoad::Weak;2306    LibraryLoadQueue.push_back(std::move(LL));2307  }2308 2309  // Sort library loads by position in the argument list.2310  llvm::sort(LibraryLoadQueue,2311             [](const LibraryLoad &LHS, const LibraryLoad &RHS) {2312               return LHS.Position < RHS.Position;2313             });2314 2315  // 3. Process library loads.2316  auto AddArchive = [&](JITDylib &JD, const char *Path, const LibraryLoad &LL)2317      -> Expected<std::unique_ptr<StaticLibraryDefinitionGenerator>> {2318    StaticLibraryDefinitionGenerator::GetObjectFileInterface2319        GetObjFileInterface;2320    switch (LL.Modifier) {2321    case LibraryLoad::Standard:2322      GetObjFileInterface = getObjectFileInterface;2323      break;2324    case LibraryLoad::Hidden:2325      GetObjFileInterface = getObjectFileInterfaceHidden;2326      S.HiddenArchives.insert(Path);2327      break;2328    case LibraryLoad::Weak:2329      llvm_unreachable("Unsupported");2330      break;2331    }2332 2333    auto &LinkLayer = S.getLinkLayer(LazyLinkIdxs.count(LL.Position));2334 2335    std::set<std::string> ImportedDynamicLibraries;2336    StaticLibraryDefinitionGenerator::VisitMembersFunction VisitMembers;2337 2338    // COFF gets special handling due to import libraries.2339    if (S.ES.getTargetTriple().isOSBinFormatCOFF()) {2340      if (AllLoad) {2341        VisitMembers =2342            [ImportScanner = COFFImportFileScanner(ImportedDynamicLibraries),2343             LoadAll =2344                 StaticLibraryDefinitionGenerator::loadAllObjectFileMembers(2345                     LinkLayer, JD)](object::Archive &A,2346                                     MemoryBufferRef MemberBuf,2347                                     size_t Index) mutable -> Expected<bool> {2348          if (!ImportScanner(A, MemberBuf, Index))2349            return false;2350          return LoadAll(A, MemberBuf, Index);2351        };2352      } else2353        VisitMembers = COFFImportFileScanner(ImportedDynamicLibraries);2354    } else if (AllLoad)2355      VisitMembers = StaticLibraryDefinitionGenerator::loadAllObjectFileMembers(2356          LinkLayer, JD);2357    else if (S.ES.getTargetTriple().isOSBinFormatMachO() && ForceLoadObjC)2358      VisitMembers = ForceLoadMachOArchiveMembers(LinkLayer, JD, true);2359 2360    auto G = StaticLibraryDefinitionGenerator::Load(2361        LinkLayer, Path, std::move(VisitMembers),2362        std::move(GetObjFileInterface));2363    if (!G)2364      return G.takeError();2365 2366    // Push additional dynamic libraries to search.2367    // Note that this mechanism only happens in COFF.2368    for (auto FileName : ImportedDynamicLibraries) {2369      LibraryLoad NewLL;2370      auto FileNameRef = StringRef(FileName);2371      if (!FileNameRef.ends_with_insensitive(".dll"))2372        return make_error<StringError>(2373            "COFF Imported library not ending with dll extension?",2374            inconvertibleErrorCode());2375      NewLL.LibName = FileNameRef.drop_back(strlen(".dll")).str();2376      NewLL.Position = LL.Position;2377      NewLL.CandidateExtensions = DynLibExtensionsOnly;2378      NewLL.Modifier = LibraryLoad::Standard;2379      LibraryLoadQueue.push_front(std::move(NewLL));2380    }2381    return G;2382  };2383 2384  SmallVector<StringRef, 5> SystemSearchPaths;2385  if (SearchSystemLibrary.getValue())2386    SystemSearchPaths = getSearchPathsFromEnvVar(S);2387  while (!LibraryLoadQueue.empty()) {2388    bool LibFound = false;2389    auto LL = LibraryLoadQueue.front();2390    LibraryLoadQueue.pop_front();2391    auto &JD = *std::prev(IdxToJD.lower_bound(LL.Position))->second;2392 2393    // If this is the name of a JITDylib then link against that.2394    if (auto *LJD = S.ES.getJITDylibByName(LL.LibName)) {2395      if (LL.Modifier == LibraryLoad::Weak)2396        return make_error<StringError>(2397            "Can't use -weak-lx or -weak_library to load JITDylib " +2398                LL.LibName,2399            inconvertibleErrorCode());2400      JD.addToLinkOrder(*LJD);2401      continue;2402    }2403 2404    if (LL.IsPath) {2405      // Must be -weak_library.2406      if (LL.Modifier == LibraryLoad::Weak) {2407        if (auto G = LoadLibraryWeak(S, LL.LibName)) {2408          JD.addGenerator(std::move(*G));2409          continue;2410        } else2411          return G.takeError();2412      }2413 2414      // Otherwise handle archive.2415      auto G = AddArchive(JD, LL.LibName.c_str(), LL);2416      if (!G)2417        return createFileError(LL.LibName, G.takeError());2418      JD.addGenerator(std::move(*G));2419      LLVM_DEBUG({2420        dbgs() << "Adding generator for static library " << LL.LibName << " to "2421               << JD.getName() << "\n";2422      });2423      continue;2424    }2425 2426    // Otherwise look through the search paths.2427    auto CurJDSearchPaths = JDSearchPaths[&JD];2428    for (StringRef SearchPath :2429         concat<StringRef>(CurJDSearchPaths, SystemSearchPaths)) {2430      for (auto LibExt : LL.CandidateExtensions) {2431        SmallVector<char, 256> LibPath;2432        LibPath.reserve(SearchPath.size() + strlen("lib") + LL.LibName.size() +2433                        LibExt.size() + 2); // +2 for pathsep, null term.2434        llvm::append_range(LibPath, SearchPath);2435        if (LibExt != ".lib" && LibExt != ".dll")2436          sys::path::append(LibPath, "lib" + LL.LibName + LibExt);2437        else2438          sys::path::append(LibPath, LL.LibName + LibExt);2439        LibPath.push_back('\0');2440 2441        // Skip missing or non-regular paths.2442        if (sys::fs::get_file_type(LibPath.data()) !=2443            sys::fs::file_type::regular_file) {2444          continue;2445        }2446 2447        file_magic Magic;2448        if (auto EC = identify_magic(LibPath, Magic)) {2449          // If there was an error loading the file then skip it.2450          LLVM_DEBUG({2451            dbgs() << "Library search found \"" << LibPath2452                   << "\", but could not identify file type (" << EC.message()2453                   << "). Skipping.\n";2454          });2455          continue;2456        }2457 2458        // We identified the magic. Assume that we can load it -- we'll reset2459        // in the default case.2460        LibFound = true;2461        switch (Magic) {2462        case file_magic::pecoff_executable:2463        case file_magic::elf_shared_object:2464        case file_magic::macho_dynamically_linked_shared_lib: {2465          if (LL.Modifier == LibraryLoad::Weak) {2466            if (auto G = LoadLibraryWeak(S, LibPath.data()))2467              JD.addGenerator(std::move(*G));2468            else2469              return G.takeError();2470          } else {2471            if (auto Err = S.loadAndLinkDynamicLibrary(JD, LibPath.data()))2472              return Err;2473          }2474          break;2475        }2476        case file_magic::archive:2477        case file_magic::macho_universal_binary: {2478          auto G = AddArchive(JD, LibPath.data(), LL);2479          if (!G)2480            return G.takeError();2481          JD.addGenerator(std::move(*G));2482          LLVM_DEBUG({2483            dbgs() << "Adding generator for static library " << LibPath.data()2484                   << " to " << JD.getName() << "\n";2485          });2486          break;2487        }2488        case file_magic::tapi_file:2489          assert(LL.Modifier == LibraryLoad::Weak &&2490                 "TextAPI file not being loaded as weak?");2491          if (auto G = LoadLibraryWeak(S, LibPath.data()))2492            JD.addGenerator(std::move(*G));2493          else2494            return G.takeError();2495          break;2496        default:2497          // This file isn't a recognized library kind.2498          LLVM_DEBUG({2499            dbgs() << "Library search found \"" << LibPath2500                   << "\", but file type is not supported. Skipping.\n";2501          });2502          LibFound = false;2503          break;2504        }2505        if (LibFound)2506          break;2507      }2508      if (LibFound)2509        break;2510    }2511 2512    if (!LibFound)2513      return make_error<StringError>("While linking " + JD.getName() +2514                                         ", could not find library for -l" +2515                                         LL.LibName,2516                                     inconvertibleErrorCode());2517  }2518 2519  // Add platform and process symbols if available.2520  for (auto &[Idx, JD] : IdxToJD) {2521    if (S.PlatformJD)2522      JD->addToLinkOrder(*S.PlatformJD);2523    if (S.ProcessSymsJD)2524      JD->addToLinkOrder(*S.ProcessSymsJD);2525  }2526 2527  return Error::success();2528}2529 2530static Error addSpeculationOrder(Session &S) {2531 2532  if (SpeculateOrder.empty())2533    return Error::success();2534 2535  assert(S.LazyLinking && "SpeculateOrder set, but lazy linking not enabled");2536  assert(S.LazyLinking->Speculator && "SpeculatoOrder set, but no speculator");2537 2538  auto SpecOrderBuffer = getFile(SpeculateOrder);2539  if (!SpecOrderBuffer)2540    return SpecOrderBuffer.takeError();2541 2542  StringRef LineStream((*SpecOrderBuffer)->getBuffer());2543  std::vector<std::pair<std::string, SymbolStringPtr>> SpecOrder;2544 2545  size_t LineNumber = 0;2546  while (!LineStream.empty()) {2547    ++LineNumber;2548 2549    auto MakeSpecOrderErr = [&](StringRef Reason) {2550      return make_error<StringError>("Error in speculation order file \"" +2551                                         SpeculateOrder + "\" on line " +2552                                         Twine(LineNumber) + ": " + Reason,2553                                     inconvertibleErrorCode());2554    };2555 2556    StringRef CurLine;2557    std::tie(CurLine, LineStream) = LineStream.split('\n');2558    CurLine = CurLine.trim();2559    if (CurLine.empty())2560      continue;2561 2562    auto [JDName, FuncName] = CurLine.split(',');2563 2564    if (FuncName.empty())2565      return MakeSpecOrderErr("missing ',' separator");2566 2567    JDName = JDName.trim();2568    if (JDName.empty())2569      return MakeSpecOrderErr("no value for column 1 (JIT Dylib name)");2570 2571    FuncName = FuncName.trim();2572    if (FuncName.empty())2573      return MakeSpecOrderErr("no value for column 2 (function name)");2574 2575    SpecOrder.push_back({JDName.str(), S.ES.intern(FuncName)});2576  }2577 2578  S.LazyLinking->Speculator->addSpeculationSuggestions(std::move(SpecOrder));2579 2580  return Error::success();2581}2582 2583static Error addSessionInputs(Session &S) {2584  std::map<unsigned, JITDylib *> IdxToJD;2585  DenseSet<unsigned> LazyLinkIdxs;2586 2587  for (auto LLItr = LazyLink.begin(), LLEnd = LazyLink.end(); LLItr != LLEnd;2588       ++LLItr) {2589    if (*LLItr)2590      LazyLinkIdxs.insert(LazyLink.getPosition(LLItr - LazyLink.begin()) + 1);2591  }2592 2593  if (auto Err = createJITDylibs(S, IdxToJD))2594    return Err;2595 2596  if (auto Err = addAbsoluteSymbols(S, IdxToJD))2597    return Err;2598 2599  if (auto Err = addAliases(S, IdxToJD))2600    return Err;2601 2602  if (auto Err = addSectCreates(S, IdxToJD))2603    return Err;2604 2605  if (!TestHarnesses.empty())2606    if (auto Err = addTestHarnesses(S))2607      return Err;2608 2609  if (auto Err = addObjects(S, IdxToJD, LazyLinkIdxs))2610    return Err;2611 2612  if (auto Err = addLibraries(S, IdxToJD, LazyLinkIdxs))2613    return Err;2614 2615  if (auto Err = addSpeculationOrder(S))2616    return Err;2617 2618  return Error::success();2619}2620 2621namespace {2622struct TargetInfo {2623  const Target *TheTarget;2624  std::unique_ptr<MCSubtargetInfo> STI;2625  std::unique_ptr<MCRegisterInfo> MRI;2626  std::unique_ptr<MCAsmInfo> MAI;2627  std::unique_ptr<MCContext> Ctx;2628  std::unique_ptr<MCDisassembler> Disassembler;2629  std::unique_ptr<MCInstrInfo> MII;2630  std::unique_ptr<MCInstrAnalysis> MIA;2631  std::unique_ptr<MCInstPrinter> InstPrinter;2632};2633} // anonymous namespace2634 2635static TargetInfo2636getTargetInfo(const Triple &TT,2637              const SubtargetFeatures &TF = SubtargetFeatures()) {2638  std::string ErrorStr;2639  const Target *TheTarget = TargetRegistry::lookupTarget(TT, ErrorStr);2640  if (!TheTarget)2641    ExitOnErr(make_error<StringError>("Error accessing target '" + TT.str() +2642                                          "': " + ErrorStr,2643                                      inconvertibleErrorCode()));2644 2645  std::unique_ptr<MCSubtargetInfo> STI(2646      TheTarget->createMCSubtargetInfo(TT, "", TF.getString()));2647  if (!STI)2648    ExitOnErr(2649        make_error<StringError>("Unable to create subtarget for " + TT.str(),2650                                inconvertibleErrorCode()));2651 2652  std::unique_ptr<MCRegisterInfo> MRI(TheTarget->createMCRegInfo(TT));2653  if (!MRI)2654    ExitOnErr(make_error<StringError>("Unable to create target register info "2655                                      "for " +2656                                          TT.str(),2657                                      inconvertibleErrorCode()));2658 2659  MCTargetOptions MCOptions;2660  std::unique_ptr<MCAsmInfo> MAI(2661      TheTarget->createMCAsmInfo(*MRI, TT, MCOptions));2662  if (!MAI)2663    ExitOnErr(2664        make_error<StringError>("Unable to create target asm info " + TT.str(),2665                                inconvertibleErrorCode()));2666 2667  auto Ctx = std::make_unique<MCContext>(Triple(TT.str()), MAI.get(), MRI.get(),2668                                         STI.get());2669 2670  std::unique_ptr<MCDisassembler> Disassembler(2671      TheTarget->createMCDisassembler(*STI, *Ctx));2672  if (!Disassembler)2673    ExitOnErr(2674        make_error<StringError>("Unable to create disassembler for " + TT.str(),2675                                inconvertibleErrorCode()));2676 2677  std::unique_ptr<MCInstrInfo> MII(TheTarget->createMCInstrInfo());2678  if (!MII)2679    ExitOnErr(make_error<StringError>("Unable to create instruction info for" +2680                                          TT.str(),2681                                      inconvertibleErrorCode()));2682 2683  std::unique_ptr<MCInstrAnalysis> MIA(2684      TheTarget->createMCInstrAnalysis(MII.get()));2685  if (!MIA)2686    ExitOnErr(make_error<StringError>(2687        "Unable to create instruction analysis for" + TT.str(),2688        inconvertibleErrorCode()));2689 2690  std::unique_ptr<MCInstPrinter> InstPrinter(2691      TheTarget->createMCInstPrinter(Triple(TT.str()), 0, *MAI, *MII, *MRI));2692  if (!InstPrinter)2693    ExitOnErr(make_error<StringError>(2694        "Unable to create instruction printer for" + TT.str(),2695        inconvertibleErrorCode()));2696  return {TheTarget,      std::move(STI), std::move(MRI),2697          std::move(MAI), std::move(Ctx), std::move(Disassembler),2698          std::move(MII), std::move(MIA), std::move(InstPrinter)};2699}2700static Error runChecks(Session &S, Triple TT, SubtargetFeatures Features) {2701  if (CheckFiles.empty())2702    return Error::success();2703 2704  S.waitForFilesLinkedFromEntryPointFile();2705 2706  LLVM_DEBUG(dbgs() << "Running checks...\n");2707 2708  auto IsSymbolValid = [&S](StringRef Symbol) {2709    auto InternedSymbol = S.ES.getSymbolStringPool()->intern(Symbol);2710    return S.isSymbolRegistered(InternedSymbol);2711  };2712 2713  auto GetSymbolInfo = [&S](StringRef Symbol) {2714    auto InternedSymbol = S.ES.getSymbolStringPool()->intern(Symbol);2715    return S.findSymbolInfo(InternedSymbol, "Can not get symbol info");2716  };2717 2718  auto GetSectionInfo = [&S](StringRef FileName, StringRef SectionName) {2719    return S.findSectionInfo(FileName, SectionName);2720  };2721 2722  auto GetStubInfo = [&S](StringRef FileName, StringRef SectionName,2723                          StringRef KindNameFilter) {2724    return S.findStubInfo(FileName, SectionName, KindNameFilter);2725  };2726 2727  auto GetGOTInfo = [&S](StringRef FileName, StringRef SectionName) {2728    return S.findGOTEntryInfo(FileName, SectionName);2729  };2730 2731  RuntimeDyldChecker Checker(2732      IsSymbolValid, GetSymbolInfo, GetSectionInfo, GetStubInfo, GetGOTInfo,2733      S.ES.getTargetTriple().isLittleEndian() ? llvm::endianness::little2734                                              : llvm::endianness::big,2735      TT, StringRef(), Features, dbgs());2736 2737  std::string CheckLineStart = "# " + CheckName + ":";2738  for (auto &CheckFile : CheckFiles) {2739    auto CheckerFileBuf = ExitOnErr(getFile(CheckFile));2740    if (!Checker.checkAllRulesInBuffer(CheckLineStart, &*CheckerFileBuf))2741      ExitOnErr(make_error<StringError>(2742          "Some checks in " + CheckFile + " failed", inconvertibleErrorCode()));2743  }2744 2745  return Error::success();2746}2747 2748static Error addSelfRelocations(LinkGraph &G) {2749  auto TI = getTargetInfo(G.getTargetTriple());2750  for (auto *Sym : G.defined_symbols())2751    if (Sym->isCallable())2752      if (auto Err = addFunctionPointerRelocationsToCurrentSymbol(2753              *Sym, G, *TI.Disassembler, *TI.MIA))2754        return Err;2755  return Error::success();2756}2757 2758static Expected<ExecutorSymbolDef> getMainEntryPoint(Session &S) {2759  return S.ES.lookup(S.JDSearchOrder, S.ES.intern(EntryPointName));2760}2761 2762static Expected<ExecutorSymbolDef> getOrcRuntimeEntryPoint(Session &S) {2763  std::string RuntimeEntryPoint = "__orc_rt_run_program_wrapper";2764  if (S.ES.getTargetTriple().getObjectFormat() == Triple::MachO)2765    RuntimeEntryPoint = '_' + RuntimeEntryPoint;2766  return S.ES.lookup(S.JDSearchOrder, S.ES.intern(RuntimeEntryPoint));2767}2768 2769static Expected<ExecutorSymbolDef> getEntryPoint(Session &S) {2770  ExecutorSymbolDef EntryPoint;2771 2772  // Find the entry-point function unconditionally, since we want to force2773  // it to be materialized to collect stats.2774  if (auto EP = getMainEntryPoint(S))2775    EntryPoint = *EP;2776  else2777    return EP.takeError();2778  LLVM_DEBUG({2779    dbgs() << "Using entry point \"" << EntryPointName2780           << "\": " << formatv("{0:x16}", EntryPoint.getAddress()) << "\n";2781  });2782 2783  // If we're running with the ORC runtime then replace the entry-point2784  // with the __orc_rt_run_program symbol.2785  if (!OrcRuntime.empty()) {2786    if (auto EP = getOrcRuntimeEntryPoint(S))2787      EntryPoint = *EP;2788    else2789      return EP.takeError();2790    LLVM_DEBUG({2791      dbgs() << "(called via __orc_rt_run_program_wrapper at "2792             << formatv("{0:x16}", EntryPoint.getAddress()) << ")\n";2793    });2794  }2795 2796  return EntryPoint;2797}2798 2799static Expected<int> runWithRuntime(Session &S, ExecutorAddr EntryPointAddr) {2800  StringRef DemangledEntryPoint = EntryPointName;2801  if (S.ES.getTargetTriple().getObjectFormat() == Triple::MachO &&2802      DemangledEntryPoint.front() == '_')2803    DemangledEntryPoint = DemangledEntryPoint.drop_front();2804  using llvm::orc::shared::SPSString;2805  using SPSRunProgramSig =2806      int64_t(SPSString, SPSString, shared::SPSSequence<SPSString>);2807  int64_t Result;2808  if (auto Err = S.ES.callSPSWrapper<SPSRunProgramSig>(2809          EntryPointAddr, Result, S.MainJD->getName(), DemangledEntryPoint,2810          static_cast<std::vector<std::string> &>(InputArgv)))2811    return std::move(Err);2812  return Result;2813}2814 2815static Expected<int> runWithoutRuntime(Session &S,2816                                       ExecutorAddr EntryPointAddr) {2817  return S.ES.getExecutorProcessControl().runAsMain(EntryPointAddr, InputArgv);2818}2819 2820namespace {2821struct JITLinkTimers {2822  TimerGroup JITLinkTG{"llvm-jitlink timers", "timers for llvm-jitlink phases"};2823  Timer LoadObjectsTimer{"load", "time to load/add object files", JITLinkTG};2824  Timer LinkTimer{"link", "time to link object files", JITLinkTG};2825  Timer RunTimer{"run", "time to execute jitlink'd code", JITLinkTG};2826};2827} // namespace2828 2829int main(int argc, char *argv[]) {2830  InitLLVM X(argc, argv);2831 2832  InitializeAllTargetInfos();2833  InitializeAllTargetMCs();2834  InitializeAllDisassemblers();2835 2836  cl::HideUnrelatedOptions({&JITLinkCategory, &getColorCategory()});2837  cl::ParseCommandLineOptions(argc, argv, "llvm jitlink tool");2838  ExitOnErr.setBanner(std::string(argv[0]) + ": ");2839 2840  /// If timers are enabled, create a JITLinkTimers instance.2841  std::unique_ptr<JITLinkTimers> Timers =2842      ShowTimes ? std::make_unique<JITLinkTimers>() : nullptr;2843 2844  auto [TT, Features] = getFirstFileTripleAndFeatures();2845  ExitOnErr(sanitizeArguments(TT, argv[0]));2846 2847  auto S = ExitOnErr(Session::Create(TT, Features));2848 2849  enableStatistics(*S, !OrcRuntime.empty());2850 2851  {2852    TimeRegion TR(Timers ? &Timers->LoadObjectsTimer : nullptr);2853    ExitOnErr(addSessionInputs(*S));2854  }2855 2856  if (PhonyExternals)2857    addPhonyExternalsGenerator(*S);2858 2859  if (ShowInitialExecutionSessionState)2860    S->ES.dump(outs());2861 2862  Expected<ExecutorSymbolDef> EntryPoint((ExecutorSymbolDef()));2863  {2864    ExpectedAsOutParameter<ExecutorSymbolDef> _(&EntryPoint);2865    TimeRegion TR(Timers ? &Timers->LinkTimer : nullptr);2866    EntryPoint = getEntryPoint(*S);2867  }2868 2869  // Print any reports regardless of whether we succeeded or failed.2870  if (ShowEntryExecutionSessionState)2871    S->ES.dump(outs());2872 2873  if (ShowAddrs)2874    S->dumpSessionInfo(outs());2875 2876  if (!EntryPoint) {2877    if (Timers)2878      Timers->JITLinkTG.printAll(errs());2879    reportLLVMJITLinkError(EntryPoint.takeError());2880    ExitOnErr(S->ES.endSession());2881    exit(1);2882  }2883 2884  ExitOnErr(runChecks(*S, std::move(TT), std::move(Features)));2885 2886  int Result = 0;2887  if (!NoExec) {2888    LLVM_DEBUG(dbgs() << "Running \"" << EntryPointName << "\"...\n");2889    TimeRegion TR(Timers ? &Timers->RunTimer : nullptr);2890    if (!OrcRuntime.empty())2891      Result =2892          ExitOnErr(runWithRuntime(*S, ExecutorAddr(EntryPoint->getAddress())));2893    else2894      Result = ExitOnErr(2895          runWithoutRuntime(*S, ExecutorAddr(EntryPoint->getAddress())));2896  }2897 2898  // Destroy the session.2899  ExitOnErr(S->ES.endSession());2900  S.reset();2901 2902  if (Timers)2903    Timers->JITLinkTG.printAll(errs());2904 2905  // If the executing code set a test result override then use that.2906  if (UseTestResultOverride)2907    Result = TestResultOverride;2908 2909  return Result;2910}2911