//===---- llvm-jitlink.h - Session and format-specific decls ----*- C++ -*-===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // // llvm-jitlink Session class and tool utilities. // //===----------------------------------------------------------------------===// #ifndef LLVM_TOOLS_LLVM_JITLINK_LLVM_JITLINK_H #define LLVM_TOOLS_LLVM_JITLINK_LLVM_JITLINK_H #include "llvm/ADT/StringSet.h" #include "llvm/ExecutionEngine/Orc/COFF.h" #include "llvm/ExecutionEngine/Orc/Core.h" #include "llvm/ExecutionEngine/Orc/ExecutorProcessControl.h" #include "llvm/ExecutionEngine/Orc/LazyObjectLinkingLayer.h" #include "llvm/ExecutionEngine/Orc/LazyReexports.h" #include "llvm/ExecutionEngine/Orc/ObjectLinkingLayer.h" #include "llvm/ExecutionEngine/Orc/RedirectionManager.h" #include "llvm/ExecutionEngine/Orc/SimpleRemoteEPC.h" #include "llvm/ExecutionEngine/RuntimeDyldChecker.h" #include "llvm/Support/Error.h" #include "llvm/Support/Regex.h" #include "llvm/Support/raw_ostream.h" #include "llvm/TargetParser/SubtargetFeature.h" #include "llvm/TargetParser/Triple.h" namespace llvm { struct Session { struct LazyLinkingSupport { LazyLinkingSupport( std::unique_ptr RSMgr, std::shared_ptr Speculator, std::unique_ptr LRMgr, orc::ObjectLinkingLayer &ObjLinkingLayer) : RSMgr(std::move(RSMgr)), Speculator(std::move(Speculator)), LRMgr(std::move(LRMgr)), LazyObjLinkingLayer(ObjLinkingLayer, *this->LRMgr) {} std::unique_ptr RSMgr; std::shared_ptr Speculator; std::unique_ptr LRMgr; orc::LazyObjectLinkingLayer LazyObjLinkingLayer; }; orc::ExecutionSession ES; orc::JITDylib *MainJD = nullptr; orc::JITDylib *ProcessSymsJD = nullptr; orc::JITDylib *PlatformJD = nullptr; orc::ObjectLinkingLayer ObjLayer; std::unique_ptr LazyLinking; orc::JITDylibSearchOrder JDSearchOrder; SubtargetFeatures Features; std::vector> LazyFnExecOrder; ~Session(); static Expected> Create(Triple TT, SubtargetFeatures Features); void dumpSessionInfo(raw_ostream &OS); void modifyPassConfig(jitlink::LinkGraph &G, jitlink::PassConfiguration &PassConfig); /// For -check: wait for all files that are referenced (transitively) from /// the entry point *file* to be linked. (ORC's usual dependence tracking is /// to fine-grained here: a lookup of the main symbol will return as soon as /// all reachable symbols have been linked, but testcases may want to /// inspect side-effects in unreachable symbols).. void waitForFilesLinkedFromEntryPointFile() { std::unique_lock Lock(M); return ActiveLinksCV.wait(Lock, [this]() { return ActiveLinks == 0; }); } using MemoryRegionInfo = RuntimeDyldChecker::MemoryRegionInfo; struct FileInfo { StringMap SectionInfos; StringMap> StubInfos; StringMap GOTEntryInfos; using Symbol = jitlink::Symbol; using LinkGraph = jitlink::LinkGraph; using GetSymbolTargetFunction = unique_function(LinkGraph &G, jitlink::Block &)>; Error registerGOTEntry(LinkGraph &G, Symbol &Sym, GetSymbolTargetFunction GetSymbolTarget); Error registerStubEntry(LinkGraph &G, Symbol &Sym, GetSymbolTargetFunction GetSymbolTarget); Error registerMultiStubEntry(LinkGraph &G, Symbol &Sym, GetSymbolTargetFunction GetSymbolTarget); }; using DynLibJDMap = std::map>; using SymbolInfoMap = DenseMap; using FileInfoMap = StringMap; Expected getOrLoadDynamicLibrary(StringRef LibPath); Error loadAndLinkDynamicLibrary(orc::JITDylib &JD, StringRef LibPath); orc::ObjectLayer &getLinkLayer(bool Lazy) { assert((!Lazy || LazyLinking) && "Lazy linking requested but not available"); return Lazy ? static_cast( LazyLinking->LazyObjLinkingLayer) : static_cast(ObjLayer); } Expected findFileInfo(StringRef FileName); Expected findSectionInfo(StringRef FileName, StringRef SectionName); Expected findStubInfo(StringRef FileName, StringRef TargetName, StringRef KindNameFilter); Expected findGOTEntryInfo(StringRef FileName, StringRef TargetName); bool isSymbolRegistered(const orc::SymbolStringPtr &Name); Expected findSymbolInfo(const orc::SymbolStringPtr &Name, Twine ErrorMsgStem); DynLibJDMap DynLibJDs; std::mutex M; std::condition_variable ActiveLinksCV; size_t ActiveLinks = 0; SymbolInfoMap SymbolInfos; FileInfoMap FileInfos; StringSet<> HarnessFiles; StringSet<> HarnessExternals; StringSet<> HarnessDefinitions; DenseMap CanonicalWeakDefs; StringSet<> HiddenArchives; std::optional ShowGraphsRegex; private: Session(std::unique_ptr EPC, Error &Err); }; /// Record symbols, GOT entries, stubs, and sections for ELF file. Error registerELFGraphInfo(Session &S, jitlink::LinkGraph &G); /// Record symbols, GOT entries, stubs, and sections for MachO file. Error registerMachOGraphInfo(Session &S, jitlink::LinkGraph &G); /// Record symbols, GOT entries, stubs, and sections for COFF file. Error registerCOFFGraphInfo(Session &S, jitlink::LinkGraph &G); /// Adds a statistics gathering plugin if any stats options are used. void enableStatistics(Session &S, bool UsingOrcRuntime); } // end namespace llvm #endif // LLVM_TOOLS_LLVM_JITLINK_LLVM_JITLINK_H