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
16
17#define DEBUG_TYPE "orc"
18
19namespace llvm {
20namespace orc {
21
23 ExecutorAddr ErrorHandlerAddr,
25 : ES(ES), ErrorHandlerAddr(ErrorHandlerAddr), TP(TP) {}
26
28 JITDylib &SourceJD, SymbolStringPtr SymbolName,
29 NotifyResolvedFunction NotifyResolved) {
30 assert(TP && "TrampolinePool not set");
31
32 std::lock_guard<std::mutex> Lock(LCTMMutex);
33 auto Trampoline = TP->getTrampoline();
34
35 if (!Trampoline)
36 return Trampoline.takeError();
37
38 Reexports[*Trampoline] = ReexportsEntry{&SourceJD, std::move(SymbolName)};
39 Notifiers[*Trampoline] = std::move(NotifyResolved);
40 return *Trampoline;
41}
42
44 ES.reportError(std::move(Err));
45 return ErrorHandlerAddr;
46}
47
50 std::lock_guard<std::mutex> Lock(LCTMMutex);
51 auto I = Reexports.find(TrampolineAddr);
52 if (I == Reexports.end())
54 "Missing reexport for trampoline address %p" +
55 formatv("{0:x}", TrampolineAddr));
56 return I->second;
57}
58
60 ExecutorAddr ResolvedAddr) {
61 NotifyResolvedFunction NotifyResolved;
62 {
63 std::lock_guard<std::mutex> Lock(LCTMMutex);
64 auto I = Notifiers.find(TrampolineAddr);
65 if (I != Notifiers.end()) {
66 NotifyResolved = std::move(I->second);
67 Notifiers.erase(I);
68 }
69 }
70
71 return NotifyResolved ? NotifyResolved(ResolvedAddr) : Error::success();
72}
73
75 ExecutorAddr TrampolineAddr,
76 NotifyLandingResolvedFunction NotifyLandingResolved) {
77
78 auto Entry = findReexport(TrampolineAddr);
79 if (!Entry)
80 return NotifyLandingResolved(reportCallThroughError(Entry.takeError()));
81
82 // Declaring SLS and the callback outside of the call to ES.lookup is a
83 // workaround to fix build failures on AIX and on z/OS platforms.
84 SymbolLookupSet SLS({Entry->SymbolName});
85 auto Callback = [this, TrampolineAddr, SymbolName = Entry->SymbolName,
86 NotifyLandingResolved = std::move(NotifyLandingResolved)](
88 if (Result) {
89 assert(Result->size() == 1 && "Unexpected result size");
90 assert(Result->count(SymbolName) && "Unexpected result value");
91 ExecutorAddr LandingAddr = (*Result)[SymbolName].getAddress();
92
93 if (auto Err = notifyResolved(TrampolineAddr, LandingAddr))
94 NotifyLandingResolved(reportCallThroughError(std::move(Err)));
95 else
96 NotifyLandingResolved(LandingAddr);
97 } else {
98 NotifyLandingResolved(reportCallThroughError(Result.takeError()));
99 }
100 };
101
102 ES.lookup(LookupKind::Static,
103 makeJITDylibSearchOrder(Entry->SourceJD,
105 std::move(SLS), SymbolState::Ready, std::move(Callback),
107}
108
111 ExecutorAddr ErrorHandlerAddr) {
112 switch (T.getArch()) {
113 default:
115 std::string("No callback manager available for ") + T.str(),
117
118 case Triple::aarch64:
121 ErrorHandlerAddr);
122
123 case Triple::x86:
124 return LocalLazyCallThroughManager::Create<OrcI386>(ES, ErrorHandlerAddr);
125
128 ES, ErrorHandlerAddr);
129
130 case Triple::mips:
132 ErrorHandlerAddr);
133
134 case Triple::mipsel:
136 ErrorHandlerAddr);
137
138 case Triple::mips64:
139 case Triple::mips64el:
140 return LocalLazyCallThroughManager::Create<OrcMips64>(ES, ErrorHandlerAddr);
141
142 case Triple::riscv64:
144 ErrorHandlerAddr);
145
146 case Triple::x86_64:
147 if (T.getOS() == Triple::OSType::Win32)
149 ES, ErrorHandlerAddr);
150 else
152 ES, ErrorHandlerAddr);
153 }
154}
155
158 JITDylib &SourceJD, SymbolAliasMap CallableAliases, ImplSymbolMap *SrcJDLoc)
159 : MaterializationUnit(extractFlags(CallableAliases)),
160 LCTManager(LCTManager), RSManager(RSManager), SourceJD(SourceJD),
161 CallableAliases(std::move(CallableAliases)), AliaseeTable(SrcJDLoc) {}
162
164 return "<Lazy Reexports>";
165}
166
167void LazyReexportsMaterializationUnit::materialize(
168 std::unique_ptr<MaterializationResponsibility> R) {
169 auto RequestedSymbols = R->getRequestedSymbols();
170
171 SymbolAliasMap RequestedAliases;
172 for (auto &RequestedSymbol : RequestedSymbols) {
173 auto I = CallableAliases.find(RequestedSymbol);
174 assert(I != CallableAliases.end() && "Symbol not found in alias map?");
175 RequestedAliases[I->first] = std::move(I->second);
176 CallableAliases.erase(I);
177 }
178
179 if (!CallableAliases.empty())
180 if (auto Err = R->replace(lazyReexports(LCTManager, RSManager, SourceJD,
181 std::move(CallableAliases),
182 AliaseeTable))) {
183 R->getExecutionSession().reportError(std::move(Err));
184 R->failMaterialization();
185 return;
186 }
187
188 SymbolMap Inits;
189 for (auto &Alias : RequestedAliases) {
190 auto CallThroughTrampoline = LCTManager.getCallThroughTrampoline(
191 SourceJD, Alias.second.Aliasee,
192 [&TargetJD = R->getTargetJITDylib(), &RSManager = this->RSManager,
193 StubSym = Alias.first](ExecutorAddr ResolvedAddr) -> Error {
194 return RSManager.redirect(TargetJD, StubSym,
195 ExecutorSymbolDef(ResolvedAddr, {}));
196 });
197
198 if (!CallThroughTrampoline) {
199 R->getExecutionSession().reportError(CallThroughTrampoline.takeError());
200 R->failMaterialization();
201 return;
202 }
203
204 Inits[Alias.first] = {*CallThroughTrampoline, Alias.second.AliasFlags};
205 }
206
207 if (AliaseeTable != nullptr && !RequestedAliases.empty())
208 AliaseeTable->trackImpls(RequestedAliases, &SourceJD);
209
210 if (auto Err = R->replace(std::make_unique<RedirectableMaterializationUnit>(
211 RSManager, std::move(Inits)))) {
212 R->getExecutionSession().reportError(std::move(Err));
213 return R->failMaterialization();
214 }
215}
216
217void LazyReexportsMaterializationUnit::discard(const JITDylib &JD,
218 const SymbolStringPtr &Name) {
219 assert(CallableAliases.count(Name) &&
220 "Symbol not covered by this MaterializationUnit");
221 CallableAliases.erase(Name);
222}
223
224MaterializationUnit::Interface
225LazyReexportsMaterializationUnit::extractFlags(const SymbolAliasMap &Aliases) {
227 for (auto &KV : Aliases) {
228 assert(KV.second.AliasFlags.isCallable() &&
229 "Lazy re-exports must be callable symbols");
230 SymbolFlags[KV.first] = KV.second.AliasFlags;
231 }
232 return MaterializationUnit::Interface(std::move(SymbolFlags), nullptr);
233}
234
236public:
238 : MaterializationUnit(getInterface(Reexports)), LRMgr(LRMgr),
239 Reexports(std::move(Reexports)) {}
240
241private:
242 Interface getInterface(const SymbolAliasMap &Reexports) {
244 for (auto &[Alias, AI] : Reexports)
245 SF[Alias] = AI.AliasFlags;
246 return {std::move(SF), nullptr};
247 }
248
249 StringRef getName() const override { return "LazyReexportsManager::MU"; }
250
251 void materialize(std::unique_ptr<MaterializationResponsibility> R) override {
252 LRMgr.emitReentryTrampolines(std::move(R), std::move(Reexports));
253 }
254
255 void discard(const JITDylib &JD, const SymbolStringPtr &Name) override {
256 Reexports.erase(Name);
257 }
258
259 LazyReexportsManager &LRMgr;
260 SymbolAliasMap Reexports;
261};
262
264public:
268
272
274 return Error::success();
275 }
276
278 ResourceKey SrcKey) override {}
279
280private:
281 std::mutex M;
282};
283
285
289 JITDylib &PlatformJD, Listener *L) {
290 Error Err = Error::success();
291 std::unique_ptr<LazyReexportsManager> LRM(new LazyReexportsManager(
292 std::move(EmitTrampolines), RSMgr, PlatformJD, L, Err));
293 if (Err)
294 return std::move(Err);
295 return std::move(LRM);
296}
297
299 return JD.getExecutionSession().runSessionLocked([&]() -> Error {
300 auto I = KeyToReentryAddrs.find(K);
301 if (I == KeyToReentryAddrs.end())
302 return Error::success();
303
304 auto &ReentryAddrs = I->second;
305 for (auto &ReentryAddr : ReentryAddrs) {
306 assert(CallThroughs.count(ReentryAddr) && "CallTrhough missing");
307 CallThroughs.erase(ReentryAddr);
308 }
309 KeyToReentryAddrs.erase(I);
310 return L ? L->onLazyReexportsRemoved(JD, K) : Error::success();
311 });
312}
313
315 ResourceKey DstK,
316 ResourceKey SrcK) {
317 auto I = KeyToReentryAddrs.find(SrcK);
318 if (I != KeyToReentryAddrs.end()) {
319 auto J = KeyToReentryAddrs.find(DstK);
320 if (J == KeyToReentryAddrs.end()) {
321 auto Tmp = std::move(I->second);
322 KeyToReentryAddrs.erase(I);
323 KeyToReentryAddrs[DstK] = std::move(Tmp);
324 } else {
325 auto &SrcAddrs = I->second;
326 auto &DstAddrs = J->second;
327 llvm::append_range(DstAddrs, SrcAddrs);
328 KeyToReentryAddrs.erase(I);
329 }
330 if (L)
331 L->onLazyReexportsTransfered(JD, DstK, SrcK);
332 }
333}
334
335LazyReexportsManager::LazyReexportsManager(EmitTrampolinesFn EmitTrampolines,
337 JITDylib &PlatformJD, Listener *L,
338 Error &Err)
339 : ES(PlatformJD.getExecutionSession()),
340 EmitTrampolines(std::move(EmitTrampolines)), RSMgr(RSMgr), L(L) {
341
342 using namespace shared;
344 using ResolveSPSSig = SPSExpected<SPSExecutorSymbolDef>(SPSExecutorAddr);
347 SymbolNameSpec::c("__orc_rt_resolve_tag"), this,
348 &LazyReexportsManager::resolve));
349}
350
351std::unique_ptr<MaterializationUnit>
352LazyReexportsManager::createLazyReexports(SymbolAliasMap Reexports) {
353 return std::make_unique<MU>(*this, std::move(Reexports));
354}
355
356void LazyReexportsManager::emitReentryTrampolines(
357 std::unique_ptr<MaterializationResponsibility> MR,
358 SymbolAliasMap Reexports) {
359 size_t NumTrampolines = Reexports.size();
360 auto RT = MR->getResourceTracker();
361 EmitTrampolines(
362 std::move(RT), NumTrampolines,
363 [this, MR = std::move(MR), Reexports = std::move(Reexports)](
364 Expected<std::vector<ExecutorSymbolDef>> ReentryPoints) mutable {
365 emitRedirectableSymbols(std::move(MR), std::move(Reexports),
366 std::move(ReentryPoints));
367 });
368}
369
370void LazyReexportsManager::emitRedirectableSymbols(
371 std::unique_ptr<MaterializationResponsibility> MR, SymbolAliasMap Reexports,
372 Expected<std::vector<ExecutorSymbolDef>> ReentryPoints) {
373
374 if (!ReentryPoints) {
375 MR->getExecutionSession().reportError(ReentryPoints.takeError());
376 MR->failMaterialization();
377 return;
378 }
379
380 assert(Reexports.size() == ReentryPoints->size() &&
381 "Number of reentry points doesn't match number of reexports");
382
383 // Bind entry points to names.
384 SymbolMap Redirs;
385 size_t I = 0;
386 for (auto &[Name, AI] : Reexports)
387 Redirs[Name] = {(*ReentryPoints)[I++].getAddress(), AI.AliasFlags};
388
389 I = 0;
390 if (!Reexports.empty()) {
391 if (auto Err = MR->withResourceKeyDo([&](ResourceKey K) {
392 auto &JD = MR->getTargetJITDylib();
393 auto &ReentryAddrsForK = KeyToReentryAddrs[K];
394 for (auto &[Name, AI] : Reexports) {
395 const auto &ReentryPoint = (*ReentryPoints)[I++];
396 CallThroughs[ReentryPoint.getAddress()] = {&JD, Name, AI.Aliasee};
397 ReentryAddrsForK.push_back(ReentryPoint.getAddress());
398 }
399 if (L)
400 L->onLazyReexportsCreated(JD, K, Reexports);
401 })) {
402 MR->getExecutionSession().reportError(std::move(Err));
403 MR->failMaterialization();
404 return;
405 }
406 }
407
408 RSMgr.emitRedirectableSymbols(std::move(MR), std::move(Redirs));
409}
410
411void LazyReexportsManager::resolve(ResolveSendResultFn SendResult,
412 ExecutorAddr ReentryStubAddr) {
413
414 CallThroughInfo LandingInfo;
415
416 ES.runSessionLocked([&]() {
417 auto I = CallThroughs.find(ReentryStubAddr);
418 if (I == CallThroughs.end())
419 return SendResult(make_error<StringError>(
420 "Reentry address " + formatv("{0:x}", ReentryStubAddr) +
421 " not registered",
423 LandingInfo = I->second;
424 });
425
426 if (L)
427 L->onLazyReexportCalled(LandingInfo);
428
429 ES.lookup(
430 LookupKind::Static,
431 {{LandingInfo.JD.get(), JITDylibLookupFlags::MatchAllSymbols}},
432 SymbolLookupSet(std::move(LandingInfo.BodyName)), SymbolState::Ready,
433 [this, JD = std::move(LandingInfo.JD),
434 ReentryName = std::move(LandingInfo.Name),
435 SendResult = std::move(SendResult)](Expected<SymbolMap> Result) mutable {
436 if (!Result)
437 return SendResult(Result.takeError());
438
439 assert(Result->size() == 1 && "Unexpected number of results");
440 auto BodySym = Result->begin()->second;
441 if (auto Err = RSMgr.redirect(*JD, ReentryName, BodySym))
442 SendResult(std::move(Err));
443 SendResult(BodySym);
444 },
446}
447
449public:
450 SpeculateTask(std::weak_ptr<SimpleLazyReexportsSpeculator> Speculator)
451 : Speculator(std::move(Speculator)) {}
452
453 void printDescription(raw_ostream &OS) override {
454 OS << "Speculative Lookup Task";
455 }
456
457 void run() override {
458 if (auto S = Speculator.lock())
459 S->doNextSpeculativeLookup();
460 }
461
462private:
463 std::weak_ptr<SimpleLazyReexportsSpeculator> Speculator;
464};
465
467 for (auto &[JD, _] : LazyReexports)
468 JITDylibSP(JD)->Release();
469}
470
472 JITDylib &JD, ResourceKey K, const SymbolAliasMap &Reexports) {
473 if (!LazyReexports.count(&JD))
474 JD.Retain();
475 auto &BodiesVec = LazyReexports[&JD][K];
476 for (auto &[Name, AI] : Reexports)
477 BodiesVec.push_back(AI.Aliasee);
478 if (!SpeculateTaskActive) {
479 SpeculateTaskActive = true;
480 ES.dispatchTask(std::make_unique<SpeculateTask>(WeakThis));
481 }
482}
483
485 JITDylib &JD, ResourceKey DstK, ResourceKey SrcK) {
486
487 auto I = LazyReexports.find(&JD);
488 if (I == LazyReexports.end())
489 return;
490
491 auto &MapForJD = I->second;
492 auto J = MapForJD.find(SrcK);
493 if (J == MapForJD.end())
494 return;
495
496 // We have something to transfer.
497 auto K = MapForJD.find(DstK);
498 if (K == MapForJD.end()) {
499 auto Tmp = std::move(J->second);
500 MapForJD.erase(J);
501 MapForJD[DstK] = std::move(Tmp);
502 } else {
503 auto &SrcNames = J->second;
504 auto &DstNames = K->second;
505 llvm::append_range(DstNames, SrcNames);
506 MapForJD.erase(J);
507 }
508}
509
511 ResourceKey K) {
512
513 auto I = LazyReexports.find(&JD);
514 if (I == LazyReexports.end())
515 return Error::success();
516
517 auto &MapForJD = I->second;
518 MapForJD.erase(K);
519
520 if (MapForJD.empty()) {
521 LazyReexports.erase(I);
522 JD.Release();
523 }
524
525 return Error::success();
526}
527
529 const CallThroughInfo &CTI) {
530 if (RecordExec)
531 RecordExec(CTI);
532}
533
535 std::vector<std::pair<std::string, SymbolStringPtr>> NewSuggestions) {
536 ES.runSessionLocked([&]() {
537 for (auto &[JDName, SymbolName] : NewSuggestions)
538 SpeculateSuggestions.push_back(
539 {std::move(JDName), std::move(SymbolName)});
540 });
541}
542
543bool SimpleLazyReexportsSpeculator::doNextSpeculativeLookup() {
544 // Use existing speculation queue if available, otherwise take the next
545 // element from LazyReexports.
546 JITDylibSP SpeculateJD = nullptr;
547 SymbolStringPtr SpeculateFn;
548
549 auto SpeculateAgain = ES.runSessionLocked([&]() {
550 while (!SpeculateSuggestions.empty()) {
551 auto [JDName, SymbolName] = std::move(SpeculateSuggestions.front());
552 SpeculateSuggestions.pop_front();
553
554 if (auto *JD = ES.getJITDylibByName(JDName)) {
555 SpeculateJD = JD;
556 SpeculateFn = std::move(SymbolName);
557 break;
558 }
559 }
560
561 if (!SpeculateJD) {
562 assert(!LazyReexports.empty() && "LazyReexports map is empty");
563 auto LRItr =
564 std::next(LazyReexports.begin(), rand() % LazyReexports.size());
565 auto &[JD, KeyToFnBodies] = *LRItr;
566
567 assert(!KeyToFnBodies.empty() && "Key to function bodies map empty");
568 auto KeyToFnBodiesItr =
569 std::next(KeyToFnBodies.begin(), rand() % KeyToFnBodies.size());
570 auto &[Key, FnBodies] = *KeyToFnBodiesItr;
571
572 assert(!FnBodies.empty() && "Function bodies list empty");
573 auto FnBodyItr = std::next(FnBodies.begin(), rand() % FnBodies.size());
574
575 SpeculateJD = JITDylibSP(JD);
576 SpeculateFn = std::move(*FnBodyItr);
577
578 FnBodies.erase(FnBodyItr);
579 if (FnBodies.empty()) {
580 KeyToFnBodies.erase(KeyToFnBodiesItr);
581 if (KeyToFnBodies.empty()) {
582 LRItr->first->Release();
583 LazyReexports.erase(LRItr);
584 }
585 }
586 }
587
588 SpeculateTaskActive =
589 !SpeculateSuggestions.empty() || !LazyReexports.empty();
590 return SpeculateTaskActive;
591 });
592
593 LLVM_DEBUG({
594 dbgs() << "Issuing speculative lookup for ( " << SpeculateJD->getName()
595 << ", " << SpeculateFn << " )...\n";
596 });
597
598 ES.lookup(
599 LookupKind::Static, makeJITDylibSearchOrder(SpeculateJD.get()),
600 {{std::move(SpeculateFn), SymbolLookupFlags::WeaklyReferencedSymbol}},
601 SymbolState::Ready,
602 [](Expected<SymbolMap> Result) { consumeError(Result.takeError()); },
604
605 if (SpeculateAgain)
606 ES.dispatchTask(std::make_unique<SpeculateTask>(WeakThis));
607
608 return false;
609}
610
611} // End namespace orc.
612} // 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:732
iterator find(const_arg_type_t< KeyT > Val)
Definition DenseMap.h:782
iterator end()
Definition DenseMap.h:702
bool erase(const KeyT &Val)
Definition DenseMap.h:946
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:1112
LLVM_ABI Error registerCallControllerHandlers(JITDylib &JD, std::vector< CallControllerHandlerBinding > Hs)
For each binding, look up its tag symbol in JD and register the binding's call-controller handler for...
Definition Core.cpp:1859
decltype(auto) runSessionLocked(Func &&F)
Run the given lambda with the session mutex locked.
Definition Core.h:1219
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:676
ExecutionSession & getExecutionSession() const
Get a reference to the ExecutionSession for this JITDylib.
Definition Core.h:695
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.
virtual Error redirect(JITDylib &JD, const SymbolMap &NewDests)=0
Change the redirection destination of given symbols to new destination symbols.
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.
static constexpr SymbolNameSpec c(StringRef Name)
Pointer to a pooled string representing a symbol name.
Base class for pools of compiler re-entry trampolines.
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
ExecutionSession::CallControllerHandlerBinding bindCallControllerHandlerSPS(SymbolNameSpec Name, HandlerT &&Handler, SymbolLookupFlags LF=SymbolLookupFlags::RequiredSymbol)
Bind a call-controller handler that takes concrete argument types (and a sender for a concrete return...
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
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:41
@ 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:878