summaryrefslogtreecommitdiff
path: root/include/llvm/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/llvm/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.h')
-rw-r--r--include/llvm/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.h206
1 files changed, 96 insertions, 110 deletions
diff --git a/include/llvm/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.h b/include/llvm/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.h
index aabb44eef99dc..66ad36be01c8d 100644
--- a/include/llvm/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.h
+++ b/include/llvm/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.h
@@ -1,4 +1,4 @@
-//===-- RTDyldObjectLinkingLayer.h - RTDyld-based jit linking --*- C++ -*-===//
+//===- RTDyldObjectLinkingLayer.h - RTDyld-based jit linking ---*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -17,10 +17,8 @@
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/StringRef.h"
-#include "llvm/ExecutionEngine/ExecutionEngine.h"
#include "llvm/ExecutionEngine/JITSymbol.h"
#include "llvm/ExecutionEngine/RuntimeDyld.h"
-#include "llvm/ExecutionEngine/SectionMemoryManager.h"
#include "llvm/Object/ObjectFile.h"
#include "llvm/Support/Error.h"
#include <algorithm>
@@ -36,20 +34,26 @@ namespace llvm {
namespace orc {
class RTDyldObjectLinkingLayerBase {
+public:
+
+ using ObjectPtr =
+ std::shared_ptr<object::OwningBinary<object::ObjectFile>>;
+
protected:
+
/// @brief Holds a set of objects to be allocated/linked as a unit in the JIT.
///
/// An instance of this class will be created for each set of objects added
- /// via JITObjectLayer::addObjectSet. Deleting the instance (via
- /// removeObjectSet) frees its memory, removing all symbol definitions that
+ /// 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 LinkedObjectSet {
+ class LinkedObject {
public:
- LinkedObjectSet() = default;
- LinkedObjectSet(const LinkedObjectSet&) = delete;
- void operator=(const LinkedObjectSet&) = delete;
- virtual ~LinkedObjectSet() = default;
+ LinkedObject() = default;
+ LinkedObject(const LinkedObject&) = delete;
+ void operator=(const LinkedObject&) = delete;
+ virtual ~LinkedObject() = default;
virtual void finalize() = 0;
@@ -76,19 +80,11 @@ protected:
bool Finalized = false;
};
- typedef std::list<std::unique_ptr<LinkedObjectSet>> LinkedObjectSetListT;
+ using LinkedObjectListT = std::list<std::unique_ptr<LinkedObject>>;
public:
/// @brief Handle to a set of loaded objects.
- typedef LinkedObjectSetListT::iterator ObjSetHandleT;
-};
-
-/// @brief Default (no-op) action to perform when loading objects.
-class DoNothingOnNotifyLoaded {
-public:
- template <typename ObjSetT, typename LoadResult>
- void operator()(RTDyldObjectLinkingLayerBase::ObjSetHandleT, const ObjSetT &,
- const LoadResult &) {}
+ using ObjHandleT = LinkedObjectListT::iterator;
};
/// @brief Bare bones object linking layer.
@@ -97,46 +93,54 @@ public:
/// 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.
-template <typename NotifyLoadedFtor = DoNothingOnNotifyLoaded>
class RTDyldObjectLinkingLayer : public RTDyldObjectLinkingLayerBase {
public:
+
+ using RTDyldObjectLinkingLayerBase::ObjectPtr;
+
+ /// @brief Functor for receiving object-loaded notifications.
+ using NotifyLoadedFtor = std::function<void(ObjHandleT, const ObjectPtr &Obj,
+ const LoadedObjectInfo &)>;
+
/// @brief Functor for receiving finalization notifications.
- typedef std::function<void(ObjSetHandleT)> NotifyFinalizedFtor;
+ using NotifyFinalizedFtor = std::function<void(ObjHandleT)>;
private:
- template <typename ObjSetT, typename MemoryManagerPtrT,
- typename SymbolResolverPtrT, typename FinalizerFtor>
- class ConcreteLinkedObjectSet : public LinkedObjectSet {
+
+
+ template <typename MemoryManagerPtrT, typename SymbolResolverPtrT,
+ typename FinalizerFtor>
+ class ConcreteLinkedObject : public LinkedObject {
public:
- ConcreteLinkedObjectSet(ObjSetT Objects, MemoryManagerPtrT MemMgr,
- SymbolResolverPtrT Resolver,
- FinalizerFtor Finalizer,
- bool ProcessAllSections)
+ ConcreteLinkedObject(ObjectPtr Obj, MemoryManagerPtrT MemMgr,
+ SymbolResolverPtrT Resolver,
+ FinalizerFtor Finalizer,
+ bool ProcessAllSections)
: MemMgr(std::move(MemMgr)),
- PFC(llvm::make_unique<PreFinalizeContents>(std::move(Objects),
+ PFC(llvm::make_unique<PreFinalizeContents>(std::move(Obj),
std::move(Resolver),
std::move(Finalizer),
ProcessAllSections)) {
- buildInitialSymbolTable(PFC->Objects);
+ buildInitialSymbolTable(PFC->Obj);
}
- ~ConcreteLinkedObjectSet() override {
+ ~ConcreteLinkedObject() override {
MemMgr->deregisterEHFrames();
}
-
- void setHandle(ObjSetHandleT H) {
+
+ void setHandle(ObjHandleT H) {
PFC->Handle = H;
}
void finalize() override {
- assert(PFC && "mapSectionAddress called on finalized LinkedObjectSet");
+ assert(PFC && "mapSectionAddress called on finalized LinkedObject");
RuntimeDyld RTDyld(*MemMgr, *PFC->Resolver);
RTDyld.setProcessAllSections(PFC->ProcessAllSections);
PFC->RTDyld = &RTDyld;
this->Finalized = true;
- PFC->Finalizer(PFC->Handle, RTDyld, std::move(PFC->Objects),
+ PFC->Finalizer(PFC->Handle, RTDyld, std::move(PFC->Obj),
[&]() {
this->updateSymbolTable(RTDyld);
});
@@ -158,27 +162,27 @@ private:
void mapSectionAddress(const void *LocalAddress,
JITTargetAddress TargetAddr) const override {
- assert(PFC && "mapSectionAddress called on finalized LinkedObjectSet");
- assert(PFC->RTDyld && "mapSectionAddress called on raw LinkedObjectSet");
+ assert(PFC && "mapSectionAddress called on finalized LinkedObject");
+ assert(PFC->RTDyld && "mapSectionAddress called on raw LinkedObject");
PFC->RTDyld->mapSectionAddress(LocalAddress, TargetAddr);
}
private:
- void buildInitialSymbolTable(const ObjSetT &Objects) {
- for (const auto &Obj : Objects)
- for (auto &Symbol : getObject(*Obj).symbols()) {
- if (Symbol.getFlags() & object::SymbolRef::SF_Undefined)
- continue;
- Expected<StringRef> SymbolName = Symbol.getName();
- // FIXME: Raise an error for bad symbols.
- if (!SymbolName) {
- consumeError(SymbolName.takeError());
- continue;
- }
- auto Flags = JITSymbolFlags::fromObjectSymbol(Symbol);
- SymbolTable.insert(
- std::make_pair(*SymbolName, JITEvaluatedSymbol(0, Flags)));
+
+ void buildInitialSymbolTable(const ObjectPtr &Obj) {
+ for (auto &Symbol : Obj->getBinary()->symbols()) {
+ if (Symbol.getFlags() & object::SymbolRef::SF_Undefined)
+ continue;
+ Expected<StringRef> SymbolName = Symbol.getName();
+ // FIXME: Raise an error for bad symbols.
+ if (!SymbolName) {
+ consumeError(SymbolName.takeError());
+ continue;
}
+ auto Flags = JITSymbolFlags::fromObjectSymbol(Symbol);
+ SymbolTable.insert(
+ std::make_pair(*SymbolName, JITEvaluatedSymbol(0, Flags)));
+ }
}
void updateSymbolTable(const RuntimeDyld &RTDyld) {
@@ -189,17 +193,17 @@ private:
// Contains the information needed prior to finalization: the object files,
// memory manager, resolver, and flags needed for RuntimeDyld.
struct PreFinalizeContents {
- PreFinalizeContents(ObjSetT Objects, SymbolResolverPtrT Resolver,
+ PreFinalizeContents(ObjectPtr Obj, SymbolResolverPtrT Resolver,
FinalizerFtor Finalizer, bool ProcessAllSections)
- : Objects(std::move(Objects)), Resolver(std::move(Resolver)),
+ : Obj(std::move(Obj)), Resolver(std::move(Resolver)),
Finalizer(std::move(Finalizer)),
ProcessAllSections(ProcessAllSections) {}
- ObjSetT Objects;
+ ObjectPtr Obj;
SymbolResolverPtrT Resolver;
FinalizerFtor Finalizer;
bool ProcessAllSections;
- ObjSetHandleT Handle;
+ ObjHandleT Handle;
RuntimeDyld *RTDyld;
};
@@ -207,27 +211,22 @@ private:
std::unique_ptr<PreFinalizeContents> PFC;
};
- template <typename ObjSetT, typename MemoryManagerPtrT,
- typename SymbolResolverPtrT, typename FinalizerFtor>
+ template <typename MemoryManagerPtrT, typename SymbolResolverPtrT,
+ typename FinalizerFtor>
std::unique_ptr<
- ConcreteLinkedObjectSet<ObjSetT, MemoryManagerPtrT,
- SymbolResolverPtrT, FinalizerFtor>>
- createLinkedObjectSet(ObjSetT Objects, MemoryManagerPtrT MemMgr,
- SymbolResolverPtrT Resolver,
- FinalizerFtor Finalizer,
- bool ProcessAllSections) {
- typedef ConcreteLinkedObjectSet<ObjSetT, MemoryManagerPtrT,
- SymbolResolverPtrT, FinalizerFtor> LOS;
- return llvm::make_unique<LOS>(std::move(Objects), std::move(MemMgr),
+ ConcreteLinkedObject<MemoryManagerPtrT, SymbolResolverPtrT, FinalizerFtor>>
+ createLinkedObject(ObjectPtr Obj, MemoryManagerPtrT MemMgr,
+ SymbolResolverPtrT Resolver,
+ FinalizerFtor Finalizer,
+ bool ProcessAllSections) {
+ using LOS = ConcreteLinkedObject<MemoryManagerPtrT, SymbolResolverPtrT,
+ FinalizerFtor>;
+ return llvm::make_unique<LOS>(std::move(Obj), std::move(MemMgr),
std::move(Resolver), std::move(Finalizer),
ProcessAllSections);
}
public:
- /// @brief LoadedObjectInfo list. Contains a list of owning pointers to
- /// RuntimeDyld::LoadedObjectInfo instances.
- typedef std::vector<std::unique_ptr<RuntimeDyld::LoadedObjectInfo>>
- LoadedObjInfoList;
/// @brief Construct an ObjectLinkingLayer with the given NotifyLoaded,
/// and NotifyFinalized functors.
@@ -235,8 +234,7 @@ public:
NotifyLoadedFtor NotifyLoaded = NotifyLoadedFtor(),
NotifyFinalizedFtor NotifyFinalized = NotifyFinalizedFtor())
: NotifyLoaded(std::move(NotifyLoaded)),
- NotifyFinalized(std::move(NotifyFinalized)),
- ProcessAllSections(false) {}
+ NotifyFinalized(std::move(NotifyFinalized)) {}
/// @brief Set the 'ProcessAllSections' flag.
///
@@ -253,23 +251,22 @@ public:
///
/// @return A handle that can be used to refer to the loaded objects (for
/// symbol searching, finalization, freeing memory, etc.).
- template <typename ObjSetT,
- typename MemoryManagerPtrT,
+ template <typename MemoryManagerPtrT,
typename SymbolResolverPtrT>
- ObjSetHandleT addObjectSet(ObjSetT Objects,
- MemoryManagerPtrT MemMgr,
- SymbolResolverPtrT Resolver) {
- auto Finalizer = [&](ObjSetHandleT H, RuntimeDyld &RTDyld,
- const ObjSetT &Objs,
- std::function<void()> LOSHandleLoad) {
- LoadedObjInfoList LoadedObjInfos;
+ ObjHandleT addObject(ObjectPtr Obj,
+ MemoryManagerPtrT MemMgr,
+ SymbolResolverPtrT Resolver) {
- for (auto &Obj : Objs)
- LoadedObjInfos.push_back(RTDyld.loadObject(this->getObject(*Obj)));
+ auto Finalizer = [&](ObjHandleT H, RuntimeDyld &RTDyld,
+ const ObjectPtr &ObjToLoad,
+ std::function<void()> LOSHandleLoad) {
+ std::unique_ptr<RuntimeDyld::LoadedObjectInfo> Info =
+ RTDyld.loadObject(*ObjToLoad->getBinary());
LOSHandleLoad();
- this->NotifyLoaded(H, Objs, LoadedObjInfos);
+ if (this->NotifyLoaded)
+ this->NotifyLoaded(H, ObjToLoad, *Info);
RTDyld.finalizeWithMemoryManagerLocking();
@@ -277,17 +274,15 @@ public:
this->NotifyFinalized(H);
};
- auto LOS =
- createLinkedObjectSet(std::move(Objects), std::move(MemMgr),
- std::move(Resolver), std::move(Finalizer),
- ProcessAllSections);
+ auto LO =
+ createLinkedObject(std::move(Obj), std::move(MemMgr), std::move(Resolver),
+ std::move(Finalizer), ProcessAllSections);
// LOS is an owning-ptr. Keep a non-owning one so that we can set the handle
// below.
- auto *LOSPtr = LOS.get();
+ auto *LOPtr = LO.get();
- ObjSetHandleT Handle = LinkedObjSetList.insert(LinkedObjSetList.end(),
- std::move(LOS));
- LOSPtr->setHandle(Handle);
+ ObjHandleT Handle = LinkedObjList.insert(LinkedObjList.end(), std::move(LO));
+ LOPtr->setHandle(Handle);
return Handle;
}
@@ -300,9 +295,9 @@ public:
/// 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.
- void removeObjectSet(ObjSetHandleT H) {
+ void removeObject(ObjHandleT H) {
// How do we invalidate the symbols in H?
- LinkedObjSetList.erase(H);
+ LinkedObjList.erase(H);
}
/// @brief Search for the given named symbol.
@@ -310,7 +305,7 @@ public:
/// @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 I = LinkedObjSetList.begin(), E = LinkedObjSetList.end(); I != E;
+ for (auto I = LinkedObjList.begin(), E = LinkedObjList.end(); I != E;
++I)
if (auto Symbol = findSymbolIn(I, Name, ExportedSymbolsOnly))
return Symbol;
@@ -325,13 +320,13 @@ public:
/// @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 set.
- JITSymbol findSymbolIn(ObjSetHandleT H, StringRef Name,
+ JITSymbol findSymbolIn(ObjHandleT H, StringRef Name,
bool ExportedSymbolsOnly) {
return (*H)->getSymbol(Name, ExportedSymbolsOnly);
}
/// @brief Map section addresses for the objects associated with the handle H.
- void mapSectionAddress(ObjSetHandleT H, const void *LocalAddress,
+ void mapSectionAddress(ObjHandleT H, const void *LocalAddress,
JITTargetAddress TargetAddr) {
(*H)->mapSectionAddress(LocalAddress, TargetAddr);
}
@@ -339,25 +334,16 @@ public:
/// @brief Immediately emit and finalize the object set represented by the
/// given handle.
/// @param H Handle for object set to emit/finalize.
- void emitAndFinalize(ObjSetHandleT H) {
+ void emitAndFinalize(ObjHandleT H) {
(*H)->finalize();
}
private:
- static const object::ObjectFile& getObject(const object::ObjectFile &Obj) {
- return Obj;
- }
-
- template <typename ObjT>
- static const object::ObjectFile&
- getObject(const object::OwningBinary<ObjT> &Obj) {
- return *Obj.getBinary();
- }
- LinkedObjectSetListT LinkedObjSetList;
+ LinkedObjectListT LinkedObjList;
NotifyLoadedFtor NotifyLoaded;
NotifyFinalizedFtor NotifyFinalized;
- bool ProcessAllSections;
+ bool ProcessAllSections = false;
};
} // end namespace orc