1 //===---- llvm-jitlink.h - Session and format-specific decls ----*- C++ -*-===// 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-exception 6 // 7 //===----------------------------------------------------------------------===// 8 // 9 // llvm-jitlink Session class and tool utilities. 10 // 11 //===----------------------------------------------------------------------===// 12 13 #ifndef LLVM_TOOLS_LLVM_JITLINK_LLVM_JITLINK_H 14 #define LLVM_TOOLS_LLVM_JITLINK_LLVM_JITLINK_H 15 16 #include "llvm/ADT/StringSet.h" 17 #include "llvm/ExecutionEngine/Orc/Core.h" 18 #include "llvm/ExecutionEngine/Orc/ExecutorProcessControl.h" 19 #include "llvm/ExecutionEngine/Orc/LazyObjectLinkingLayer.h" 20 #include "llvm/ExecutionEngine/Orc/LazyReexports.h" 21 #include "llvm/ExecutionEngine/Orc/ObjectLinkingLayer.h" 22 #include "llvm/ExecutionEngine/Orc/RedirectionManager.h" 23 #include "llvm/ExecutionEngine/Orc/SimpleRemoteEPC.h" 24 #include "llvm/ExecutionEngine/RuntimeDyldChecker.h" 25 #include "llvm/Support/Error.h" 26 #include "llvm/Support/Regex.h" 27 #include "llvm/Support/raw_ostream.h" 28 #include "llvm/TargetParser/SubtargetFeature.h" 29 #include "llvm/TargetParser/Triple.h" 30 31 namespace llvm { 32 33 struct Session { 34 35 struct LazyLinkingSupport { 36 LazyLinkingSupport( 37 std::unique_ptr<orc::RedirectableSymbolManager> RSMgr, 38 std::shared_ptr<orc::SimpleLazyReexportsSpeculator> Speculator, 39 std::unique_ptr<orc::LazyReexportsManager> LRMgr, 40 orc::ObjectLinkingLayer &ObjLinkingLayer) 41 : RSMgr(std::move(RSMgr)), Speculator(std::move(Speculator)), 42 LRMgr(std::move(LRMgr)), 43 LazyObjLinkingLayer(ObjLinkingLayer, *this->LRMgr) {} 44 45 std::unique_ptr<orc::RedirectableSymbolManager> RSMgr; 46 std::shared_ptr<orc::SimpleLazyReexportsSpeculator> Speculator; 47 std::unique_ptr<orc::LazyReexportsManager> LRMgr; 48 orc::LazyObjectLinkingLayer LazyObjLinkingLayer; 49 }; 50 51 orc::ExecutionSession ES; 52 orc::JITDylib *MainJD = nullptr; 53 orc::JITDylib *ProcessSymsJD = nullptr; 54 orc::JITDylib *PlatformJD = nullptr; 55 orc::ObjectLinkingLayer ObjLayer; 56 std::unique_ptr<LazyLinkingSupport> LazyLinking; 57 orc::JITDylibSearchOrder JDSearchOrder; 58 SubtargetFeatures Features; 59 std::vector<std::pair<std::string, orc::SymbolStringPtr>> LazyFnExecOrder; 60 61 ~Session(); 62 63 static Expected<std::unique_ptr<Session>> Create(Triple TT, 64 SubtargetFeatures Features); 65 void dumpSessionInfo(raw_ostream &OS); 66 void modifyPassConfig(jitlink::LinkGraph &G, 67 jitlink::PassConfiguration &PassConfig); 68 69 /// For -check: wait for all files that are referenced (transitively) from 70 /// the entry point *file* to be linked. (ORC's usual dependence tracking is 71 /// to fine-grained here: a lookup of the main symbol will return as soon as 72 /// all reachable symbols have been linked, but testcases may want to 73 /// inspect side-effects in unreachable symbols).. 74 void waitForFilesLinkedFromEntryPointFile() { 75 std::unique_lock<std::mutex> Lock(M); 76 return ActiveLinksCV.wait(Lock, [this]() { return ActiveLinks == 0; }); 77 } 78 79 using MemoryRegionInfo = RuntimeDyldChecker::MemoryRegionInfo; 80 81 struct FileInfo { 82 StringMap<MemoryRegionInfo> SectionInfos; 83 StringMap<SmallVector<MemoryRegionInfo, 1>> StubInfos; 84 StringMap<MemoryRegionInfo> GOTEntryInfos; 85 86 using Symbol = jitlink::Symbol; 87 using LinkGraph = jitlink::LinkGraph; 88 using GetSymbolTargetFunction = 89 unique_function<Expected<Symbol &>(LinkGraph &G, jitlink::Block &)>; 90 Error registerGOTEntry(LinkGraph &G, Symbol &Sym, 91 GetSymbolTargetFunction GetSymbolTarget); 92 Error registerStubEntry(LinkGraph &G, Symbol &Sym, 93 GetSymbolTargetFunction GetSymbolTarget); 94 Error registerMultiStubEntry(LinkGraph &G, Symbol &Sym, 95 GetSymbolTargetFunction GetSymbolTarget); 96 }; 97 98 using DynLibJDMap = std::map<std::string, orc::JITDylib *, std::less<>>; 99 using SymbolInfoMap = DenseMap<orc::SymbolStringPtr, MemoryRegionInfo>; 100 using FileInfoMap = StringMap<FileInfo>; 101 102 Expected<orc::JITDylib *> getOrLoadDynamicLibrary(StringRef LibPath); 103 Error loadAndLinkDynamicLibrary(orc::JITDylib &JD, StringRef LibPath); 104 105 orc::ObjectLayer &getLinkLayer(bool Lazy) { 106 assert((!Lazy || LazyLinking) && 107 "Lazy linking requested but not available"); 108 return Lazy ? static_cast<orc::ObjectLayer &>( 109 LazyLinking->LazyObjLinkingLayer) 110 : static_cast<orc::ObjectLayer &>(ObjLayer); 111 } 112 113 Expected<FileInfo &> findFileInfo(StringRef FileName); 114 Expected<MemoryRegionInfo &> findSectionInfo(StringRef FileName, 115 StringRef SectionName); 116 Expected<MemoryRegionInfo &> findStubInfo(StringRef FileName, 117 StringRef TargetName, 118 StringRef KindNameFilter); 119 Expected<MemoryRegionInfo &> findGOTEntryInfo(StringRef FileName, 120 StringRef TargetName); 121 122 bool isSymbolRegistered(const orc::SymbolStringPtr &Name); 123 Expected<MemoryRegionInfo &> findSymbolInfo(const orc::SymbolStringPtr &Name, 124 Twine ErrorMsgStem); 125 126 DynLibJDMap DynLibJDs; 127 128 std::mutex M; 129 std::condition_variable ActiveLinksCV; 130 size_t ActiveLinks = 0; 131 SymbolInfoMap SymbolInfos; 132 FileInfoMap FileInfos; 133 134 StringSet<> HarnessFiles; 135 StringSet<> HarnessExternals; 136 StringSet<> HarnessDefinitions; 137 DenseMap<StringRef, StringRef> CanonicalWeakDefs; 138 139 std::optional<Regex> ShowGraphsRegex; 140 141 private: 142 Session(std::unique_ptr<orc::ExecutorProcessControl> EPC, Error &Err); 143 }; 144 145 /// Record symbols, GOT entries, stubs, and sections for ELF file. 146 Error registerELFGraphInfo(Session &S, jitlink::LinkGraph &G); 147 148 /// Record symbols, GOT entries, stubs, and sections for MachO file. 149 Error registerMachOGraphInfo(Session &S, jitlink::LinkGraph &G); 150 151 /// Record symbols, GOT entries, stubs, and sections for COFF file. 152 Error registerCOFFGraphInfo(Session &S, jitlink::LinkGraph &G); 153 154 /// Adds a statistics gathering plugin if any stats options are used. 155 void enableStatistics(Session &S, bool UsingOrcRuntime); 156 157 } // end namespace llvm 158 159 #endif // LLVM_TOOLS_LLVM_JITLINK_LLVM_JITLINK_H 160