diff options
Diffstat (limited to 'contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.h')
-rw-r--r-- | contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.h | 387 |
1 files changed, 20 insertions, 367 deletions
diff --git a/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.h b/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.h index 9ada0871cf0c..7dfbf32b1ffa 100644 --- a/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.h +++ b/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.h @@ -20,7 +20,6 @@ #include "llvm/ExecutionEngine/JITSymbol.h" #include "llvm/ExecutionEngine/Orc/Core.h" #include "llvm/ExecutionEngine/Orc/Layer.h" -#include "llvm/ExecutionEngine/Orc/Legacy.h" #include "llvm/ExecutionEngine/RuntimeDyld.h" #include "llvm/Object/ObjectFile.h" #include "llvm/Support/Error.h" @@ -36,16 +35,16 @@ namespace llvm { namespace orc { -class RTDyldObjectLinkingLayer : public ObjectLayer { +class RTDyldObjectLinkingLayer : public ObjectLayer, private ResourceManager { public: /// Functor for receiving object-loaded notifications. - using NotifyLoadedFunction = - std::function<void(VModuleKey, const object::ObjectFile &Obj, - const RuntimeDyld::LoadedObjectInfo &)>; + using NotifyLoadedFunction = std::function<void( + MaterializationResponsibility &R, const object::ObjectFile &Obj, + const RuntimeDyld::LoadedObjectInfo &)>; /// Functor for receiving finalization notifications. - using NotifyEmittedFunction = - std::function<void(VModuleKey, std::unique_ptr<MemoryBuffer>)>; + using NotifyEmittedFunction = std::function<void( + MaterializationResponsibility &R, std::unique_ptr<MemoryBuffer>)>; using GetMemoryManagerFunction = std::function<std::unique_ptr<RuntimeDyld::MemoryManager>()>; @@ -58,7 +57,7 @@ public: ~RTDyldObjectLinkingLayer(); /// Emit the object. - void emit(MaterializationResponsibility R, + void emit(std::unique_ptr<MaterializationResponsibility> R, std::unique_ptr<MemoryBuffer> O) override; /// Set the NotifyLoaded callback. @@ -123,16 +122,23 @@ public: void unregisterJITEventListener(JITEventListener &L); private: - Error onObjLoad(VModuleKey K, MaterializationResponsibility &R, + using MemoryManagerUP = std::unique_ptr<RuntimeDyld::MemoryManager>; + + Error onObjLoad(MaterializationResponsibility &R, const object::ObjectFile &Obj, - RuntimeDyld::MemoryManager *MemMgr, - std::unique_ptr<RuntimeDyld::LoadedObjectInfo> LoadedObjInfo, + RuntimeDyld::MemoryManager &MemMgr, + RuntimeDyld::LoadedObjectInfo &LoadedObjInfo, std::map<StringRef, JITEvaluatedSymbol> Resolved, std::set<StringRef> &InternalSymbols); - void onObjEmit(VModuleKey K, MaterializationResponsibility &R, + void onObjEmit(MaterializationResponsibility &R, object::OwningBinary<object::ObjectFile> O, - RuntimeDyld::MemoryManager *MemMgr, Error Err); + std::unique_ptr<RuntimeDyld::MemoryManager> MemMgr, + std::unique_ptr<RuntimeDyld::LoadedObjectInfo> LoadedObjInfo, + Error Err); + + Error handleRemoveResources(ResourceKey K) override; + void handleTransferResources(ResourceKey DstKey, ResourceKey SrcKey) override; mutable std::mutex RTDyldLayerMutex; GetMemoryManagerFunction GetMemoryManager; @@ -141,361 +147,8 @@ private: bool ProcessAllSections = false; bool OverrideObjectFlags = false; bool AutoClaimObjectSymbols = false; - std::vector<std::unique_ptr<RuntimeDyld::MemoryManager>> MemMgrs; + DenseMap<ResourceKey, std::vector<MemoryManagerUP>> MemMgrs; std::vector<JITEventListener *> EventListeners; - DenseMap<RuntimeDyld::MemoryManager *, - std::unique_ptr<RuntimeDyld::LoadedObjectInfo>> - LoadedObjInfos; -}; - -class LegacyRTDyldObjectLinkingLayerBase { -public: - using ObjectPtr = std::unique_ptr<MemoryBuffer>; - -protected: - - /// Holds an object to be allocated/linked as a unit in the JIT. - /// - /// An instance of this class will be created for each object added - /// via JITObjectLayer::addObject. Deleting the instance (via - /// removeObject) frees its memory, removing all symbol definitions that - /// had been provided by this instance. Higher level layers are responsible - /// for taking any action required to handle the missing symbols. - class LinkedObject { - public: - LinkedObject() = default; - LinkedObject(const LinkedObject&) = delete; - void operator=(const LinkedObject&) = delete; - virtual ~LinkedObject() = default; - - virtual Error finalize() = 0; - - virtual JITSymbol::GetAddressFtor - getSymbolMaterializer(std::string Name) = 0; - - virtual void mapSectionAddress(const void *LocalAddress, - JITTargetAddress TargetAddr) const = 0; - - JITSymbol getSymbol(StringRef Name, bool ExportedSymbolsOnly) { - auto SymEntry = SymbolTable.find(Name); - if (SymEntry == SymbolTable.end()) - return nullptr; - if (!SymEntry->second.getFlags().isExported() && ExportedSymbolsOnly) - return nullptr; - if (!Finalized) - return JITSymbol(getSymbolMaterializer(std::string(Name)), - SymEntry->second.getFlags()); - return JITSymbol(SymEntry->second); - } - - protected: - StringMap<JITEvaluatedSymbol> SymbolTable; - bool Finalized = false; - }; -}; - -/// Bare bones object linking layer. -/// -/// This class is intended to be used as the base layer for a JIT. It allows -/// object files to be loaded into memory, linked, and the addresses of their -/// symbols queried. All objects added to this layer can see each other's -/// symbols. -class LegacyRTDyldObjectLinkingLayer : public LegacyRTDyldObjectLinkingLayerBase { -public: - - using LegacyRTDyldObjectLinkingLayerBase::ObjectPtr; - - /// Functor for receiving object-loaded notifications. - using NotifyLoadedFtor = - std::function<void(VModuleKey, const object::ObjectFile &Obj, - const RuntimeDyld::LoadedObjectInfo &)>; - - /// Functor for receiving finalization notifications. - using NotifyFinalizedFtor = - std::function<void(VModuleKey, const object::ObjectFile &Obj, - const RuntimeDyld::LoadedObjectInfo &)>; - - /// Functor for receiving deallocation notifications. - using NotifyFreedFtor = std::function<void(VModuleKey, const object::ObjectFile &Obj)>; - -private: - using OwnedObject = object::OwningBinary<object::ObjectFile>; - - template <typename MemoryManagerPtrT> - class ConcreteLinkedObject : public LinkedObject { - public: - ConcreteLinkedObject(LegacyRTDyldObjectLinkingLayer &Parent, VModuleKey K, - OwnedObject Obj, MemoryManagerPtrT MemMgr, - std::shared_ptr<SymbolResolver> Resolver, - bool ProcessAllSections) - : K(std::move(K)), - Parent(Parent), - MemMgr(std::move(MemMgr)), - PFC(std::make_unique<PreFinalizeContents>( - std::move(Obj), std::move(Resolver), - ProcessAllSections)) { - buildInitialSymbolTable(PFC->Obj); - } - - ~ConcreteLinkedObject() override { - if (this->Parent.NotifyFreed && ObjForNotify.getBinary()) - this->Parent.NotifyFreed(K, *ObjForNotify.getBinary()); - - MemMgr->deregisterEHFrames(); - } - - Error finalize() override { - assert(PFC && "mapSectionAddress called on finalized LinkedObject"); - - JITSymbolResolverAdapter ResolverAdapter(Parent.ES, *PFC->Resolver, - nullptr); - PFC->RTDyld = std::make_unique<RuntimeDyld>(*MemMgr, ResolverAdapter); - PFC->RTDyld->setProcessAllSections(PFC->ProcessAllSections); - - Finalized = true; - - std::unique_ptr<RuntimeDyld::LoadedObjectInfo> Info = - PFC->RTDyld->loadObject(*PFC->Obj.getBinary()); - - // Copy the symbol table out of the RuntimeDyld instance. - { - auto SymTab = PFC->RTDyld->getSymbolTable(); - for (auto &KV : SymTab) - SymbolTable[KV.first] = KV.second; - } - - if (Parent.NotifyLoaded) - Parent.NotifyLoaded(K, *PFC->Obj.getBinary(), *Info); - - PFC->RTDyld->finalizeWithMemoryManagerLocking(); - - if (PFC->RTDyld->hasError()) - return make_error<StringError>(PFC->RTDyld->getErrorString(), - inconvertibleErrorCode()); - - if (Parent.NotifyFinalized) - Parent.NotifyFinalized(K, *PFC->Obj.getBinary(), *Info); - - // Release resources. - if (this->Parent.NotifyFreed) - ObjForNotify = std::move(PFC->Obj); // needed for callback - PFC = nullptr; - return Error::success(); - } - - JITSymbol::GetAddressFtor getSymbolMaterializer(std::string Name) override { - return [this, Name]() -> Expected<JITTargetAddress> { - // The symbol may be materialized between the creation of this lambda - // and its execution, so we need to double check. - if (!this->Finalized) - if (auto Err = this->finalize()) - return std::move(Err); - return this->getSymbol(Name, false).getAddress(); - }; - } - - void mapSectionAddress(const void *LocalAddress, - JITTargetAddress TargetAddr) const override { - assert(PFC && "mapSectionAddress called on finalized LinkedObject"); - assert(PFC->RTDyld && "mapSectionAddress called on raw LinkedObject"); - PFC->RTDyld->mapSectionAddress(LocalAddress, TargetAddr); - } - - private: - void buildInitialSymbolTable(const OwnedObject &Obj) { - for (auto &Symbol : Obj.getBinary()->symbols()) { - if (Expected<uint32_t> SymbolFlagsOrErr = Symbol.getFlags()) { - if (*SymbolFlagsOrErr & object::SymbolRef::SF_Undefined) - continue; - } else { - // FIXME: Raise an error for bad symbols. - consumeError(SymbolFlagsOrErr.takeError()); - continue; - } - - Expected<StringRef> SymbolName = Symbol.getName(); - // FIXME: Raise an error for bad symbols. - if (!SymbolName) { - consumeError(SymbolName.takeError()); - continue; - } - // FIXME: Raise an error for bad symbols. - auto Flags = JITSymbolFlags::fromObjectSymbol(Symbol); - if (!Flags) { - consumeError(Flags.takeError()); - continue; - } - SymbolTable.insert( - std::make_pair(*SymbolName, JITEvaluatedSymbol(0, *Flags))); - } - } - - // Contains the information needed prior to finalization: the object files, - // memory manager, resolver, and flags needed for RuntimeDyld. - struct PreFinalizeContents { - PreFinalizeContents(OwnedObject Obj, - std::shared_ptr<SymbolResolver> Resolver, - bool ProcessAllSections) - : Obj(std::move(Obj)), - Resolver(std::move(Resolver)), - ProcessAllSections(ProcessAllSections) {} - - OwnedObject Obj; - std::shared_ptr<SymbolResolver> Resolver; - bool ProcessAllSections; - std::unique_ptr<RuntimeDyld> RTDyld; - }; - - VModuleKey K; - LegacyRTDyldObjectLinkingLayer &Parent; - MemoryManagerPtrT MemMgr; - OwnedObject ObjForNotify; - std::unique_ptr<PreFinalizeContents> PFC; - }; - - template <typename MemoryManagerPtrT> - std::unique_ptr<ConcreteLinkedObject<MemoryManagerPtrT>> - createLinkedObject(LegacyRTDyldObjectLinkingLayer &Parent, VModuleKey K, - OwnedObject Obj, MemoryManagerPtrT MemMgr, - std::shared_ptr<SymbolResolver> Resolver, - bool ProcessAllSections) { - using LOS = ConcreteLinkedObject<MemoryManagerPtrT>; - return std::make_unique<LOS>(Parent, std::move(K), std::move(Obj), - std::move(MemMgr), std::move(Resolver), - ProcessAllSections); - } - -public: - struct Resources { - std::shared_ptr<RuntimeDyld::MemoryManager> MemMgr; - std::shared_ptr<SymbolResolver> Resolver; - }; - - using ResourcesGetter = std::function<Resources(VModuleKey)>; - - /// Construct an ObjectLinkingLayer with the given NotifyLoaded, - /// and NotifyFinalized functors. - LLVM_ATTRIBUTE_DEPRECATED( - LegacyRTDyldObjectLinkingLayer( - ExecutionSession &ES, ResourcesGetter GetResources, - NotifyLoadedFtor NotifyLoaded = NotifyLoadedFtor(), - NotifyFinalizedFtor NotifyFinalized = NotifyFinalizedFtor(), - NotifyFreedFtor NotifyFreed = NotifyFreedFtor()), - "ORCv1 layers (layers with the 'Legacy' prefix) are deprecated. Please " - "use " - "ORCv2 (see docs/ORCv2.rst)"); - - // Legacy layer constructor with deprecation acknowledgement. - LegacyRTDyldObjectLinkingLayer( - ORCv1DeprecationAcknowledgement, ExecutionSession &ES, - ResourcesGetter GetResources, - NotifyLoadedFtor NotifyLoaded = NotifyLoadedFtor(), - NotifyFinalizedFtor NotifyFinalized = NotifyFinalizedFtor(), - NotifyFreedFtor NotifyFreed = NotifyFreedFtor()) - : ES(ES), GetResources(std::move(GetResources)), - NotifyLoaded(std::move(NotifyLoaded)), - NotifyFinalized(std::move(NotifyFinalized)), - NotifyFreed(std::move(NotifyFreed)), ProcessAllSections(false) {} - - /// Set the 'ProcessAllSections' flag. - /// - /// If set to true, all sections in each object file will be allocated using - /// the memory manager, rather than just the sections required for execution. - /// - /// This is kludgy, and may be removed in the future. - void setProcessAllSections(bool ProcessAllSections) { - this->ProcessAllSections = ProcessAllSections; - } - - /// Add an object to the JIT. - Error addObject(VModuleKey K, ObjectPtr ObjBuffer) { - - auto Obj = - object::ObjectFile::createObjectFile(ObjBuffer->getMemBufferRef()); - if (!Obj) - return Obj.takeError(); - - assert(!LinkedObjects.count(K) && "VModuleKey already in use"); - - auto R = GetResources(K); - - LinkedObjects[K] = createLinkedObject( - *this, K, OwnedObject(std::move(*Obj), std::move(ObjBuffer)), - std::move(R.MemMgr), std::move(R.Resolver), ProcessAllSections); - - return Error::success(); - } - - /// Remove the object associated with VModuleKey K. - /// - /// All memory allocated for the object will be freed, and the sections and - /// symbols it provided will no longer be available. No attempt is made to - /// re-emit the missing symbols, and any use of these symbols (directly or - /// indirectly) will result in undefined behavior. If dependence tracking is - /// required to detect or resolve such issues it should be added at a higher - /// layer. - Error removeObject(VModuleKey K) { - assert(LinkedObjects.count(K) && "VModuleKey not associated with object"); - // How do we invalidate the symbols in H? - LinkedObjects.erase(K); - return Error::success(); - } - - /// Search for the given named symbol. - /// @param Name The name of the symbol to search for. - /// @param ExportedSymbolsOnly If true, search only for exported symbols. - /// @return A handle for the given named symbol, if it exists. - JITSymbol findSymbol(StringRef Name, bool ExportedSymbolsOnly) { - for (auto &KV : LinkedObjects) - if (auto Sym = KV.second->getSymbol(Name, ExportedSymbolsOnly)) - return Sym; - else if (auto Err = Sym.takeError()) - return std::move(Err); - - return nullptr; - } - - /// Search for the given named symbol in the context of the loaded - /// object represented by the VModuleKey K. - /// @param K The VModuleKey for the object to search in. - /// @param Name The name of the symbol to search for. - /// @param ExportedSymbolsOnly If true, search only for exported symbols. - /// @return A handle for the given named symbol, if it is found in the - /// given object. - JITSymbol findSymbolIn(VModuleKey K, StringRef Name, - bool ExportedSymbolsOnly) { - assert(LinkedObjects.count(K) && "VModuleKey not associated with object"); - return LinkedObjects[K]->getSymbol(Name, ExportedSymbolsOnly); - } - - /// Map section addresses for the object associated with the - /// VModuleKey K. - void mapSectionAddress(VModuleKey K, const void *LocalAddress, - JITTargetAddress TargetAddr) { - assert(LinkedObjects.count(K) && "VModuleKey not associated with object"); - LinkedObjects[K]->mapSectionAddress(LocalAddress, TargetAddr); - } - - /// Immediately emit and finalize the object represented by the given - /// VModuleKey. - /// @param K VModuleKey for object to emit/finalize. - Error emitAndFinalize(VModuleKey K) { - assert(LinkedObjects.count(K) && "VModuleKey not associated with object"); - return LinkedObjects[K]->finalize(); - } - -private: - ExecutionSession &ES; - - ResourcesGetter GetResources; - NotifyLoadedFtor NotifyLoaded; - NotifyFinalizedFtor NotifyFinalized; - NotifyFreedFtor NotifyFreed; - - // NB! `LinkedObjects` needs to be destroyed before `NotifyFreed` because - // `~ConcreteLinkedObject` calls `NotifyFreed` - std::map<VModuleKey, std::unique_ptr<LinkedObject>> LinkedObjects; - bool ProcessAllSections = false; }; } // end namespace orc |