aboutsummaryrefslogtreecommitdiff
path: root/include/llvm/ExecutionEngine/Orc/ObjectLinkingLayer.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/llvm/ExecutionEngine/Orc/ObjectLinkingLayer.h')
-rw-r--r--include/llvm/ExecutionEngine/Orc/ObjectLinkingLayer.h362
1 files changed, 0 insertions, 362 deletions
diff --git a/include/llvm/ExecutionEngine/Orc/ObjectLinkingLayer.h b/include/llvm/ExecutionEngine/Orc/ObjectLinkingLayer.h
deleted file mode 100644
index 0588d2228598..000000000000
--- a/include/llvm/ExecutionEngine/Orc/ObjectLinkingLayer.h
+++ /dev/null
@@ -1,362 +0,0 @@
-//===- ObjectLinkingLayer.h - Add object files to a JIT process -*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// Contains the definition for the object layer of the JIT.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_EXECUTIONENGINE_ORC_OBJECTLINKINGLAYER_H
-#define LLVM_EXECUTIONENGINE_ORC_OBJECTLINKINGLAYER_H
-
-#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 <cassert>
-#include <algorithm>
-#include <functional>
-#include <list>
-#include <memory>
-#include <string>
-#include <utility>
-#include <vector>
-
-namespace llvm {
-namespace orc {
-
-class ObjectLinkingLayerBase {
-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
- /// had been provided by this instance. Higher level layers are responsible
- /// for taking any action required to handle the missing symbols.
- class LinkedObjectSet {
- public:
- LinkedObjectSet() = default;
- LinkedObjectSet(const LinkedObjectSet&) = delete;
- void operator=(const LinkedObjectSet&) = delete;
- virtual ~LinkedObjectSet() = default;
-
- virtual void 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(Name),
- SymEntry->second.getFlags());
- return JITSymbol(SymEntry->second);
- }
-
- protected:
- StringMap<JITEvaluatedSymbol> SymbolTable;
- bool Finalized = false;
- };
-
- typedef std::list<std::unique_ptr<LinkedObjectSet>> LinkedObjectSetListT;
-
-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()(ObjectLinkingLayerBase::ObjSetHandleT, const ObjSetT &,
- const LoadResult &) {}
-};
-
-/// @brief 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.
-template <typename NotifyLoadedFtor = DoNothingOnNotifyLoaded>
-class ObjectLinkingLayer : public ObjectLinkingLayerBase {
-public:
- /// @brief Functor for receiving finalization notifications.
- typedef std::function<void(ObjSetHandleT)> NotifyFinalizedFtor;
-
-private:
- template <typename ObjSetT, typename MemoryManagerPtrT,
- typename SymbolResolverPtrT, typename FinalizerFtor>
- class ConcreteLinkedObjectSet : public LinkedObjectSet {
- public:
- ConcreteLinkedObjectSet(ObjSetT Objects, MemoryManagerPtrT MemMgr,
- SymbolResolverPtrT Resolver,
- FinalizerFtor Finalizer,
- bool ProcessAllSections)
- : MemMgr(std::move(MemMgr)),
- PFC(llvm::make_unique<PreFinalizeContents>(std::move(Objects),
- std::move(Resolver),
- std::move(Finalizer),
- ProcessAllSections)) {
- buildInitialSymbolTable(PFC->Objects);
- }
-
- void setHandle(ObjSetHandleT H) {
- PFC->Handle = H;
- }
-
- void finalize() override {
- assert(PFC && "mapSectionAddress called on finalized LinkedObjectSet");
-
- RuntimeDyld RTDyld(*MemMgr, *PFC->Resolver);
- RTDyld.setProcessAllSections(PFC->ProcessAllSections);
- PFC->RTDyld = &RTDyld;
-
- this->Finalized = true;
- PFC->Finalizer(PFC->Handle, RTDyld, std::move(PFC->Objects),
- [&]() {
- this->updateSymbolTable(RTDyld);
- });
-
- // Release resources.
- PFC = nullptr;
- }
-
- JITSymbol::GetAddressFtor getSymbolMaterializer(std::string Name) override {
- return
- [this, Name]() {
- // The symbol may be materialized between the creation of this lambda
- // and its execution, so we need to double check.
- if (!this->Finalized)
- this->finalize();
- return this->getSymbol(Name, false).getAddress();
- };
- }
-
- void mapSectionAddress(const void *LocalAddress,
- JITTargetAddress TargetAddr) const override {
- assert(PFC && "mapSectionAddress called on finalized LinkedObjectSet");
- assert(PFC->RTDyld && "mapSectionAddress called on raw LinkedObjectSet");
- 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 updateSymbolTable(const RuntimeDyld &RTDyld) {
- for (auto &SymEntry : SymbolTable)
- SymEntry.second = RTDyld.getSymbol(SymEntry.first());
- }
-
- // 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,
- FinalizerFtor Finalizer, bool ProcessAllSections)
- : Objects(std::move(Objects)), Resolver(std::move(Resolver)),
- Finalizer(std::move(Finalizer)),
- ProcessAllSections(ProcessAllSections) {}
-
- ObjSetT Objects;
- SymbolResolverPtrT Resolver;
- FinalizerFtor Finalizer;
- bool ProcessAllSections;
- ObjSetHandleT Handle;
- RuntimeDyld *RTDyld;
- };
-
- MemoryManagerPtrT MemMgr;
- std::unique_ptr<PreFinalizeContents> PFC;
- };
-
- template <typename ObjSetT, 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),
- 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.
- ObjectLinkingLayer(
- NotifyLoadedFtor NotifyLoaded = NotifyLoadedFtor(),
- NotifyFinalizedFtor NotifyFinalized = NotifyFinalizedFtor())
- : NotifyLoaded(std::move(NotifyLoaded)),
- NotifyFinalized(std::move(NotifyFinalized)),
- ProcessAllSections(false) {}
-
- /// @brief 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;
- }
-
- /// @brief Add a set of objects (or archives) that will be treated as a unit
- /// for the purposes of symbol lookup and memory management.
- ///
- /// @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,
- 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;
-
- for (auto &Obj : Objs)
- LoadedObjInfos.push_back(RTDyld.loadObject(this->getObject(*Obj)));
-
- LOSHandleLoad();
-
- this->NotifyLoaded(H, Objs, LoadedObjInfos);
-
- RTDyld.finalizeWithMemoryManagerLocking();
-
- if (this->NotifyFinalized)
- this->NotifyFinalized(H);
- };
-
- auto LOS =
- createLinkedObjectSet(std::move(Objects), 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();
-
- ObjSetHandleT Handle = LinkedObjSetList.insert(LinkedObjSetList.end(),
- std::move(LOS));
- LOSPtr->setHandle(Handle);
-
- return Handle;
- }
-
- /// @brief Remove the set of objects associated with handle H.
- ///
- /// All memory allocated for the objects will be freed, and the sections and
- /// symbols they 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.
- void removeObjectSet(ObjSetHandleT H) {
- // How do we invalidate the symbols in H?
- LinkedObjSetList.erase(H);
- }
-
- /// @brief 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 I = LinkedObjSetList.begin(), E = LinkedObjSetList.end(); I != E;
- ++I)
- if (auto Symbol = findSymbolIn(I, Name, ExportedSymbolsOnly))
- return Symbol;
-
- return nullptr;
- }
-
- /// @brief Search for the given named symbol in the context of the set of
- /// loaded objects represented by the handle H.
- /// @param H The handle for the object set 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 set.
- JITSymbol findSymbolIn(ObjSetHandleT 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,
- JITTargetAddress TargetAddr) {
- (*H)->mapSectionAddress(LocalAddress, TargetAddr);
- }
-
- /// @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) {
- (*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;
- NotifyLoadedFtor NotifyLoaded;
- NotifyFinalizedFtor NotifyFinalized;
- bool ProcessAllSections;
-};
-
-} // end namespace orc
-} // end namespace llvm
-
-#endif // LLVM_EXECUTIONENGINE_ORC_OBJECTLINKINGLAYER_H