aboutsummaryrefslogtreecommitdiff
path: root/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.h
diff options
context:
space:
mode:
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.h387
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