blob: 479658b11e97cef71498852c07befbaa8f3179ec [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 Walbran3d2c1972020-04-07 12:24:26 +010046 using NotifyEmittedFunction =
47 std::function<void(VModuleKey, std::unique_ptr<MemoryBuffer>)>;
Andrew Scullcdfcccc2018-10-05 20:58:37 +010048
49 using GetMemoryManagerFunction =
Andrew Walbran16937d02019-10-22 13:54:20 +010050 std::function<std::unique_ptr<RuntimeDyld::MemoryManager>()>;
Andrew Scullcdfcccc2018-10-05 20:58:37 +010051
52 /// Construct an ObjectLinkingLayer with the given NotifyLoaded,
Andrew Scull0372a572018-11-16 15:47:06 +000053 /// and NotifyEmitted functors.
Andrew Walbran3d2c1972020-04-07 12:24:26 +010054 RTDyldObjectLinkingLayer(ExecutionSession &ES,
55 GetMemoryManagerFunction GetMemoryManager);
Andrew Scullcdfcccc2018-10-05 20:58:37 +010056
57 /// Emit the object.
Andrew Walbran16937d02019-10-22 13:54:20 +010058 void emit(MaterializationResponsibility R,
Andrew Scullcdfcccc2018-10-05 20:58:37 +010059 std::unique_ptr<MemoryBuffer> O) override;
60
Andrew Walbran3d2c1972020-04-07 12:24:26 +010061 /// Set the NotifyLoaded callback.
62 RTDyldObjectLinkingLayer &setNotifyLoaded(NotifyLoadedFunction NotifyLoaded) {
63 this->NotifyLoaded = std::move(NotifyLoaded);
64 return *this;
65 }
66
67 /// Set the NotifyEmitted callback.
68 RTDyldObjectLinkingLayer &
69 setNotifyEmitted(NotifyEmittedFunction NotifyEmitted) {
70 this->NotifyEmitted = std::move(NotifyEmitted);
71 return *this;
72 }
73
Andrew Scullcdfcccc2018-10-05 20:58:37 +010074 /// Set the 'ProcessAllSections' flag.
75 ///
76 /// If set to true, all sections in each object file will be allocated using
77 /// the memory manager, rather than just the sections required for execution.
78 ///
79 /// This is kludgy, and may be removed in the future.
Andrew Walbran16937d02019-10-22 13:54:20 +010080 RTDyldObjectLinkingLayer &setProcessAllSections(bool ProcessAllSections) {
Andrew Scullcdfcccc2018-10-05 20:58:37 +010081 this->ProcessAllSections = ProcessAllSections;
Andrew Scull0372a572018-11-16 15:47:06 +000082 return *this;
83 }
84
85 /// Instructs this RTDyldLinkingLayer2 instance to override the symbol flags
86 /// returned by RuntimeDyld for any given object file with the flags supplied
87 /// by the MaterializationResponsibility instance. This is a workaround to
88 /// support symbol visibility in COFF, which does not use the libObject's
89 /// SF_Exported flag. Use only when generating / adding COFF object files.
90 ///
91 /// FIXME: We should be able to remove this if/when COFF properly tracks
92 /// exported symbols.
Andrew Walbran16937d02019-10-22 13:54:20 +010093 RTDyldObjectLinkingLayer &
Andrew Scull0372a572018-11-16 15:47:06 +000094 setOverrideObjectFlagsWithResponsibilityFlags(bool OverrideObjectFlags) {
95 this->OverrideObjectFlags = OverrideObjectFlags;
96 return *this;
97 }
98
Andrew Walbran16937d02019-10-22 13:54:20 +010099 /// If set, this RTDyldObjectLinkingLayer instance will claim responsibility
Andrew Scull0372a572018-11-16 15:47:06 +0000100 /// for any symbols provided by a given object file that were not already in
101 /// the MaterializationResponsibility instance. Setting this flag allows
102 /// higher-level program representations (e.g. LLVM IR) to be added based on
103 /// only a subset of the symbols they provide, without having to write
104 /// intervening layers to scan and add the additional symbols. This trades
105 /// diagnostic quality for convenience however: If all symbols are enumerated
106 /// up-front then clashes can be detected and reported early (and usually
107 /// deterministically). If this option is set, clashes for the additional
108 /// symbols may not be detected until late, and detection may depend on
109 /// the flow of control through JIT'd code. Use with care.
Andrew Walbran16937d02019-10-22 13:54:20 +0100110 RTDyldObjectLinkingLayer &
Andrew Scull0372a572018-11-16 15:47:06 +0000111 setAutoClaimResponsibilityForObjectSymbols(bool AutoClaimObjectSymbols) {
112 this->AutoClaimObjectSymbols = AutoClaimObjectSymbols;
113 return *this;
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100114 }
115
116private:
Andrew Scull0372a572018-11-16 15:47:06 +0000117 Error onObjLoad(VModuleKey K, MaterializationResponsibility &R,
118 object::ObjectFile &Obj,
119 std::unique_ptr<RuntimeDyld::LoadedObjectInfo> LoadedObjInfo,
120 std::map<StringRef, JITEvaluatedSymbol> Resolved,
121 std::set<StringRef> &InternalSymbols);
122
Andrew Walbran3d2c1972020-04-07 12:24:26 +0100123 void onObjEmit(VModuleKey K, std::unique_ptr<MemoryBuffer> ObjBuffer,
124 MaterializationResponsibility &R, Error Err);
Andrew Scull0372a572018-11-16 15:47:06 +0000125
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100126 mutable std::mutex RTDyldLayerMutex;
127 GetMemoryManagerFunction GetMemoryManager;
128 NotifyLoadedFunction NotifyLoaded;
Andrew Scull0372a572018-11-16 15:47:06 +0000129 NotifyEmittedFunction NotifyEmitted;
130 bool ProcessAllSections = false;
131 bool OverrideObjectFlags = false;
132 bool AutoClaimObjectSymbols = false;
Andrew Walbran16937d02019-10-22 13:54:20 +0100133 std::vector<std::unique_ptr<RuntimeDyld::MemoryManager>> MemMgrs;
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100134};
135
Andrew Walbran16937d02019-10-22 13:54:20 +0100136class LegacyRTDyldObjectLinkingLayerBase {
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100137public:
138 using ObjectPtr = std::unique_ptr<MemoryBuffer>;
139
140protected:
141
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100142 /// Holds an object to be allocated/linked as a unit in the JIT.
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100143 ///
144 /// An instance of this class will be created for each object added
145 /// via JITObjectLayer::addObject. Deleting the instance (via
146 /// removeObject) frees its memory, removing all symbol definitions that
147 /// had been provided by this instance. Higher level layers are responsible
148 /// for taking any action required to handle the missing symbols.
149 class LinkedObject {
150 public:
151 LinkedObject() = default;
152 LinkedObject(const LinkedObject&) = delete;
153 void operator=(const LinkedObject&) = delete;
154 virtual ~LinkedObject() = default;
155
156 virtual Error finalize() = 0;
157
158 virtual JITSymbol::GetAddressFtor
159 getSymbolMaterializer(std::string Name) = 0;
160
161 virtual void mapSectionAddress(const void *LocalAddress,
162 JITTargetAddress TargetAddr) const = 0;
163
164 JITSymbol getSymbol(StringRef Name, bool ExportedSymbolsOnly) {
165 auto SymEntry = SymbolTable.find(Name);
166 if (SymEntry == SymbolTable.end())
167 return nullptr;
168 if (!SymEntry->second.getFlags().isExported() && ExportedSymbolsOnly)
169 return nullptr;
170 if (!Finalized)
171 return JITSymbol(getSymbolMaterializer(Name),
172 SymEntry->second.getFlags());
173 return JITSymbol(SymEntry->second);
174 }
175
176 protected:
177 StringMap<JITEvaluatedSymbol> SymbolTable;
178 bool Finalized = false;
179 };
180};
181
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100182/// Bare bones object linking layer.
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100183///
184/// This class is intended to be used as the base layer for a JIT. It allows
185/// object files to be loaded into memory, linked, and the addresses of their
186/// symbols queried. All objects added to this layer can see each other's
187/// symbols.
Andrew Walbran16937d02019-10-22 13:54:20 +0100188class LegacyRTDyldObjectLinkingLayer : public LegacyRTDyldObjectLinkingLayerBase {
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100189public:
190
Andrew Walbran16937d02019-10-22 13:54:20 +0100191 using LegacyRTDyldObjectLinkingLayerBase::ObjectPtr;
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100192
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100193 /// Functor for receiving object-loaded notifications.
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100194 using NotifyLoadedFtor =
195 std::function<void(VModuleKey, const object::ObjectFile &Obj,
196 const RuntimeDyld::LoadedObjectInfo &)>;
197
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100198 /// Functor for receiving finalization notifications.
199 using NotifyFinalizedFtor =
200 std::function<void(VModuleKey, const object::ObjectFile &Obj,
201 const RuntimeDyld::LoadedObjectInfo &)>;
202
203 /// Functor for receiving deallocation notifications.
204 using NotifyFreedFtor = std::function<void(VModuleKey, const object::ObjectFile &Obj)>;
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100205
206private:
207 using OwnedObject = object::OwningBinary<object::ObjectFile>;
208
209 template <typename MemoryManagerPtrT>
210 class ConcreteLinkedObject : public LinkedObject {
211 public:
Andrew Walbran16937d02019-10-22 13:54:20 +0100212 ConcreteLinkedObject(LegacyRTDyldObjectLinkingLayer &Parent, VModuleKey K,
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100213 OwnedObject Obj, MemoryManagerPtrT MemMgr,
214 std::shared_ptr<SymbolResolver> Resolver,
215 bool ProcessAllSections)
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100216 : K(std::move(K)),
217 Parent(Parent),
218 MemMgr(std::move(MemMgr)),
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100219 PFC(llvm::make_unique<PreFinalizeContents>(
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100220 std::move(Obj), std::move(Resolver),
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100221 ProcessAllSections)) {
222 buildInitialSymbolTable(PFC->Obj);
223 }
224
225 ~ConcreteLinkedObject() override {
Andrew Scull0372a572018-11-16 15:47:06 +0000226 if (this->Parent.NotifyFreed && ObjForNotify.getBinary())
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100227 this->Parent.NotifyFreed(K, *ObjForNotify.getBinary());
228
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100229 MemMgr->deregisterEHFrames();
230 }
231
232 Error finalize() override {
233 assert(PFC && "mapSectionAddress called on finalized LinkedObject");
234
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100235 JITSymbolResolverAdapter ResolverAdapter(Parent.ES, *PFC->Resolver,
236 nullptr);
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100237 PFC->RTDyld = llvm::make_unique<RuntimeDyld>(*MemMgr, ResolverAdapter);
238 PFC->RTDyld->setProcessAllSections(PFC->ProcessAllSections);
239
240 Finalized = true;
241
242 std::unique_ptr<RuntimeDyld::LoadedObjectInfo> Info =
243 PFC->RTDyld->loadObject(*PFC->Obj.getBinary());
244
245 // Copy the symbol table out of the RuntimeDyld instance.
246 {
247 auto SymTab = PFC->RTDyld->getSymbolTable();
248 for (auto &KV : SymTab)
249 SymbolTable[KV.first] = KV.second;
250 }
251
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100252 if (Parent.NotifyLoaded)
253 Parent.NotifyLoaded(K, *PFC->Obj.getBinary(), *Info);
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100254
255 PFC->RTDyld->finalizeWithMemoryManagerLocking();
256
257 if (PFC->RTDyld->hasError())
258 return make_error<StringError>(PFC->RTDyld->getErrorString(),
259 inconvertibleErrorCode());
260
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100261 if (Parent.NotifyFinalized)
262 Parent.NotifyFinalized(K, *PFC->Obj.getBinary(), *Info);
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100263
264 // Release resources.
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100265 if (this->Parent.NotifyFreed)
266 ObjForNotify = std::move(PFC->Obj); // needed for callback
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100267 PFC = nullptr;
268 return Error::success();
269 }
270
271 JITSymbol::GetAddressFtor getSymbolMaterializer(std::string Name) override {
272 return [this, Name]() -> Expected<JITTargetAddress> {
273 // The symbol may be materialized between the creation of this lambda
274 // and its execution, so we need to double check.
275 if (!this->Finalized)
276 if (auto Err = this->finalize())
277 return std::move(Err);
278 return this->getSymbol(Name, false).getAddress();
279 };
280 }
281
282 void mapSectionAddress(const void *LocalAddress,
283 JITTargetAddress TargetAddr) const override {
284 assert(PFC && "mapSectionAddress called on finalized LinkedObject");
285 assert(PFC->RTDyld && "mapSectionAddress called on raw LinkedObject");
286 PFC->RTDyld->mapSectionAddress(LocalAddress, TargetAddr);
287 }
288
289 private:
290 void buildInitialSymbolTable(const OwnedObject &Obj) {
291 for (auto &Symbol : Obj.getBinary()->symbols()) {
292 if (Symbol.getFlags() & object::SymbolRef::SF_Undefined)
293 continue;
294 Expected<StringRef> SymbolName = Symbol.getName();
295 // FIXME: Raise an error for bad symbols.
296 if (!SymbolName) {
297 consumeError(SymbolName.takeError());
298 continue;
299 }
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100300 // FIXME: Raise an error for bad symbols.
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100301 auto Flags = JITSymbolFlags::fromObjectSymbol(Symbol);
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100302 if (!Flags) {
303 consumeError(Flags.takeError());
304 continue;
305 }
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100306 SymbolTable.insert(
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100307 std::make_pair(*SymbolName, JITEvaluatedSymbol(0, *Flags)));
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100308 }
309 }
310
311 // Contains the information needed prior to finalization: the object files,
312 // memory manager, resolver, and flags needed for RuntimeDyld.
313 struct PreFinalizeContents {
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100314 PreFinalizeContents(OwnedObject Obj,
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100315 std::shared_ptr<SymbolResolver> Resolver,
316 bool ProcessAllSections)
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100317 : Obj(std::move(Obj)),
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100318 Resolver(std::move(Resolver)),
319 ProcessAllSections(ProcessAllSections) {}
320
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100321 OwnedObject Obj;
322 std::shared_ptr<SymbolResolver> Resolver;
323 bool ProcessAllSections;
324 std::unique_ptr<RuntimeDyld> RTDyld;
325 };
326
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100327 VModuleKey K;
Andrew Walbran16937d02019-10-22 13:54:20 +0100328 LegacyRTDyldObjectLinkingLayer &Parent;
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100329 MemoryManagerPtrT MemMgr;
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100330 OwnedObject ObjForNotify;
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100331 std::unique_ptr<PreFinalizeContents> PFC;
332 };
333
334 template <typename MemoryManagerPtrT>
335 std::unique_ptr<ConcreteLinkedObject<MemoryManagerPtrT>>
Andrew Walbran16937d02019-10-22 13:54:20 +0100336 createLinkedObject(LegacyRTDyldObjectLinkingLayer &Parent, VModuleKey K,
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100337 OwnedObject Obj, MemoryManagerPtrT MemMgr,
338 std::shared_ptr<SymbolResolver> Resolver,
339 bool ProcessAllSections) {
340 using LOS = ConcreteLinkedObject<MemoryManagerPtrT>;
341 return llvm::make_unique<LOS>(Parent, std::move(K), std::move(Obj),
342 std::move(MemMgr), std::move(Resolver),
343 ProcessAllSections);
344 }
345
346public:
347 struct Resources {
348 std::shared_ptr<RuntimeDyld::MemoryManager> MemMgr;
349 std::shared_ptr<SymbolResolver> Resolver;
350 };
351
352 using ResourcesGetter = std::function<Resources(VModuleKey)>;
353
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100354 /// Construct an ObjectLinkingLayer with the given NotifyLoaded,
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100355 /// and NotifyFinalized functors.
Andrew Walbran16937d02019-10-22 13:54:20 +0100356 LegacyRTDyldObjectLinkingLayer(
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100357 ExecutionSession &ES, ResourcesGetter GetResources,
358 NotifyLoadedFtor NotifyLoaded = NotifyLoadedFtor(),
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100359 NotifyFinalizedFtor NotifyFinalized = NotifyFinalizedFtor(),
360 NotifyFreedFtor NotifyFreed = NotifyFreedFtor())
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100361 : ES(ES), GetResources(std::move(GetResources)),
362 NotifyLoaded(std::move(NotifyLoaded)),
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100363 NotifyFinalized(std::move(NotifyFinalized)),
364 NotifyFreed(std::move(NotifyFreed)),
365 ProcessAllSections(false) {
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100366 }
367
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100368 /// Set the 'ProcessAllSections' flag.
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100369 ///
370 /// If set to true, all sections in each object file will be allocated using
371 /// the memory manager, rather than just the sections required for execution.
372 ///
373 /// This is kludgy, and may be removed in the future.
374 void setProcessAllSections(bool ProcessAllSections) {
375 this->ProcessAllSections = ProcessAllSections;
376 }
377
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100378 /// Add an object to the JIT.
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100379 Error addObject(VModuleKey K, ObjectPtr ObjBuffer) {
380
381 auto Obj =
382 object::ObjectFile::createObjectFile(ObjBuffer->getMemBufferRef());
383 if (!Obj)
384 return Obj.takeError();
385
386 assert(!LinkedObjects.count(K) && "VModuleKey already in use");
387
388 auto R = GetResources(K);
389
390 LinkedObjects[K] = createLinkedObject(
391 *this, K, OwnedObject(std::move(*Obj), std::move(ObjBuffer)),
392 std::move(R.MemMgr), std::move(R.Resolver), ProcessAllSections);
393
394 return Error::success();
395 }
396
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100397 /// Remove the object associated with VModuleKey K.
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100398 ///
399 /// All memory allocated for the object will be freed, and the sections and
400 /// symbols it provided will no longer be available. No attempt is made to
401 /// re-emit the missing symbols, and any use of these symbols (directly or
402 /// indirectly) will result in undefined behavior. If dependence tracking is
403 /// required to detect or resolve such issues it should be added at a higher
404 /// layer.
405 Error removeObject(VModuleKey K) {
406 assert(LinkedObjects.count(K) && "VModuleKey not associated with object");
407 // How do we invalidate the symbols in H?
408 LinkedObjects.erase(K);
409 return Error::success();
410 }
411
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100412 /// Search for the given named symbol.
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100413 /// @param Name The name of the symbol to search for.
414 /// @param ExportedSymbolsOnly If true, search only for exported symbols.
415 /// @return A handle for the given named symbol, if it exists.
416 JITSymbol findSymbol(StringRef Name, bool ExportedSymbolsOnly) {
417 for (auto &KV : LinkedObjects)
418 if (auto Sym = KV.second->getSymbol(Name, ExportedSymbolsOnly))
419 return Sym;
420 else if (auto Err = Sym.takeError())
421 return std::move(Err);
422
423 return nullptr;
424 }
425
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100426 /// Search for the given named symbol in the context of the loaded
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100427 /// object represented by the VModuleKey K.
428 /// @param K The VModuleKey for the object to search in.
429 /// @param Name The name of the symbol to search for.
430 /// @param ExportedSymbolsOnly If true, search only for exported symbols.
431 /// @return A handle for the given named symbol, if it is found in the
432 /// given object.
433 JITSymbol findSymbolIn(VModuleKey K, StringRef Name,
434 bool ExportedSymbolsOnly) {
435 assert(LinkedObjects.count(K) && "VModuleKey not associated with object");
436 return LinkedObjects[K]->getSymbol(Name, ExportedSymbolsOnly);
437 }
438
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100439 /// Map section addresses for the object associated with the
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100440 /// VModuleKey K.
441 void mapSectionAddress(VModuleKey K, const void *LocalAddress,
442 JITTargetAddress TargetAddr) {
443 assert(LinkedObjects.count(K) && "VModuleKey not associated with object");
444 LinkedObjects[K]->mapSectionAddress(LocalAddress, TargetAddr);
445 }
446
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100447 /// Immediately emit and finalize the object represented by the given
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100448 /// VModuleKey.
449 /// @param K VModuleKey for object to emit/finalize.
450 Error emitAndFinalize(VModuleKey K) {
451 assert(LinkedObjects.count(K) && "VModuleKey not associated with object");
452 return LinkedObjects[K]->finalize();
453 }
454
455private:
456 ExecutionSession &ES;
457
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100458 ResourcesGetter GetResources;
459 NotifyLoadedFtor NotifyLoaded;
460 NotifyFinalizedFtor NotifyFinalized;
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100461 NotifyFreedFtor NotifyFreed;
Andrew Walbran16937d02019-10-22 13:54:20 +0100462
463 // NB! `LinkedObjects` needs to be destroyed before `NotifyFreed` because
464 // `~ConcreteLinkedObject` calls `NotifyFreed`
465 std::map<VModuleKey, std::unique_ptr<LinkedObject>> LinkedObjects;
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100466 bool ProcessAllSections = false;
467};
468
469} // end namespace orc
470} // end namespace llvm
471
472#endif // LLVM_EXECUTIONENGINE_ORC_RTDYLDOBJECTLINKINGLAYER_H