1 //===- ObjectLinkingLayer.h - Add object files to a JIT process -*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // Contains the definition for the object layer of the JIT.
12 //===----------------------------------------------------------------------===//
14 #ifndef LLVM_EXECUTIONENGINE_ORC_OBJECTLINKINGLAYER_H
15 #define LLVM_EXECUTIONENGINE_ORC_OBJECTLINKINGLAYER_H
17 #include "LookasideRTDyldMM.h"
18 #include "llvm/ExecutionEngine/ExecutionEngine.h"
19 #include "llvm/ExecutionEngine/SectionMemoryManager.h"
25 class ObjectLinkingLayerBase {
27 /// @brief Holds a set of objects to be allocated/linked as a unit in the JIT.
29 /// An instance of this class will be created for each set of objects added
30 /// via JITObjectLayer::addObjectSet. Deleting the instance (via
31 /// removeObjectSet) frees its memory, removing all symbol definitions that
32 /// had been provided by this instance. Higher level layers are responsible
33 /// for taking any action required to handle the missing symbols.
34 class LinkedObjectSet {
35 LinkedObjectSet(const LinkedObjectSet&) LLVM_DELETED_FUNCTION;
36 void operator=(const LinkedObjectSet&) LLVM_DELETED_FUNCTION;
38 LinkedObjectSet(std::unique_ptr<RTDyldMemoryManager> MM)
39 : MM(std::move(MM)), RTDyld(llvm::make_unique<RuntimeDyld>(&*this->MM)),
42 // MSVC 2012 cannot infer a move constructor, so write it out longhand.
43 LinkedObjectSet(LinkedObjectSet &&O)
44 : MM(std::move(O.MM)), RTDyld(std::move(O.RTDyld)), State(O.State) {}
46 std::unique_ptr<RuntimeDyld::LoadedObjectInfo>
47 addObject(const object::ObjectFile &Obj) {
48 return RTDyld->loadObject(Obj);
51 uint64_t getSymbolAddress(StringRef Name, bool ExportedSymbolsOnly) {
52 if (ExportedSymbolsOnly)
53 return RTDyld->getExportedSymbolLoadAddress(Name);
54 return RTDyld->getSymbolLoadAddress(Name);
57 bool NeedsFinalization() const { return (State == Raw); }
61 RTDyld->resolveRelocations();
62 RTDyld->registerEHFrames();
68 void mapSectionAddress(const void *LocalAddress, uint64_t TargetAddress) {
69 assert((State != Finalized) &&
70 "Attempting to remap sections for finalized objects.");
71 RTDyld->mapSectionAddress(LocalAddress, TargetAddress);
74 void takeOwnershipOfBuffer(std::unique_ptr<MemoryBuffer> B) {
75 OwnedBuffers.push_back(std::move(B));
79 std::unique_ptr<RTDyldMemoryManager> MM;
80 std::unique_ptr<RuntimeDyld> RTDyld;
81 enum { Raw, Finalizing, Finalized } State;
83 // FIXME: This ownership hack only exists because RuntimeDyldELF still
84 // wants to be able to inspect the original object when resolving
85 // relocations. As soon as that can be fixed this should be removed.
86 std::vector<std::unique_ptr<MemoryBuffer>> OwnedBuffers;
89 typedef std::list<LinkedObjectSet> LinkedObjectSetListT;
92 /// @brief Handle to a set of loaded objects.
93 typedef LinkedObjectSetListT::iterator ObjSetHandleT;
96 // FIXME: Remove this as soon as RuntimeDyldELF can apply relocations without
97 // referencing the original object.
98 template <typename OwningMBSet>
99 void takeOwnershipOfBuffers(ObjSetHandleT H, OwningMBSet MBs) {
101 H->takeOwnershipOfBuffer(std::move(MB));
106 /// @brief Default (no-op) action to perform when loading objects.
107 class DoNothingOnNotifyLoaded {
109 template <typename ObjSetT, typename LoadResult>
110 void operator()(ObjectLinkingLayerBase::ObjSetHandleT, const ObjSetT &,
111 const LoadResult &) {}
114 /// @brief Bare bones object linking layer.
116 /// This class is intended to be used as the base layer for a JIT. It allows
117 /// object files to be loaded into memory, linked, and the addresses of their
118 /// symbols queried. All objects added to this layer can see each other's
120 template <typename NotifyLoadedFtor = DoNothingOnNotifyLoaded>
121 class ObjectLinkingLayer : public ObjectLinkingLayerBase {
124 /// @brief LoadedObjectInfo list. Contains a list of owning pointers to
125 /// RuntimeDyld::LoadedObjectInfo instances.
126 typedef std::vector<std::unique_ptr<RuntimeDyld::LoadedObjectInfo>>
129 /// @brief Functor to create RTDyldMemoryManager instances.
130 typedef std::function<std::unique_ptr<RTDyldMemoryManager>()> CreateRTDyldMMFtor;
132 /// @brief Functor for receiving finalization notifications.
133 typedef std::function<void(ObjSetHandleT)> NotifyFinalizedFtor;
135 /// @brief Construct an ObjectLinkingLayer with the given NotifyLoaded,
136 /// NotifyFinalized and CreateMemoryManager functors.
138 CreateRTDyldMMFtor CreateMemoryManager = CreateRTDyldMMFtor(),
139 NotifyLoadedFtor NotifyLoaded = NotifyLoadedFtor(),
140 NotifyFinalizedFtor NotifyFinalized = NotifyFinalizedFtor())
141 : NotifyLoaded(std::move(NotifyLoaded)),
142 NotifyFinalized(std::move(NotifyFinalized)),
143 CreateMemoryManager(std::move(CreateMemoryManager)) {}
145 /// @brief Add a set of objects (or archives) that will be treated as a unit
146 /// for the purposes of symbol lookup and memory management.
148 /// @return A pair containing (1) A handle that can be used to free the memory
149 /// allocated for the objects, and (2) a LoadedObjInfoList containing
150 /// one LoadedObjInfo instance for each object at the corresponding
151 /// index in the Objects list.
153 /// This version of this method allows the client to pass in an
154 /// RTDyldMemoryManager instance that will be used to allocate memory and look
155 /// up external symbol addresses for the given objects.
156 template <typename ObjSetT>
157 ObjSetHandleT addObjectSet(const ObjSetT &Objects,
158 std::unique_ptr<RTDyldMemoryManager> MM) {
161 assert(CreateMemoryManager &&
162 "No memory manager or memory manager creator provided.");
163 MM = CreateMemoryManager();
166 ObjSetHandleT Handle = LinkedObjSetList.insert(
167 LinkedObjSetList.end(), LinkedObjectSet(std::move(MM)));
168 LinkedObjectSet &LOS = *Handle;
169 LoadedObjInfoList LoadedObjInfos;
171 for (auto &Obj : Objects)
172 LoadedObjInfos.push_back(LOS.addObject(*Obj));
174 NotifyLoaded(Handle, Objects, LoadedObjInfos);
179 /// @brief Map section addresses for the objects associated with the handle H.
180 void mapSectionAddress(ObjSetHandleT H, const void *LocalAddress,
181 uint64_t TargetAddress) {
182 H->mapSectionAddress(LocalAddress, TargetAddress);
185 /// @brief Remove the set of objects associated with handle H.
187 /// All memory allocated for the objects will be freed, and the sections and
188 /// symbols they provided will no longer be available. No attempt is made to
189 /// re-emit the missing symbols, and any use of these symbols (directly or
190 /// indirectly) will result in undefined behavior. If dependence tracking is
191 /// required to detect or resolve such issues it should be added at a higher
193 void removeObjectSet(ObjSetHandleT H) {
194 // How do we invalidate the symbols in H?
195 LinkedObjSetList.erase(H);
198 /// @brief Get the address of a loaded symbol.
200 /// @return The address in the target process's address space of the named
201 /// symbol. Null if no such symbol is known.
203 /// This method will trigger the finalization of the linked object set
204 /// containing the definition of the given symbol, if it is found.
205 uint64_t getSymbolAddress(StringRef Name, bool ExportedSymbolsOnly) {
206 for (auto I = LinkedObjSetList.begin(), E = LinkedObjSetList.end(); I != E;
208 if (uint64_t Addr = lookupSymbolAddressIn(I, Name, ExportedSymbolsOnly))
214 /// @brief Search for a given symbol in the context of the set of loaded
215 /// objects represented by the handle H.
217 /// @return The address in the target process's address space of the named
218 /// symbol. Null if the given object set does not contain a definition
221 /// This method will trigger the finalization of the linked object set
222 /// represented by the handle H if that set contains the requested symbol.
223 uint64_t lookupSymbolAddressIn(ObjSetHandleT H, StringRef Name,
224 bool ExportedSymbolsOnly) {
225 if (uint64_t Addr = H->getSymbolAddress(Name, ExportedSymbolsOnly)) {
226 if (H->NeedsFinalization()) {
237 LinkedObjectSetListT LinkedObjSetList;
238 NotifyLoadedFtor NotifyLoaded;
239 NotifyFinalizedFtor NotifyFinalized;
240 CreateRTDyldMMFtor CreateMemoryManager;
243 } // end namespace llvm
245 #endif // LLVM_EXECUTIONENGINE_ORC_OBJECTLINKINGLAYER_H