blob: cd9ec36da0dea08ae683be8a112026b19979b5ce [file] [log] [blame]
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01001//===- RTDyldObjectLinkingLayer.h - RTDyld-based jit linking ---*- C++ -*-===//
2//
Andrew Walbran16937d02019-10-22 13:54:20 +01003// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01006//
7//===----------------------------------------------------------------------===//
8//
9// Contains the definition for an RTDyld-based, in-process object linking layer.
10//
11//===----------------------------------------------------------------------===//
12
13#ifndef LLVM_EXECUTIONENGINE_ORC_RTDYLDOBJECTLINKINGLAYER_H
14#define LLVM_EXECUTIONENGINE_ORC_RTDYLDOBJECTLINKINGLAYER_H
15
16#include "llvm/ADT/STLExtras.h"
17#include "llvm/ADT/StringMap.h"
18#include "llvm/ADT/StringRef.h"
19#include "llvm/ExecutionEngine/JITSymbol.h"
20#include "llvm/ExecutionEngine/Orc/Core.h"
Andrew Scullcdfcccc2018-10-05 20:58:37 +010021#include "llvm/ExecutionEngine/Orc/Layer.h"
Andrew Scull5e1ddfa2018-08-14 10:06:54 +010022#include "llvm/ExecutionEngine/Orc/Legacy.h"
23#include "llvm/ExecutionEngine/RuntimeDyld.h"
24#include "llvm/Object/ObjectFile.h"
25#include "llvm/Support/Error.h"
26#include <algorithm>
27#include <cassert>
28#include <functional>
29#include <list>
30#include <memory>
31#include <string>
32#include <utility>
33#include <vector>
34
35namespace llvm {
36namespace orc {
37
Andrew Walbran16937d02019-10-22 13:54:20 +010038class RTDyldObjectLinkingLayer : public ObjectLayer {
Andrew Scullcdfcccc2018-10-05 20:58:37 +010039public:
40 /// Functor for receiving object-loaded notifications.
41 using NotifyLoadedFunction =
42 std::function<void(VModuleKey, const object::ObjectFile &Obj,
43 const RuntimeDyld::LoadedObjectInfo &)>;
44
45 /// Functor for receiving finalization notifications.
Andrew Scull0372a572018-11-16 15:47:06 +000046 using NotifyEmittedFunction = std::function<void(VModuleKey)>;
Andrew Scullcdfcccc2018-10-05 20:58:37 +010047
48 using GetMemoryManagerFunction =
Andrew Walbran16937d02019-10-22 13:54:20 +010049 std::function<std::unique_ptr<RuntimeDyld::MemoryManager>()>;
Andrew Scullcdfcccc2018-10-05 20:58:37 +010050
51 /// Construct an ObjectLinkingLayer with the given NotifyLoaded,
Andrew Scull0372a572018-11-16 15:47:06 +000052 /// and NotifyEmitted functors.
Andrew Walbran16937d02019-10-22 13:54:20 +010053 RTDyldObjectLinkingLayer(
Andrew Scullcdfcccc2018-10-05 20:58:37 +010054 ExecutionSession &ES, GetMemoryManagerFunction GetMemoryManager,
55 NotifyLoadedFunction NotifyLoaded = NotifyLoadedFunction(),
Andrew Scull0372a572018-11-16 15:47:06 +000056 NotifyEmittedFunction NotifyEmitted = NotifyEmittedFunction());
Andrew Scullcdfcccc2018-10-05 20:58:37 +010057
58 /// Emit the object.
Andrew Walbran16937d02019-10-22 13:54:20 +010059 void emit(MaterializationResponsibility R,
Andrew Scullcdfcccc2018-10-05 20:58:37 +010060 std::unique_ptr<MemoryBuffer> O) override;
61
Andrew Scullcdfcccc2018-10-05 20:58:37 +010062 /// Set the 'ProcessAllSections' flag.
63 ///
64 /// If set to true, all sections in each object file will be allocated using
65 /// the memory manager, rather than just the sections required for execution.
66 ///
67 /// This is kludgy, and may be removed in the future.
Andrew Walbran16937d02019-10-22 13:54:20 +010068 RTDyldObjectLinkingLayer &setProcessAllSections(bool ProcessAllSections) {
Andrew Scullcdfcccc2018-10-05 20:58:37 +010069 this->ProcessAllSections = ProcessAllSections;
Andrew Scull0372a572018-11-16 15:47:06 +000070 return *this;
71 }
72
73 /// Instructs this RTDyldLinkingLayer2 instance to override the symbol flags
74 /// returned by RuntimeDyld for any given object file with the flags supplied
75 /// by the MaterializationResponsibility instance. This is a workaround to
76 /// support symbol visibility in COFF, which does not use the libObject's
77 /// SF_Exported flag. Use only when generating / adding COFF object files.
78 ///
79 /// FIXME: We should be able to remove this if/when COFF properly tracks
80 /// exported symbols.
Andrew Walbran16937d02019-10-22 13:54:20 +010081 RTDyldObjectLinkingLayer &
Andrew Scull0372a572018-11-16 15:47:06 +000082 setOverrideObjectFlagsWithResponsibilityFlags(bool OverrideObjectFlags) {
83 this->OverrideObjectFlags = OverrideObjectFlags;
84 return *this;
85 }
86
Andrew Walbran16937d02019-10-22 13:54:20 +010087 /// If set, this RTDyldObjectLinkingLayer instance will claim responsibility
Andrew Scull0372a572018-11-16 15:47:06 +000088 /// for any symbols provided by a given object file that were not already in
89 /// the MaterializationResponsibility instance. Setting this flag allows
90 /// higher-level program representations (e.g. LLVM IR) to be added based on
91 /// only a subset of the symbols they provide, without having to write
92 /// intervening layers to scan and add the additional symbols. This trades
93 /// diagnostic quality for convenience however: If all symbols are enumerated
94 /// up-front then clashes can be detected and reported early (and usually
95 /// deterministically). If this option is set, clashes for the additional
96 /// symbols may not be detected until late, and detection may depend on
97 /// the flow of control through JIT'd code. Use with care.
Andrew Walbran16937d02019-10-22 13:54:20 +010098 RTDyldObjectLinkingLayer &
Andrew Scull0372a572018-11-16 15:47:06 +000099 setAutoClaimResponsibilityForObjectSymbols(bool AutoClaimObjectSymbols) {
100 this->AutoClaimObjectSymbols = AutoClaimObjectSymbols;
101 return *this;
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100102 }
103
104private:
Andrew Scull0372a572018-11-16 15:47:06 +0000105 Error onObjLoad(VModuleKey K, MaterializationResponsibility &R,
106 object::ObjectFile &Obj,
107 std::unique_ptr<RuntimeDyld::LoadedObjectInfo> LoadedObjInfo,
108 std::map<StringRef, JITEvaluatedSymbol> Resolved,
109 std::set<StringRef> &InternalSymbols);
110
111 void onObjEmit(VModuleKey K, MaterializationResponsibility &R, Error Err);
112
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100113 mutable std::mutex RTDyldLayerMutex;
114 GetMemoryManagerFunction GetMemoryManager;
115 NotifyLoadedFunction NotifyLoaded;
Andrew Scull0372a572018-11-16 15:47:06 +0000116 NotifyEmittedFunction NotifyEmitted;
117 bool ProcessAllSections = false;
118 bool OverrideObjectFlags = false;
119 bool AutoClaimObjectSymbols = false;
Andrew Walbran16937d02019-10-22 13:54:20 +0100120 std::vector<std::unique_ptr<RuntimeDyld::MemoryManager>> MemMgrs;
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100121};
122
Andrew Walbran16937d02019-10-22 13:54:20 +0100123class LegacyRTDyldObjectLinkingLayerBase {
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100124public:
125 using ObjectPtr = std::unique_ptr<MemoryBuffer>;
126
127protected:
128
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100129 /// Holds an object to be allocated/linked as a unit in the JIT.
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100130 ///
131 /// An instance of this class will be created for each object added
132 /// via JITObjectLayer::addObject. Deleting the instance (via
133 /// removeObject) frees its memory, removing all symbol definitions that
134 /// had been provided by this instance. Higher level layers are responsible
135 /// for taking any action required to handle the missing symbols.
136 class LinkedObject {
137 public:
138 LinkedObject() = default;
139 LinkedObject(const LinkedObject&) = delete;
140 void operator=(const LinkedObject&) = delete;
141 virtual ~LinkedObject() = default;
142
143 virtual Error finalize() = 0;
144
145 virtual JITSymbol::GetAddressFtor
146 getSymbolMaterializer(std::string Name) = 0;
147
148 virtual void mapSectionAddress(const void *LocalAddress,
149 JITTargetAddress TargetAddr) const = 0;
150
151 JITSymbol getSymbol(StringRef Name, bool ExportedSymbolsOnly) {
152 auto SymEntry = SymbolTable.find(Name);
153 if (SymEntry == SymbolTable.end())
154 return nullptr;
155 if (!SymEntry->second.getFlags().isExported() && ExportedSymbolsOnly)
156 return nullptr;
157 if (!Finalized)
158 return JITSymbol(getSymbolMaterializer(Name),
159 SymEntry->second.getFlags());
160 return JITSymbol(SymEntry->second);
161 }
162
163 protected:
164 StringMap<JITEvaluatedSymbol> SymbolTable;
165 bool Finalized = false;
166 };
167};
168
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100169/// Bare bones object linking layer.
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100170///
171/// This class is intended to be used as the base layer for a JIT. It allows
172/// object files to be loaded into memory, linked, and the addresses of their
173/// symbols queried. All objects added to this layer can see each other's
174/// symbols.
Andrew Walbran16937d02019-10-22 13:54:20 +0100175class LegacyRTDyldObjectLinkingLayer : public LegacyRTDyldObjectLinkingLayerBase {
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100176public:
177
Andrew Walbran16937d02019-10-22 13:54:20 +0100178 using LegacyRTDyldObjectLinkingLayerBase::ObjectPtr;
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100179
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100180 /// Functor for receiving object-loaded notifications.
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100181 using NotifyLoadedFtor =
182 std::function<void(VModuleKey, const object::ObjectFile &Obj,
183 const RuntimeDyld::LoadedObjectInfo &)>;
184
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100185 /// Functor for receiving finalization notifications.
186 using NotifyFinalizedFtor =
187 std::function<void(VModuleKey, const object::ObjectFile &Obj,
188 const RuntimeDyld::LoadedObjectInfo &)>;
189
190 /// Functor for receiving deallocation notifications.
191 using NotifyFreedFtor = std::function<void(VModuleKey, const object::ObjectFile &Obj)>;
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100192
193private:
194 using OwnedObject = object::OwningBinary<object::ObjectFile>;
195
196 template <typename MemoryManagerPtrT>
197 class ConcreteLinkedObject : public LinkedObject {
198 public:
Andrew Walbran16937d02019-10-22 13:54:20 +0100199 ConcreteLinkedObject(LegacyRTDyldObjectLinkingLayer &Parent, VModuleKey K,
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100200 OwnedObject Obj, MemoryManagerPtrT MemMgr,
201 std::shared_ptr<SymbolResolver> Resolver,
202 bool ProcessAllSections)
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100203 : K(std::move(K)),
204 Parent(Parent),
205 MemMgr(std::move(MemMgr)),
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100206 PFC(llvm::make_unique<PreFinalizeContents>(
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100207 std::move(Obj), std::move(Resolver),
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100208 ProcessAllSections)) {
209 buildInitialSymbolTable(PFC->Obj);
210 }
211
212 ~ConcreteLinkedObject() override {
Andrew Scull0372a572018-11-16 15:47:06 +0000213 if (this->Parent.NotifyFreed && ObjForNotify.getBinary())
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100214 this->Parent.NotifyFreed(K, *ObjForNotify.getBinary());
215
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100216 MemMgr->deregisterEHFrames();
217 }
218
219 Error finalize() override {
220 assert(PFC && "mapSectionAddress called on finalized LinkedObject");
221
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100222 JITSymbolResolverAdapter ResolverAdapter(Parent.ES, *PFC->Resolver,
223 nullptr);
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100224 PFC->RTDyld = llvm::make_unique<RuntimeDyld>(*MemMgr, ResolverAdapter);
225 PFC->RTDyld->setProcessAllSections(PFC->ProcessAllSections);
226
227 Finalized = true;
228
229 std::unique_ptr<RuntimeDyld::LoadedObjectInfo> Info =
230 PFC->RTDyld->loadObject(*PFC->Obj.getBinary());
231
232 // Copy the symbol table out of the RuntimeDyld instance.
233 {
234 auto SymTab = PFC->RTDyld->getSymbolTable();
235 for (auto &KV : SymTab)
236 SymbolTable[KV.first] = KV.second;
237 }
238
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100239 if (Parent.NotifyLoaded)
240 Parent.NotifyLoaded(K, *PFC->Obj.getBinary(), *Info);
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100241
242 PFC->RTDyld->finalizeWithMemoryManagerLocking();
243
244 if (PFC->RTDyld->hasError())
245 return make_error<StringError>(PFC->RTDyld->getErrorString(),
246 inconvertibleErrorCode());
247
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100248 if (Parent.NotifyFinalized)
249 Parent.NotifyFinalized(K, *PFC->Obj.getBinary(), *Info);
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100250
251 // Release resources.
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100252 if (this->Parent.NotifyFreed)
253 ObjForNotify = std::move(PFC->Obj); // needed for callback
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100254 PFC = nullptr;
255 return Error::success();
256 }
257
258 JITSymbol::GetAddressFtor getSymbolMaterializer(std::string Name) override {
259 return [this, Name]() -> Expected<JITTargetAddress> {
260 // The symbol may be materialized between the creation of this lambda
261 // and its execution, so we need to double check.
262 if (!this->Finalized)
263 if (auto Err = this->finalize())
264 return std::move(Err);
265 return this->getSymbol(Name, false).getAddress();
266 };
267 }
268
269 void mapSectionAddress(const void *LocalAddress,
270 JITTargetAddress TargetAddr) const override {
271 assert(PFC && "mapSectionAddress called on finalized LinkedObject");
272 assert(PFC->RTDyld && "mapSectionAddress called on raw LinkedObject");
273 PFC->RTDyld->mapSectionAddress(LocalAddress, TargetAddr);
274 }
275
276 private:
277 void buildInitialSymbolTable(const OwnedObject &Obj) {
278 for (auto &Symbol : Obj.getBinary()->symbols()) {
279 if (Symbol.getFlags() & object::SymbolRef::SF_Undefined)
280 continue;
281 Expected<StringRef> SymbolName = Symbol.getName();
282 // FIXME: Raise an error for bad symbols.
283 if (!SymbolName) {
284 consumeError(SymbolName.takeError());
285 continue;
286 }
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100287 // FIXME: Raise an error for bad symbols.
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100288 auto Flags = JITSymbolFlags::fromObjectSymbol(Symbol);
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100289 if (!Flags) {
290 consumeError(Flags.takeError());
291 continue;
292 }
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100293 SymbolTable.insert(
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100294 std::make_pair(*SymbolName, JITEvaluatedSymbol(0, *Flags)));
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100295 }
296 }
297
298 // Contains the information needed prior to finalization: the object files,
299 // memory manager, resolver, and flags needed for RuntimeDyld.
300 struct PreFinalizeContents {
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100301 PreFinalizeContents(OwnedObject Obj,
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100302 std::shared_ptr<SymbolResolver> Resolver,
303 bool ProcessAllSections)
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100304 : Obj(std::move(Obj)),
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100305 Resolver(std::move(Resolver)),
306 ProcessAllSections(ProcessAllSections) {}
307
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100308 OwnedObject Obj;
309 std::shared_ptr<SymbolResolver> Resolver;
310 bool ProcessAllSections;
311 std::unique_ptr<RuntimeDyld> RTDyld;
312 };
313
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100314 VModuleKey K;
Andrew Walbran16937d02019-10-22 13:54:20 +0100315 LegacyRTDyldObjectLinkingLayer &Parent;
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100316 MemoryManagerPtrT MemMgr;
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100317 OwnedObject ObjForNotify;
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100318 std::unique_ptr<PreFinalizeContents> PFC;
319 };
320
321 template <typename MemoryManagerPtrT>
322 std::unique_ptr<ConcreteLinkedObject<MemoryManagerPtrT>>
Andrew Walbran16937d02019-10-22 13:54:20 +0100323 createLinkedObject(LegacyRTDyldObjectLinkingLayer &Parent, VModuleKey K,
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100324 OwnedObject Obj, MemoryManagerPtrT MemMgr,
325 std::shared_ptr<SymbolResolver> Resolver,
326 bool ProcessAllSections) {
327 using LOS = ConcreteLinkedObject<MemoryManagerPtrT>;
328 return llvm::make_unique<LOS>(Parent, std::move(K), std::move(Obj),
329 std::move(MemMgr), std::move(Resolver),
330 ProcessAllSections);
331 }
332
333public:
334 struct Resources {
335 std::shared_ptr<RuntimeDyld::MemoryManager> MemMgr;
336 std::shared_ptr<SymbolResolver> Resolver;
337 };
338
339 using ResourcesGetter = std::function<Resources(VModuleKey)>;
340
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100341 /// Construct an ObjectLinkingLayer with the given NotifyLoaded,
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100342 /// and NotifyFinalized functors.
Andrew Walbran16937d02019-10-22 13:54:20 +0100343 LegacyRTDyldObjectLinkingLayer(
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100344 ExecutionSession &ES, ResourcesGetter GetResources,
345 NotifyLoadedFtor NotifyLoaded = NotifyLoadedFtor(),
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100346 NotifyFinalizedFtor NotifyFinalized = NotifyFinalizedFtor(),
347 NotifyFreedFtor NotifyFreed = NotifyFreedFtor())
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100348 : ES(ES), GetResources(std::move(GetResources)),
349 NotifyLoaded(std::move(NotifyLoaded)),
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100350 NotifyFinalized(std::move(NotifyFinalized)),
351 NotifyFreed(std::move(NotifyFreed)),
352 ProcessAllSections(false) {
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100353 }
354
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100355 /// Set the 'ProcessAllSections' flag.
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100356 ///
357 /// If set to true, all sections in each object file will be allocated using
358 /// the memory manager, rather than just the sections required for execution.
359 ///
360 /// This is kludgy, and may be removed in the future.
361 void setProcessAllSections(bool ProcessAllSections) {
362 this->ProcessAllSections = ProcessAllSections;
363 }
364
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100365 /// Add an object to the JIT.
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100366 Error addObject(VModuleKey K, ObjectPtr ObjBuffer) {
367
368 auto Obj =
369 object::ObjectFile::createObjectFile(ObjBuffer->getMemBufferRef());
370 if (!Obj)
371 return Obj.takeError();
372
373 assert(!LinkedObjects.count(K) && "VModuleKey already in use");
374
375 auto R = GetResources(K);
376
377 LinkedObjects[K] = createLinkedObject(
378 *this, K, OwnedObject(std::move(*Obj), std::move(ObjBuffer)),
379 std::move(R.MemMgr), std::move(R.Resolver), ProcessAllSections);
380
381 return Error::success();
382 }
383
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100384 /// Remove the object associated with VModuleKey K.
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100385 ///
386 /// All memory allocated for the object will be freed, and the sections and
387 /// symbols it provided will no longer be available. No attempt is made to
388 /// re-emit the missing symbols, and any use of these symbols (directly or
389 /// indirectly) will result in undefined behavior. If dependence tracking is
390 /// required to detect or resolve such issues it should be added at a higher
391 /// layer.
392 Error removeObject(VModuleKey K) {
393 assert(LinkedObjects.count(K) && "VModuleKey not associated with object");
394 // How do we invalidate the symbols in H?
395 LinkedObjects.erase(K);
396 return Error::success();
397 }
398
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100399 /// Search for the given named symbol.
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100400 /// @param Name The name of the symbol to search for.
401 /// @param ExportedSymbolsOnly If true, search only for exported symbols.
402 /// @return A handle for the given named symbol, if it exists.
403 JITSymbol findSymbol(StringRef Name, bool ExportedSymbolsOnly) {
404 for (auto &KV : LinkedObjects)
405 if (auto Sym = KV.second->getSymbol(Name, ExportedSymbolsOnly))
406 return Sym;
407 else if (auto Err = Sym.takeError())
408 return std::move(Err);
409
410 return nullptr;
411 }
412
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100413 /// Search for the given named symbol in the context of the loaded
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100414 /// object represented by the VModuleKey K.
415 /// @param K The VModuleKey for the object to search in.
416 /// @param Name The name of the symbol to search for.
417 /// @param ExportedSymbolsOnly If true, search only for exported symbols.
418 /// @return A handle for the given named symbol, if it is found in the
419 /// given object.
420 JITSymbol findSymbolIn(VModuleKey K, StringRef Name,
421 bool ExportedSymbolsOnly) {
422 assert(LinkedObjects.count(K) && "VModuleKey not associated with object");
423 return LinkedObjects[K]->getSymbol(Name, ExportedSymbolsOnly);
424 }
425
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100426 /// Map section addresses for the object associated with the
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100427 /// VModuleKey K.
428 void mapSectionAddress(VModuleKey K, const void *LocalAddress,
429 JITTargetAddress TargetAddr) {
430 assert(LinkedObjects.count(K) && "VModuleKey not associated with object");
431 LinkedObjects[K]->mapSectionAddress(LocalAddress, TargetAddr);
432 }
433
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100434 /// Immediately emit and finalize the object represented by the given
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100435 /// VModuleKey.
436 /// @param K VModuleKey for object to emit/finalize.
437 Error emitAndFinalize(VModuleKey K) {
438 assert(LinkedObjects.count(K) && "VModuleKey not associated with object");
439 return LinkedObjects[K]->finalize();
440 }
441
442private:
443 ExecutionSession &ES;
444
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100445 ResourcesGetter GetResources;
446 NotifyLoadedFtor NotifyLoaded;
447 NotifyFinalizedFtor NotifyFinalized;
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100448 NotifyFreedFtor NotifyFreed;
Andrew Walbran16937d02019-10-22 13:54:20 +0100449
450 // NB! `LinkedObjects` needs to be destroyed before `NotifyFreed` because
451 // `~ConcreteLinkedObject` calls `NotifyFreed`
452 std::map<VModuleKey, std::unique_ptr<LinkedObject>> LinkedObjects;
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100453 bool ProcessAllSections = false;
454};
455
456} // end namespace orc
457} // end namespace llvm
458
459#endif // LLVM_EXECUTIONENGINE_ORC_RTDYLDOBJECTLINKINGLAYER_H