#include "ForwardingMemoryManager.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/Bitcode/BitcodeReader.h"
#include "llvm/CodeGen/CommandFlags.h"
#include "llvm/CodeGen/LinkAllCodegenComponents.h"
#include "llvm/Config/llvm-config.h"
#include "llvm/ExecutionEngine/GenericValue.h"
#include "llvm/ExecutionEngine/Interpreter.h"
#include "llvm/ExecutionEngine/JITEventListener.h"
#include "llvm/ExecutionEngine/JITSymbol.h"
#include "llvm/ExecutionEngine/MCJIT.h"
#include "llvm/ExecutionEngine/ObjectCache.h"
#include "llvm/ExecutionEngine/Orc/DebugUtils.h"
#include "llvm/ExecutionEngine/Orc/Debugging/DebuggerSupport.h"
#include "llvm/ExecutionEngine/Orc/EPCDynamicLibrarySearchGenerator.h"
#include "llvm/ExecutionEngine/Orc/EPCEHFrameRegistrar.h"
#include "llvm/ExecutionEngine/Orc/EPCGenericRTDyldMemoryManager.h"
#include "llvm/ExecutionEngine/Orc/ExecutionUtils.h"
#include "llvm/ExecutionEngine/Orc/JITTargetMachineBuilder.h"
#include "llvm/ExecutionEngine/Orc/LLJIT.h"
#include "llvm/ExecutionEngine/Orc/ObjectTransformLayer.h"
#include "llvm/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.h"
#include "llvm/ExecutionEngine/Orc/SimpleRemoteEPC.h"
#include "llvm/ExecutionEngine/Orc/SymbolStringPool.h"
#include "llvm/ExecutionEngine/Orc/TargetProcess/JITLoaderGDB.h"
#include "llvm/ExecutionEngine/Orc/TargetProcess/RegisterEHFrames.h"
#include "llvm/ExecutionEngine/Orc/TargetProcess/TargetExecutionUtils.h"
#include "llvm/ExecutionEngine/SectionMemoryManager.h"
#include "llvm/IR/IRBuilder.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/Module.h"
#include "llvm/IR/Type.h"
#include "llvm/IR/Verifier.h"
#include "llvm/IRReader/IRReader.h"
#include "llvm/Object/Archive.h"
#include "llvm/Object/ObjectFile.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/DynamicLibrary.h"
#include "llvm/Support/Format.h"
#include "llvm/Support/InitLLVM.h"
#include "llvm/Support/MathExtras.h"
#include "llvm/Support/Memory.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/PluginLoader.h"
#include "llvm/Support/Process.h"
#include "llvm/Support/Program.h"
#include "llvm/Support/SourceMgr.h"
#include "llvm/Support/TargetSelect.h"
#include "llvm/Support/ToolOutputFile.h"
#include "llvm/Support/WithColor.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/TargetParser/Triple.h"
#include <cerrno>
#include <optional>
#if !defined(_MSC_VER) && !defined(__MINGW32__)
#include <unistd.h>
#else
#include <io.h>
#endif
#ifdef __CYGWIN__
#include <cygwin/version.h>
#if defined(CYGWIN_VERSION_DLL_MAJOR) && CYGWIN_VERSION_DLL_MAJOR<1007
#define DO_NOTHING_ATEXIT …
#endif
#endif
usingnamespacellvm;
static codegen::RegisterCodeGenFlags CGF;
#define DEBUG_TYPE …
namespace {
enum class JITKind { … };
enum class JITLinkerKind { … };
cl::opt<std::string>
InputFile(cl::desc("<input bitcode>"), cl::Positional, cl::init("-"));
cl::list<std::string>
InputArgv(cl::ConsumeAfter, cl::desc("<program arguments>..."));
cl::opt<bool> ForceInterpreter("force-interpreter",
cl::desc("Force interpretation: disable JIT"),
cl::init(false));
cl::opt<JITKind> UseJITKind(
"jit-kind", cl::desc("Choose underlying JIT kind."),
cl::init(JITKind::Orc),
cl::values(clEnumValN(JITKind::MCJIT, "mcjit", "MCJIT"),
clEnumValN(JITKind::Orc, "orc", "Orc JIT"),
clEnumValN(JITKind::OrcLazy, "orc-lazy",
"Orc-based lazy JIT.")));
cl::opt<JITLinkerKind>
JITLinker("jit-linker", cl::desc("Choose the dynamic linker/loader."),
cl::init(JITLinkerKind::Default),
cl::values(clEnumValN(JITLinkerKind::Default, "default",
"Default for platform and JIT-kind"),
clEnumValN(JITLinkerKind::RuntimeDyld, "rtdyld",
"RuntimeDyld"),
clEnumValN(JITLinkerKind::JITLink, "jitlink",
"Orc-specific linker")));
cl::opt<std::string> OrcRuntime("orc-runtime",
cl::desc("Use ORC runtime from given path"),
cl::init(""));
cl::opt<unsigned>
LazyJITCompileThreads("compile-threads",
cl::desc("Choose the number of compile threads "
"(jit-kind=orc-lazy only)"),
cl::init(0));
cl::list<std::string>
ThreadEntryPoints("thread-entry",
cl::desc("calls the given entry-point on a new thread "
"(jit-kind=orc-lazy only)"));
cl::opt<bool> PerModuleLazy(
"per-module-lazy",
cl::desc("Performs lazy compilation on whole module boundaries "
"rather than individual functions"),
cl::init(false));
cl::list<std::string>
JITDylibs("jd",
cl::desc("Specifies the JITDylib to be used for any subsequent "
"-extra-module arguments."));
cl::list<std::string>
Dylibs("dlopen", cl::desc("Dynamic libraries to load before linking"));
cl::opt<bool> RemoteMCJIT("remote-mcjit",
cl::desc("Execute MCJIT'ed code in a separate process."),
cl::init(false));
cl::opt<std::string>
ChildExecPath("mcjit-remote-process",
cl::desc("Specify the filename of the process to launch "
"for remote MCJIT execution. If none is specified,"
"\n\tremote execution will be simulated in-process."),
cl::value_desc("filename"), cl::init(""));
cl::opt<char> OptLevel("O",
cl::desc("Optimization level. [-O0, -O1, -O2, or -O3] "
"(default = '-O2')"),
cl::Prefix, cl::init('2'));
cl::opt<std::string>
TargetTriple("mtriple", cl::desc("Override target triple for module"));
cl::opt<std::string>
EntryFunc("entry-function",
cl::desc("Specify the entry function (default = 'main') "
"of the executable"),
cl::value_desc("function"),
cl::init("main"));
cl::list<std::string>
ExtraModules("extra-module",
cl::desc("Extra modules to be loaded"),
cl::value_desc("input bitcode"));
cl::list<std::string>
ExtraObjects("extra-object",
cl::desc("Extra object files to be loaded"),
cl::value_desc("input object"));
cl::list<std::string>
ExtraArchives("extra-archive",
cl::desc("Extra archive files to be loaded"),
cl::value_desc("input archive"));
cl::opt<bool>
EnableCacheManager("enable-cache-manager",
cl::desc("Use cache manager to save/load modules"),
cl::init(false));
cl::opt<std::string>
ObjectCacheDir("object-cache-dir",
cl::desc("Directory to store cached object files "
"(must be user writable)"),
cl::init(""));
cl::opt<std::string>
FakeArgv0("fake-argv0",
cl::desc("Override the 'argv[0]' value passed into the executing"
" program"), cl::value_desc("executable"));
cl::opt<bool>
DisableCoreFiles("disable-core-files", cl::Hidden,
cl::desc("Disable emission of core files if possible"));
cl::opt<bool>
NoLazyCompilation("disable-lazy-compilation",
cl::desc("Disable JIT lazy compilation"),
cl::init(false));
cl::opt<bool>
GenerateSoftFloatCalls("soft-float",
cl::desc("Generate software floating point library calls"),
cl::init(false));
cl::opt<bool> NoProcessSymbols(
"no-process-syms",
cl::desc("Do not resolve lli process symbols in JIT'd code"),
cl::init(false));
enum class LLJITPlatform { … };
cl::opt<LLJITPlatform> Platform(
"lljit-platform", cl::desc("Platform to use with LLJIT"),
cl::init(LLJITPlatform::Auto),
cl::values(clEnumValN(LLJITPlatform::Auto, "Auto",
"Like 'ExecutorNative' if ORC runtime "
"provided, otherwise like 'GenericIR'"),
clEnumValN(LLJITPlatform::ExecutorNative, "ExecutorNative",
"Use the native platform for the executor."
"Requires -orc-runtime"),
clEnumValN(LLJITPlatform::GenericIR, "GenericIR",
"Use LLJITGenericIRPlatform"),
clEnumValN(LLJITPlatform::Inactive, "Inactive",
"Disable platform support explicitly")),
cl::Hidden);
enum class DumpKind { … };
cl::opt<DumpKind> OrcDumpKind(
"orc-lazy-debug", cl::desc("Debug dumping for the orc-lazy JIT."),
cl::init(DumpKind::NoDump),
cl::values(
clEnumValN(DumpKind::NoDump, "no-dump", "Don't dump anything."),
clEnumValN(DumpKind::DumpFuncsToStdOut, "funcs-to-stdout",
"Dump function names to stdout."),
clEnumValN(DumpKind::DumpModsToStdOut, "mods-to-stdout",
"Dump modules to stdout."),
clEnumValN(DumpKind::DumpModsToDisk, "mods-to-disk",
"Dump modules to the current "
"working directory. (WARNING: "
"will overwrite existing files)."),
clEnumValN(DumpKind::DumpDebugDescriptor, "jit-debug-descriptor",
"Dump __jit_debug_descriptor contents to stdout"),
clEnumValN(DumpKind::DumpDebugObjects, "jit-debug-objects",
"Dump __jit_debug_descriptor in-memory debug "
"objects as tool output")),
cl::Hidden);
ExitOnError ExitOnErr;
}
LLVM_ATTRIBUTE_USED void linkComponents() { … }
class LLIObjectCache : public ObjectCache { … };
static void addCygMingExtraModule(ExecutionEngine &EE, LLVMContext &Context,
StringRef TargetTripleStr) { … }
CodeGenOptLevel getOptLevel() { … }
[[noreturn]] static void reportError(SMDiagnostic Err, const char *ProgName) { … }
Error loadDylibs();
int runOrcJIT(const char *ProgName);
void disallowOrcOptions();
Expected<std::unique_ptr<orc::ExecutorProcessControl>> launchRemote();
int main(int argc, char **argv, char * const *envp) { … }
extern "C" struct jit_descriptor __jit_debug_descriptor;
static struct jit_code_entry *
findNextDebugDescriptorEntry(struct jit_code_entry *Latest) { … }
static ToolOutputFile &claimToolOutput() { … }
static std::function<void(Module &)> createIRDebugDumper() { … }
static std::function<void(MemoryBuffer &)> createObjDebugDumper() { … }
Error loadDylibs() { … }
static void exitOnLazyCallThroughFailure() { … }
Expected<orc::ThreadSafeModule>
loadModule(StringRef Path, orc::ThreadSafeContext TSCtx) { … }
int mingw_noop_main(void) { … }
Error tryEnableDebugSupport(orc::LLJIT &J) { … }
int runOrcJIT(const char *ProgName) { … }
void disallowOrcOptions() { … }
Expected<std::unique_ptr<orc::ExecutorProcessControl>> launchRemote() { … }
#ifdef __MINGW32__
#if defined(__i386__)
#undef _alloca
extern "C" void _alloca(void);
static __attribute__((used)) void (*const ref_func)(void) = _alloca;
static __attribute__((section(".drectve"), used)) const char export_chkstk[] =
"-export:_alloca";
#elif defined(__x86_64__)
extern "C" void ___chkstk_ms(void);
static __attribute__((used)) void (*const ref_func)(void) = ___chkstk_ms;
static __attribute__((section(".drectve"), used)) const char export_chkstk[] =
"-export:___chkstk_ms";
#else
extern "C" void __chkstk(void);
static __attribute__((used)) void (*const ref_func)(void) = __chkstk;
static __attribute__((section(".drectve"), used)) const char export_chkstk[] =
"-export:__chkstk";
#endif
#endif