#include "llvm-jitlink.h"
#include "llvm/BinaryFormat/Magic.h"
#include "llvm/Config/llvm-config.h"
#include "llvm/ExecutionEngine/Orc/COFFPlatform.h"
#include "llvm/ExecutionEngine/Orc/COFFVCRuntimeSupport.h"
#include "llvm/ExecutionEngine/Orc/DebugObjectManagerPlugin.h"
#include "llvm/ExecutionEngine/Orc/Debugging/DebugInfoSupport.h"
#include "llvm/ExecutionEngine/Orc/Debugging/DebuggerSupportPlugin.h"
#include "llvm/ExecutionEngine/Orc/Debugging/PerfSupportPlugin.h"
#include "llvm/ExecutionEngine/Orc/Debugging/VTuneSupportPlugin.h"
#include "llvm/ExecutionEngine/Orc/ELFNixPlatform.h"
#include "llvm/ExecutionEngine/Orc/EPCDebugObjectRegistrar.h"
#include "llvm/ExecutionEngine/Orc/EPCDynamicLibrarySearchGenerator.h"
#include "llvm/ExecutionEngine/Orc/EPCEHFrameRegistrar.h"
#include "llvm/ExecutionEngine/Orc/ExecutionUtils.h"
#include "llvm/ExecutionEngine/Orc/IndirectionUtils.h"
#include "llvm/ExecutionEngine/Orc/JITTargetMachineBuilder.h"
#include "llvm/ExecutionEngine/Orc/LoadLinkableFile.h"
#include "llvm/ExecutionEngine/Orc/MachOPlatform.h"
#include "llvm/ExecutionEngine/Orc/MapperJITLinkMemoryManager.h"
#include "llvm/ExecutionEngine/Orc/ObjectFileInterface.h"
#include "llvm/ExecutionEngine/Orc/SectCreate.h"
#include "llvm/ExecutionEngine/Orc/Shared/OrcRTBridge.h"
#include "llvm/ExecutionEngine/Orc/TargetProcess/JITLoaderGDB.h"
#include "llvm/ExecutionEngine/Orc/TargetProcess/JITLoaderPerf.h"
#include "llvm/ExecutionEngine/Orc/TargetProcess/JITLoaderVTune.h"
#include "llvm/ExecutionEngine/Orc/TargetProcess/RegisterEHFrames.h"
#include "llvm/MC/MCAsmInfo.h"
#include "llvm/MC/MCContext.h"
#include "llvm/MC/MCDisassembler/MCDisassembler.h"
#include "llvm/MC/MCInstPrinter.h"
#include "llvm/MC/MCInstrAnalysis.h"
#include "llvm/MC/MCInstrInfo.h"
#include "llvm/MC/MCRegisterInfo.h"
#include "llvm/MC/MCSubtargetInfo.h"
#include "llvm/MC/MCTargetOptions.h"
#include "llvm/MC/TargetRegistry.h"
#include "llvm/Object/COFF.h"
#include "llvm/Object/MachO.h"
#include "llvm/Object/ObjectFile.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/InitLLVM.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/Process.h"
#include "llvm/Support/TargetSelect.h"
#include "llvm/Support/Timer.h"
#include <cstring>
#include <deque>
#include <string>
#ifdef LLVM_ON_UNIX
#include <netdb.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <unistd.h>
#endif
#define DEBUG_TYPE …
usingnamespacellvm;
usingnamespacellvm::jitlink;
usingnamespacellvm::orc;
static cl::OptionCategory JITLinkCategory("JITLink Options");
static cl::list<std::string> InputFiles(cl::Positional, cl::OneOrMore,
cl::desc("input files"),
cl::cat(JITLinkCategory));
static cl::list<std::string>
LibrarySearchPaths("L",
cl::desc("Add dir to the list of library search paths"),
cl::Prefix, cl::cat(JITLinkCategory));
static cl::list<std::string>
Libraries("l",
cl::desc("Link against library X in the library search paths"),
cl::Prefix, cl::cat(JITLinkCategory));
static cl::list<std::string>
LibrariesHidden("hidden-l",
cl::desc("Link against library X in the library search "
"paths with hidden visibility"),
cl::Prefix, cl::cat(JITLinkCategory));
static cl::list<std::string>
LoadHidden("load_hidden",
cl::desc("Link against library X with hidden visibility"),
cl::cat(JITLinkCategory));
static cl::opt<bool> SearchSystemLibrary(
"search-sys-lib",
cl::desc("Add system library paths to library search paths"),
cl::init(false), cl::cat(JITLinkCategory));
static cl::opt<bool> NoExec("noexec", cl::desc("Do not execute loaded code"),
cl::init(false), cl::cat(JITLinkCategory));
static cl::list<std::string>
CheckFiles("check", cl::desc("File containing verifier checks"),
cl::cat(JITLinkCategory));
static cl::opt<std::string>
CheckName("check-name", cl::desc("Name of checks to match against"),
cl::init("jitlink-check"), cl::cat(JITLinkCategory));
static cl::opt<std::string>
EntryPointName("entry", cl::desc("Symbol to call as main entry point"),
cl::init(""), cl::cat(JITLinkCategory));
static cl::list<std::string> JITDylibs(
"jd",
cl::desc("Specifies the JITDylib to be used for any subsequent "
"input file, -L<seacrh-path>, and -l<library> arguments"),
cl::cat(JITLinkCategory));
static cl::list<std::string>
Dylibs("preload",
cl::desc("Pre-load dynamic libraries (e.g. language runtimes "
"required by the ORC runtime)"),
cl::cat(JITLinkCategory));
static cl::list<std::string> InputArgv("args", cl::Positional,
cl::desc("<program arguments>..."),
cl::PositionalEatsArgs,
cl::cat(JITLinkCategory));
static cl::opt<bool>
DebuggerSupport("debugger-support",
cl::desc("Enable debugger suppport (default = !-noexec)"),
cl::init(true), cl::Hidden, cl::cat(JITLinkCategory));
static cl::opt<bool> PerfSupport("perf-support",
cl::desc("Enable perf profiling support"),
cl::init(false), cl::Hidden,
cl::cat(JITLinkCategory));
static cl::opt<bool> VTuneSupport("vtune-support",
cl::desc("Enable vtune profiling support"),
cl::init(false), cl::Hidden,
cl::cat(JITLinkCategory));
static cl::opt<bool>
NoProcessSymbols("no-process-syms",
cl::desc("Do not resolve to llvm-jitlink process symbols"),
cl::init(false), cl::cat(JITLinkCategory));
static cl::list<std::string> AbsoluteDefs(
"abs",
cl::desc("Inject absolute symbol definitions (syntax: <name>=<addr>)"),
cl::cat(JITLinkCategory));
static cl::list<std::string>
Aliases("alias",
cl::desc("Inject symbol aliases (syntax: <alias-name>=<aliasee>)"),
cl::cat(JITLinkCategory));
static cl::list<std::string>
SectCreate("sectcreate",
cl::desc("given <sectname>,<filename>[@<sym>=<offset>,...] "
"add the content of <filename> to <sectname>"),
cl::cat(JITLinkCategory));
static cl::list<std::string> TestHarnesses("harness", cl::Positional,
cl::desc("Test harness files"),
cl::PositionalEatsArgs,
cl::cat(JITLinkCategory));
static cl::opt<bool> ShowInitialExecutionSessionState(
"show-init-es",
cl::desc("Print ExecutionSession state before resolving entry point"),
cl::init(false), cl::cat(JITLinkCategory));
static cl::opt<bool> ShowEntryExecutionSessionState(
"show-entry-es",
cl::desc("Print ExecutionSession state after resolving entry point"),
cl::init(false), cl::cat(JITLinkCategory));
static cl::opt<bool> ShowAddrs(
"show-addrs",
cl::desc("Print registered symbol, section, got and stub addresses"),
cl::init(false), cl::cat(JITLinkCategory));
static cl::opt<std::string> ShowLinkGraphs(
"show-graphs",
cl::desc("Takes a posix regex and prints the link graphs of all files "
"matching that regex after fixups have been applied"),
cl::Optional, cl::cat(JITLinkCategory));
static cl::opt<bool> ShowTimes("show-times",
cl::desc("Show times for llvm-jitlink phases"),
cl::init(false), cl::cat(JITLinkCategory));
static cl::opt<std::string> SlabAllocateSizeString(
"slab-allocate",
cl::desc("Allocate from a slab of the given size "
"(allowable suffixes: Kb, Mb, Gb. default = "
"Kb)"),
cl::init(""), cl::cat(JITLinkCategory));
static cl::opt<uint64_t> SlabAddress(
"slab-address",
cl::desc("Set slab target address (requires -slab-allocate and -noexec)"),
cl::init(~0ULL), cl::cat(JITLinkCategory));
static cl::opt<uint64_t> SlabPageSize(
"slab-page-size",
cl::desc("Set page size for slab (requires -slab-allocate and -noexec)"),
cl::init(0), cl::cat(JITLinkCategory));
static cl::opt<bool> ShowRelocatedSectionContents(
"show-relocated-section-contents",
cl::desc("show section contents after fixups have been applied"),
cl::init(false), cl::cat(JITLinkCategory));
static cl::opt<bool> PhonyExternals(
"phony-externals",
cl::desc("resolve all otherwise unresolved externals to null"),
cl::init(false), cl::cat(JITLinkCategory));
static cl::opt<std::string> OutOfProcessExecutor(
"oop-executor", cl::desc("Launch an out-of-process executor to run code"),
cl::ValueOptional, cl::cat(JITLinkCategory));
static cl::opt<std::string> OutOfProcessExecutorConnect(
"oop-executor-connect",
cl::desc("Connect to an out-of-process executor via TCP"),
cl::cat(JITLinkCategory));
static cl::opt<std::string>
OrcRuntime("orc-runtime", cl::desc("Use ORC runtime from given path"),
cl::init(""), cl::cat(JITLinkCategory));
static cl::opt<bool> AddSelfRelocations(
"add-self-relocations",
cl::desc("Add relocations to function pointers to the current function"),
cl::init(false), cl::cat(JITLinkCategory));
static cl::opt<bool>
ShowErrFailedToMaterialize("show-err-failed-to-materialize",
cl::desc("Show FailedToMaterialize errors"),
cl::init(false), cl::cat(JITLinkCategory));
static cl::opt<bool> UseSharedMemory(
"use-shared-memory",
cl::desc("Use shared memory to transfer generated code and data"),
cl::init(false), cl::cat(JITLinkCategory));
static cl::opt<std::string>
OverrideTriple("triple", cl::desc("Override target triple detection"),
cl::init(""), cl::cat(JITLinkCategory));
static ExitOnError ExitOnErr;
static LLVM_ATTRIBUTE_USED void linkComponents() { … }
static bool UseTestResultOverride = …;
static int64_t TestResultOverride = …;
extern "C" LLVM_ATTRIBUTE_USED void
llvm_jitlink_setTestResultOverride(int64_t Value) { … }
static Error addSelfRelocations(LinkGraph &G);
namespace {
template <typename ErrT>
class ConditionalPrintErr { … };
Expected<std::unique_ptr<MemoryBuffer>> getFile(const Twine &FileName) { … }
void reportLLVMJITLinkError(Error Err) { … }
}
namespace llvm {
static raw_ostream &
operator<<(raw_ostream &OS, const Session::MemoryRegionInfo &MRI) { … }
static raw_ostream &
operator<<(raw_ostream &OS, const Session::SymbolInfoMap &SIM) { … }
static raw_ostream &
operator<<(raw_ostream &OS, const Session::FileInfo &FI) { … }
static raw_ostream &
operator<<(raw_ostream &OS, const Session::FileInfoMap &FIM) { … }
static Error applyHarnessPromotions(Session &S, LinkGraph &G) { … }
static void dumpSectionContents(raw_ostream &OS, LinkGraph &G) { … }
class InProcessDeltaMapper final : public InProcessMemoryMapper { … };
Expected<uint64_t> getSlabAllocSize(StringRef SizeString) { … }
static std::unique_ptr<JITLinkMemoryManager> createInProcessMemoryManager() { … }
Expected<std::unique_ptr<jitlink::JITLinkMemoryManager>>
createSharedMemoryManager(SimpleRemoteEPC &SREPC) { … }
static Expected<MaterializationUnit::Interface>
getTestObjectFileInterface(Session &S, MemoryBufferRef O) { … }
static Error loadProcessSymbols(Session &S) { … }
static Error loadDylibs(Session &S) { … }
static Expected<std::unique_ptr<ExecutorProcessControl>> launchExecutor() { … }
#if LLVM_ON_UNIX && LLVM_ENABLE_THREADS
static Error createTCPSocketError(Twine Details) { … }
static Expected<int> connectTCPSocket(std::string Host, std::string PortStr) { … }
#endif
static Expected<std::unique_ptr<ExecutorProcessControl>> connectToExecutor() { … }
class PhonyExternalsGenerator : public DefinitionGenerator { … };
Expected<std::unique_ptr<Session>> Session::Create(Triple TT,
SubtargetFeatures Features) { … }
Session::~Session() { … }
Session::Session(std::unique_ptr<ExecutorProcessControl> EPC, Error &Err)
: … { … }
void Session::dumpSessionInfo(raw_ostream &OS) { … }
void Session::modifyPassConfig(const Triple &TT,
PassConfiguration &PassConfig) { … }
Expected<JITDylib *> Session::getOrLoadDynamicLibrary(StringRef LibPath) { … }
Error Session::loadAndLinkDynamicLibrary(JITDylib &JD, StringRef LibPath) { … }
Error Session::FileInfo::registerGOTEntry(
LinkGraph &G, Symbol &Sym, GetSymbolTargetFunction GetSymbolTarget) { … }
Error Session::FileInfo::registerStubEntry(
LinkGraph &G, Symbol &Sym, GetSymbolTargetFunction GetSymbolTarget) { … }
Error Session::FileInfo::registerMultiStubEntry(
LinkGraph &G, Symbol &Sym, GetSymbolTargetFunction GetSymbolTarget) { … }
Expected<Session::FileInfo &> Session::findFileInfo(StringRef FileName) { … }
Expected<Session::MemoryRegionInfo &>
Session::findSectionInfo(StringRef FileName, StringRef SectionName) { … }
class MemoryMatcher { … };
static StringRef detectStubKind(const Session::MemoryRegionInfo &Stub) { … }
Expected<Session::MemoryRegionInfo &>
Session::findStubInfo(StringRef FileName, StringRef TargetName,
StringRef KindNameFilter) { … }
Expected<Session::MemoryRegionInfo &>
Session::findGOTEntryInfo(StringRef FileName, StringRef TargetName) { … }
bool Session::isSymbolRegistered(StringRef SymbolName) { … }
Expected<Session::MemoryRegionInfo &>
Session::findSymbolInfo(StringRef SymbolName, Twine ErrorMsgStem) { … }
}
static std::pair<Triple, SubtargetFeatures> getFirstFileTripleAndFeatures() { … }
static Error sanitizeArguments(const Triple &TT, const char *ArgV0) { … }
static void addPhonyExternalsGenerator(Session &S) { … }
static Error createJITDylibs(Session &S,
std::map<unsigned, JITDylib *> &IdxToJD) { … }
static Error addAbsoluteSymbols(Session &S,
const std::map<unsigned, JITDylib *> &IdxToJD) { … }
static Error addAliases(Session &S,
const std::map<unsigned, JITDylib *> &IdxToJD) { … }
static Error addSectCreates(Session &S,
const std::map<unsigned, JITDylib *> &IdxToJD) { … }
static Error addTestHarnesses(Session &S) { … }
static Error addObjects(Session &S,
const std::map<unsigned, JITDylib *> &IdxToJD) { … }
static Expected<MaterializationUnit::Interface>
getObjectFileInterfaceHidden(ExecutionSession &ES, MemoryBufferRef ObjBuffer) { … }
static SmallVector<StringRef, 5> getSearchPathsFromEnvVar(Session &S) { … }
static Error addLibraries(Session &S,
const std::map<unsigned, JITDylib *> &IdxToJD) { … }
static Error addSessionInputs(Session &S) { … }
namespace {
struct TargetInfo { … };
}
static TargetInfo
getTargetInfo(const Triple &TT,
const SubtargetFeatures &TF = SubtargetFeatures()) { … }
static Error runChecks(Session &S, Triple TT, SubtargetFeatures Features) { … }
static Error addSelfRelocations(LinkGraph &G) { … }
static Expected<ExecutorSymbolDef> getMainEntryPoint(Session &S) { … }
static Expected<ExecutorSymbolDef> getOrcRuntimeEntryPoint(Session &S) { … }
static Expected<ExecutorSymbolDef> getEntryPoint(Session &S) { … }
static Expected<int> runWithRuntime(Session &S, ExecutorAddr EntryPointAddr) { … }
static Expected<int> runWithoutRuntime(Session &S,
ExecutorAddr EntryPointAddr) { … }
namespace {
struct JITLinkTimers { … };
}
int main(int argc, char *argv[]) { … }