brintos

brintos / llvm-project-archived public Read only

0
0
Text · 46.7 KiB · 847ee32 Raw
1312 lines · cpp
1//===- lli.cpp - LLVM Interpreter / Dynamic compiler ----------------------===//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 wrapper around the LLVM Execution Engines,10// which allow the direct execution of LLVM programs through a Just-In-Time11// compiler, or through an interpreter if no JIT is available for this platform.12//13//===----------------------------------------------------------------------===//14 15#include "ForwardingMemoryManager.h"16#include "llvm/ADT/StringExtras.h"17#include "llvm/Bitcode/BitcodeReader.h"18#include "llvm/CodeGen/CommandFlags.h"19#include "llvm/CodeGen/LinkAllCodegenComponents.h"20#include "llvm/Config/llvm-config.h"21#include "llvm/ExecutionEngine/GenericValue.h"22#include "llvm/ExecutionEngine/Interpreter.h"23#include "llvm/ExecutionEngine/JITEventListener.h"24#include "llvm/ExecutionEngine/JITSymbol.h"25#include "llvm/ExecutionEngine/MCJIT.h"26#include "llvm/ExecutionEngine/ObjectCache.h"27#include "llvm/ExecutionEngine/Orc/AbsoluteSymbols.h"28#include "llvm/ExecutionEngine/Orc/DebugUtils.h"29#include "llvm/ExecutionEngine/Orc/Debugging/DebuggerSupport.h"30#include "llvm/ExecutionEngine/Orc/EPCDynamicLibrarySearchGenerator.h"31#include "llvm/ExecutionEngine/Orc/EPCGenericRTDyldMemoryManager.h"32#include "llvm/ExecutionEngine/Orc/ExecutionUtils.h"33#include "llvm/ExecutionEngine/Orc/IRPartitionLayer.h"34#include "llvm/ExecutionEngine/Orc/JITTargetMachineBuilder.h"35#include "llvm/ExecutionEngine/Orc/LLJIT.h"36#include "llvm/ExecutionEngine/Orc/ObjectTransformLayer.h"37#include "llvm/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.h"38#include "llvm/ExecutionEngine/Orc/SelfExecutorProcessControl.h"39#include "llvm/ExecutionEngine/Orc/SimpleRemoteEPC.h"40#include "llvm/ExecutionEngine/Orc/SymbolStringPool.h"41#include "llvm/ExecutionEngine/Orc/TargetProcess/JITLoaderGDB.h"42#include "llvm/ExecutionEngine/Orc/TargetProcess/RegisterEHFrames.h"43#include "llvm/ExecutionEngine/Orc/TargetProcess/TargetExecutionUtils.h"44#include "llvm/ExecutionEngine/SectionMemoryManager.h"45#include "llvm/IR/IRBuilder.h"46#include "llvm/IR/LLVMContext.h"47#include "llvm/IR/Module.h"48#include "llvm/IR/Type.h"49#include "llvm/IR/Verifier.h"50#include "llvm/IRReader/IRReader.h"51#include "llvm/Object/Archive.h"52#include "llvm/Object/ObjectFile.h"53#include "llvm/Support/CommandLine.h"54#include "llvm/Support/Compiler.h"55#include "llvm/Support/Debug.h"56#include "llvm/Support/DynamicLibrary.h"57#include "llvm/Support/Format.h"58#include "llvm/Support/InitLLVM.h"59#include "llvm/Support/MathExtras.h"60#include "llvm/Support/Memory.h"61#include "llvm/Support/MemoryBuffer.h"62#include "llvm/Support/Path.h"63#include "llvm/Support/PluginLoader.h"64#include "llvm/Support/Process.h"65#include "llvm/Support/Program.h"66#include "llvm/Support/SourceMgr.h"67#include "llvm/Support/TargetSelect.h"68#include "llvm/Support/ToolOutputFile.h"69#include "llvm/Support/WithColor.h"70#include "llvm/Support/raw_ostream.h"71#include "llvm/TargetParser/Triple.h"72#include <cerrno>73#include <optional>74 75#if !defined(_MSC_VER) && !defined(__MINGW32__)76#include <unistd.h>77#else78#include <io.h>79#endif80 81#ifdef __CYGWIN__82#include <cygwin/version.h>83#if defined(CYGWIN_VERSION_DLL_MAJOR) && CYGWIN_VERSION_DLL_MAJOR<100784#define DO_NOTHING_ATEXIT 185#endif86#endif87 88using namespace llvm;89 90static codegen::RegisterCodeGenFlags CGF;91 92#define DEBUG_TYPE "lli"93 94namespace {95enum class JITKind { MCJIT, Orc, OrcLazy };96enum class JITLinkerKind { Default, RuntimeDyld, JITLink };97} // namespace98 99static cl::opt<std::string> InputFile(cl::desc("<input bitcode>"),100                                      cl::Positional, cl::init("-"));101 102static cl::list<std::string> InputArgv(cl::ConsumeAfter,103                                       cl::desc("<program arguments>..."));104 105static cl::opt<bool>106    ForceInterpreter("force-interpreter",107                     cl::desc("Force interpretation: disable JIT"),108                     cl::init(false));109 110static cl::opt<JITKind>111    UseJITKind("jit-kind", cl::desc("Choose underlying JIT kind."),112               cl::init(JITKind::Orc),113               cl::values(clEnumValN(JITKind::MCJIT, "mcjit", "MCJIT"),114                          clEnumValN(JITKind::Orc, "orc", "Orc JIT"),115                          clEnumValN(JITKind::OrcLazy, "orc-lazy",116                                     "Orc-based lazy JIT.")));117 118static cl::opt<JITLinkerKind> JITLinker(119    "jit-linker", cl::desc("Choose the dynamic linker/loader."),120    cl::init(JITLinkerKind::Default),121    cl::values(clEnumValN(JITLinkerKind::Default, "default",122                          "Default for platform and JIT-kind"),123               clEnumValN(JITLinkerKind::RuntimeDyld, "rtdyld", "RuntimeDyld"),124               clEnumValN(JITLinkerKind::JITLink, "jitlink",125                          "Orc-specific linker")));126static cl::opt<std::string>127    OrcRuntime("orc-runtime", cl::desc("Use ORC runtime from given path"),128               cl::init(""));129 130static cl::opt<unsigned>131    LazyJITCompileThreads("compile-threads",132                          cl::desc("Choose the number of compile threads "133                                   "(jit-kind=orc-lazy only)"),134                          cl::init(0));135 136static cl::list<std::string>137    ThreadEntryPoints("thread-entry",138                      cl::desc("calls the given entry-point on a new thread "139                               "(jit-kind=orc-lazy only)"));140 141static cl::opt<bool> PerModuleLazy(142    "per-module-lazy",143    cl::desc("Performs lazy compilation on whole module boundaries "144             "rather than individual functions"),145    cl::init(false));146 147static cl::list<std::string>148    JITDylibs("jd",149              cl::desc("Specifies the JITDylib to be used for any subsequent "150                       "-extra-module arguments."));151 152static cl::list<std::string>153    Dylibs("dlopen", cl::desc("Dynamic libraries to load before linking"));154 155// The MCJIT supports building for a target address space separate from156// the JIT compilation process. Use a forked process and a copying157// memory manager with IPC to execute using this functionality.158static cl::opt<bool>159    RemoteMCJIT("remote-mcjit",160                cl::desc("Execute MCJIT'ed code in a separate process."),161                cl::init(false));162 163// Manually specify the child process for remote execution. This overrides164// the simulated remote execution that allocates address space for child165// execution. The child process will be executed and will communicate with166// lli via stdin/stdout pipes.167static cl::opt<std::string> ChildExecPath(168    "mcjit-remote-process",169    cl::desc("Specify the filename of the process to launch "170             "for remote MCJIT execution.  If none is specified,"171             "\n\tremote execution will be simulated in-process."),172    cl::value_desc("filename"), cl::init(""));173 174// Determine optimization level.175static cl::opt<char>176    OptLevel("O",177             cl::desc("Optimization level. [-O0, -O1, -O2, or -O3] "178                      "(default = '-O2')"),179             cl::Prefix, cl::init('2'));180 181static cl::opt<std::string>182    TargetTriple("mtriple", cl::desc("Override target triple for module"));183 184static cl::opt<std::string>185    EntryFunc("entry-function",186              cl::desc("Specify the entry function (default = 'main') "187                       "of the executable"),188              cl::value_desc("function"), cl::init("main"));189 190static cl::list<std::string>191    ExtraModules("extra-module", cl::desc("Extra modules to be loaded"),192                 cl::value_desc("input bitcode"));193 194static cl::list<std::string>195    ExtraObjects("extra-object", cl::desc("Extra object files to be loaded"),196                 cl::value_desc("input object"));197 198static cl::list<std::string>199    ExtraArchives("extra-archive", cl::desc("Extra archive files to be loaded"),200                  cl::value_desc("input archive"));201 202static cl::opt<bool>203    EnableCacheManager("enable-cache-manager",204                       cl::desc("Use cache manager to save/load modules"),205                       cl::init(false));206 207static cl::opt<std::string>208    ObjectCacheDir("object-cache-dir",209                   cl::desc("Directory to store cached object files "210                            "(must be user writable)"),211                   cl::init(""));212 213static cl::opt<std::string>214    FakeArgv0("fake-argv0",215              cl::desc("Override the 'argv[0]' value passed into the executing"216                       " program"),217              cl::value_desc("executable"));218 219static cl::opt<bool>220    DisableCoreFiles("disable-core-files", cl::Hidden,221                     cl::desc("Disable emission of core files if possible"));222 223static cl::opt<bool> NoLazyCompilation("disable-lazy-compilation",224                                       cl::desc("Disable JIT lazy compilation"),225                                       cl::init(false));226 227static cl::opt<bool> GenerateSoftFloatCalls(228    "soft-float", cl::desc("Generate software floating point library calls"),229    cl::init(false));230 231static cl::opt<bool> NoProcessSymbols(232    "no-process-syms",233    cl::desc("Do not resolve lli process symbols in JIT'd code"),234    cl::init(false));235 236enum class LLJITPlatform { Inactive, Auto, ExecutorNative, GenericIR };237 238static cl::opt<LLJITPlatform> Platform(239    "lljit-platform", cl::desc("Platform to use with LLJIT"),240    cl::init(LLJITPlatform::Auto),241    cl::values(clEnumValN(LLJITPlatform::Auto, "Auto",242                          "Like 'ExecutorNative' if ORC runtime "243                          "provided, otherwise like 'GenericIR'"),244               clEnumValN(LLJITPlatform::ExecutorNative, "ExecutorNative",245                          "Use the native platform for the executor."246                          "Requires -orc-runtime"),247               clEnumValN(LLJITPlatform::GenericIR, "GenericIR",248                          "Use LLJITGenericIRPlatform"),249               clEnumValN(LLJITPlatform::Inactive, "Inactive",250                          "Disable platform support explicitly")),251    cl::Hidden);252 253enum class DumpKind {254  NoDump,255  DumpFuncsToStdOut,256  DumpModsToStdOut,257  DumpModsToDisk,258  DumpDebugDescriptor,259  DumpDebugObjects,260};261 262static cl::opt<DumpKind> OrcDumpKind(263    "orc-lazy-debug", cl::desc("Debug dumping for the orc-lazy JIT."),264    cl::init(DumpKind::NoDump),265    cl::values(clEnumValN(DumpKind::NoDump, "no-dump", "Don't dump anything."),266               clEnumValN(DumpKind::DumpFuncsToStdOut, "funcs-to-stdout",267                          "Dump function names to stdout."),268               clEnumValN(DumpKind::DumpModsToStdOut, "mods-to-stdout",269                          "Dump modules to stdout."),270               clEnumValN(DumpKind::DumpModsToDisk, "mods-to-disk",271                          "Dump modules to the current "272                          "working directory. (WARNING: "273                          "will overwrite existing files)."),274               clEnumValN(DumpKind::DumpDebugDescriptor, "jit-debug-descriptor",275                          "Dump __jit_debug_descriptor contents to stdout"),276               clEnumValN(DumpKind::DumpDebugObjects, "jit-debug-objects",277                          "Dump __jit_debug_descriptor in-memory debug "278                          "objects as tool output")),279    cl::Hidden);280 281static ExitOnError ExitOnErr;282 283LLVM_ATTRIBUTE_USED static void linkComponents() {284  errs() << (void *)&llvm_orc_registerEHFrameSectionAllocAction285         << (void *)&llvm_orc_deregisterEHFrameSectionAllocAction286         << (void *)&llvm_orc_registerJITLoaderGDBAllocAction;287}288 289namespace {290//===----------------------------------------------------------------------===//291// Object cache292//293// This object cache implementation writes cached objects to disk to the294// directory specified by CacheDir, using a filename provided in the module295// descriptor. The cache tries to load a saved object using that path if the296// file exists. CacheDir defaults to "", in which case objects are cached297// alongside their originating bitcodes.298//299class LLIObjectCache : public ObjectCache {300public:301  LLIObjectCache(const std::string& CacheDir) : CacheDir(CacheDir) {302    // Add trailing '/' to cache dir if necessary.303    if (!this->CacheDir.empty() &&304        this->CacheDir[this->CacheDir.size() - 1] != '/')305      this->CacheDir += '/';306  }307  ~LLIObjectCache() override = default;308 309  void notifyObjectCompiled(const Module *M, MemoryBufferRef Obj) override {310    const std::string &ModuleID = M->getModuleIdentifier();311    std::string CacheName;312    if (!getCacheFilename(ModuleID, CacheName))313      return;314    if (!CacheDir.empty()) { // Create user-defined cache dir.315      SmallString<128> dir(sys::path::parent_path(CacheName));316      sys::fs::create_directories(Twine(dir));317    }318 319    std::error_code EC;320    raw_fd_ostream outfile(CacheName, EC, sys::fs::OF_None);321    outfile.write(Obj.getBufferStart(), Obj.getBufferSize());322    outfile.close();323  }324 325  std::unique_ptr<MemoryBuffer> getObject(const Module* M) override {326    const std::string &ModuleID = M->getModuleIdentifier();327    std::string CacheName;328    if (!getCacheFilename(ModuleID, CacheName))329      return nullptr;330    // Load the object from the cache filename331    ErrorOr<std::unique_ptr<MemoryBuffer>> IRObjectBuffer =332        MemoryBuffer::getFile(CacheName, /*IsText=*/false,333                              /*RequiresNullTerminator=*/false);334    // If the file isn't there, that's OK.335    if (!IRObjectBuffer)336      return nullptr;337    // MCJIT will want to write into this buffer, and we don't want that338    // because the file has probably just been mmapped.  Instead we make339    // a copy.  The filed-based buffer will be released when it goes340    // out of scope.341    return MemoryBuffer::getMemBufferCopy(IRObjectBuffer.get()->getBuffer());342  }343 344private:345  std::string CacheDir;346 347  bool getCacheFilename(StringRef ModID, std::string &CacheName) {348    if (!ModID.consume_front("file:"))349      return false;350 351    std::string CacheSubdir = std::string(ModID);352    // Transform "X:\foo" => "/X\foo" for convenience on Windows.353    if (is_style_windows(llvm::sys::path::Style::native) &&354        isalpha(CacheSubdir[0]) && CacheSubdir[1] == ':') {355      CacheSubdir[1] = CacheSubdir[0];356      CacheSubdir[0] = '/';357    }358 359    CacheName = CacheDir + CacheSubdir;360    size_t pos = CacheName.rfind('.');361    CacheName.replace(pos, CacheName.length() - pos, ".o");362    return true;363  }364};365} // namespace366 367// On Mingw and Cygwin, an external symbol named '__main' is called from the368// generated 'main' function to allow static initialization.  To avoid linking369// problems with remote targets (because lli's remote target support does not370// currently handle external linking) we add a secondary module which defines371// an empty '__main' function.372static void addCygMingExtraModule(ExecutionEngine &EE, LLVMContext &Context,373                                  const Triple &TargetTriple) {374  IRBuilder<> Builder(Context);375 376  // Create a new module.377  std::unique_ptr<Module> M = std::make_unique<Module>("CygMingHelper", Context);378  M->setTargetTriple(TargetTriple);379 380  // Create an empty function named "__main".381  Type *ReturnTy;382  if (TargetTriple.isArch64Bit())383    ReturnTy = Type::getInt64Ty(Context);384  else385    ReturnTy = Type::getInt32Ty(Context);386  Function *Result =387      Function::Create(FunctionType::get(ReturnTy, {}, false),388                       GlobalValue::ExternalLinkage, "__main", M.get());389 390  BasicBlock *BB = BasicBlock::Create(Context, "__main", Result);391  Builder.SetInsertPoint(BB);392  Value *ReturnVal = ConstantInt::get(ReturnTy, 0);393  Builder.CreateRet(ReturnVal);394 395  // Add this new module to the ExecutionEngine.396  EE.addModule(std::move(M));397}398 399static CodeGenOptLevel getOptLevel() {400  if (auto Level = CodeGenOpt::parseLevel(OptLevel))401    return *Level;402  WithColor::error(errs(), "lli") << "invalid optimization level.\n";403  exit(1);404}405 406[[noreturn]] static void reportError(SMDiagnostic Err, const char *ProgName) {407  Err.print(ProgName, errs());408  exit(1);409}410 411static Error loadDylibs();412static int runOrcJIT(const char *ProgName);413static void disallowOrcOptions();414static Expected<std::unique_ptr<orc::ExecutorProcessControl>> launchRemote();415 416//===----------------------------------------------------------------------===//417// main Driver function418//419int main(int argc, char **argv, char * const *envp) {420  InitLLVM X(argc, argv);421 422  if (argc > 1)423    ExitOnErr.setBanner(std::string(argv[0]) + ": ");424 425  // If we have a native target, initialize it to ensure it is linked in and426  // usable by the JIT.427  InitializeNativeTarget();428  InitializeNativeTargetAsmPrinter();429  InitializeNativeTargetAsmParser();430 431  cl::ParseCommandLineOptions(argc, argv,432                              "llvm interpreter & dynamic compiler\n");433 434  // If the user doesn't want core files, disable them.435  if (DisableCoreFiles)436    sys::Process::PreventCoreFiles();437 438  ExitOnErr(loadDylibs());439 440  if (EntryFunc.empty()) {441    WithColor::error(errs(), argv[0])442        << "--entry-function name cannot be empty\n";443    exit(1);444  }445 446  if (UseJITKind == JITKind::MCJIT || ForceInterpreter)447    disallowOrcOptions();448  else449    return runOrcJIT(argv[0]);450 451  // Old lli implementation based on ExecutionEngine and MCJIT.452  LLVMContext Context;453 454  // Load the bitcode...455  SMDiagnostic Err;456  std::unique_ptr<Module> Owner = parseIRFile(InputFile, Err, Context);457  Module *Mod = Owner.get();458  if (!Mod)459    reportError(Err, argv[0]);460 461  if (EnableCacheManager) {462    std::string CacheName("file:");463    CacheName.append(InputFile);464    Mod->setModuleIdentifier(CacheName);465  }466 467  // If not jitting lazily, load the whole bitcode file eagerly too.468  if (NoLazyCompilation) {469    // Use *argv instead of argv[0] to work around a wrong GCC warning.470    ExitOnError ExitOnErr(std::string(*argv) +471                          ": bitcode didn't read correctly: ");472    ExitOnErr(Mod->materializeAll());473  }474 475  std::string ErrorMsg;476  EngineBuilder builder(std::move(Owner));477  builder.setMArch(codegen::getMArch());478  builder.setMCPU(codegen::getCPUStr());479  builder.setMAttrs(codegen::getFeatureList());480  if (auto RM = codegen::getExplicitRelocModel())481    builder.setRelocationModel(*RM);482  if (auto CM = codegen::getExplicitCodeModel())483    builder.setCodeModel(*CM);484  builder.setErrorStr(&ErrorMsg);485  builder.setEngineKind(ForceInterpreter486                        ? EngineKind::Interpreter487                        : EngineKind::JIT);488 489  // If we are supposed to override the target triple, do so now.490  if (!TargetTriple.empty())491    Mod->setTargetTriple(Triple(Triple::normalize(TargetTriple)));492 493  // Enable MCJIT if desired.494  RTDyldMemoryManager *RTDyldMM = nullptr;495  if (!ForceInterpreter) {496    if (RemoteMCJIT)497      RTDyldMM = new ForwardingMemoryManager();498    else499      RTDyldMM = new SectionMemoryManager();500 501    // Deliberately construct a temp std::unique_ptr to pass in. Do not null out502    // RTDyldMM: We still use it below, even though we don't own it.503    builder.setMCJITMemoryManager(504      std::unique_ptr<RTDyldMemoryManager>(RTDyldMM));505  } else if (RemoteMCJIT) {506    WithColor::error(errs(), argv[0])507        << "remote process execution does not work with the interpreter.\n";508    exit(1);509  }510 511  builder.setOptLevel(getOptLevel());512 513  TargetOptions Options =514      codegen::InitTargetOptionsFromCodeGenFlags(Triple(TargetTriple));515  if (codegen::getFloatABIForCalls() != FloatABI::Default)516    Options.FloatABIType = codegen::getFloatABIForCalls();517 518  builder.setTargetOptions(Options);519 520  std::unique_ptr<ExecutionEngine> EE(builder.create());521  if (!EE) {522    if (!ErrorMsg.empty())523      WithColor::error(errs(), argv[0])524          << "error creating EE: " << ErrorMsg << "\n";525    else526      WithColor::error(errs(), argv[0]) << "unknown error creating EE!\n";527    exit(1);528  }529 530  std::unique_ptr<LLIObjectCache> CacheManager;531  if (EnableCacheManager) {532    CacheManager.reset(new LLIObjectCache(ObjectCacheDir));533    EE->setObjectCache(CacheManager.get());534  }535 536  // Load any additional modules specified on the command line.537  for (unsigned i = 0, e = ExtraModules.size(); i != e; ++i) {538    std::unique_ptr<Module> XMod = parseIRFile(ExtraModules[i], Err, Context);539    if (!XMod)540      reportError(Err, argv[0]);541    if (EnableCacheManager) {542      std::string CacheName("file:");543      CacheName.append(ExtraModules[i]);544      XMod->setModuleIdentifier(CacheName);545    }546    EE->addModule(std::move(XMod));547  }548 549  for (unsigned i = 0, e = ExtraObjects.size(); i != e; ++i) {550    Expected<object::OwningBinary<object::ObjectFile>> Obj =551        object::ObjectFile::createObjectFile(ExtraObjects[i]);552    if (!Obj) {553      // TODO: Actually report errors helpfully.554      consumeError(Obj.takeError());555      reportError(Err, argv[0]);556    }557    object::OwningBinary<object::ObjectFile> &O = Obj.get();558    EE->addObjectFile(std::move(O));559  }560 561  for (unsigned i = 0, e = ExtraArchives.size(); i != e; ++i) {562    ErrorOr<std::unique_ptr<MemoryBuffer>> ArBufOrErr =563        MemoryBuffer::getFileOrSTDIN(ExtraArchives[i]);564    if (!ArBufOrErr)565      reportError(Err, argv[0]);566    std::unique_ptr<MemoryBuffer> &ArBuf = ArBufOrErr.get();567 568    Expected<std::unique_ptr<object::Archive>> ArOrErr =569        object::Archive::create(ArBuf->getMemBufferRef());570    if (!ArOrErr) {571      std::string Buf;572      raw_string_ostream OS(Buf);573      logAllUnhandledErrors(ArOrErr.takeError(), OS);574      OS.flush();575      errs() << Buf;576      exit(1);577    }578    std::unique_ptr<object::Archive> &Ar = ArOrErr.get();579 580    object::OwningBinary<object::Archive> OB(std::move(Ar), std::move(ArBuf));581 582    EE->addArchive(std::move(OB));583  }584 585  // If the target is Cygwin/MingW and we are generating remote code, we586  // need an extra module to help out with linking.587  if (RemoteMCJIT && Mod->getTargetTriple().isOSCygMing()) {588    addCygMingExtraModule(*EE, Context, Mod->getTargetTriple());589  }590 591  // The following functions have no effect if their respective profiling592  // support wasn't enabled in the build configuration.593  EE->RegisterJITEventListener(594                JITEventListener::createOProfileJITEventListener());595  EE->RegisterJITEventListener(596                JITEventListener::createIntelJITEventListener());597  if (!RemoteMCJIT)598    EE->RegisterJITEventListener(599                JITEventListener::createPerfJITEventListener());600 601  if (!NoLazyCompilation && RemoteMCJIT) {602    WithColor::warning(errs(), argv[0])603        << "remote mcjit does not support lazy compilation\n";604    NoLazyCompilation = true;605  }606  EE->DisableLazyCompilation(NoLazyCompilation);607 608  // If the user specifically requested an argv[0] to pass into the program,609  // do it now.610  if (!FakeArgv0.empty()) {611    InputFile = static_cast<std::string>(FakeArgv0);612  } else {613    // Otherwise, if there is a .bc suffix on the executable strip it off, it614    // might confuse the program.615    if (StringRef(InputFile).ends_with(".bc"))616      InputFile.erase(InputFile.length() - 3);617  }618 619  // Add the module's name to the start of the vector of arguments to main().620  InputArgv.insert(InputArgv.begin(), InputFile);621 622  // Call the main function from M as if its signature were:623  //   int main (int argc, char **argv, const char **envp)624  // using the contents of Args to determine argc & argv, and the contents of625  // EnvVars to determine envp.626  //627  Function *EntryFn = Mod->getFunction(EntryFunc);628  if (!EntryFn) {629    WithColor::error(errs(), argv[0])630        << '\'' << EntryFunc << "\' function not found in module.\n";631    return -1;632  }633 634  // Reset errno to zero on entry to main.635  errno = 0;636 637  int Result = -1;638 639  // Sanity check use of remote-jit: LLI currently only supports use of the640  // remote JIT on Unix platforms.641  if (RemoteMCJIT) {642#ifndef LLVM_ON_UNIX643    WithColor::warning(errs(), argv[0])644        << "host does not support external remote targets.\n";645    WithColor::note() << "defaulting to local execution\n";646    return -1;647#else648    if (ChildExecPath.empty()) {649      WithColor::error(errs(), argv[0])650          << "-remote-mcjit requires -mcjit-remote-process.\n";651      exit(1);652    } else if (!sys::fs::can_execute(ChildExecPath)) {653      WithColor::error(errs(), argv[0])654          << "unable to find usable child executable: '" << ChildExecPath655          << "'\n";656      return -1;657    }658#endif659  }660 661  if (!RemoteMCJIT) {662    // If the program doesn't explicitly call exit, we will need the Exit663    // function later on to make an explicit call, so get the function now.664    FunctionCallee Exit = Mod->getOrInsertFunction(665        "exit", Type::getVoidTy(Context), Type::getInt32Ty(Context));666 667    // Run static constructors.668    if (!ForceInterpreter) {669      // Give MCJIT a chance to apply relocations and set page permissions.670      EE->finalizeObject();671    }672    EE->runStaticConstructorsDestructors(false);673 674    // Trigger compilation separately so code regions that need to be675    // invalidated will be known.676    (void)EE->getPointerToFunction(EntryFn);677    // Clear instruction cache before code will be executed.678    if (RTDyldMM)679      static_cast<SectionMemoryManager*>(RTDyldMM)->invalidateInstructionCache();680 681    // Run main.682    Result = EE->runFunctionAsMain(EntryFn, InputArgv, envp);683 684    // Run static destructors.685    EE->runStaticConstructorsDestructors(true);686 687    // If the program didn't call exit explicitly, we should call it now.688    // This ensures that any atexit handlers get called correctly.689    if (Function *ExitF =690            dyn_cast<Function>(Exit.getCallee()->stripPointerCasts())) {691      if (ExitF->getFunctionType() == Exit.getFunctionType()) {692        std::vector<GenericValue> Args;693        GenericValue ResultGV;694        ResultGV.IntVal = APInt(32, Result);695        Args.push_back(ResultGV);696        EE->runFunction(ExitF, Args);697        WithColor::error(errs(), argv[0])698            << "exit(" << Result << ") returned!\n";699        abort();700      }701    }702    WithColor::error(errs(), argv[0]) << "exit defined with wrong prototype!\n";703    abort();704  } else {705    // else == "if (RemoteMCJIT)"706    std::unique_ptr<orc::ExecutorProcessControl> EPC = ExitOnErr(launchRemote());707 708    // Remote target MCJIT doesn't (yet) support static constructors. No reason709    // it couldn't. This is a limitation of the LLI implementation, not the710    // MCJIT itself. FIXME.711 712    // Create a remote memory manager.713    auto RemoteMM = ExitOnErr(714        orc::EPCGenericRTDyldMemoryManager::CreateWithDefaultBootstrapSymbols(715            *EPC));716 717    // Forward MCJIT's memory manager calls to the remote memory manager.718    static_cast<ForwardingMemoryManager*>(RTDyldMM)->setMemMgr(719      std::move(RemoteMM));720 721    // Forward MCJIT's symbol resolution calls to the remote.722    static_cast<ForwardingMemoryManager *>(RTDyldMM)->setResolver(723        ExitOnErr(RemoteResolver::Create(*EPC)));724    // Grab the target address of the JIT'd main function on the remote and call725    // it.726    // FIXME: argv and envp handling.727    auto Entry =728        orc::ExecutorAddr(EE->getFunctionAddress(EntryFn->getName().str()));729    EE->finalizeObject();730    LLVM_DEBUG(dbgs() << "Executing '" << EntryFn->getName() << "' at 0x"731                      << format("%llx", Entry.getValue()) << "\n");732    Result = ExitOnErr(EPC->runAsMain(Entry, {}));733 734    // Like static constructors, the remote target MCJIT support doesn't handle735    // this yet. It could. FIXME.736 737    // Delete the EE - we need to tear it down *before* we terminate the session738    // with the remote, otherwise it'll crash when it tries to release resources739    // on a remote that has already been disconnected.740    EE.reset();741 742    // Signal the remote target that we're done JITing.743    ExitOnErr(EPC->disconnect());744  }745 746  return Result;747}748 749// JITLink debug support plugins put information about JITed code in this GDB750// JIT Interface global from OrcTargetProcess.751extern "C" LLVM_ABI struct jit_descriptor __jit_debug_descriptor;752 753static struct jit_code_entry *754findNextDebugDescriptorEntry(struct jit_code_entry *Latest) {755  if (Latest == nullptr)756    return __jit_debug_descriptor.first_entry;757  if (Latest->next_entry)758    return Latest->next_entry;759  return nullptr;760}761 762static ToolOutputFile &claimToolOutput() {763  static std::unique_ptr<ToolOutputFile> ToolOutput = nullptr;764  if (ToolOutput) {765    WithColor::error(errs(), "lli")766        << "Can not claim stdout for tool output twice\n";767    exit(1);768  }769  std::error_code EC;770  ToolOutput = std::make_unique<ToolOutputFile>("-", EC, sys::fs::OF_None);771  if (EC) {772    WithColor::error(errs(), "lli")773        << "Failed to create tool output file: " << EC.message() << "\n";774    exit(1);775  }776  return *ToolOutput;777}778 779static std::function<void(Module &)> createIRDebugDumper() {780  switch (OrcDumpKind) {781  case DumpKind::NoDump:782  case DumpKind::DumpDebugDescriptor:783  case DumpKind::DumpDebugObjects:784    return [](Module &M) {};785 786  case DumpKind::DumpFuncsToStdOut:787    return [](Module &M) {788      printf("[ ");789 790      for (const auto &F : M) {791        if (F.isDeclaration())792          continue;793 794        if (F.hasName()) {795          std::string Name(std::string(F.getName()));796          printf("%s ", Name.c_str());797        } else798          printf("<anon> ");799      }800 801      printf("]\n");802    };803 804  case DumpKind::DumpModsToStdOut:805    return [](Module &M) {806      outs() << "----- Module Start -----\n" << M << "----- Module End -----\n";807    };808 809  case DumpKind::DumpModsToDisk:810    return [](Module &M) {811      std::error_code EC;812      raw_fd_ostream Out(M.getModuleIdentifier() + ".ll", EC,813                         sys::fs::OF_TextWithCRLF);814      if (EC) {815        errs() << "Couldn't open " << M.getModuleIdentifier()816               << " for dumping.\nError:" << EC.message() << "\n";817        exit(1);818      }819      Out << M;820    };821  }822  llvm_unreachable("Unknown DumpKind");823}824 825static std::function<void(MemoryBuffer &)> createObjDebugDumper() {826  switch (OrcDumpKind) {827  case DumpKind::NoDump:828  case DumpKind::DumpFuncsToStdOut:829  case DumpKind::DumpModsToStdOut:830  case DumpKind::DumpModsToDisk:831    return [](MemoryBuffer &) {};832 833  case DumpKind::DumpDebugDescriptor: {834    // Dump the empty descriptor at startup once835    fprintf(stderr, "jit_debug_descriptor 0x%016" PRIx64 "\n",836            pointerToJITTargetAddress(__jit_debug_descriptor.first_entry));837    return [](MemoryBuffer &) {838      // Dump new entries as they appear839      static struct jit_code_entry *Latest = nullptr;840      while (auto *NewEntry = findNextDebugDescriptorEntry(Latest)) {841        fprintf(stderr, "jit_debug_descriptor 0x%016" PRIx64 "\n",842                pointerToJITTargetAddress(NewEntry));843        Latest = NewEntry;844      }845    };846  }847 848  case DumpKind::DumpDebugObjects: {849    return [](MemoryBuffer &Obj) {850      static struct jit_code_entry *Latest = nullptr;851      static ToolOutputFile &ToolOutput = claimToolOutput();852      while (auto *NewEntry = findNextDebugDescriptorEntry(Latest)) {853        ToolOutput.os().write(NewEntry->symfile_addr, NewEntry->symfile_size);854        Latest = NewEntry;855      }856    };857  }858  }859  llvm_unreachable("Unknown DumpKind");860}861 862static Error loadDylibs() {863  for (const auto &Dylib : Dylibs) {864    std::string ErrMsg;865    if (sys::DynamicLibrary::LoadLibraryPermanently(Dylib.c_str(), &ErrMsg))866      return make_error<StringError>(ErrMsg, inconvertibleErrorCode());867  }868 869  return Error::success();870}871 872static void exitOnLazyCallThroughFailure() { exit(1); }873 874static Expected<orc::ThreadSafeModule>875loadModule(StringRef Path, orc::ThreadSafeContext TSCtx) {876  SMDiagnostic Err;877  auto M = TSCtx.withContextDo(878      [&](LLVMContext *Ctx) { return parseIRFile(Path, Err, *Ctx); });879  if (!M) {880    std::string ErrMsg;881    {882      raw_string_ostream ErrMsgStream(ErrMsg);883      Err.print("lli", ErrMsgStream);884    }885    return make_error<StringError>(std::move(ErrMsg), inconvertibleErrorCode());886  }887 888  if (EnableCacheManager)889    M->setModuleIdentifier("file:" + M->getModuleIdentifier());890 891  return orc::ThreadSafeModule(std::move(M), std::move(TSCtx));892}893 894static int mingw_noop_main(void) {895  // Cygwin and MinGW insert calls from the main function to the runtime896  // function __main. The __main function is responsible for setting up main's897  // environment (e.g. running static constructors), however this is not needed898  // when running under lli: the executor process will have run non-JIT ctors,899  // and ORC will take care of running JIT'd ctors. To avoid a missing symbol900  // error we just implement __main as a no-op.901  //902  // FIXME: Move this to ORC-RT (and the ORC-RT substitution library once it903  //        exists). That will allow it to work out-of-process, and for all904  //        ORC tools (the problem isn't lli specific).905  return 0;906}907 908// Try to enable debugger support for the given instance.909// This alway returns success, but prints a warning if it's not able to enable910// debugger support.911static Error tryEnableDebugSupport(orc::LLJIT &J) {912  if (auto Err = enableDebuggerSupport(J)) {913    [[maybe_unused]] std::string ErrMsg = toString(std::move(Err));914    LLVM_DEBUG(dbgs() << "lli: " << ErrMsg << "\n");915  }916  return Error::success();917}918 919static int runOrcJIT(const char *ProgName) {920  // Start setting up the JIT environment.921 922  // Parse the main module.923  orc::ThreadSafeContext TSCtx(std::make_unique<LLVMContext>());924  auto MainModule = ExitOnErr(loadModule(InputFile, TSCtx));925 926  // Get TargetTriple and DataLayout from the main module if they're explicitly927  // set.928  std::optional<Triple> TT;929  std::optional<DataLayout> DL;930  MainModule.withModuleDo([&](Module &M) {931      if (!M.getTargetTriple().empty())932        TT = M.getTargetTriple();933      if (!M.getDataLayout().isDefault())934        DL = M.getDataLayout();935    });936 937  orc::LLLazyJITBuilder Builder;938 939  Builder.setJITTargetMachineBuilder(940      TT ? orc::JITTargetMachineBuilder(*TT)941         : ExitOnErr(orc::JITTargetMachineBuilder::detectHost()));942 943  TT = Builder.getJITTargetMachineBuilder()->getTargetTriple();944  if (DL)945    Builder.setDataLayout(DL);946 947  if (!codegen::getMArch().empty())948    Builder.getJITTargetMachineBuilder()->getTargetTriple().setArchName(949        codegen::getMArch());950 951  Builder.getJITTargetMachineBuilder()952      ->setCPU(codegen::getCPUStr())953      .addFeatures(codegen::getFeatureList())954      .setRelocationModel(codegen::getExplicitRelocModel())955      .setCodeModel(codegen::getExplicitCodeModel());956 957  // Link process symbols unless NoProcessSymbols is set.958  Builder.setLinkProcessSymbolsByDefault(!NoProcessSymbols);959 960  // FIXME: Setting a dummy call-through manager in non-lazy mode prevents the961  // JIT builder to instantiate a default (which would fail with an error for962  // unsupported architectures).963  if (UseJITKind != JITKind::OrcLazy) {964    auto ES = std::make_unique<orc::ExecutionSession>(965        ExitOnErr(orc::SelfExecutorProcessControl::Create()));966    Builder.setLazyCallthroughManager(967        std::make_unique<orc::LazyCallThroughManager>(*ES, orc::ExecutorAddr(),968                                                      nullptr));969    Builder.setExecutionSession(std::move(ES));970  }971 972  Builder.setLazyCompileFailureAddr(973      orc::ExecutorAddr::fromPtr(exitOnLazyCallThroughFailure));974  Builder.setNumCompileThreads(LazyJITCompileThreads);975 976  // If the object cache is enabled then set a custom compile function977  // creator to use the cache.978  std::unique_ptr<LLIObjectCache> CacheManager;979  if (EnableCacheManager) {980 981    CacheManager = std::make_unique<LLIObjectCache>(ObjectCacheDir);982 983    Builder.setCompileFunctionCreator(984      [&](orc::JITTargetMachineBuilder JTMB)985            -> Expected<std::unique_ptr<orc::IRCompileLayer::IRCompiler>> {986        if (LazyJITCompileThreads > 0)987          return std::make_unique<orc::ConcurrentIRCompiler>(std::move(JTMB),988                                                        CacheManager.get());989 990        auto TM = JTMB.createTargetMachine();991        if (!TM)992          return TM.takeError();993 994        return std::make_unique<orc::TMOwningSimpleCompiler>(std::move(*TM),995                                                        CacheManager.get());996      });997  }998 999  // Enable debugging of JIT'd code (only works on JITLink for ELF and MachO).1000  Builder.setPrePlatformSetup(tryEnableDebugSupport);1001 1002  // Set up LLJIT platform.1003  LLJITPlatform P = Platform;1004  if (P == LLJITPlatform::Auto)1005    P = OrcRuntime.empty() ? LLJITPlatform::GenericIR1006                           : LLJITPlatform::ExecutorNative;1007 1008  switch (P) {1009  case LLJITPlatform::ExecutorNative: {1010    Builder.setPlatformSetUp(orc::ExecutorNativePlatform(OrcRuntime));1011    break;1012  }1013  case LLJITPlatform::GenericIR:1014    // Nothing to do: LLJITBuilder will use this by default.1015    break;1016  case LLJITPlatform::Inactive:1017    Builder.setPlatformSetUp(orc::setUpInactivePlatform);1018    break;1019  default:1020    llvm_unreachable("Unrecognized platform value");1021  }1022 1023  std::unique_ptr<orc::ExecutorProcessControl> EPC = nullptr;1024  if (JITLinker == JITLinkerKind::JITLink) {1025    EPC = ExitOnErr(orc::SelfExecutorProcessControl::Create(1026        std::make_shared<orc::SymbolStringPool>()));1027 1028    Builder.getJITTargetMachineBuilder()1029        ->setRelocationModel(Reloc::PIC_)1030        .setCodeModel(CodeModel::Small);1031    Builder.setObjectLinkingLayerCreator([&](orc::ExecutionSession &ES) {1032      return std::make_unique<orc::ObjectLinkingLayer>(ES);1033    });1034  }1035 1036  auto J = ExitOnErr(Builder.create());1037 1038  auto *ObjLayer = &J->getObjLinkingLayer();1039  if (auto *RTDyldObjLayer = dyn_cast<orc::RTDyldObjectLinkingLayer>(ObjLayer)) {1040    RTDyldObjLayer->registerJITEventListener(1041        *JITEventListener::createGDBRegistrationListener());1042#if LLVM_USE_OPROFILE1043    RTDyldObjLayer->registerJITEventListener(1044        *JITEventListener::createOProfileJITEventListener());1045#endif1046#if LLVM_USE_INTEL_JITEVENTS1047    RTDyldObjLayer->registerJITEventListener(1048        *JITEventListener::createIntelJITEventListener());1049#endif1050#if LLVM_USE_PERF1051    RTDyldObjLayer->registerJITEventListener(1052        *JITEventListener::createPerfJITEventListener());1053#endif1054  }1055 1056  if (PerModuleLazy)1057    J->setPartitionFunction(orc::IRPartitionLayer::compileWholeModule);1058 1059  auto IRDump = createIRDebugDumper();1060  J->getIRTransformLayer().setTransform(1061      [&](orc::ThreadSafeModule TSM,1062          const orc::MaterializationResponsibility &R) {1063        TSM.withModuleDo([&](Module &M) {1064          if (verifyModule(M, &dbgs())) {1065            dbgs() << "Bad module: " << &M << "\n";1066            exit(1);1067          }1068          IRDump(M);1069        });1070        return TSM;1071      });1072 1073  auto ObjDump = createObjDebugDumper();1074  J->getObjTransformLayer().setTransform(1075      [&](std::unique_ptr<MemoryBuffer> Obj)1076          -> Expected<std::unique_ptr<MemoryBuffer>> {1077        ObjDump(*Obj);1078        return std::move(Obj);1079      });1080 1081  // If this is a Mingw or Cygwin executor then we need to alias __main to1082  // orc_rt_int_void_return_0.1083  if (J->getTargetTriple().isOSCygMing()) {1084    auto &WorkaroundJD = J->getProcessSymbolsJITDylib()1085                             ? *J->getProcessSymbolsJITDylib()1086                             : J->getMainJITDylib();1087    ExitOnErr(WorkaroundJD.define(1088        orc::absoluteSymbols({{J->mangleAndIntern("__main"),1089                               {orc::ExecutorAddr::fromPtr(mingw_noop_main),1090                                JITSymbolFlags::Exported}}})));1091  }1092 1093  // Regular modules are greedy: They materialize as a whole and trigger1094  // materialization for all required symbols recursively. Lazy modules go1095  // through partitioning and they replace outgoing calls with reexport stubs1096  // that resolve on call-through.1097  auto AddModule = [&](orc::JITDylib &JD, orc::ThreadSafeModule M) {1098    return UseJITKind == JITKind::OrcLazy ? J->addLazyIRModule(JD, std::move(M))1099                                          : J->addIRModule(JD, std::move(M));1100  };1101 1102  // Add the main module.1103  ExitOnErr(AddModule(J->getMainJITDylib(), std::move(MainModule)));1104 1105  // Create JITDylibs and add any extra modules.1106  {1107    // Create JITDylibs, keep a map from argument index to dylib. We will use1108    // -extra-module argument indexes to determine what dylib to use for each1109    // -extra-module.1110    std::map<unsigned, orc::JITDylib *> IdxToDylib;1111    IdxToDylib[0] = &J->getMainJITDylib();1112    for (auto JDItr = JITDylibs.begin(), JDEnd = JITDylibs.end();1113         JDItr != JDEnd; ++JDItr) {1114      orc::JITDylib *JD = J->getJITDylibByName(*JDItr);1115      if (!JD) {1116        JD = &ExitOnErr(J->createJITDylib(*JDItr));1117        J->getMainJITDylib().addToLinkOrder(*JD);1118        JD->addToLinkOrder(J->getMainJITDylib());1119      }1120      IdxToDylib[JITDylibs.getPosition(JDItr - JITDylibs.begin())] = JD;1121    }1122 1123    for (auto EMItr = ExtraModules.begin(), EMEnd = ExtraModules.end();1124         EMItr != EMEnd; ++EMItr) {1125      auto M = ExitOnErr(loadModule(*EMItr, TSCtx));1126 1127      auto EMIdx = ExtraModules.getPosition(EMItr - ExtraModules.begin());1128      assert(EMIdx != 0 && "ExtraModule should have index > 0");1129      auto JDItr = std::prev(IdxToDylib.lower_bound(EMIdx));1130      auto &JD = *JDItr->second;1131      ExitOnErr(AddModule(JD, std::move(M)));1132    }1133 1134    for (auto EAItr = ExtraArchives.begin(), EAEnd = ExtraArchives.end();1135         EAItr != EAEnd; ++EAItr) {1136      auto EAIdx = ExtraArchives.getPosition(EAItr - ExtraArchives.begin());1137      assert(EAIdx != 0 && "ExtraArchive should have index > 0");1138      auto JDItr = std::prev(IdxToDylib.lower_bound(EAIdx));1139      auto &JD = *JDItr->second;1140      ExitOnErr(J->linkStaticLibraryInto(JD, EAItr->c_str()));1141    }1142  }1143 1144  // Add the objects.1145  for (auto &ObjPath : ExtraObjects) {1146    auto Obj = ExitOnErr(errorOrToExpected(MemoryBuffer::getFile(ObjPath)));1147    ExitOnErr(J->addObjectFile(std::move(Obj)));1148  }1149 1150  // Run any static constructors.1151  ExitOnErr(J->initialize(J->getMainJITDylib()));1152 1153  // Run any -thread-entry points.1154  std::vector<std::thread> AltEntryThreads;1155  for (auto &ThreadEntryPoint : ThreadEntryPoints) {1156    auto EntryPointSym = ExitOnErr(J->lookup(ThreadEntryPoint));1157    typedef void (*EntryPointPtr)();1158    auto EntryPoint = EntryPointSym.toPtr<EntryPointPtr>();1159    AltEntryThreads.push_back(std::thread([EntryPoint]() { EntryPoint(); }));1160  }1161 1162  // Resolve and run the main function.1163  auto MainAddr = ExitOnErr(J->lookup(EntryFunc));1164  int Result;1165 1166  if (EPC) {1167    // ExecutorProcessControl-based execution with JITLink.1168    Result = ExitOnErr(EPC->runAsMain(MainAddr, InputArgv));1169  } else {1170    // Manual in-process execution with RuntimeDyld.1171    using MainFnTy = int(int, char *[]);1172    auto MainFn = MainAddr.toPtr<MainFnTy *>();1173    Result = orc::runAsMain(MainFn, InputArgv, StringRef(InputFile));1174  }1175 1176  // Wait for -entry-point threads.1177  for (auto &AltEntryThread : AltEntryThreads)1178    AltEntryThread.join();1179 1180  // Run destructors.1181  ExitOnErr(J->deinitialize(J->getMainJITDylib()));1182 1183  return Result;1184}1185 1186static void disallowOrcOptions() {1187  // Make sure nobody used an orc-lazy specific option accidentally.1188 1189  if (LazyJITCompileThreads != 0) {1190    errs() << "-compile-threads requires -jit-kind=orc-lazy\n";1191    exit(1);1192  }1193 1194  if (!ThreadEntryPoints.empty()) {1195    errs() << "-thread-entry requires -jit-kind=orc-lazy\n";1196    exit(1);1197  }1198 1199  if (PerModuleLazy) {1200    errs() << "-per-module-lazy requires -jit-kind=orc-lazy\n";1201    exit(1);1202  }1203}1204 1205static Expected<std::unique_ptr<orc::ExecutorProcessControl>> launchRemote() {1206#ifndef LLVM_ON_UNIX1207  llvm_unreachable("launchRemote not supported on non-Unix platforms");1208#else1209  int PipeFD[2][2];1210  pid_t ChildPID;1211 1212  // Create two pipes.1213  if (pipe(PipeFD[0]) != 0 || pipe(PipeFD[1]) != 0)1214    perror("Error creating pipe: ");1215 1216  ChildPID = fork();1217 1218  if (ChildPID == 0) {1219    // In the child...1220 1221    // Close the parent ends of the pipes1222    close(PipeFD[0][1]);1223    close(PipeFD[1][0]);1224 1225 1226    // Execute the child process.1227    std::unique_ptr<char[]> ChildPath, ChildIn, ChildOut;1228    {1229      ChildPath.reset(new char[ChildExecPath.size() + 1]);1230      llvm::copy(ChildExecPath, &ChildPath[0]);1231      ChildPath[ChildExecPath.size()] = '\0';1232      std::string ChildInStr = utostr(PipeFD[0][0]);1233      ChildIn.reset(new char[ChildInStr.size() + 1]);1234      llvm::copy(ChildInStr, &ChildIn[0]);1235      ChildIn[ChildInStr.size()] = '\0';1236      std::string ChildOutStr = utostr(PipeFD[1][1]);1237      ChildOut.reset(new char[ChildOutStr.size() + 1]);1238      llvm::copy(ChildOutStr, &ChildOut[0]);1239      ChildOut[ChildOutStr.size()] = '\0';1240    }1241 1242    char * const args[] = { &ChildPath[0], &ChildIn[0], &ChildOut[0], nullptr };1243    int rc = execv(ChildExecPath.c_str(), args);1244    if (rc != 0)1245      perror("Error executing child process: ");1246    llvm_unreachable("Error executing child process");1247  }1248  // else we're the parent...1249 1250  // Close the child ends of the pipes1251  close(PipeFD[0][0]);1252  close(PipeFD[1][1]);1253 1254  // Return a SimpleRemoteEPC instance connected to our end of the pipes.1255  return orc::SimpleRemoteEPC::Create<orc::FDSimpleRemoteEPCTransport>(1256      std::make_unique<llvm::orc::InPlaceTaskDispatcher>(),1257      llvm::orc::SimpleRemoteEPC::Setup(), PipeFD[1][0], PipeFD[0][1]);1258#endif1259}1260 1261// For MinGW environments, manually export the __chkstk function from the lli1262// executable.1263//1264// Normally, this function is provided by compiler-rt builtins or libgcc.1265// It is named "_alloca" on i386, "___chkstk_ms" on x86_64, and "__chkstk" on1266// arm/aarch64. In MSVC configurations, it's named "__chkstk" in all1267// configurations.1268//1269// When Orc tries to resolve symbols at runtime, this succeeds in MSVC1270// configurations, somewhat by accident/luck; kernelbase.dll does export a1271// symbol named "__chkstk" which gets found by Orc, even if regular applications1272// never link against that function from that DLL (it's linked in statically1273// from a compiler support library).1274//1275// The MinGW specific symbol names aren't available in that DLL though.1276// Therefore, manually export the relevant symbol from lli, to let it be1277// found at runtime during tests.1278//1279// For real JIT uses, the real compiler support libraries should be linked1280// in, somehow; this is a workaround to let tests pass.1281//1282// We need to make sure that this symbol actually is linked in when we1283// try to export it; if no functions allocate a large enough stack area,1284// nothing would reference it. Therefore, manually declare it and add a1285// reference to it. (Note, the declarations of _alloca/___chkstk_ms/__chkstk1286// are somewhat bogus, these functions use a different custom calling1287// convention.)1288//1289// TODO: Move this into libORC at some point, see1290// https://github.com/llvm/llvm-project/issues/56603.1291#ifdef __MINGW32__1292// This is a MinGW version of #pragma comment(linker, "...") that doesn't1293// require compiling with -fms-extensions.1294#if defined(__i386__)1295#undef _alloca1296extern "C" void _alloca(void);1297static __attribute__((used)) void (*const ref_func)(void) = _alloca;1298static __attribute__((section(".drectve"), used)) const char export_chkstk[] =1299    "-export:_alloca";1300#elif defined(__x86_64__)1301extern "C" void ___chkstk_ms(void);1302static __attribute__((used)) void (*const ref_func)(void) = ___chkstk_ms;1303static __attribute__((section(".drectve"), used)) const char export_chkstk[] =1304    "-export:___chkstk_ms";1305#else1306extern "C" void __chkstk(void);1307static __attribute__((used)) void (*const ref_func)(void) = __chkstk;1308static __attribute__((section(".drectve"), used)) const char export_chkstk[] =1309    "-export:__chkstk";1310#endif1311#endif1312