diff --git a/llvm/examples/ThinLtoJIT/OnDemandLayer.cpp b/llvm/examples/ThinLtoJIT/OnDemandLayer.cpp --- a/llvm/examples/ThinLtoJIT/OnDemandLayer.cpp +++ b/llvm/examples/ThinLtoJIT/OnDemandLayer.cpp @@ -239,15 +239,30 @@ JITTargetAddress NotifyingCallThroughManager::callThroughToSymbol( JITTargetAddress TrampolineAddr) { - // TODO: Allow derived classes to find the reexports entry for TrampolineAddr + auto Entry = findReexport(TrampolineAddr); + if (!Entry) + return reportCallThroughError(Entry.takeError()); + + PSTATS("[Call-through to ", *Entry->SymbolName , "] Found reexport"); // Kick-off discovery from here if (NotifyCallThroughToSymbol) { - NotifyCallThroughToSymbol(SymbolStringPtr()); + NotifyCallThroughToSymbol(Entry->SymbolName); } - // TODO: Allow derived classes to resolve the call-through. - return JITTargetAddress(); + PSTATS("[Call-through to ", *Entry->SymbolName , "] Kicked-off discovery"); + + auto ResolvedAddr = resolveSymbol(*Entry); + if (!ResolvedAddr) + return reportCallThroughError(ResolvedAddr.takeError()); + + PSTATS("[Call-through to ", *Entry->SymbolName , "] Resolved address"); + + if (Error Err = notifyResolved(TrampolineAddr, *ResolvedAddr)) + return reportCallThroughError(std::move(Err)); + + PSTATS("[Call-through to ", *Entry->SymbolName , "] Returning"); + return *ResolvedAddr; } CompileWholeModuleOnDemandLayer::CompileWholeModuleOnDemandLayer( diff --git a/llvm/include/llvm/ExecutionEngine/Orc/LazyReexports.h b/llvm/include/llvm/ExecutionEngine/Orc/LazyReexports.h --- a/llvm/include/llvm/ExecutionEngine/Orc/LazyReexports.h +++ b/llvm/include/llvm/ExecutionEngine/Orc/LazyReexports.h @@ -51,7 +51,21 @@ JITTargetAddress ErrorHandlerAddr, std::unique_ptr TP); - JITTargetAddress callThroughToSymbol(JITTargetAddress TrampolineAddr); + struct ReexportsEntry { + JITDylib *SourceJD; + SymbolStringPtr SymbolName; + }; + + Expected findReexport(JITTargetAddress TrampolineAddr); + Expected resolveSymbol(const ReexportsEntry &RE); + + Error notifyResolved(JITTargetAddress TrampolineAddr, + JITTargetAddress ResolvedAddr); + + JITTargetAddress reportCallThroughError(Error Err) { + ES.reportError(std::move(Err)); + return ErrorHandlerAddr; + } void setTrampolinePool(std::unique_ptr TP) { this->TP = std::move(TP); @@ -59,7 +73,7 @@ private: using ReexportsMap = - std::map>; + std::map; using NotifiersMap = std::map; @@ -81,7 +95,18 @@ template Error init() { auto TP = LocalTrampolinePool::Create( [this](JITTargetAddress TrampolineAddr) { - return callThroughToSymbol(TrampolineAddr); + auto Entry = findReexport(TrampolineAddr); + if (!Entry) + return reportCallThroughError(Entry.takeError()); + + auto ResolvedAddr = resolveSymbol(std::move(*Entry)); + if (!ResolvedAddr) + return reportCallThroughError(ResolvedAddr.takeError()); + + if (Error Err = notifyResolved(TrampolineAddr, *ResolvedAddr)) + return reportCallThroughError(std::move(Err)); + + return *ResolvedAddr; }); if (!TP) diff --git a/llvm/lib/ExecutionEngine/Orc/LazyReexports.cpp b/llvm/lib/ExecutionEngine/Orc/LazyReexports.cpp --- a/llvm/lib/ExecutionEngine/Orc/LazyReexports.cpp +++ b/llvm/lib/ExecutionEngine/Orc/LazyReexports.cpp @@ -30,36 +30,38 @@ 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 Lock(LCTMMutex); - auto I = Reexports.find(TrampolineAddr); - if (I == Reexports.end()) - return ErrorHandlerAddr; - SourceJD = I->second.first; - SymbolName = I->second.second; - } +Expected +LazyCallThroughManager::findReexport(JITTargetAddress TrampolineAddr) { + std::lock_guard Lock(LCTMMutex); + auto I = Reexports.find(TrampolineAddr); + if (I == Reexports.end()) + return createStringError(inconvertibleErrorCode(), + "Missing reexport for trampoline address %p", + TrampolineAddr); + + assert(Notifiers.find(TrampolineAddr) != Notifiers.end()); + return I->second; +} +Expected +LazyCallThroughManager::resolveSymbol(const ReexportsEntry &RE) { auto LookupResult = ES.lookup( - makeJITDylibSearchOrder(SourceJD, JITDylibLookupFlags::MatchAllSymbols), - SymbolName, SymbolState::Ready); + makeJITDylibSearchOrder(RE.SourceJD, JITDylibLookupFlags::MatchAllSymbols), + RE.SymbolName, SymbolState::Ready); - if (!LookupResult) { - ES.reportError(LookupResult.takeError()); - return ErrorHandlerAddr; - } + if (!LookupResult) + return LookupResult.takeError(); - auto ResolvedAddr = LookupResult->getAddress(); + return LookupResult->getAddress(); +} +Error LazyCallThroughManager::notifyResolved(JITTargetAddress TrampolineAddr, + JITTargetAddress ResolvedAddr) { NotifyResolvedFunction NotifyResolved; { std::lock_guard Lock(LCTMMutex); @@ -70,14 +72,7 @@ } } - if (NotifyResolved) { - if (auto Err = NotifyResolved(ResolvedAddr)) { - ES.reportError(std::move(Err)); - return ErrorHandlerAddr; - } - } - - return ResolvedAddr; + return NotifyResolved ? NotifyResolved(ResolvedAddr) : Error::success(); } Expected>