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