LLVM 24.0.0git
LazyReexports.cpp
Go to the documentation of this file.
1//===---------- LazyReexports.cpp - Utilities for lazy reexports ----------===//
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
17
18#define DEBUG_TYPE "orc"
19
20namespace llvm {
21namespace orc {
22
24 ExecutorAddr ErrorHandlerAddr,
26 : ES(ES), ErrorHandlerAddr(ErrorHandlerAddr), TP(TP) {}
27
29 JITDylib &SourceJD, SymbolStringPtr SymbolName,
30 NotifyResolvedFunction NotifyResolved) {
31 assert(TP && "TrampolinePool not set");
32
33 std::lock_guard<std::mutex> Lock(LCTMMutex);
34 auto Trampoline = TP->getTrampoline();
35
36 if (!Trampoline)
37 return Trampoline.takeError();
38
39 Reexports[*Trampoline] = ReexportsEntry{&SourceJD, std::move(SymbolName)};
40 Notifiers[*Trampoline] = std::move(NotifyResolved);
41 return *Trampoline;
42}
43
45 ES.reportError(std::move(Err));
46 return ErrorHandlerAddr;
47}
48
51 std::lock_guard<std::mutex> Lock(LCTMMutex);
52 auto I = Reexports.find(TrampolineAddr);
53 if (I == Reexports.end())
55 "Missing reexport for trampoline address %p" +
56 formatv("{0:x}", TrampolineAddr));
57 return I->second;
58}
59
61 ExecutorAddr ResolvedAddr) {
62 NotifyResolvedFunction NotifyResolved;
63 {
64 std::lock_guard<std::mutex> Lock(LCTMMutex);
65 auto I = Notifiers.find(TrampolineAddr);
66 if (I != Notifiers.end()) {
67 NotifyResolved = std::move(I->second);
68 Notifiers.erase(I);
69 }
70 }
71
72 return NotifyResolved ? NotifyResolved(ResolvedAddr) : Error::success();
73}
74
76 ExecutorAddr TrampolineAddr,
77 NotifyLandingResolvedFunction NotifyLandingResolved) {
78
79 auto Entry = findReexport(TrampolineAddr);
80 if (!Entry)
81 return NotifyLandingResolved(reportCallThroughError(Entry.takeError()));
82
83 // Declaring SLS and the callback outside of the call to ES.lookup is a
84 // workaround to fix build failures on AIX and on z/OS platforms.
85 SymbolLookupSet SLS({Entry->SymbolName});
86 auto Callback = [this, TrampolineAddr, SymbolName = Entry->SymbolName,
87 NotifyLandingResolved = std::move(NotifyLandingResolved)](
89 if (Result) {
90 assert(Result->size() == 1 && "Unexpected result size");
91 assert(Result->count(SymbolName) && "Unexpected result value");
92 ExecutorAddr LandingAddr = (*Result)[SymbolName].getAddress();
93
94 if (auto Err = notifyResolved(TrampolineAddr, LandingAddr))
95 NotifyLandingResolved(reportCallThroughError(std::move(Err)));
96 else
97 NotifyLandingResolved(LandingAddr);
98 } else {
99 NotifyLandingResolved(reportCallThroughError(Result.takeError()));
100 }
101 };
102
103 ES.lookup(LookupKind::Static,
104 makeJITDylibSearchOrder(Entry->SourceJD,
106 std::move(SLS), SymbolState::Ready, std::move(Callback),
108}
109
112 ExecutorAddr ErrorHandlerAddr) {
113 switch (T.getArch()) {
114 default:
116 std::string("No callback manager available for ") + T.str(),
118
119 case Triple::aarch64:
122 ErrorHandlerAddr);
123
124 case Triple::x86:
125 return LocalLazyCallThroughManager::Create<OrcI386>(ES, ErrorHandlerAddr);
126
129 ES, ErrorHandlerAddr);
130
131 case Triple::mips:
133 ErrorHandlerAddr);
134
135 case Triple::mipsel:
137 ErrorHandlerAddr);
138
139 case Triple::mips64:
140 case Triple::mips64el:
141 return LocalLazyCallThroughManager::Create<OrcMips64>(ES, ErrorHandlerAddr);
142
143 case Triple::riscv64:
145 ErrorHandlerAddr);
146
147 case Triple::x86_64:
148 if (T.getOS() == Triple::OSType::Win32)
150 ES, ErrorHandlerAddr);
151 else
153 ES, ErrorHandlerAddr);
154 }
155}
156
159 JITDylib &SourceJD, SymbolAliasMap CallableAliases, ImplSymbolMap *SrcJDLoc)
160 : MaterializationUnit(extractFlags(CallableAliases)),
161 LCTManager(LCTManager), RSManager(RSManager), SourceJD(SourceJD),
162 CallableAliases(std::move(CallableAliases)), AliaseeTable(SrcJDLoc) {}
163
165 return "<Lazy Reexports>";
166}
167
168void LazyReexportsMaterializationUnit::materialize(
169 std::unique_ptr<MaterializationResponsibility> R) {
170 auto RequestedSymbols = R->getRequestedSymbols();
171
172 SymbolAliasMap RequestedAliases;
173 for (auto &RequestedSymbol : RequestedSymbols) {
174 auto I = CallableAliases.find(RequestedSymbol);
175 assert(I != CallableAliases.end() && "Symbol not found in alias map?");
176 RequestedAliases[I->first] = std::move(I->second);
177 CallableAliases.erase(I);
178 }
179
180 if (!CallableAliases.empty())
181 if (auto Err = R->replace(lazyReexports(LCTManager, RSManager, SourceJD,
182 std::move(CallableAliases),
183 AliaseeTable))) {
184 R->getExecutionSession().reportError(std::move(Err));
185 R->failMaterialization();
186 return;
187 }
188
189 SymbolMap Inits;
190 for (auto &Alias : RequestedAliases) {
191 auto CallThroughTrampoline = LCTManager.getCallThroughTrampoline(
192 SourceJD, Alias.second.Aliasee,
193 [&TargetJD = R->getTargetJITDylib(), &RSManager = this->RSManager,
194 StubSym = Alias.first](ExecutorAddr ResolvedAddr) -> Error {
195 return RSManager.redirect(TargetJD, StubSym,
196 ExecutorSymbolDef(ResolvedAddr, {}));
197 });
198
199 if (!CallThroughTrampoline) {
200 R->getExecutionSession().reportError(CallThroughTrampoline.takeError());
201 R->failMaterialization();
202 return;
203 }
204
205 Inits[Alias.first] = {*CallThroughTrampoline, Alias.second.AliasFlags};
206 }
207
208 if (AliaseeTable != nullptr && !RequestedAliases.empty())
209 AliaseeTable->trackImpls(RequestedAliases, &SourceJD);
210
211 if (auto Err = R->replace(std::make_unique<RedirectableMaterializationUnit>(
212 RSManager, std::move(Inits)))) {
213 R->getExecutionSession().reportError(std::move(Err));
214 return R->failMaterialization();
215 }
216}
217
218void LazyReexportsMaterializationUnit::discard(const JITDylib &JD,
219 const SymbolStringPtr &Name) {
220 assert(CallableAliases.count(Name) &&
221 "Symbol not covered by this MaterializationUnit");
222 CallableAliases.erase(Name);
223}
224
225MaterializationUnit::Interface
226LazyReexportsMaterializationUnit::extractFlags(const SymbolAliasMap &Aliases) {
228 for (auto &KV : Aliases) {
229 assert(KV.second.AliasFlags.isCallable() &&
230 "Lazy re-exports must be callable symbols");
231 SymbolFlags[KV.first] = KV.second.AliasFlags;
232 }
233 return MaterializationUnit::Interface(std::move(SymbolFlags), nullptr);
234}
235
237public:
239 : MaterializationUnit(getInterface(Reexports)), LRMgr(LRMgr),
240 Reexports(std::move(Reexports)) {}
241
242private:
243 Interface getInterface(const SymbolAliasMap &Reexports) {
245 for (auto &[Alias, AI] : Reexports)
246 SF[Alias] = AI.AliasFlags;
247 return {std::move(SF), nullptr};
248 }
249
250 StringRef getName() const override { return "LazyReexportsManager::MU"; }
251
252 void materialize(std::unique_ptr<MaterializationResponsibility> R) override {
253 LRMgr.emitReentryTrampolines(std::move(R), std::move(Reexports));
254 }
255
256 void discard(const JITDylib &JD, const SymbolStringPtr &Name) override {
257 Reexports.erase(Name);
258 }
259
260 LazyReexportsManager &LRMgr;
261 SymbolAliasMap Reexports;
262};
263
265public:
269
273
275 return Error::success();
276 }
277
279 ResourceKey SrcKey) override {}
280
281private:
282 std::mutex M;
283};
284
286
290 JITDylib &PlatformJD, Listener *L) {
291 Error Err = Error::success();
292 std::unique_ptr<LazyReexportsManager> LRM(new LazyReexportsManager(
293 std::move(EmitTrampolines), RSMgr, PlatformJD, L, Err));
294 if (Err)
295 return std::move(Err);
296 return std::move(LRM);
297}
298
300 return JD.getExecutionSession().runSessionLocked([&]() -> Error {
301 auto I = KeyToReentryAddrs.find(K);
302 if (I == KeyToReentryAddrs.end())
303 return Error::success();
304
305 auto &ReentryAddrs = I->second;
306 for (auto &ReentryAddr : ReentryAddrs) {
307 assert(CallThroughs.count(ReentryAddr) && "CallTrhough missing");
308 CallThroughs.erase(ReentryAddr);
309 }
310 KeyToReentryAddrs.erase(I);
311 return L ? L->onLazyReexportsRemoved(JD, K) : Error::success();
312 });
313}
314
316 ResourceKey DstK,
317 ResourceKey SrcK) {
318 auto I = KeyToReentryAddrs.find(SrcK);
319 if (I != KeyToReentryAddrs.end()) {
320 auto J = KeyToReentryAddrs.find(DstK);
321 if (J == KeyToReentryAddrs.end()) {
322 auto Tmp = std::move(I->second);
323 KeyToReentryAddrs.erase(I);
324 KeyToReentryAddrs[DstK] = std::move(Tmp);
325 } else {
326 auto &SrcAddrs = I->second;
327 auto &DstAddrs = J->second;
328 llvm::append_range(DstAddrs, SrcAddrs);
329 KeyToReentryAddrs.erase(I);
330 }
331 if (L)
332 L->onLazyReexportsTransfered(JD, DstK, SrcK);
333 }
334}
335
336// Spec for the call-controller handler that the ORC runtime calls to
337// resolve lazy reexports.
340 : sps::HandlerSpec<shared::SPSExpected<shared::SPSExecutorSymbolDef>(
341 shared::SPSExecutorAddr)> {
342 static constexpr SymbolNameSpec Name =
343 SymbolNameSpec::c("__orc_rt_resolve_tag");
344};
345} // namespace lazy_reexports_sps_handlers
346
347LazyReexportsManager::LazyReexportsManager(EmitTrampolinesFn EmitTrampolines,
349 JITDylib &PlatformJD, Listener *L,
350 Error &Err)
351 : ES(PlatformJD.getExecutionSession()),
352 EmitTrampolines(std::move(EmitTrampolines)), RSMgr(RSMgr), L(L) {
353
354 using namespace shared;
356 Err = ES.registerCallControllerHandlers(
357 PlatformJD,
359 this, &LazyReexportsManager::resolve));
360}
361
362std::unique_ptr<MaterializationUnit>
363LazyReexportsManager::createLazyReexports(SymbolAliasMap Reexports) {
364 return std::make_unique<MU>(*this, std::move(Reexports));
365}
366
367void LazyReexportsManager::emitReentryTrampolines(
368 std::unique_ptr<MaterializationResponsibility> MR,
369 SymbolAliasMap Reexports) {
370 size_t NumTrampolines = Reexports.size();
371 auto RT = MR->getResourceTracker();
372 EmitTrampolines(
373 std::move(RT), NumTrampolines,
374 [this, MR = std::move(MR), Reexports = std::move(Reexports)](
375 Expected<std::vector<ExecutorSymbolDef>> ReentryPoints) mutable {
376 emitRedirectableSymbols(std::move(MR), std::move(Reexports),
377 std::move(ReentryPoints));
378 });
379}
380
381void LazyReexportsManager::emitRedirectableSymbols(
382 std::unique_ptr<MaterializationResponsibility> MR, SymbolAliasMap Reexports,
383 Expected<std::vector<ExecutorSymbolDef>> ReentryPoints) {
384
385 if (!ReentryPoints) {
386 MR->getExecutionSession().reportError(ReentryPoints.takeError());
387 MR->failMaterialization();
388 return;
389 }
390
391 assert(Reexports.size() == ReentryPoints->size() &&
392 "Number of reentry points doesn't match number of reexports");
393
394 // Bind entry points to names.
395 SymbolMap Redirs;
396 size_t I = 0;
397 for (auto &[Name, AI] : Reexports)
398 Redirs[Name] = {(*ReentryPoints)[I++].getAddress(), AI.AliasFlags};
399
400 I = 0;
401 if (!Reexports.empty()) {
402 if (auto Err = MR->withResourceKeyDo([&](ResourceKey K) {
403 auto &JD = MR->getTargetJITDylib();
404 auto &ReentryAddrsForK = KeyToReentryAddrs[K];
405 for (auto &[Name, AI] : Reexports) {
406 const auto &ReentryPoint = (*ReentryPoints)[I++];
407 CallThroughs[ReentryPoint.getAddress()] = {&JD, Name, AI.Aliasee};
408 ReentryAddrsForK.push_back(ReentryPoint.getAddress());
409 }
410 if (L)
411 L->onLazyReexportsCreated(JD, K, Reexports);
412 })) {
413 MR->getExecutionSession().reportError(std::move(Err));
414 MR->failMaterialization();
415 return;
416 }
417 }
418
419 RSMgr.emitRedirectableSymbols(std::move(MR), std::move(Redirs));
420}
421
422void LazyReexportsManager::resolve(ResolveSendResultFn SendResult,
423 ExecutorAddr ReentryStubAddr) {
424
425 CallThroughInfo LandingInfo;
426
427 ES.runSessionLocked([&]() {
428 auto I = CallThroughs.find(ReentryStubAddr);
429 if (I == CallThroughs.end())
430 return SendResult(make_error<StringError>(
431 "Reentry address " + formatv("{0:x}", ReentryStubAddr) +
432 " not registered",
434 LandingInfo = I->second;
435 });
436
437 if (L)
438 L->onLazyReexportCalled(LandingInfo);
439
440 ES.lookup(
442 {{LandingInfo.JD.get(), JITDylibLookupFlags::MatchAllSymbols}},
443 SymbolLookupSet(std::move(LandingInfo.BodyName)), SymbolState::Ready,
444 [this, JD = std::move(LandingInfo.JD),
445 ReentryName = std::move(LandingInfo.Name),
446 SendResult = std::move(SendResult)](Expected<SymbolMap> Result) mutable {
447 if (!Result)
448 return SendResult(Result.takeError());
449
450 assert(Result->size() == 1 && "Unexpected number of results");
451 auto BodySym = Result->begin()->second;
452 if (auto Err = RSMgr.redirect(*JD, ReentryName, BodySym))
453 SendResult(std::move(Err));
454 SendResult(BodySym);
455 },
457}
458
460public:
461 SpeculateTask(std::weak_ptr<SimpleLazyReexportsSpeculator> Speculator)
462 : Speculator(std::move(Speculator)) {}
463
464 void printDescription(raw_ostream &OS) override {
465 OS << "Speculative Lookup Task";
466 }
467
468 void run() override {
469 if (auto S = Speculator.lock())
470 S->doNextSpeculativeLookup();
471 }
472
473private:
474 std::weak_ptr<SimpleLazyReexportsSpeculator> Speculator;
475};
476
478 for (auto &[JD, _] : LazyReexports)
479 JITDylibSP(JD)->Release();
480}
481
483 JITDylib &JD, ResourceKey K, const SymbolAliasMap &Reexports) {
484 if (!LazyReexports.count(&JD))
485 JD.Retain();
486 auto &BodiesVec = LazyReexports[&JD][K];
487 for (auto &[Name, AI] : Reexports)
488 BodiesVec.push_back(AI.Aliasee);
489 if (!SpeculateTaskActive) {
490 SpeculateTaskActive = true;
491 ES.dispatchTask(std::make_unique<SpeculateTask>(WeakThis));
492 }
493}
494
496 JITDylib &JD, ResourceKey DstK, ResourceKey SrcK) {
497
498 auto I = LazyReexports.find(&JD);
499 if (I == LazyReexports.end())
500 return;
501
502 auto &MapForJD = I->second;
503 auto J = MapForJD.find(SrcK);
504 if (J == MapForJD.end())
505 return;
506
507 // We have something to transfer.
508 auto K = MapForJD.find(DstK);
509 if (K == MapForJD.end()) {
510 auto Tmp = std::move(J->second);
511 MapForJD.erase(J);
512 MapForJD[DstK] = std::move(Tmp);
513 } else {
514 auto &SrcNames = J->second;
515 auto &DstNames = K->second;
516 llvm::append_range(DstNames, SrcNames);
517 MapForJD.erase(J);
518 }
519}
520
522 ResourceKey K) {
523
524 auto I = LazyReexports.find(&JD);
525 if (I == LazyReexports.end())
526 return Error::success();
527
528 auto &MapForJD = I->second;
529 MapForJD.erase(K);
530
531 if (MapForJD.empty()) {
532 LazyReexports.erase(I);
533 JD.Release();
534 }
535
536 return Error::success();
537}
538
540 const CallThroughInfo &CTI) {
541 if (RecordExec)
542 RecordExec(CTI);
543}
544
546 std::vector<std::pair<std::string, SymbolStringPtr>> NewSuggestions) {
547 ES.runSessionLocked([&]() {
548 for (auto &[JDName, SymbolName] : NewSuggestions)
549 SpeculateSuggestions.push_back(
550 {std::move(JDName), std::move(SymbolName)});
551 });
552}
553
554bool SimpleLazyReexportsSpeculator::doNextSpeculativeLookup() {
555 // Use existing speculation queue if available, otherwise take the next
556 // element from LazyReexports.
557 JITDylibSP SpeculateJD = nullptr;
558 SymbolStringPtr SpeculateFn;
559
560 auto SpeculateAgain = ES.runSessionLocked([&]() {
561 while (!SpeculateSuggestions.empty()) {
562 auto [JDName, SymbolName] = std::move(SpeculateSuggestions.front());
563 SpeculateSuggestions.pop_front();
564
565 if (auto *JD = ES.getJITDylibByName(JDName)) {
566 SpeculateJD = JD;
567 SpeculateFn = std::move(SymbolName);
568 break;
569 }
570 }
571
572 if (!SpeculateJD) {
573 assert(!LazyReexports.empty() && "LazyReexports map is empty");
574 auto LRItr =
575 std::next(LazyReexports.begin(), rand() % LazyReexports.size());
576 auto &[JD, KeyToFnBodies] = *LRItr;
577
578 assert(!KeyToFnBodies.empty() && "Key to function bodies map empty");
579 auto KeyToFnBodiesItr =
580 std::next(KeyToFnBodies.begin(), rand() % KeyToFnBodies.size());
581 auto &[Key, FnBodies] = *KeyToFnBodiesItr;
582
583 assert(!FnBodies.empty() && "Function bodies list empty");
584 auto FnBodyItr = std::next(FnBodies.begin(), rand() % FnBodies.size());
585
586 SpeculateJD = JITDylibSP(JD);
587 SpeculateFn = std::move(*FnBodyItr);
588
589 FnBodies.erase(FnBodyItr);
590 if (FnBodies.empty()) {
591 KeyToFnBodies.erase(KeyToFnBodiesItr);
592 if (KeyToFnBodies.empty()) {
593 LRItr->first->Release();
594 LazyReexports.erase(LRItr);
595 }
596 }
597 }
598
599 SpeculateTaskActive =
600 !SpeculateSuggestions.empty() || !LazyReexports.empty();
601 return SpeculateTaskActive;
602 });
603
604 LLVM_DEBUG({
605 dbgs() << "Issuing speculative lookup for ( " << SpeculateJD->getName()
606 << ", " << SpeculateFn << " )...\n";
607 });
608
609 ES.lookup(
611 {{std::move(SpeculateFn), SymbolLookupFlags::WeaklyReferencedSymbol}},
613 [](Expected<SymbolMap> Result) { consumeError(Result.takeError()); },
615
616 if (SpeculateAgain)
617 ES.dispatchTask(std::make_unique<SpeculateTask>(WeakThis));
618
619 return false;
620}
621
622} // End namespace orc.
623} // End namespace llvm.
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
#define _
#define I(x, y, z)
Definition MD5.cpp:57
#define G(x, y, z)
Definition MD5.cpp:55
#define T
if(PassOpts->AAPipeline)
static StringRef getName(Value *V)
#define LLVM_DEBUG(...)
Definition Debug.h:119
bool empty() const
Definition DenseMap.h:716
iterator find(const_arg_type_t< KeyT > Val)
Definition DenseMap.h:766
iterator end()
Definition DenseMap.h:686
bool erase(const KeyT &Val)
Definition DenseMap.h:930
Helper for Errors used as out-parameters.
Definition Error.h:1160
Lightweight error class with error context and mandatory checking.
Definition Error.h:159
static ErrorSuccess success()
Create a success value.
Definition Error.h:336
Tagged union holding either a T or a Error.
Definition Error.h:485
Represent a constant reference to a string, i.e.
Definition StringRef.h:56
Triple - Helper class for working with autoconf configuration names.
Definition Triple.h:48
@ loongarch64
Definition Triple.h:66
An ExecutionSession represents a running JIT program.
Definition Core.h:1104
LLVM_ABI JITDylib * getJITDylibByName(StringRef Name)
Return a pointer to the "name" JITDylib.
Definition Core.cpp:1636
decltype(auto) runSessionLocked(Func &&F)
Run the given lambda with the session mutex locked.
Definition Core.h:1211
Represents an address in the executor process.
IdleTask can be used as the basis for low-priority tasks, e.g.
Represents a JIT'd dynamic library.
Definition Core.h:675
ExecutionSession & getExecutionSession() const
Get a reference to the ExecutionSession for this JITDylib.
Definition Core.h:694
Manages a set of 'lazy call-through' trampolines.
LLVM_ABI ExecutorAddr reportCallThroughError(Error Err)
TrampolinePool::NotifyLandingResolvedFunction NotifyLandingResolvedFunction
LLVM_ABI Expected< ReexportsEntry > findReexport(ExecutorAddr TrampolineAddr)
LLVM_ABI Error notifyResolved(ExecutorAddr TrampolineAddr, ExecutorAddr ResolvedAddr)
LLVM_ABI void resolveTrampolineLandingAddress(ExecutorAddr TrampolineAddr, TrampolinePool::NotifyLandingResolvedFunction NotifyLandingResolved)
unique_function< Error(ExecutorAddr ResolvedAddr)> NotifyResolvedFunction
LLVM_ABI LazyCallThroughManager(ExecutionSession &ES, ExecutorAddr ErrorHandlerAddr, TrampolinePool *TP)
LLVM_ABI Expected< ExecutorAddr > getCallThroughTrampoline(JITDylib &SourceJD, SymbolStringPtr SymbolName, NotifyResolvedFunction NotifyResolved)
LazyReexportsManager::CallThroughInfo CallThroughInfo
MU(LazyReexportsManager &LRMgr, SymbolAliasMap Reexports)
void modifyPassConfig(MaterializationResponsibility &MR, jitlink::LinkGraph &G, jitlink::PassConfiguration &Config) override
void notifyTransferringResources(JITDylib &JD, ResourceKey DstKey, ResourceKey SrcKey) override
Error notifyFailed(MaterializationResponsibility &MR) override
Error notifyRemovingResources(JITDylib &JD, ResourceKey K) override
void handleTransferResources(JITDylib &JD, ResourceKey DstK, ResourceKey SrcK) override
This function will be called inside the session lock.
Error handleRemoveResources(JITDylib &JD, ResourceKey K) override
This function will be called outside the session lock.
unique_function< void(ResourceTrackerSP RT, size_t NumTrampolines, OnTrampolinesReadyFn OnTrampolinesReady)> EmitTrampolinesFn
LazyReexportsManager(LazyReexportsManager &&)=delete
static Expected< std::unique_ptr< LazyReexportsManager > > Create(EmitTrampolinesFn EmitTrampolines, RedirectableSymbolManager &RSMgr, JITDylib &PlatformJD, Listener *L=nullptr)
Create a LazyReexportsManager that uses the ORC runtime for reentry.
LazyReexportsMaterializationUnit(LazyCallThroughManager &LCTManager, RedirectableSymbolManager &RSManager, JITDylib &SourceJD, SymbolAliasMap CallableAliases, ImplSymbolMap *SrcJDLoc)
StringRef getName() const override
Return the name of this materialization unit.
Plugin instances can be added to the ObjectLinkingLayer to receive callbacks when code is loaded or e...
static Expected< std::unique_ptr< LocalLazyCallThroughManager > > Create(ExecutionSession &ES, ExecutorAddr ErrorHandlerAddr)
Create a LocalLazyCallThroughManager using the given ABI.
Tracks responsibility for materialization, and mediates interactions between MaterializationUnits and...
Definition Core.h:350
Base class for managing redirectable symbols in which a call gets redirected to another symbol in run...
virtual void emitRedirectableSymbols(std::unique_ptr< MaterializationResponsibility > MR, SymbolMap InitialDests)=0
Emit redirectable symbol.
SpeculateTask(std::weak_ptr< SimpleLazyReexportsSpeculator > Speculator)
Error onLazyReexportsRemoved(JITDylib &JD, ResourceKey K) override
Called under the session lock when lazy reexports are removed.
void onLazyReexportsCreated(JITDylib &JD, ResourceKey K, const SymbolAliasMap &Reexports) override
Called under the session lock when new lazy reexports are created.
void onLazyReexportCalled(const CallThroughInfo &CTI) override
Called outside the session lock when a lazy reexport is called.
void onLazyReexportsTransfered(JITDylib &JD, ResourceKey DstK, ResourceKey SrcK) override
Called under the session lock when lazy reexports have their ownership transferred to a new ResourceK...
void addSpeculationSuggestions(std::vector< std::pair< std::string, SymbolStringPtr > > NewSuggestions)
A set of symbols to look up, each associated with a SymbolLookupFlags value.
A symbol name together with the naming level (SymbolNameKind) it is expressed in, so that a Mangler /...
static constexpr SymbolNameSpec c(StringRef Name)
Pointer to a pooled string representing a symbol name.
Base class for pools of compiler re-entry trampolines.
Base class for specs that bind handlers for calls with the SPS signature SPSSigT.
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition raw_ostream.h:53
SymbolFlags
Symbol flags.
Definition Symbol.h:25
JITDylibSearchOrder makeJITDylibSearchOrder(ArrayRef< JITDylib * > JDs, JITDylibLookupFlags Flags=JITDylibLookupFlags::MatchExportedSymbolsOnly)
Convenience function for creating a search order from an ArrayRef of JITDylib*, all with the same fla...
Definition Core.h:154
IntrusiveRefCntPtr< JITDylib > JITDylibSP
Definition Core.h:59
ExecutionSession::CallControllerHandlerBinding bindCallControllerHandler(HandlerT &&H, SymbolLookupFlags LF=SymbolLookupFlags::RequiredSymbol)
Bind H, using the given spec, to the tag with the spec's default name.
uintptr_t ResourceKey
Definition Core.h:61
DenseMap< SymbolStringPtr, ExecutorSymbolDef > SymbolMap
A map from symbol names (as SymbolStringPtrs) to JITSymbols (address/flags pairs).
LLVM_ABI Expected< std::unique_ptr< LazyCallThroughManager > > createLocalLazyCallThroughManager(const Triple &T, ExecutionSession &ES, ExecutorAddr ErrorHandlerAddr)
Create a LocalLazyCallThroughManager from the given triple and execution session.
std::unique_ptr< LazyReexportsMaterializationUnit > lazyReexports(LazyCallThroughManager &LCTManager, RedirectableSymbolManager &RSManager, JITDylib &SourceJD, SymbolAliasMap CallableAliases, ImplSymbolMap *SrcJDLoc=nullptr)
Define lazy-reexports based on the given SymbolAliasMap.
LLVM_ABI RegisterDependenciesFunction NoDependenciesToRegister
This can be used as the value for a RegisterDependenciesFunction if there are no dependants to regist...
Definition Core.cpp:42
@ Ready
Emitted to memory, but waiting on transitive dependencies.
Definition Core.h:552
DenseMap< SymbolStringPtr, SymbolAliasMapEntry > SymbolAliasMap
A map of Symbols to (Symbol, Flags) pairs.
Definition Core.h:174
DenseMap< SymbolStringPtr, JITSymbolFlags > SymbolFlagsMap
A map from symbol names (as SymbolStringPtrs) to JITSymbolFlags.
This is an optimization pass for GlobalISel generic memory operations.
LLVM_ABI std::error_code inconvertibleErrorCode()
The value returned by this function can be returned from convertToErrorCode for Error values where no...
Definition Error.cpp:94
void append_range(Container &C, Range &&R)
Wrapper function to append range R to container C.
Definition STLExtras.h:2224
Error createStringError(std::error_code EC, char const *Fmt, const Ts &... Vals)
Create formatted StringError object.
Definition Error.h:1321
auto formatv(bool Validate, const char *Fmt, Ts &&...Vals)
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition Debug.cpp:209
LLVM_ATTRIBUTE_VISIBILITY_DEFAULT AnalysisKey InnerAnalysisManagerProxy< AnalysisManagerT, IRUnitT, ExtraArgTs... >::Key
Error make_error(ArgTs &&... Args)
Make a Error instance representing failure using the given error info type.
Definition Error.h:340
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:1933
void consumeError(Error Err)
Consume a Error without doing anything.
Definition Error.h:1106
Implement std::hash so that hash_code can be used in STL containers.
Definition BitVector.h:879