diff options
Diffstat (limited to 'llvm/lib/ExecutionEngine/Orc/LazyReexports.cpp')
-rw-r--r-- | llvm/lib/ExecutionEngine/Orc/LazyReexports.cpp | 110 |
1 files changed, 62 insertions, 48 deletions
diff --git a/llvm/lib/ExecutionEngine/Orc/LazyReexports.cpp b/llvm/lib/ExecutionEngine/Orc/LazyReexports.cpp index aab490feb8ea2..153f6b80784f0 100644 --- a/llvm/lib/ExecutionEngine/Orc/LazyReexports.cpp +++ b/llvm/lib/ExecutionEngine/Orc/LazyReexports.cpp @@ -16,70 +16,86 @@ namespace llvm { namespace orc { -void LazyCallThroughManager::NotifyResolvedFunction::anchor() {} - LazyCallThroughManager::LazyCallThroughManager( - ExecutionSession &ES, JITTargetAddress ErrorHandlerAddr, - std::unique_ptr<TrampolinePool> TP) - : ES(ES), ErrorHandlerAddr(ErrorHandlerAddr), TP(std::move(TP)) {} + ExecutionSession &ES, JITTargetAddress ErrorHandlerAddr, TrampolinePool *TP) + : ES(ES), ErrorHandlerAddr(ErrorHandlerAddr), TP(TP) {} Expected<JITTargetAddress> LazyCallThroughManager::getCallThroughTrampoline( JITDylib &SourceJD, SymbolStringPtr SymbolName, - std::shared_ptr<NotifyResolvedFunction> NotifyResolved) { + NotifyResolvedFunction NotifyResolved) { + assert(TP && "TrampolinePool not set"); + std::lock_guard<std::mutex> Lock(LCTMMutex); auto Trampoline = TP->getTrampoline(); if (!Trampoline) return Trampoline.takeError(); - Reexports[*Trampoline] = std::make_pair(&SourceJD, std::move(SymbolName)); + Reexports[*Trampoline] = ReexportsEntry{&SourceJD, std::move(SymbolName)}; Notifiers[*Trampoline] = std::move(NotifyResolved); return *Trampoline; } -JITTargetAddress -LazyCallThroughManager::callThroughToSymbol(JITTargetAddress TrampolineAddr) { - JITDylib *SourceJD = nullptr; - SymbolStringPtr SymbolName; - - { - std::lock_guard<std::mutex> Lock(LCTMMutex); - auto I = Reexports.find(TrampolineAddr); - if (I == Reexports.end()) - return ErrorHandlerAddr; - SourceJD = I->second.first; - SymbolName = I->second.second; - } - - auto LookupResult = ES.lookup( - makeJITDylibSearchOrder(SourceJD, JITDylibLookupFlags::MatchAllSymbols), - SymbolName); - - if (!LookupResult) { - ES.reportError(LookupResult.takeError()); - return ErrorHandlerAddr; - } +JITTargetAddress LazyCallThroughManager::reportCallThroughError(Error Err) { + ES.reportError(std::move(Err)); + return ErrorHandlerAddr; +} - auto ResolvedAddr = LookupResult->getAddress(); +Expected<LazyCallThroughManager::ReexportsEntry> +LazyCallThroughManager::findReexport(JITTargetAddress TrampolineAddr) { + std::lock_guard<std::mutex> Lock(LCTMMutex); + auto I = Reexports.find(TrampolineAddr); + if (I == Reexports.end()) + return createStringError(inconvertibleErrorCode(), + "Missing reexport for trampoline address %p", + TrampolineAddr); + return I->second; +} - std::shared_ptr<NotifyResolvedFunction> NotifyResolved = nullptr; +Error LazyCallThroughManager::notifyResolved(JITTargetAddress TrampolineAddr, + JITTargetAddress ResolvedAddr) { + NotifyResolvedFunction NotifyResolved; { std::lock_guard<std::mutex> Lock(LCTMMutex); auto I = Notifiers.find(TrampolineAddr); if (I != Notifiers.end()) { - NotifyResolved = I->second; + NotifyResolved = std::move(I->second); Notifiers.erase(I); } } - if (NotifyResolved) { - if (auto Err = (*NotifyResolved)(*SourceJD, SymbolName, ResolvedAddr)) { - ES.reportError(std::move(Err)); - return ErrorHandlerAddr; - } - } + return NotifyResolved ? NotifyResolved(ResolvedAddr) : Error::success(); +} - return ResolvedAddr; +void LazyCallThroughManager::resolveTrampolineLandingAddress( + JITTargetAddress TrampolineAddr, + NotifyLandingResolvedFunction NotifyLandingResolved) { + + auto Entry = findReexport(TrampolineAddr); + if (!Entry) + return NotifyLandingResolved(reportCallThroughError(Entry.takeError())); + + ES.lookup( + LookupKind::Static, + makeJITDylibSearchOrder(Entry->SourceJD, + JITDylibLookupFlags::MatchAllSymbols), + SymbolLookupSet({Entry->SymbolName}), SymbolState::Ready, + [this, TrampolineAddr, SymbolName = Entry->SymbolName, + NotifyLandingResolved = std::move(NotifyLandingResolved)]( + Expected<SymbolMap> Result) mutable { + if (Result) { + assert(Result->size() == 1 && "Unexpected result size"); + assert(Result->count(SymbolName) && "Unexpected result value"); + JITTargetAddress LandingAddr = (*Result)[SymbolName].getAddress(); + + if (auto Err = notifyResolved(TrampolineAddr, LandingAddr)) + NotifyLandingResolved(reportCallThroughError(std::move(Err))); + else + NotifyLandingResolved(LandingAddr); + } else + NotifyLandingResolved(reportCallThroughError(Result.takeError())); + }, + NoDependenciesToRegister); } Expected<std::unique_ptr<LazyCallThroughManager>> @@ -125,15 +141,9 @@ LazyReexportsMaterializationUnit::LazyReexportsMaterializationUnit( LazyCallThroughManager &LCTManager, IndirectStubsManager &ISManager, JITDylib &SourceJD, SymbolAliasMap CallableAliases, ImplSymbolMap *SrcJDLoc, VModuleKey K) - : MaterializationUnit(extractFlags(CallableAliases), std::move(K)), + : MaterializationUnit(extractFlags(CallableAliases), nullptr, std::move(K)), LCTManager(LCTManager), ISManager(ISManager), SourceJD(SourceJD), - CallableAliases(std::move(CallableAliases)), - NotifyResolved(LazyCallThroughManager::createNotifyResolvedFunction( - [&ISManager](JITDylib &JD, const SymbolStringPtr &SymbolName, - JITTargetAddress ResolvedAddr) { - return ISManager.updatePointer(*SymbolName, ResolvedAddr); - })), - AliaseeTable(SrcJDLoc) {} + CallableAliases(std::move(CallableAliases)), AliaseeTable(SrcJDLoc) {} StringRef LazyReexportsMaterializationUnit::getName() const { return "<Lazy Reexports>"; @@ -159,7 +169,11 @@ void LazyReexportsMaterializationUnit::materialize( for (auto &Alias : RequestedAliases) { auto CallThroughTrampoline = LCTManager.getCallThroughTrampoline( - SourceJD, Alias.second.Aliasee, NotifyResolved); + SourceJD, Alias.second.Aliasee, + [&ISManager = this->ISManager, + StubSym = Alias.first](JITTargetAddress ResolvedAddr) -> Error { + return ISManager.updatePointer(*StubSym, ResolvedAddr); + }); if (!CallThroughTrampoline) { SourceJD.getExecutionSession().reportError( |