diff --git a/llvm/include/llvm/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.h b/llvm/include/llvm/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.h --- a/llvm/include/llvm/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.h +++ b/llvm/include/llvm/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.h @@ -16,6 +16,7 @@ #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/StringMap.h" #include "llvm/ADT/StringRef.h" +#include "llvm/ExecutionEngine/JITEventListener.h" #include "llvm/ExecutionEngine/JITSymbol.h" #include "llvm/ExecutionEngine/Orc/Core.h" #include "llvm/ExecutionEngine/Orc/Layer.h" @@ -115,15 +116,23 @@ return *this; } + /// Register a JITEventListener. + void registerJITEventListener(JITEventListener &L); + + /// Unregister a JITEventListener. + void unregisterJITEventListener(JITEventListener &L); + private: Error onObjLoad(VModuleKey K, MaterializationResponsibility &R, - object::ObjectFile &Obj, + object::ObjectFile &Obj, RuntimeDyld::MemoryManager *MemMgr, std::unique_ptr LoadedObjInfo, std::map Resolved, std::set &InternalSymbols); - void onObjEmit(VModuleKey K, std::unique_ptr ObjBuffer, - MaterializationResponsibility &R, Error Err); + void onObjEmit(VModuleKey K, MaterializationResponsibility &R, + object::ObjectFile &Obj, + std::unique_ptr ObjBuffer, + RuntimeDyld::MemoryManager *MemMgr, Error Err); mutable std::mutex RTDyldLayerMutex; GetMemoryManagerFunction GetMemoryManager; @@ -133,6 +142,10 @@ bool OverrideObjectFlags = false; bool AutoClaimObjectSymbols = false; std::vector> MemMgrs; + std::vector EventListeners; + DenseMap> + LoadedObjInfos; }; class LegacyRTDyldObjectLinkingLayerBase { diff --git a/llvm/lib/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.cpp b/llvm/lib/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.cpp --- a/llvm/lib/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.cpp +++ b/llvm/lib/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.cpp @@ -81,8 +81,12 @@ RTDyldObjectLinkingLayer::~RTDyldObjectLinkingLayer() { std::lock_guard Lock(RTDyldLayerMutex); - for (auto &MemMgr : MemMgrs) + for (auto &MemMgr : MemMgrs) { + for (auto *L : EventListeners) + L->notifyFreeingObject( + static_cast(reinterpret_cast(&MemMgr))); MemMgr->deregisterEHFrames(); + } } void RTDyldObjectLinkingLayer::emit(MaterializationResponsibility R, @@ -155,19 +159,35 @@ jitLinkForORC( **Obj, std::move(O), *MemMgr, Resolver, ProcessAllSections, - [this, K, SharedR, &Obj, InternalSymbols]( + [this, K, SharedR, &Obj, MemMgr, InternalSymbols]( std::unique_ptr LoadedObjInfo, std::map ResolvedSymbols) { - return onObjLoad(K, *SharedR, **Obj, std::move(LoadedObjInfo), + return onObjLoad(K, *SharedR, **Obj, MemMgr, std::move(LoadedObjInfo), ResolvedSymbols, *InternalSymbols); }, - [this, K, SharedR, O = std::move(O)](Error Err) mutable { - onObjEmit(K, std::move(O), *SharedR, std::move(Err)); + [this, K, SharedR, &Obj, O = std::move(O), MemMgr](Error Err) mutable { + onObjEmit(K, *SharedR, **Obj, std::move(O), MemMgr, std::move(Err)); }); } +void RTDyldObjectLinkingLayer::registerJITEventListener(JITEventListener &L) { + std::lock_guard Lock(RTDyldLayerMutex); + assert(llvm::none_of(EventListeners, + [&](JITEventListener *O) { return O == &L; }) && + "Listener has already been registered"); + EventListeners.push_back(&L); +} + +void RTDyldObjectLinkingLayer::unregisterJITEventListener(JITEventListener &L) { + std::lock_guard Lock(RTDyldLayerMutex); + auto I = llvm::find(EventListeners, &L); + assert(I != EventListeners.end() && "Listener not registered"); + EventListeners.erase(I); +} + Error RTDyldObjectLinkingLayer::onObjLoad( VModuleKey K, MaterializationResponsibility &R, object::ObjectFile &Obj, + RuntimeDyld::MemoryManager *MemMgr, std::unique_ptr LoadedObjInfo, std::map Resolved, std::set &InternalSymbols) { @@ -252,12 +272,17 @@ if (NotifyLoaded) NotifyLoaded(K, Obj, *LoadedObjInfo); + std::lock_guard Lock(RTDyldLayerMutex); + assert(!LoadedObjInfos.count(MemMgr) && "Duplicate loaded info for MemMgr"); + LoadedObjInfos[MemMgr] = std::move(LoadedObjInfo); + return Error::success(); } void RTDyldObjectLinkingLayer::onObjEmit( - VModuleKey K, std::unique_ptr ObjBuffer, - MaterializationResponsibility &R, Error Err) { + VModuleKey K, MaterializationResponsibility &R, object::ObjectFile &Obj, + std::unique_ptr ObjBuffer, RuntimeDyld::MemoryManager *MemMgr, + Error Err) { if (Err) { getExecutionSession().reportError(std::move(Err)); R.failMaterialization(); @@ -272,6 +297,16 @@ if (NotifyEmitted) NotifyEmitted(K, std::move(ObjBuffer)); + + // Run EventListener notifyLoaded callbacks. + std::lock_guard Lock(RTDyldLayerMutex); + auto LOIItr = LoadedObjInfos.find(MemMgr); + assert(LOIItr != LoadedObjInfos.end() && "LoadedObjInfo missing"); + for (auto *L : EventListeners) + L->notifyObjectLoaded( + static_cast(reinterpret_cast(MemMgr)), Obj, + *LOIItr->second); + LoadedObjInfos.erase(MemMgr); } LegacyRTDyldObjectLinkingLayer::LegacyRTDyldObjectLinkingLayer( diff --git a/llvm/tools/lli/lli.cpp b/llvm/tools/lli/lli.cpp --- a/llvm/tools/lli/lli.cpp +++ b/llvm/tools/lli/lli.cpp @@ -30,6 +30,7 @@ #include "llvm/ExecutionEngine/Orc/LLJIT.h" #include "llvm/ExecutionEngine/Orc/MachOPlatform.h" #include "llvm/ExecutionEngine/Orc/OrcRemoteTargetClient.h" +#include "llvm/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.h" #include "llvm/ExecutionEngine/OrcMCJITReplacement.h" #include "llvm/ExecutionEngine/SectionMemoryManager.h" #include "llvm/IR/IRBuilder.h" @@ -892,6 +893,11 @@ auto J = ExitOnErr(Builder.create()); + if (!TT->isOSBinFormatMachO()) + static_cast(J->getObjLinkingLayer()) + .registerJITEventListener( + *JITEventListener::createGDBRegistrationListener()); + if (PerModuleLazy) J->setPartitionFunction(orc::CompileOnDemandLayer::compileWholeModule);