blob: 9e3245d9cc9910410a83d4f1030105b97b8a756f [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:
Lang Hames7dcd0042020-09-11 09:23:14 -070027 ObjectLinkingLayerJITLinkContext(
28 ObjectLinkingLayer &Layer,
29 std::unique_ptr<MaterializationResponsibility> MR,
30 std::unique_ptr<MemoryBuffer> ObjBuffer)
Lang Hames11c8dfa52019-04-20 17:10:34 +000031 : Layer(Layer), MR(std::move(MR)), ObjBuffer(std::move(ObjBuffer)) {}
32
Lang Hamesa98546eb2019-10-15 21:41:12 +000033 ~ObjectLinkingLayerJITLinkContext() {
34 // If there is an object buffer return function then use it to
35 // return ownership of the buffer.
36 if (Layer.ReturnObjectBuffer)
37 Layer.ReturnObjectBuffer(std::move(ObjBuffer));
38 }
39
Lang Hames69091eb2020-07-23 16:03:45 -070040 JITLinkMemoryManager &getMemoryManager() override { return Layer.MemMgr; }
Lang Hames11c8dfa52019-04-20 17:10:34 +000041
42 MemoryBufferRef getObjectBuffer() const override {
43 return ObjBuffer->getMemBufferRef();
44 }
45
46 void notifyFailed(Error Err) override {
47 Layer.getExecutionSession().reportError(std::move(Err));
Lang Hames7dcd0042020-09-11 09:23:14 -070048 MR->failMaterialization();
Lang Hames11c8dfa52019-04-20 17:10:34 +000049 }
50
Lang Hames674df132019-11-25 21:57:27 -080051 void lookup(const LookupMap &Symbols,
Lang Hames4e920e52019-10-04 03:55:26 +000052 std::unique_ptr<JITLinkAsyncLookupContinuation> LC) override {
Lang Hames11c8dfa52019-04-20 17:10:34 +000053
Lang Hamesc66f8902020-05-04 16:43:42 -070054 JITDylibSearchOrder LinkOrder;
Lang Hames7dcd0042020-09-11 09:23:14 -070055 MR->getTargetJITDylib().withLinkOrderDo(
Lang Hamesc66f8902020-05-04 16:43:42 -070056 [&](const JITDylibSearchOrder &LO) { LinkOrder = LO; });
Lang Hames11c8dfa52019-04-20 17:10:34 +000057
58 auto &ES = Layer.getExecutionSession();
59
Lang Hames674df132019-11-25 21:57:27 -080060 SymbolLookupSet LookupSet;
61 for (auto &KV : Symbols) {
62 orc::SymbolLookupFlags LookupFlags;
63 switch (KV.second) {
64 case jitlink::SymbolLookupFlags::RequiredSymbol:
65 LookupFlags = orc::SymbolLookupFlags::RequiredSymbol;
66 break;
67 case jitlink::SymbolLookupFlags::WeaklyReferencedSymbol:
68 LookupFlags = orc::SymbolLookupFlags::WeaklyReferencedSymbol;
69 break;
70 }
71 LookupSet.add(ES.intern(KV.first), LookupFlags);
72 }
Lang Hames11c8dfa52019-04-20 17:10:34 +000073
74 // OnResolve -- De-intern the symbols and pass the result to the linker.
Lang Hamesb79e19e2020-08-31 15:16:03 -070075 auto OnResolve = [LookupContinuation =
76 std::move(LC)](Expected<SymbolMap> Result) mutable {
Lang Hames11c8dfa52019-04-20 17:10:34 +000077 if (!Result)
Lang Hames4e920e52019-10-04 03:55:26 +000078 LookupContinuation->run(Result.takeError());
Lang Hames11c8dfa52019-04-20 17:10:34 +000079 else {
80 AsyncLookupResult LR;
81 for (auto &KV : *Result)
82 LR[*KV.first] = KV.second;
Lang Hames4e920e52019-10-04 03:55:26 +000083 LookupContinuation->run(std::move(LR));
Lang Hames11c8dfa52019-04-20 17:10:34 +000084 }
85 };
86
Lang Hamesca6f5842020-02-11 09:02:22 -080087 for (auto &KV : InternalNamedSymbolDeps) {
88 SymbolDependenceMap InternalDeps;
Lang Hames7dcd0042020-09-11 09:23:14 -070089 InternalDeps[&MR->getTargetJITDylib()] = std::move(KV.second);
90 MR->addDependencies(KV.first, InternalDeps);
Lang Hamesca6f5842020-02-11 09:02:22 -080091 }
92
Lang Hamesc66f8902020-05-04 16:43:42 -070093 ES.lookup(LookupKind::Static, LinkOrder, std::move(LookupSet),
Lang Hames674df132019-11-25 21:57:27 -080094 SymbolState::Resolved, std::move(OnResolve),
95 [this](const SymbolDependenceMap &Deps) {
Lang Hamesd4a80892019-06-07 19:33:51 +000096 registerDependencies(Deps);
97 });
Lang Hames11c8dfa52019-04-20 17:10:34 +000098 }
99
Lang Hames9f1dcdc2020-07-29 20:46:56 -0700100 Error notifyResolved(LinkGraph &G) override {
Lang Hames11c8dfa52019-04-20 17:10:34 +0000101 auto &ES = Layer.getExecutionSession();
102
103 SymbolFlagsMap ExtraSymbolsToClaim;
104 bool AutoClaim = Layer.AutoClaimObjectSymbols;
105
106 SymbolMap InternedResult;
Lang Hames4e920e52019-10-04 03:55:26 +0000107 for (auto *Sym : G.defined_symbols())
108 if (Sym->hasName() && Sym->getScope() != Scope::Local) {
109 auto InternedName = ES.intern(Sym->getName());
Lang Hames11c8dfa52019-04-20 17:10:34 +0000110 JITSymbolFlags Flags;
111
Lang Hames4e920e52019-10-04 03:55:26 +0000112 if (Sym->isCallable())
Lang Hames11c8dfa52019-04-20 17:10:34 +0000113 Flags |= JITSymbolFlags::Callable;
Lang Hames4e920e52019-10-04 03:55:26 +0000114 if (Sym->getScope() == Scope::Default)
115 Flags |= JITSymbolFlags::Exported;
Lang Hames11c8dfa52019-04-20 17:10:34 +0000116
117 InternedResult[InternedName] =
Lang Hames4e920e52019-10-04 03:55:26 +0000118 JITEvaluatedSymbol(Sym->getAddress(), Flags);
Lang Hames7dcd0042020-09-11 09:23:14 -0700119 if (AutoClaim && !MR->getSymbols().count(InternedName)) {
Lang Hames11c8dfa52019-04-20 17:10:34 +0000120 assert(!ExtraSymbolsToClaim.count(InternedName) &&
121 "Duplicate symbol to claim?");
122 ExtraSymbolsToClaim[InternedName] = Flags;
123 }
124 }
125
Lang Hames4e920e52019-10-04 03:55:26 +0000126 for (auto *Sym : G.absolute_symbols())
127 if (Sym->hasName()) {
128 auto InternedName = ES.intern(Sym->getName());
Lang Hames11c8dfa52019-04-20 17:10:34 +0000129 JITSymbolFlags Flags;
130 Flags |= JITSymbolFlags::Absolute;
Lang Hames4e920e52019-10-04 03:55:26 +0000131 if (Sym->isCallable())
Lang Hames11c8dfa52019-04-20 17:10:34 +0000132 Flags |= JITSymbolFlags::Callable;
Lang Hames4e920e52019-10-04 03:55:26 +0000133 if (Sym->getLinkage() == Linkage::Weak)
134 Flags |= JITSymbolFlags::Weak;
Lang Hames11c8dfa52019-04-20 17:10:34 +0000135 InternedResult[InternedName] =
Lang Hames4e920e52019-10-04 03:55:26 +0000136 JITEvaluatedSymbol(Sym->getAddress(), Flags);
Lang Hames7dcd0042020-09-11 09:23:14 -0700137 if (AutoClaim && !MR->getSymbols().count(InternedName)) {
Lang Hames11c8dfa52019-04-20 17:10:34 +0000138 assert(!ExtraSymbolsToClaim.count(InternedName) &&
139 "Duplicate symbol to claim?");
140 ExtraSymbolsToClaim[InternedName] = Flags;
141 }
142 }
143
144 if (!ExtraSymbolsToClaim.empty())
Lang Hames7dcd0042020-09-11 09:23:14 -0700145 if (auto Err = MR->defineMaterializing(ExtraSymbolsToClaim))
Lang Hames9f1dcdc2020-07-29 20:46:56 -0700146 return Err;
Lang Hames85fb9972019-12-16 02:50:40 -0800147
Lang Hames81726892020-02-21 17:38:42 -0800148 {
Lang Hamescb84e482020-03-25 13:07:00 -0700149
Lang Hames7dcd0042020-09-11 09:23:14 -0700150 // Check that InternedResult matches up with MR->getSymbols().
Lang Hames81726892020-02-21 17:38:42 -0800151 // This guards against faulty transformations / compilers / object caches.
152
Lang Hamescb84e482020-03-25 13:07:00 -0700153 // First check that there aren't any missing symbols.
154 size_t NumMaterializationSideEffectsOnlySymbols = 0;
155 SymbolNameVector ExtraSymbols;
156 SymbolNameVector MissingSymbols;
Lang Hames7dcd0042020-09-11 09:23:14 -0700157 for (auto &KV : MR->getSymbols()) {
Lang Hamescb84e482020-03-25 13:07:00 -0700158
159 // If this is a materialization-side-effects only symbol then bump
160 // the counter and make sure it's *not* defined, otherwise make
161 // sure that it is defined.
162 if (KV.second.hasMaterializationSideEffectsOnly()) {
163 ++NumMaterializationSideEffectsOnlySymbols;
164 if (InternedResult.count(KV.first))
Lang Hames81726892020-02-21 17:38:42 -0800165 ExtraSymbols.push_back(KV.first);
Lang Hamescb84e482020-03-25 13:07:00 -0700166 continue;
167 } else if (!InternedResult.count(KV.first))
168 MissingSymbols.push_back(KV.first);
169 }
170
171 // If there were missing symbols then report the error.
Lang Hames9f1dcdc2020-07-29 20:46:56 -0700172 if (!MissingSymbols.empty())
173 return make_error<MissingSymbolDefinitions>(G.getName(),
174 std::move(MissingSymbols));
Lang Hames81726892020-02-21 17:38:42 -0800175
Lang Hamescb84e482020-03-25 13:07:00 -0700176 // If there are more definitions than expected, add them to the
177 // ExtraSymbols vector.
178 if (InternedResult.size() >
Lang Hames7dcd0042020-09-11 09:23:14 -0700179 MR->getSymbols().size() - NumMaterializationSideEffectsOnlySymbols) {
Lang Hamescb84e482020-03-25 13:07:00 -0700180 for (auto &KV : InternedResult)
Lang Hames7dcd0042020-09-11 09:23:14 -0700181 if (!MR->getSymbols().count(KV.first))
Lang Hamescb84e482020-03-25 13:07:00 -0700182 ExtraSymbols.push_back(KV.first);
183 }
Lang Hames81726892020-02-21 17:38:42 -0800184
Lang Hamescb84e482020-03-25 13:07:00 -0700185 // If there were extra definitions then report the error.
Lang Hames9f1dcdc2020-07-29 20:46:56 -0700186 if (!ExtraSymbols.empty())
187 return make_error<UnexpectedSymbolDefinitions>(G.getName(),
188 std::move(ExtraSymbols));
Lang Hames81726892020-02-21 17:38:42 -0800189 }
190
Lang Hames7dcd0042020-09-11 09:23:14 -0700191 if (auto Err = MR->notifyResolved(InternedResult))
Lang Hames9f1dcdc2020-07-29 20:46:56 -0700192 return Err;
193
Lang Hames7dcd0042020-09-11 09:23:14 -0700194 Layer.notifyLoaded(*MR);
Lang Hames9f1dcdc2020-07-29 20:46:56 -0700195 return Error::success();
Lang Hames11c8dfa52019-04-20 17:10:34 +0000196 }
197
198 void notifyFinalized(
199 std::unique_ptr<JITLinkMemoryManager::Allocation> A) override {
Lang Hames7dcd0042020-09-11 09:23:14 -0700200 if (auto Err = Layer.notifyEmitted(*MR, std::move(A))) {
Lang Hamesa9fdf372019-04-26 22:58:39 +0000201 Layer.getExecutionSession().reportError(std::move(Err));
Lang Hames7dcd0042020-09-11 09:23:14 -0700202 MR->failMaterialization();
Lang Hamesa9fdf372019-04-26 22:58:39 +0000203 return;
204 }
Lang Hames7dcd0042020-09-11 09:23:14 -0700205 if (auto Err = MR->notifyEmitted()) {
Lang Hamese00585c2019-08-23 20:37:31 +0000206 Layer.getExecutionSession().reportError(std::move(Err));
Lang Hames7dcd0042020-09-11 09:23:14 -0700207 MR->failMaterialization();
Lang Hamese00585c2019-08-23 20:37:31 +0000208 }
Lang Hames11c8dfa52019-04-20 17:10:34 +0000209 }
210
Lang Hames4e920e52019-10-04 03:55:26 +0000211 LinkGraphPassFunction getMarkLivePass(const Triple &TT) const override {
212 return [this](LinkGraph &G) { return markResponsibilitySymbolsLive(G); };
Lang Hames11c8dfa52019-04-20 17:10:34 +0000213 }
214
215 Error modifyPassConfig(const Triple &TT, PassConfiguration &Config) override {
216 // Add passes to mark duplicate defs as should-discard, and to walk the
Lang Hames4e920e52019-10-04 03:55:26 +0000217 // link graph to build the symbol dependence graph.
Lang Hames11c8dfa52019-04-20 17:10:34 +0000218 Config.PrePrunePasses.push_back(
Lang Hames4e920e52019-10-04 03:55:26 +0000219 [this](LinkGraph &G) { return externalizeWeakAndCommonSymbols(G); });
Lang Hames11c8dfa52019-04-20 17:10:34 +0000220
Lang Hames7dcd0042020-09-11 09:23:14 -0700221 Layer.modifyPassConfig(*MR, TT, Config);
Lang Hames11c8dfa52019-04-20 17:10:34 +0000222
Lang Hamesca6f5842020-02-11 09:02:22 -0800223 Config.PostPrunePasses.push_back(
224 [this](LinkGraph &G) { return computeNamedSymbolDependencies(G); });
225
Lang Hames11c8dfa52019-04-20 17:10:34 +0000226 return Error::success();
227 }
228
229private:
Lang Hames85fb9972019-12-16 02:50:40 -0800230 struct LocalSymbolNamedDependencies {
231 SymbolNameSet Internal, External;
232 };
233
234 using LocalSymbolNamedDependenciesMap =
235 DenseMap<const Symbol *, LocalSymbolNamedDependencies>;
Lang Hames11c8dfa52019-04-20 17:10:34 +0000236
Lang Hames4e920e52019-10-04 03:55:26 +0000237 Error externalizeWeakAndCommonSymbols(LinkGraph &G) {
Lang Hames11c8dfa52019-04-20 17:10:34 +0000238 auto &ES = Layer.getExecutionSession();
Lang Hames4e920e52019-10-04 03:55:26 +0000239 for (auto *Sym : G.defined_symbols())
240 if (Sym->hasName() && Sym->getLinkage() == Linkage::Weak) {
Lang Hames7dcd0042020-09-11 09:23:14 -0700241 if (!MR->getSymbols().count(ES.intern(Sym->getName())))
Lang Hames4e920e52019-10-04 03:55:26 +0000242 G.makeExternal(*Sym);
Lang Hames11c8dfa52019-04-20 17:10:34 +0000243 }
244
Lang Hames4e920e52019-10-04 03:55:26 +0000245 for (auto *Sym : G.absolute_symbols())
246 if (Sym->hasName() && Sym->getLinkage() == Linkage::Weak) {
Lang Hames7dcd0042020-09-11 09:23:14 -0700247 if (!MR->getSymbols().count(ES.intern(Sym->getName())))
Lang Hames4e920e52019-10-04 03:55:26 +0000248 G.makeExternal(*Sym);
Lang Hames11c8dfa52019-04-20 17:10:34 +0000249 }
250
251 return Error::success();
252 }
253
Lang Hames4e920e52019-10-04 03:55:26 +0000254 Error markResponsibilitySymbolsLive(LinkGraph &G) const {
Lang Hames11c8dfa52019-04-20 17:10:34 +0000255 auto &ES = Layer.getExecutionSession();
Lang Hames4e920e52019-10-04 03:55:26 +0000256 for (auto *Sym : G.defined_symbols())
Lang Hames7dcd0042020-09-11 09:23:14 -0700257 if (Sym->hasName() && MR->getSymbols().count(ES.intern(Sym->getName())))
Lang Hames4e920e52019-10-04 03:55:26 +0000258 Sym->setLive(true);
Lang Hames11c8dfa52019-04-20 17:10:34 +0000259 return Error::success();
260 }
261
Lang Hames4e920e52019-10-04 03:55:26 +0000262 Error computeNamedSymbolDependencies(LinkGraph &G) {
Lang Hames7dcd0042020-09-11 09:23:14 -0700263 auto &ES = MR->getTargetJITDylib().getExecutionSession();
Lang Hamesca6f5842020-02-11 09:02:22 -0800264 auto LocalDeps = computeLocalDeps(G);
Lang Hames11c8dfa52019-04-20 17:10:34 +0000265
Lang Hames85fb9972019-12-16 02:50:40 -0800266 // Compute dependencies for symbols defined in the JITLink graph.
Lang Hames4e920e52019-10-04 03:55:26 +0000267 for (auto *Sym : G.defined_symbols()) {
Lang Hames11c8dfa52019-04-20 17:10:34 +0000268
Lang Hamesca6f5842020-02-11 09:02:22 -0800269 // Skip local symbols: we do not track dependencies for these.
Lang Hames4e920e52019-10-04 03:55:26 +0000270 if (Sym->getScope() == Scope::Local)
Lang Hames11c8dfa52019-04-20 17:10:34 +0000271 continue;
Lang Hamesca6f5842020-02-11 09:02:22 -0800272 assert(Sym->hasName() &&
273 "Defined non-local jitlink::Symbol should have a name");
Lang Hames11c8dfa52019-04-20 17:10:34 +0000274
Lang Hamesca6f5842020-02-11 09:02:22 -0800275 SymbolNameSet ExternalSymDeps, InternalSymDeps;
Lang Hames11c8dfa52019-04-20 17:10:34 +0000276
Lang Hamesca6f5842020-02-11 09:02:22 -0800277 // Find internal and external named symbol dependencies.
Lang Hames4e920e52019-10-04 03:55:26 +0000278 for (auto &E : Sym->getBlock().edges()) {
279 auto &TargetSym = E.getTarget();
Lang Hames11c8dfa52019-04-20 17:10:34 +0000280
Lang Hamesca6f5842020-02-11 09:02:22 -0800281 if (TargetSym.getScope() != Scope::Local) {
282 if (TargetSym.isExternal())
283 ExternalSymDeps.insert(ES.intern(TargetSym.getName()));
284 else if (&TargetSym != Sym)
285 InternalSymDeps.insert(ES.intern(TargetSym.getName()));
286 } else {
Lang Hames4e920e52019-10-04 03:55:26 +0000287 assert(TargetSym.isDefined() &&
Lang Hamesca6f5842020-02-11 09:02:22 -0800288 "local symbols must be defined");
289 auto I = LocalDeps.find(&TargetSym);
Lang Hames85fb9972019-12-16 02:50:40 -0800290 if (I != LocalDeps.end()) {
291 for (auto &S : I->second.External)
292 ExternalSymDeps.insert(S);
293 for (auto &S : I->second.Internal)
294 InternalSymDeps.insert(S);
295 }
Lang Hames11c8dfa52019-04-20 17:10:34 +0000296 }
297 }
Lang Hamesca6f5842020-02-11 09:02:22 -0800298
299 if (ExternalSymDeps.empty() && InternalSymDeps.empty())
300 continue;
301
302 auto SymName = ES.intern(Sym->getName());
303 if (!ExternalSymDeps.empty())
304 ExternalNamedSymbolDeps[SymName] = std::move(ExternalSymDeps);
305 if (!InternalSymDeps.empty())
306 InternalNamedSymbolDeps[SymName] = std::move(InternalSymDeps);
Lang Hames11c8dfa52019-04-20 17:10:34 +0000307 }
308
Lang Hames85fb9972019-12-16 02:50:40 -0800309 for (auto &P : Layer.Plugins) {
Lang Hames7dcd0042020-09-11 09:23:14 -0700310 auto SyntheticLocalDeps = P->getSyntheticSymbolLocalDependencies(*MR);
Lang Hames85fb9972019-12-16 02:50:40 -0800311 if (SyntheticLocalDeps.empty())
312 continue;
313
314 for (auto &KV : SyntheticLocalDeps) {
315 auto &Name = KV.first;
316 auto &LocalDepsForName = KV.second;
317 for (auto *Local : LocalDepsForName) {
318 assert(Local->getScope() == Scope::Local &&
319 "Dependence on non-local symbol");
320 auto LocalNamedDepsItr = LocalDeps.find(Local);
321 if (LocalNamedDepsItr == LocalDeps.end())
322 continue;
323 for (auto &S : LocalNamedDepsItr->second.Internal)
324 InternalNamedSymbolDeps[Name].insert(S);
325 for (auto &S : LocalNamedDepsItr->second.External)
326 ExternalNamedSymbolDeps[Name].insert(S);
327 }
328 }
329 }
330
Lang Hames11c8dfa52019-04-20 17:10:34 +0000331 return Error::success();
332 }
333
Lang Hames85fb9972019-12-16 02:50:40 -0800334 LocalSymbolNamedDependenciesMap computeLocalDeps(LinkGraph &G) {
335 DenseMap<jitlink::Symbol *, DenseSet<jitlink::Symbol *>> DepMap;
Lang Hames11c8dfa52019-04-20 17:10:34 +0000336
Lang Hamesca6f5842020-02-11 09:02:22 -0800337 // For all local symbols:
Lang Hames11c8dfa52019-04-20 17:10:34 +0000338 // (1) Add their named dependencies.
339 // (2) Add them to the worklist for further iteration if they have any
Lang Hamesca6f5842020-02-11 09:02:22 -0800340 // depend on any other local symbols.
Lang Hames11c8dfa52019-04-20 17:10:34 +0000341 struct WorklistEntry {
Lang Hamesca6f5842020-02-11 09:02:22 -0800342 WorklistEntry(Symbol *Sym, DenseSet<Symbol *> LocalDeps)
343 : Sym(Sym), LocalDeps(std::move(LocalDeps)) {}
Lang Hames11c8dfa52019-04-20 17:10:34 +0000344
Lang Hames4e920e52019-10-04 03:55:26 +0000345 Symbol *Sym = nullptr;
Lang Hamesca6f5842020-02-11 09:02:22 -0800346 DenseSet<Symbol *> LocalDeps;
Lang Hames11c8dfa52019-04-20 17:10:34 +0000347 };
348 std::vector<WorklistEntry> Worklist;
Lang Hames4e920e52019-10-04 03:55:26 +0000349 for (auto *Sym : G.defined_symbols())
Lang Hamesca6f5842020-02-11 09:02:22 -0800350 if (Sym->getScope() == Scope::Local) {
Lang Hames4e920e52019-10-04 03:55:26 +0000351 auto &SymNamedDeps = DepMap[Sym];
Lang Hamesca6f5842020-02-11 09:02:22 -0800352 DenseSet<Symbol *> LocalDeps;
Lang Hames11c8dfa52019-04-20 17:10:34 +0000353
Lang Hames4e920e52019-10-04 03:55:26 +0000354 for (auto &E : Sym->getBlock().edges()) {
355 auto &TargetSym = E.getTarget();
Lang Hamesca6f5842020-02-11 09:02:22 -0800356 if (TargetSym.getScope() != Scope::Local)
357 SymNamedDeps.insert(&TargetSym);
Lang Hames11c8dfa52019-04-20 17:10:34 +0000358 else {
Lang Hames4e920e52019-10-04 03:55:26 +0000359 assert(TargetSym.isDefined() &&
Lang Hamesca6f5842020-02-11 09:02:22 -0800360 "local symbols must be defined");
361 LocalDeps.insert(&TargetSym);
Lang Hames11c8dfa52019-04-20 17:10:34 +0000362 }
363 }
364
Lang Hamesca6f5842020-02-11 09:02:22 -0800365 if (!LocalDeps.empty())
366 Worklist.push_back(WorklistEntry(Sym, std::move(LocalDeps)));
Lang Hames11c8dfa52019-04-20 17:10:34 +0000367 }
368
Lang Hamesca6f5842020-02-11 09:02:22 -0800369 // Loop over all local symbols with local dependencies, propagating
370 // their respective non-local dependencies. Iterate until we hit a stable
Lang Hames11c8dfa52019-04-20 17:10:34 +0000371 // state.
372 bool Changed;
373 do {
374 Changed = false;
375 for (auto &WLEntry : Worklist) {
Lang Hames4e920e52019-10-04 03:55:26 +0000376 auto *Sym = WLEntry.Sym;
Lang Hamesca6f5842020-02-11 09:02:22 -0800377 auto &NamedDeps = DepMap[Sym];
378 auto &LocalDeps = WLEntry.LocalDeps;
Lang Hames11c8dfa52019-04-20 17:10:34 +0000379
Lang Hamesca6f5842020-02-11 09:02:22 -0800380 for (auto *TargetSym : LocalDeps) {
Lang Hames4e920e52019-10-04 03:55:26 +0000381 auto I = DepMap.find(TargetSym);
Lang Hames11c8dfa52019-04-20 17:10:34 +0000382 if (I != DepMap.end())
383 for (const auto &S : I->second)
Lang Hamesca6f5842020-02-11 09:02:22 -0800384 Changed |= NamedDeps.insert(S).second;
Lang Hames11c8dfa52019-04-20 17:10:34 +0000385 }
386 }
387 } while (Changed);
388
Lang Hames85fb9972019-12-16 02:50:40 -0800389 // Intern the results to produce a mapping of jitlink::Symbol* to internal
390 // and external symbol names.
391 auto &ES = Layer.getExecutionSession();
392 LocalSymbolNamedDependenciesMap Result;
393 for (auto &KV : DepMap) {
394 auto *Local = KV.first;
395 assert(Local->getScope() == Scope::Local &&
396 "DepMap keys should all be local symbols");
397 auto &LocalNamedDeps = Result[Local];
398 for (auto *Named : KV.second) {
399 assert(Named->getScope() != Scope::Local &&
400 "DepMap values should all be non-local symbol sets");
401 if (Named->isExternal())
402 LocalNamedDeps.External.insert(ES.intern(Named->getName()));
403 else
404 LocalNamedDeps.Internal.insert(ES.intern(Named->getName()));
405 }
406 }
407
408 return Result;
Lang Hames11c8dfa52019-04-20 17:10:34 +0000409 }
410
411 void registerDependencies(const SymbolDependenceMap &QueryDeps) {
Lang Hamesca6f5842020-02-11 09:02:22 -0800412 for (auto &NamedDepsEntry : ExternalNamedSymbolDeps) {
Lang Hames11c8dfa52019-04-20 17:10:34 +0000413 auto &Name = NamedDepsEntry.first;
414 auto &NameDeps = NamedDepsEntry.second;
415 SymbolDependenceMap SymbolDeps;
416
417 for (const auto &QueryDepsEntry : QueryDeps) {
418 JITDylib &SourceJD = *QueryDepsEntry.first;
419 const SymbolNameSet &Symbols = QueryDepsEntry.second;
420 auto &DepsForJD = SymbolDeps[&SourceJD];
421
422 for (const auto &S : Symbols)
423 if (NameDeps.count(S))
424 DepsForJD.insert(S);
425
426 if (DepsForJD.empty())
427 SymbolDeps.erase(&SourceJD);
428 }
429
Lang Hames7dcd0042020-09-11 09:23:14 -0700430 MR->addDependencies(Name, SymbolDeps);
Lang Hames11c8dfa52019-04-20 17:10:34 +0000431 }
432 }
433
434 ObjectLinkingLayer &Layer;
Lang Hames7dcd0042020-09-11 09:23:14 -0700435 std::unique_ptr<MaterializationResponsibility> MR;
Lang Hames11c8dfa52019-04-20 17:10:34 +0000436 std::unique_ptr<MemoryBuffer> ObjBuffer;
Lang Hamesca6f5842020-02-11 09:02:22 -0800437 DenseMap<SymbolStringPtr, SymbolNameSet> ExternalNamedSymbolDeps;
438 DenseMap<SymbolStringPtr, SymbolNameSet> InternalNamedSymbolDeps;
Lang Hames11c8dfa52019-04-20 17:10:34 +0000439};
440
Lang Hamesa9fdf372019-04-26 22:58:39 +0000441ObjectLinkingLayer::Plugin::~Plugin() {}
442
Lang Hames69091eb2020-07-23 16:03:45 -0700443ObjectLinkingLayer::ObjectLinkingLayer(ExecutionSession &ES,
444 JITLinkMemoryManager &MemMgr)
445 : ObjectLayer(ES), MemMgr(MemMgr) {}
446
Lang Hamesc0143f32019-12-15 17:23:36 -0800447ObjectLinkingLayer::ObjectLinkingLayer(
448 ExecutionSession &ES, std::unique_ptr<JITLinkMemoryManager> MemMgr)
Lang Hames69091eb2020-07-23 16:03:45 -0700449 : ObjectLayer(ES), MemMgr(*MemMgr), MemMgrOwnership(std::move(MemMgr)) {}
Lang Hamesa9fdf372019-04-26 22:58:39 +0000450
451ObjectLinkingLayer::~ObjectLinkingLayer() {
452 if (auto Err = removeAllModules())
453 getExecutionSession().reportError(std::move(Err));
454}
Lang Hames11c8dfa52019-04-20 17:10:34 +0000455
Lang Hames7dcd0042020-09-11 09:23:14 -0700456void ObjectLinkingLayer::emit(std::unique_ptr<MaterializationResponsibility> R,
Lang Hames11c8dfa52019-04-20 17:10:34 +0000457 std::unique_ptr<MemoryBuffer> O) {
458 assert(O && "Object must not be null");
Jonas Devlieghere0eaee542019-08-15 15:54:37 +0000459 jitLink(std::make_unique<ObjectLinkingLayerJITLinkContext>(
Lang Hames11c8dfa52019-04-20 17:10:34 +0000460 *this, std::move(R), std::move(O)));
461}
462
Lang Hamesa9fdf372019-04-26 22:58:39 +0000463void ObjectLinkingLayer::modifyPassConfig(MaterializationResponsibility &MR,
464 const Triple &TT,
465 PassConfiguration &PassConfig) {
466 for (auto &P : Plugins)
467 P->modifyPassConfig(MR, TT, PassConfig);
Lang Hames11c8dfa52019-04-20 17:10:34 +0000468}
469
Lang Hamesa9fdf372019-04-26 22:58:39 +0000470void ObjectLinkingLayer::notifyLoaded(MaterializationResponsibility &MR) {
471 for (auto &P : Plugins)
472 P->notifyLoaded(MR);
Lang Hames11c8dfa52019-04-20 17:10:34 +0000473}
474
Lang Hamesa9fdf372019-04-26 22:58:39 +0000475Error ObjectLinkingLayer::notifyEmitted(MaterializationResponsibility &MR,
476 AllocPtr Alloc) {
477 Error Err = Error::success();
478 for (auto &P : Plugins)
479 Err = joinErrors(std::move(Err), P->notifyEmitted(MR));
Lang Hames11c8dfa52019-04-20 17:10:34 +0000480
Lang Hamesa9fdf372019-04-26 22:58:39 +0000481 if (Err)
482 return Err;
Lang Hames11c8dfa52019-04-20 17:10:34 +0000483
Lang Hamesa9fdf372019-04-26 22:58:39 +0000484 {
485 std::lock_guard<std::mutex> Lock(LayerMutex);
486 UntrackedAllocs.push_back(std::move(Alloc));
487 }
Lang Hames11c8dfa52019-04-20 17:10:34 +0000488
Lang Hamesa9fdf372019-04-26 22:58:39 +0000489 return Error::success();
490}
491
492Error ObjectLinkingLayer::removeModule(VModuleKey K) {
493 Error Err = Error::success();
494
495 for (auto &P : Plugins)
496 Err = joinErrors(std::move(Err), P->notifyRemovingModule(K));
497
498 AllocPtr Alloc;
499
500 {
501 std::lock_guard<std::mutex> Lock(LayerMutex);
502 auto AllocItr = TrackedAllocs.find(K);
503 Alloc = std::move(AllocItr->second);
504 TrackedAllocs.erase(AllocItr);
505 }
506
507 assert(Alloc && "No allocation for key K");
508
509 return joinErrors(std::move(Err), Alloc->deallocate());
510}
511
512Error ObjectLinkingLayer::removeAllModules() {
513
514 Error Err = Error::success();
515
516 for (auto &P : Plugins)
517 Err = joinErrors(std::move(Err), P->notifyRemovingAllModules());
518
519 std::vector<AllocPtr> Allocs;
520 {
521 std::lock_guard<std::mutex> Lock(LayerMutex);
522 Allocs = std::move(UntrackedAllocs);
523
524 for (auto &KV : TrackedAllocs)
525 Allocs.push_back(std::move(KV.second));
526
527 TrackedAllocs.clear();
528 }
529
530 while (!Allocs.empty()) {
531 Err = joinErrors(std::move(Err), Allocs.back()->deallocate());
532 Allocs.pop_back();
533 }
534
535 return Err;
536}
537
Lang Hamesf5a885f2019-07-04 00:05:12 +0000538EHFrameRegistrationPlugin::EHFrameRegistrationPlugin(
Lang Hames605df812020-08-26 16:56:33 -0700539 std::unique_ptr<EHFrameRegistrar> Registrar)
540 : Registrar(std::move(Registrar)) {}
Lang Hamesf5a885f2019-07-04 00:05:12 +0000541
542void EHFrameRegistrationPlugin::modifyPassConfig(
Lang Hamesa9fdf372019-04-26 22:58:39 +0000543 MaterializationResponsibility &MR, const Triple &TT,
544 PassConfiguration &PassConfig) {
Lang Hamesa9fdf372019-04-26 22:58:39 +0000545
Lang Hames214a9f02020-03-12 15:08:30 -0700546 PassConfig.PostFixupPasses.push_back(createEHFrameRecorderPass(
547 TT, [this, &MR](JITTargetAddress Addr, size_t Size) {
548 if (Addr) {
549 std::lock_guard<std::mutex> Lock(EHFramePluginMutex);
550 assert(!InProcessLinks.count(&MR) &&
551 "Link for MR already being tracked?");
552 InProcessLinks[&MR] = {Addr, Size};
553 }
Lang Hamesa9fdf372019-04-26 22:58:39 +0000554 }));
555}
556
Lang Hamesf5a885f2019-07-04 00:05:12 +0000557Error EHFrameRegistrationPlugin::notifyEmitted(
Lang Hamesa9fdf372019-04-26 22:58:39 +0000558 MaterializationResponsibility &MR) {
Lang Hames214a9f02020-03-12 15:08:30 -0700559 std::lock_guard<std::mutex> Lock(EHFramePluginMutex);
Lang Hamesa9fdf372019-04-26 22:58:39 +0000560
Lang Hamesc48f1f62019-08-27 15:50:32 +0000561 auto EHFrameRangeItr = InProcessLinks.find(&MR);
562 if (EHFrameRangeItr == InProcessLinks.end())
Lang Hamesa9fdf372019-04-26 22:58:39 +0000563 return Error::success();
564
Lang Hamesc48f1f62019-08-27 15:50:32 +0000565 auto EHFrameRange = EHFrameRangeItr->second;
566 assert(EHFrameRange.Addr &&
567 "eh-frame addr to register can not be null");
Lang Hamesa9fdf372019-04-26 22:58:39 +0000568
Lang Hamesc48f1f62019-08-27 15:50:32 +0000569 InProcessLinks.erase(EHFrameRangeItr);
Lang Hamesa9fdf372019-04-26 22:58:39 +0000570 if (auto Key = MR.getVModuleKey())
Lang Hamesc48f1f62019-08-27 15:50:32 +0000571 TrackedEHFrameRanges[Key] = EHFrameRange;
Lang Hamesa9fdf372019-04-26 22:58:39 +0000572 else
Lang Hamesc48f1f62019-08-27 15:50:32 +0000573 UntrackedEHFrameRanges.push_back(EHFrameRange);
Lang Hamesa9fdf372019-04-26 22:58:39 +0000574
Lang Hames605df812020-08-26 16:56:33 -0700575 return Registrar->registerEHFrames(EHFrameRange.Addr, EHFrameRange.Size);
Lang Hamesa9fdf372019-04-26 22:58:39 +0000576}
577
Lang Hamesf5a885f2019-07-04 00:05:12 +0000578Error EHFrameRegistrationPlugin::notifyRemovingModule(VModuleKey K) {
Lang Hames214a9f02020-03-12 15:08:30 -0700579 std::lock_guard<std::mutex> Lock(EHFramePluginMutex);
580
Lang Hamesc48f1f62019-08-27 15:50:32 +0000581 auto EHFrameRangeItr = TrackedEHFrameRanges.find(K);
582 if (EHFrameRangeItr == TrackedEHFrameRanges.end())
Lang Hamesa9fdf372019-04-26 22:58:39 +0000583 return Error::success();
584
Lang Hamesc48f1f62019-08-27 15:50:32 +0000585 auto EHFrameRange = EHFrameRangeItr->second;
586 assert(EHFrameRange.Addr && "Tracked eh-frame range must not be null");
Lang Hamesa9fdf372019-04-26 22:58:39 +0000587
Lang Hamesc48f1f62019-08-27 15:50:32 +0000588 TrackedEHFrameRanges.erase(EHFrameRangeItr);
Lang Hamesa9fdf372019-04-26 22:58:39 +0000589
Lang Hames605df812020-08-26 16:56:33 -0700590 return Registrar->deregisterEHFrames(EHFrameRange.Addr, EHFrameRange.Size);
Lang Hamesa9fdf372019-04-26 22:58:39 +0000591}
592
Lang Hamesf5a885f2019-07-04 00:05:12 +0000593Error EHFrameRegistrationPlugin::notifyRemovingAllModules() {
Lang Hames214a9f02020-03-12 15:08:30 -0700594 std::lock_guard<std::mutex> Lock(EHFramePluginMutex);
Lang Hamesa9fdf372019-04-26 22:58:39 +0000595
Lang Hamesc48f1f62019-08-27 15:50:32 +0000596 std::vector<EHFrameRange> EHFrameRanges =
597 std::move(UntrackedEHFrameRanges);
598 EHFrameRanges.reserve(EHFrameRanges.size() + TrackedEHFrameRanges.size());
Lang Hamesa9fdf372019-04-26 22:58:39 +0000599
Lang Hamesc48f1f62019-08-27 15:50:32 +0000600 for (auto &KV : TrackedEHFrameRanges)
601 EHFrameRanges.push_back(KV.second);
Lang Hamesa9fdf372019-04-26 22:58:39 +0000602
Lang Hamesc48f1f62019-08-27 15:50:32 +0000603 TrackedEHFrameRanges.clear();
Lang Hamesa9fdf372019-04-26 22:58:39 +0000604
605 Error Err = Error::success();
606
Lang Hamesc48f1f62019-08-27 15:50:32 +0000607 while (!EHFrameRanges.empty()) {
608 auto EHFrameRange = EHFrameRanges.back();
609 assert(EHFrameRange.Addr && "Untracked eh-frame range must not be null");
610 EHFrameRanges.pop_back();
Lang Hames605df812020-08-26 16:56:33 -0700611 Err = joinErrors(std::move(Err), Registrar->deregisterEHFrames(
612 EHFrameRange.Addr, EHFrameRange.Size));
Lang Hamesa9fdf372019-04-26 22:58:39 +0000613 }
614
615 return Err;
Lang Hames11c8dfa52019-04-20 17:10:34 +0000616}
617
618} // End namespace orc.
619} // End namespace llvm.