LLVM 20.0.0git
JITLinkReentryTrampolines.cpp
Go to the documentation of this file.
1//===----- JITLinkReentryTrampolines.cpp -- JITLink-based trampoline- -----===//
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
10
14
15#include <memory>
16
17#define DEBUG_TYPE "orc"
18
19using namespace llvm;
20using namespace llvm::jitlink;
21
22namespace {
23constexpr StringRef ReentryFnName = "__orc_rt_reenter";
24constexpr StringRef ReentrySectionName = "__orc_stubs";
25} // namespace
26
27namespace llvm::orc {
28
30 : public ObjectLinkingLayer::Plugin {
31public:
35 Config.PreFixupPasses.push_back(
36 [this](LinkGraph &G) { return recordTrampolineAddrs(G); });
37 }
38
40 return Error::success();
41 }
42
44 return Error::success();
45 }
46
48 ResourceKey SrcKey) override {}
49
51 std::shared_ptr<std::vector<ExecutorSymbolDef>> Addrs) {
52 std::lock_guard<std::mutex> Lock(M);
53 assert(!PendingAddrs.count(&G) && "Duplicate registration");
54 PendingAddrs[&G] = std::move(Addrs);
55 }
56
58 std::shared_ptr<std::vector<ExecutorSymbolDef>> Addrs;
59 {
60 std::lock_guard<std::mutex> Lock(M);
61 auto I = PendingAddrs.find(&G);
62 if (I == PendingAddrs.end())
63 return Error::success();
64 Addrs = std::move(I->second);
65 PendingAddrs.erase(I);
66 }
67
68 auto *Sec = G.findSectionByName(ReentrySectionName);
69 assert(Sec && "Reentry graph missing reentry section");
70 assert(!Sec->empty() && "Reentry graph is empty");
71
72 for (auto *Sym : Sec->symbols())
73 if (!Sym->hasName())
74 Addrs->push_back({Sym->getAddress(), JITSymbolFlags()});
75
76 return Error::success();
77 }
78
79private:
80 std::mutex M;
82 PendingAddrs;
83};
84
87
88 EmitTrampolineFn EmitTrampoline;
89
90 const auto &TT = ObjLinkingLayer.getExecutionSession().getTargetTriple();
91 switch (TT.getArch()) {
92 case Triple::aarch64:
94 break;
95 case Triple::x86_64:
97 break;
98 default:
99 return make_error<StringError>("JITLinkReentryTrampolines: architecture " +
100 TT.getArchName() + " not supported",
102 }
103
104 return std::make_unique<JITLinkReentryTrampolines>(ObjLinkingLayer,
105 std::move(EmitTrampoline));
106}
107
109 ObjectLinkingLayer &ObjLinkingLayer, EmitTrampolineFn EmitTrampoline)
110 : ObjLinkingLayer(ObjLinkingLayer),
111 EmitTrampoline(std::move(EmitTrampoline)) {
112 auto TAS = std::make_shared<TrampolineAddrScraperPlugin>();
113 TrampolineAddrScraper = TAS.get();
114 ObjLinkingLayer.addPlugin(std::move(TAS));
115}
116
118 size_t NumTrampolines,
119 OnTrampolinesReadyFn OnTrampolinesReady) {
120
121 if (NumTrampolines == 0)
122 return OnTrampolinesReady(std::vector<ExecutorSymbolDef>());
123
124 JITDylibSP JD(&RT->getJITDylib());
125 auto &ES = ObjLinkingLayer.getExecutionSession();
126 Triple TT = ES.getTargetTriple();
127
128 auto ReentryGraphSym =
129 ES.intern(("__orc_reentry_graph_#" + Twine(++ReentryGraphIdx)).str());
130
131 auto G = std::make_unique<jitlink::LinkGraph>(
132 (*ReentryGraphSym).str(), ES.getSymbolStringPool(), TT,
133 TT.isArch64Bit() ? 8 : 4,
134 TT.isLittleEndian() ? endianness::little : endianness::big,
136
137 auto &ReentryFnSym = G->addExternalSymbol(ReentryFnName, 0, false);
138
139 auto &ReentrySection =
140 G->createSection(ReentrySectionName, MemProt::Exec | MemProt::Read);
141
142 for (size_t I = 0; I != NumTrampolines; ++I)
143 EmitTrampoline(*G, ReentrySection, ReentryFnSym).setLive(true);
144
145 auto &FirstBlock = **ReentrySection.blocks().begin();
146 G->addDefinedSymbol(FirstBlock, 0, *ReentryGraphSym, FirstBlock.getSize(),
147 Linkage::Strong, Scope::SideEffectsOnly, true, true);
148
149 auto TrampolineAddrs = std::make_shared<std::vector<ExecutorSymbolDef>>();
150 TrampolineAddrScraper->registerGraph(*G, TrampolineAddrs);
151
152 // Add Graph via object linking layer.
153 if (auto Err = ObjLinkingLayer.add(std::move(RT), std::move(G)))
154 return OnTrampolinesReady(std::move(Err));
155
156 // Trigger graph emission.
157 ES.lookup(
159 SymbolLookupSet(ReentryGraphSym,
162 [OnTrampolinesReady = std::move(OnTrampolinesReady),
163 TrampolineAddrs =
164 std::move(TrampolineAddrs)](Expected<SymbolMap> Result) mutable {
165 if (Result)
166 OnTrampolinesReady(std::move(*TrampolineAddrs));
167 else
168 OnTrampolinesReady(Result.takeError());
169 },
171}
172
176 JITDylib &PlatformJD) {
177 auto JLT = JITLinkReentryTrampolines::Create(ObjLinkingLayer);
178 if (!JLT)
179 return JLT.takeError();
180
182 [JLT = std::move(*JLT)](ResourceTrackerSP RT, size_t NumTrampolines,
184 OnTrampolinesReady) mutable {
185 JLT->emit(std::move(RT), NumTrampolines, std::move(OnTrampolinesReady));
186 },
187 RSMgr, PlatformJD);
188}
189
190} // namespace llvm::orc
RelaxConfig Config
Definition: ELF_riscv.cpp:506
Symbol * Sym
Definition: ELF_riscv.cpp:479
#define I(x, y, z)
Definition: MD5.cpp:58
#define G(x, y, z)
Definition: MD5.cpp:56
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
Lightweight error class with error context and mandatory checking.
Definition: Error.h:160
static ErrorSuccess success()
Create a success value.
Definition: Error.h:337
Tagged union holding either a T or a Error.
Definition: Error.h:481
Flags for symbols in the JIT.
Definition: JITSymbol.h:74
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:51
Triple - Helper class for working with autoconf configuration names.
Definition: Triple.h:44
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition: Twine.h:81
const Triple & getTargetTriple() const
Return the triple for the executor.
Definition: Core.h:1382
Represents a JIT'd dynamic library.
Definition: Core.h:897
void registerGraph(LinkGraph &G, std::shared_ptr< std::vector< ExecutorSymbolDef > > Addrs)
Error notifyFailed(MaterializationResponsibility &MR) override
void notifyTransferringResources(JITDylib &JD, ResourceKey DstKey, ResourceKey SrcKey) override
void modifyPassConfig(MaterializationResponsibility &MR, jitlink::LinkGraph &G, jitlink::PassConfiguration &Config) override
JITLinkReentryTrampolines(ObjectLinkingLayer &ObjLinkingLayer, EmitTrampolineFn EmitTrampoline)
void emit(ResourceTrackerSP RT, size_t NumTrampolines, OnTrampolinesReadyFn OnTrampolinesReady)
static Expected< std::unique_ptr< JITLinkReentryTrampolines > > Create(ObjectLinkingLayer &ObjLinkingLayer)
Create trampolines using the default reentry trampoline function for the session triple.
static Expected< std::unique_ptr< LazyReexportsManager > > Create(EmitTrampolinesFn EmitTrampolines, RedirectableSymbolManager &RSMgr, JITDylib &PlatformJD)
Create a LazyReexportsManager that uses the ORC runtime for reentry.
ExecutionSession & getExecutionSession()
LinkGraphLinkingLayer & addPlugin(std::shared_ptr< Plugin > P)
Add a plugin.
Tracks responsibility for materialization, and mediates interactions between MaterializationUnits and...
Definition: Core.h:571
An ObjectLayer implementation built on JITLink.
virtual Error add(ResourceTrackerSP RT, std::unique_ptr< MemoryBuffer > O, MaterializationUnit::Interface I)
Adds a MaterializationUnit for the object file in the given memory buffer to the JITDylib for the giv...
Definition: Layer.cpp:170
Base class for managing redirectable symbols in which a call gets redirected to another symbol in run...
A set of symbols to look up, each associated with a SymbolLookupFlags value.
Definition: Core.h:194
Expected< std::unique_ptr< LazyReexportsManager > > createJITLinkLazyReexportsManager(ObjectLinkingLayer &ObjLinkingLayer, RedirectableSymbolManager &RSMgr, JITDylib &PlatformJD)
RegisterDependenciesFunction NoDependenciesToRegister
This can be used as the value for a RegisterDependenciesFunction if there are no dependants to regist...
Definition: Core.cpp:38
@ Ready
Emitted to memory, but waiting on transitive dependencies.
uintptr_t ResourceKey
Definition: Core.h:74
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
std::error_code inconvertibleErrorCode()
The value returned by this function can be returned from convertToErrorCode for Error values where no...
Definition: Error.cpp:98
OutputIt move(R &&Range, OutputIt Out)
Provide wrappers to std::move which take ranges instead of having to pass begin/end explicitly.
Definition: STLExtras.h:1873
Implement std::hash so that hash_code can be used in STL containers.
Definition: BitVector.h:858