blob: 874decb2ade0bc9569b73b8af306def16794b92a [file] [log] [blame]
Lang Hames11c8dfa52019-04-20 17:10:34 +00001//===------- ObjectLinkingLayer.cpp - JITLink backed ORC ObjectLayer ------===//
2//
3// 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
6//
7//===----------------------------------------------------------------------===//
8
9#include "llvm/ExecutionEngine/Orc/ObjectLinkingLayer.h"
10
11#include "llvm/ADT/Optional.h"
Lang Hames1233c152019-04-22 03:03:09 +000012#include "llvm/ExecutionEngine/JITLink/EHFrameSupport.h"
Lang Hames11c8dfa52019-04-20 17:10:34 +000013
14#include <vector>
15
16#define DEBUG_TYPE "orc"
17
18using namespace llvm;
19using namespace llvm::jitlink;
20using namespace llvm::orc;
21
22namespace llvm {
23namespace orc {
24
25class ObjectLinkingLayerJITLinkContext final : public JITLinkContext {
26public:
27 ObjectLinkingLayerJITLinkContext(ObjectLinkingLayer &Layer,
28 MaterializationResponsibility MR,
29 std::unique_ptr<MemoryBuffer> ObjBuffer)
30 : Layer(Layer), MR(std::move(MR)), ObjBuffer(std::move(ObjBuffer)) {}
31
Lang Hamesa98546eb2019-10-15 21:41:12 +000032 ~ObjectLinkingLayerJITLinkContext() {
33 // If there is an object buffer return function then use it to
34 // return ownership of the buffer.
35 if (Layer.ReturnObjectBuffer)
36 Layer.ReturnObjectBuffer(std::move(ObjBuffer));
37 }
38
Lang Hames11c8dfa52019-04-20 17:10:34 +000039 JITLinkMemoryManager &getMemoryManager() override { return Layer.MemMgr; }
40
41 MemoryBufferRef getObjectBuffer() const override {
42 return ObjBuffer->getMemBufferRef();
43 }
44
45 void notifyFailed(Error Err) override {
46 Layer.getExecutionSession().reportError(std::move(Err));
47 MR.failMaterialization();
48 }
49
50 void lookup(const DenseSet<StringRef> &Symbols,
Lang Hames4e920e52019-10-04 03:55:26 +000051 std::unique_ptr<JITLinkAsyncLookupContinuation> LC) override {
Lang Hames11c8dfa52019-04-20 17:10:34 +000052
53 JITDylibSearchList SearchOrder;
54 MR.getTargetJITDylib().withSearchOrderDo(
55 [&](const JITDylibSearchList &JDs) { SearchOrder = JDs; });
56
57 auto &ES = Layer.getExecutionSession();
58
59 SymbolNameSet InternedSymbols;
60 for (auto &S : Symbols)
61 InternedSymbols.insert(ES.intern(S));
62
63 // OnResolve -- De-intern the symbols and pass the result to the linker.
Lang Hames4e920e52019-10-04 03:55:26 +000064 auto OnResolve = [this, LookupContinuation = std::move(LC)](
65 Expected<SymbolMap> Result) mutable {
Lang Hamesc48f1f62019-08-27 15:50:32 +000066 auto Main = Layer.getExecutionSession().intern("_main");
Lang Hames11c8dfa52019-04-20 17:10:34 +000067 if (!Result)
Lang Hames4e920e52019-10-04 03:55:26 +000068 LookupContinuation->run(Result.takeError());
Lang Hames11c8dfa52019-04-20 17:10:34 +000069 else {
70 AsyncLookupResult LR;
71 for (auto &KV : *Result)
72 LR[*KV.first] = KV.second;
Lang Hames4e920e52019-10-04 03:55:26 +000073 LookupContinuation->run(std::move(LR));
Lang Hames11c8dfa52019-04-20 17:10:34 +000074 }
75 };
76
Lang Hamesd4a80892019-06-07 19:33:51 +000077 ES.lookup(SearchOrder, std::move(InternedSymbols), SymbolState::Resolved,
78 std::move(OnResolve), [this](const SymbolDependenceMap &Deps) {
79 registerDependencies(Deps);
80 });
Lang Hames11c8dfa52019-04-20 17:10:34 +000081 }
82
Lang Hames4e920e52019-10-04 03:55:26 +000083 void notifyResolved(LinkGraph &G) override {
Lang Hames11c8dfa52019-04-20 17:10:34 +000084 auto &ES = Layer.getExecutionSession();
85
86 SymbolFlagsMap ExtraSymbolsToClaim;
87 bool AutoClaim = Layer.AutoClaimObjectSymbols;
88
89 SymbolMap InternedResult;
Lang Hames4e920e52019-10-04 03:55:26 +000090 for (auto *Sym : G.defined_symbols())
91 if (Sym->hasName() && Sym->getScope() != Scope::Local) {
92 auto InternedName = ES.intern(Sym->getName());
Lang Hames11c8dfa52019-04-20 17:10:34 +000093 JITSymbolFlags Flags;
94
Lang Hames4e920e52019-10-04 03:55:26 +000095 if (Sym->isCallable())
Lang Hames11c8dfa52019-04-20 17:10:34 +000096 Flags |= JITSymbolFlags::Callable;
Lang Hames4e920e52019-10-04 03:55:26 +000097 if (Sym->getScope() == Scope::Default)
98 Flags |= JITSymbolFlags::Exported;
Lang Hames11c8dfa52019-04-20 17:10:34 +000099
100 InternedResult[InternedName] =
Lang Hames4e920e52019-10-04 03:55:26 +0000101 JITEvaluatedSymbol(Sym->getAddress(), Flags);
Lang Hames11c8dfa52019-04-20 17:10:34 +0000102 if (AutoClaim && !MR.getSymbols().count(InternedName)) {
103 assert(!ExtraSymbolsToClaim.count(InternedName) &&
104 "Duplicate symbol to claim?");
105 ExtraSymbolsToClaim[InternedName] = Flags;
106 }
107 }
108
Lang Hames4e920e52019-10-04 03:55:26 +0000109 for (auto *Sym : G.absolute_symbols())
110 if (Sym->hasName()) {
111 auto InternedName = ES.intern(Sym->getName());
Lang Hames11c8dfa52019-04-20 17:10:34 +0000112 JITSymbolFlags Flags;
113 Flags |= JITSymbolFlags::Absolute;
Lang Hames4e920e52019-10-04 03:55:26 +0000114 if (Sym->isCallable())
Lang Hames11c8dfa52019-04-20 17:10:34 +0000115 Flags |= JITSymbolFlags::Callable;
Lang Hames4e920e52019-10-04 03:55:26 +0000116 if (Sym->getLinkage() == Linkage::Weak)
117 Flags |= JITSymbolFlags::Weak;
Lang Hames11c8dfa52019-04-20 17:10:34 +0000118 InternedResult[InternedName] =
Lang Hames4e920e52019-10-04 03:55:26 +0000119 JITEvaluatedSymbol(Sym->getAddress(), Flags);
Lang Hames11c8dfa52019-04-20 17:10:34 +0000120 if (AutoClaim && !MR.getSymbols().count(InternedName)) {
121 assert(!ExtraSymbolsToClaim.count(InternedName) &&
122 "Duplicate symbol to claim?");
123 ExtraSymbolsToClaim[InternedName] = Flags;
124 }
125 }
126
127 if (!ExtraSymbolsToClaim.empty())
128 if (auto Err = MR.defineMaterializing(ExtraSymbolsToClaim))
129 return notifyFailed(std::move(Err));
Lang Hamese00585c2019-08-23 20:37:31 +0000130 if (auto Err = MR.notifyResolved(InternedResult)) {
131 Layer.getExecutionSession().reportError(std::move(Err));
132 MR.failMaterialization();
133 return;
134 }
Lang Hamesa9fdf372019-04-26 22:58:39 +0000135 Layer.notifyLoaded(MR);
Lang Hames11c8dfa52019-04-20 17:10:34 +0000136 }
137
138 void notifyFinalized(
139 std::unique_ptr<JITLinkMemoryManager::Allocation> A) override {
Lang Hamesa9fdf372019-04-26 22:58:39 +0000140 if (auto Err = Layer.notifyEmitted(MR, std::move(A))) {
141 Layer.getExecutionSession().reportError(std::move(Err));
142 MR.failMaterialization();
Lang Hamesa9fdf372019-04-26 22:58:39 +0000143 return;
144 }
Lang Hamese00585c2019-08-23 20:37:31 +0000145 if (auto Err = MR.notifyEmitted()) {
146 Layer.getExecutionSession().reportError(std::move(Err));
147 MR.failMaterialization();
148 }
Lang Hames11c8dfa52019-04-20 17:10:34 +0000149 }
150
Lang Hames4e920e52019-10-04 03:55:26 +0000151 LinkGraphPassFunction getMarkLivePass(const Triple &TT) const override {
152 return [this](LinkGraph &G) { return markResponsibilitySymbolsLive(G); };
Lang Hames11c8dfa52019-04-20 17:10:34 +0000153 }
154
155 Error modifyPassConfig(const Triple &TT, PassConfiguration &Config) override {
156 // Add passes to mark duplicate defs as should-discard, and to walk the
Lang Hames4e920e52019-10-04 03:55:26 +0000157 // link graph to build the symbol dependence graph.
Lang Hames11c8dfa52019-04-20 17:10:34 +0000158 Config.PrePrunePasses.push_back(
Lang Hames4e920e52019-10-04 03:55:26 +0000159 [this](LinkGraph &G) { return externalizeWeakAndCommonSymbols(G); });
Lang Hames11c8dfa52019-04-20 17:10:34 +0000160 Config.PostPrunePasses.push_back(
Lang Hames4e920e52019-10-04 03:55:26 +0000161 [this](LinkGraph &G) { return computeNamedSymbolDependencies(G); });
Lang Hames11c8dfa52019-04-20 17:10:34 +0000162
Lang Hamesa9fdf372019-04-26 22:58:39 +0000163 Layer.modifyPassConfig(MR, TT, Config);
Lang Hames11c8dfa52019-04-20 17:10:34 +0000164
165 return Error::success();
166 }
167
168private:
Lang Hames4e920e52019-10-04 03:55:26 +0000169 using AnonToNamedDependenciesMap = DenseMap<const Symbol *, SymbolNameSet>;
Lang Hames11c8dfa52019-04-20 17:10:34 +0000170
Lang Hames4e920e52019-10-04 03:55:26 +0000171 Error externalizeWeakAndCommonSymbols(LinkGraph &G) {
Lang Hames11c8dfa52019-04-20 17:10:34 +0000172 auto &ES = Layer.getExecutionSession();
Lang Hames4e920e52019-10-04 03:55:26 +0000173 for (auto *Sym : G.defined_symbols())
174 if (Sym->hasName() && Sym->getLinkage() == Linkage::Weak) {
175 if (!MR.getSymbols().count(ES.intern(Sym->getName())))
176 G.makeExternal(*Sym);
Lang Hames11c8dfa52019-04-20 17:10:34 +0000177 }
178
Lang Hames4e920e52019-10-04 03:55:26 +0000179 for (auto *Sym : G.absolute_symbols())
180 if (Sym->hasName() && Sym->getLinkage() == Linkage::Weak) {
181 if (!MR.getSymbols().count(ES.intern(Sym->getName())))
182 G.makeExternal(*Sym);
Lang Hames11c8dfa52019-04-20 17:10:34 +0000183 }
184
185 return Error::success();
186 }
187
Lang Hames4e920e52019-10-04 03:55:26 +0000188 Error markResponsibilitySymbolsLive(LinkGraph &G) const {
Lang Hames11c8dfa52019-04-20 17:10:34 +0000189 auto &ES = Layer.getExecutionSession();
Lang Hames4e920e52019-10-04 03:55:26 +0000190 for (auto *Sym : G.defined_symbols())
191 if (Sym->hasName() && MR.getSymbols().count(ES.intern(Sym->getName())))
192 Sym->setLive(true);
Lang Hames11c8dfa52019-04-20 17:10:34 +0000193 return Error::success();
194 }
195
Lang Hames4e920e52019-10-04 03:55:26 +0000196 Error computeNamedSymbolDependencies(LinkGraph &G) {
Lang Hames11c8dfa52019-04-20 17:10:34 +0000197 auto &ES = MR.getTargetJITDylib().getExecutionSession();
198 auto AnonDeps = computeAnonDeps(G);
199
Lang Hames4e920e52019-10-04 03:55:26 +0000200 for (auto *Sym : G.defined_symbols()) {
Lang Hames11c8dfa52019-04-20 17:10:34 +0000201
202 // Skip anonymous and non-global atoms: we do not need dependencies for
203 // these.
Lang Hames4e920e52019-10-04 03:55:26 +0000204 if (Sym->getScope() == Scope::Local)
Lang Hames11c8dfa52019-04-20 17:10:34 +0000205 continue;
206
Lang Hames4e920e52019-10-04 03:55:26 +0000207 auto SymName = ES.intern(Sym->getName());
208 SymbolNameSet &SymDeps = NamedSymbolDeps[SymName];
Lang Hames11c8dfa52019-04-20 17:10:34 +0000209
Lang Hames4e920e52019-10-04 03:55:26 +0000210 for (auto &E : Sym->getBlock().edges()) {
211 auto &TargetSym = E.getTarget();
Lang Hames11c8dfa52019-04-20 17:10:34 +0000212
Lang Hames4e920e52019-10-04 03:55:26 +0000213 if (TargetSym.getScope() != Scope::Local)
214 SymDeps.insert(ES.intern(TargetSym.getName()));
Lang Hames11c8dfa52019-04-20 17:10:34 +0000215 else {
Lang Hames4e920e52019-10-04 03:55:26 +0000216 assert(TargetSym.isDefined() &&
217 "Anonymous/local symbols must be defined");
218 auto I = AnonDeps.find(&TargetSym);
Lang Hames11c8dfa52019-04-20 17:10:34 +0000219 if (I != AnonDeps.end())
220 for (auto &S : I->second)
Lang Hames4e920e52019-10-04 03:55:26 +0000221 SymDeps.insert(S);
Lang Hames11c8dfa52019-04-20 17:10:34 +0000222 }
223 }
224 }
225
226 return Error::success();
227 }
228
Lang Hames4e920e52019-10-04 03:55:26 +0000229 AnonToNamedDependenciesMap computeAnonDeps(LinkGraph &G) {
Lang Hames11c8dfa52019-04-20 17:10:34 +0000230
231 auto &ES = MR.getTargetJITDylib().getExecutionSession();
Lang Hames4e920e52019-10-04 03:55:26 +0000232 AnonToNamedDependenciesMap DepMap;
Lang Hames11c8dfa52019-04-20 17:10:34 +0000233
Lang Hames4e920e52019-10-04 03:55:26 +0000234 // For all anonymous symbols:
Lang Hames11c8dfa52019-04-20 17:10:34 +0000235 // (1) Add their named dependencies.
236 // (2) Add them to the worklist for further iteration if they have any
Lang Hames4e920e52019-10-04 03:55:26 +0000237 // depend on any other anonymous symbols.
Lang Hames11c8dfa52019-04-20 17:10:34 +0000238 struct WorklistEntry {
Lang Hames4e920e52019-10-04 03:55:26 +0000239 WorklistEntry(Symbol *Sym, DenseSet<Symbol *> SymAnonDeps)
240 : Sym(Sym), SymAnonDeps(std::move(SymAnonDeps)) {}
Lang Hames11c8dfa52019-04-20 17:10:34 +0000241
Lang Hames4e920e52019-10-04 03:55:26 +0000242 Symbol *Sym = nullptr;
243 DenseSet<Symbol *> SymAnonDeps;
Lang Hames11c8dfa52019-04-20 17:10:34 +0000244 };
245 std::vector<WorklistEntry> Worklist;
Lang Hames4e920e52019-10-04 03:55:26 +0000246 for (auto *Sym : G.defined_symbols())
247 if (!Sym->hasName()) {
248 auto &SymNamedDeps = DepMap[Sym];
249 DenseSet<Symbol *> SymAnonDeps;
Lang Hames11c8dfa52019-04-20 17:10:34 +0000250
Lang Hames4e920e52019-10-04 03:55:26 +0000251 for (auto &E : Sym->getBlock().edges()) {
252 auto &TargetSym = E.getTarget();
253 if (TargetSym.hasName())
254 SymNamedDeps.insert(ES.intern(TargetSym.getName()));
Lang Hames11c8dfa52019-04-20 17:10:34 +0000255 else {
Lang Hames4e920e52019-10-04 03:55:26 +0000256 assert(TargetSym.isDefined() &&
257 "Anonymous symbols must be defined");
258 SymAnonDeps.insert(&TargetSym);
Lang Hames11c8dfa52019-04-20 17:10:34 +0000259 }
260 }
261
Lang Hames4e920e52019-10-04 03:55:26 +0000262 if (!SymAnonDeps.empty())
263 Worklist.push_back(WorklistEntry(Sym, std::move(SymAnonDeps)));
Lang Hames11c8dfa52019-04-20 17:10:34 +0000264 }
265
Lang Hames4e920e52019-10-04 03:55:26 +0000266 // Loop over all anonymous symbols with anonymous dependencies, propagating
Lang Hames11c8dfa52019-04-20 17:10:34 +0000267 // their respective *named* dependencies. Iterate until we hit a stable
268 // state.
269 bool Changed;
270 do {
271 Changed = false;
272 for (auto &WLEntry : Worklist) {
Lang Hames4e920e52019-10-04 03:55:26 +0000273 auto *Sym = WLEntry.Sym;
274 auto &SymNamedDeps = DepMap[Sym];
275 auto &SymAnonDeps = WLEntry.SymAnonDeps;
Lang Hames11c8dfa52019-04-20 17:10:34 +0000276
Lang Hames4e920e52019-10-04 03:55:26 +0000277 for (auto *TargetSym : SymAnonDeps) {
278 auto I = DepMap.find(TargetSym);
Lang Hames11c8dfa52019-04-20 17:10:34 +0000279 if (I != DepMap.end())
280 for (const auto &S : I->second)
Lang Hames4e920e52019-10-04 03:55:26 +0000281 Changed |= SymNamedDeps.insert(S).second;
Lang Hames11c8dfa52019-04-20 17:10:34 +0000282 }
283 }
284 } while (Changed);
285
286 return DepMap;
287 }
288
289 void registerDependencies(const SymbolDependenceMap &QueryDeps) {
290 for (auto &NamedDepsEntry : NamedSymbolDeps) {
291 auto &Name = NamedDepsEntry.first;
292 auto &NameDeps = NamedDepsEntry.second;
293 SymbolDependenceMap SymbolDeps;
294
295 for (const auto &QueryDepsEntry : QueryDeps) {
296 JITDylib &SourceJD = *QueryDepsEntry.first;
297 const SymbolNameSet &Symbols = QueryDepsEntry.second;
298 auto &DepsForJD = SymbolDeps[&SourceJD];
299
300 for (const auto &S : Symbols)
301 if (NameDeps.count(S))
302 DepsForJD.insert(S);
303
304 if (DepsForJD.empty())
305 SymbolDeps.erase(&SourceJD);
306 }
307
308 MR.addDependencies(Name, SymbolDeps);
309 }
310 }
311
312 ObjectLinkingLayer &Layer;
313 MaterializationResponsibility MR;
314 std::unique_ptr<MemoryBuffer> ObjBuffer;
315 DenseMap<SymbolStringPtr, SymbolNameSet> NamedSymbolDeps;
Lang Hames11c8dfa52019-04-20 17:10:34 +0000316};
317
Lang Hamesa9fdf372019-04-26 22:58:39 +0000318ObjectLinkingLayer::Plugin::~Plugin() {}
319
320ObjectLinkingLayer::ObjectLinkingLayer(ExecutionSession &ES,
321 JITLinkMemoryManager &MemMgr)
322 : ObjectLayer(ES), MemMgr(MemMgr) {}
323
324ObjectLinkingLayer::~ObjectLinkingLayer() {
325 if (auto Err = removeAllModules())
326 getExecutionSession().reportError(std::move(Err));
327}
Lang Hames11c8dfa52019-04-20 17:10:34 +0000328
329void ObjectLinkingLayer::emit(MaterializationResponsibility R,
330 std::unique_ptr<MemoryBuffer> O) {
331 assert(O && "Object must not be null");
Jonas Devlieghere0eaee542019-08-15 15:54:37 +0000332 jitLink(std::make_unique<ObjectLinkingLayerJITLinkContext>(
Lang Hames11c8dfa52019-04-20 17:10:34 +0000333 *this, std::move(R), std::move(O)));
334}
335
Lang Hamesa9fdf372019-04-26 22:58:39 +0000336void ObjectLinkingLayer::modifyPassConfig(MaterializationResponsibility &MR,
337 const Triple &TT,
338 PassConfiguration &PassConfig) {
339 for (auto &P : Plugins)
340 P->modifyPassConfig(MR, TT, PassConfig);
Lang Hames11c8dfa52019-04-20 17:10:34 +0000341}
342
Lang Hamesa9fdf372019-04-26 22:58:39 +0000343void ObjectLinkingLayer::notifyLoaded(MaterializationResponsibility &MR) {
344 for (auto &P : Plugins)
345 P->notifyLoaded(MR);
Lang Hames11c8dfa52019-04-20 17:10:34 +0000346}
347
Lang Hamesa9fdf372019-04-26 22:58:39 +0000348Error ObjectLinkingLayer::notifyEmitted(MaterializationResponsibility &MR,
349 AllocPtr Alloc) {
350 Error Err = Error::success();
351 for (auto &P : Plugins)
352 Err = joinErrors(std::move(Err), P->notifyEmitted(MR));
Lang Hames11c8dfa52019-04-20 17:10:34 +0000353
Lang Hamesa9fdf372019-04-26 22:58:39 +0000354 if (Err)
355 return Err;
Lang Hames11c8dfa52019-04-20 17:10:34 +0000356
Lang Hamesa9fdf372019-04-26 22:58:39 +0000357 {
358 std::lock_guard<std::mutex> Lock(LayerMutex);
359 UntrackedAllocs.push_back(std::move(Alloc));
360 }
Lang Hames11c8dfa52019-04-20 17:10:34 +0000361
Lang Hamesa9fdf372019-04-26 22:58:39 +0000362 return Error::success();
363}
364
365Error ObjectLinkingLayer::removeModule(VModuleKey K) {
366 Error Err = Error::success();
367
368 for (auto &P : Plugins)
369 Err = joinErrors(std::move(Err), P->notifyRemovingModule(K));
370
371 AllocPtr Alloc;
372
373 {
374 std::lock_guard<std::mutex> Lock(LayerMutex);
375 auto AllocItr = TrackedAllocs.find(K);
376 Alloc = std::move(AllocItr->second);
377 TrackedAllocs.erase(AllocItr);
378 }
379
380 assert(Alloc && "No allocation for key K");
381
382 return joinErrors(std::move(Err), Alloc->deallocate());
383}
384
385Error ObjectLinkingLayer::removeAllModules() {
386
387 Error Err = Error::success();
388
389 for (auto &P : Plugins)
390 Err = joinErrors(std::move(Err), P->notifyRemovingAllModules());
391
392 std::vector<AllocPtr> Allocs;
393 {
394 std::lock_guard<std::mutex> Lock(LayerMutex);
395 Allocs = std::move(UntrackedAllocs);
396
397 for (auto &KV : TrackedAllocs)
398 Allocs.push_back(std::move(KV.second));
399
400 TrackedAllocs.clear();
401 }
402
403 while (!Allocs.empty()) {
404 Err = joinErrors(std::move(Err), Allocs.back()->deallocate());
405 Allocs.pop_back();
406 }
407
408 return Err;
409}
410
Lang Hamesf5a885f2019-07-04 00:05:12 +0000411EHFrameRegistrationPlugin::EHFrameRegistrationPlugin(
Lang Hames4e920e52019-10-04 03:55:26 +0000412 EHFrameRegistrar &Registrar)
Lang Hamesf5a885f2019-07-04 00:05:12 +0000413 : Registrar(Registrar) {}
414
415void EHFrameRegistrationPlugin::modifyPassConfig(
Lang Hamesa9fdf372019-04-26 22:58:39 +0000416 MaterializationResponsibility &MR, const Triple &TT,
417 PassConfiguration &PassConfig) {
418 assert(!InProcessLinks.count(&MR) && "Link for MR already being tracked?");
419
420 PassConfig.PostFixupPasses.push_back(
Lang Hamesc48f1f62019-08-27 15:50:32 +0000421 createEHFrameRecorderPass(TT, [this, &MR](JITTargetAddress Addr,
422 size_t Size) {
Lang Hamesa9fdf372019-04-26 22:58:39 +0000423 if (Addr)
Lang Hamesc48f1f62019-08-27 15:50:32 +0000424 InProcessLinks[&MR] = { Addr, Size };
Lang Hamesa9fdf372019-04-26 22:58:39 +0000425 }));
426}
427
Lang Hamesf5a885f2019-07-04 00:05:12 +0000428Error EHFrameRegistrationPlugin::notifyEmitted(
Lang Hamesa9fdf372019-04-26 22:58:39 +0000429 MaterializationResponsibility &MR) {
430
Lang Hamesc48f1f62019-08-27 15:50:32 +0000431 auto EHFrameRangeItr = InProcessLinks.find(&MR);
432 if (EHFrameRangeItr == InProcessLinks.end())
Lang Hamesa9fdf372019-04-26 22:58:39 +0000433 return Error::success();
434
Lang Hamesc48f1f62019-08-27 15:50:32 +0000435 auto EHFrameRange = EHFrameRangeItr->second;
436 assert(EHFrameRange.Addr &&
437 "eh-frame addr to register can not be null");
Lang Hamesa9fdf372019-04-26 22:58:39 +0000438
Lang Hamesc48f1f62019-08-27 15:50:32 +0000439 InProcessLinks.erase(EHFrameRangeItr);
Lang Hamesa9fdf372019-04-26 22:58:39 +0000440 if (auto Key = MR.getVModuleKey())
Lang Hamesc48f1f62019-08-27 15:50:32 +0000441 TrackedEHFrameRanges[Key] = EHFrameRange;
Lang Hamesa9fdf372019-04-26 22:58:39 +0000442 else
Lang Hamesc48f1f62019-08-27 15:50:32 +0000443 UntrackedEHFrameRanges.push_back(EHFrameRange);
Lang Hamesa9fdf372019-04-26 22:58:39 +0000444
Lang Hamesc48f1f62019-08-27 15:50:32 +0000445 return Registrar.registerEHFrames(EHFrameRange.Addr, EHFrameRange.Size);
Lang Hamesa9fdf372019-04-26 22:58:39 +0000446}
447
Lang Hamesf5a885f2019-07-04 00:05:12 +0000448Error EHFrameRegistrationPlugin::notifyRemovingModule(VModuleKey K) {
Lang Hamesc48f1f62019-08-27 15:50:32 +0000449 auto EHFrameRangeItr = TrackedEHFrameRanges.find(K);
450 if (EHFrameRangeItr == TrackedEHFrameRanges.end())
Lang Hamesa9fdf372019-04-26 22:58:39 +0000451 return Error::success();
452
Lang Hamesc48f1f62019-08-27 15:50:32 +0000453 auto EHFrameRange = EHFrameRangeItr->second;
454 assert(EHFrameRange.Addr && "Tracked eh-frame range must not be null");
Lang Hamesa9fdf372019-04-26 22:58:39 +0000455
Lang Hamesc48f1f62019-08-27 15:50:32 +0000456 TrackedEHFrameRanges.erase(EHFrameRangeItr);
Lang Hamesa9fdf372019-04-26 22:58:39 +0000457
Lang Hamesc48f1f62019-08-27 15:50:32 +0000458 return Registrar.deregisterEHFrames(EHFrameRange.Addr, EHFrameRange.Size);
Lang Hamesa9fdf372019-04-26 22:58:39 +0000459}
460
Lang Hamesf5a885f2019-07-04 00:05:12 +0000461Error EHFrameRegistrationPlugin::notifyRemovingAllModules() {
Lang Hamesa9fdf372019-04-26 22:58:39 +0000462
Lang Hamesc48f1f62019-08-27 15:50:32 +0000463 std::vector<EHFrameRange> EHFrameRanges =
464 std::move(UntrackedEHFrameRanges);
465 EHFrameRanges.reserve(EHFrameRanges.size() + TrackedEHFrameRanges.size());
Lang Hamesa9fdf372019-04-26 22:58:39 +0000466
Lang Hamesc48f1f62019-08-27 15:50:32 +0000467 for (auto &KV : TrackedEHFrameRanges)
468 EHFrameRanges.push_back(KV.second);
Lang Hamesa9fdf372019-04-26 22:58:39 +0000469
Lang Hamesc48f1f62019-08-27 15:50:32 +0000470 TrackedEHFrameRanges.clear();
Lang Hamesa9fdf372019-04-26 22:58:39 +0000471
472 Error Err = Error::success();
473
Lang Hamesc48f1f62019-08-27 15:50:32 +0000474 while (!EHFrameRanges.empty()) {
475 auto EHFrameRange = EHFrameRanges.back();
476 assert(EHFrameRange.Addr && "Untracked eh-frame range must not be null");
477 EHFrameRanges.pop_back();
478 Err = joinErrors(std::move(Err),
479 Registrar.deregisterEHFrames(EHFrameRange.Addr,
480 EHFrameRange.Size));
Lang Hamesa9fdf372019-04-26 22:58:39 +0000481 }
482
483 return Err;
Lang Hames11c8dfa52019-04-20 17:10:34 +0000484}
485
486} // End namespace orc.
487} // End namespace llvm.