blob: 7cdc6b352d11c8416988bf52dde47f0684f11f73 [file] [log] [blame]
Lang Hames373f4622018-05-21 23:45:40 +00001//===-- RTDyldObjectLinkingLayer.cpp - RuntimeDyld backed ORC ObjectLayer -===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#include "llvm/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.h"
11
Lang Hamesfd0c1e712018-07-20 18:31:50 +000012namespace {
13
14using namespace llvm;
15using namespace llvm::orc;
16
17class VSOSearchOrderResolver : public JITSymbolResolver {
18public:
Reid Kleckner7ed83592018-07-20 20:20:45 +000019 VSOSearchOrderResolver(ExecutionSession &ES,
20 MaterializationResponsibility &MR)
21 : ES(ES), MR(MR) {}
Lang Hamesfd0c1e712018-07-20 18:31:50 +000022
23 Expected<LookupResult> lookup(const LookupSet &Symbols) {
24 SymbolNameSet InternedSymbols;
25
26 for (auto &S : Symbols)
27 InternedSymbols.insert(ES.getSymbolStringPool().intern(S));
28
Reid Kleckner7ed83592018-07-20 20:20:45 +000029 auto AsyncLookup = [&](std::shared_ptr<AsynchronousSymbolQuery> Q,
30 SymbolNameSet Names) {
31 SymbolNameSet Unresolved = std::move(Names);
32 MR.getTargetVSO().withSearchOrderDo([&](const VSOList &SearchOrder) {
33 for (auto *V : SearchOrder) {
34 assert(V && "VSOList entry can not be null");
35 Unresolved = V->lookup(Q, std::move(Unresolved));
36 }
37 });
38 return Unresolved;
Lang Hamesfd0c1e712018-07-20 18:31:50 +000039 };
40
Reid Kleckner7ed83592018-07-20 20:20:45 +000041 auto InternedResult = blockingLookup(
42 ES, std::move(AsyncLookup), std::move(InternedSymbols), false, &MR);
Lang Hamesfd0c1e712018-07-20 18:31:50 +000043
44 if (!InternedResult)
45 return InternedResult.takeError();
46
47 LookupResult Result;
48 for (auto &KV : *InternedResult)
49 Result[*KV.first] = std::move(KV.second);
50
51 return Result;
52 }
53
54 Expected<LookupFlagsResult> lookupFlags(const LookupSet &Symbols) {
55 SymbolNameSet InternedSymbols;
56
57 for (auto &S : Symbols)
58 InternedSymbols.insert(ES.getSymbolStringPool().intern(S));
59
60 SymbolFlagsMap InternedResult;
61 MR.getTargetVSO().withSearchOrderDo([&](const VSOList &VSOs) {
62 // An empty search order is pathalogical, but allowed.
63 if (VSOs.empty())
64 return;
65
66 assert(VSOs.front() && "VSOList entry can not be null");
Lang Hamesd4df0f12018-07-20 18:31:52 +000067 InternedResult = VSOs.front()->lookupFlags(InternedSymbols);
Lang Hamesfd0c1e712018-07-20 18:31:50 +000068 });
69
70 LookupFlagsResult Result;
71 for (auto &KV : InternedResult)
72 Result[*KV.first] = std::move(KV.second);
73
74 return Result;
75 }
76
77private:
Reid Kleckner7ed83592018-07-20 20:20:45 +000078 ExecutionSession &ES;
Lang Hamesfd0c1e712018-07-20 18:31:50 +000079 MaterializationResponsibility &MR;
80};
81
82} // end anonymous namespace
83
Lang Hames373f4622018-05-21 23:45:40 +000084namespace llvm {
85namespace orc {
86
87RTDyldObjectLinkingLayer2::RTDyldObjectLinkingLayer2(
Lang Hamesfd0c1e712018-07-20 18:31:50 +000088 ExecutionSession &ES, GetMemoryManagerFunction GetMemoryManager,
Lang Hames373f4622018-05-21 23:45:40 +000089 NotifyLoadedFunction NotifyLoaded, NotifyFinalizedFunction NotifyFinalized)
Lang Hamesfd0c1e712018-07-20 18:31:50 +000090 : ObjectLayer(ES), GetMemoryManager(GetMemoryManager),
Lang Hames373f4622018-05-21 23:45:40 +000091 NotifyLoaded(std::move(NotifyLoaded)),
92 NotifyFinalized(std::move(NotifyFinalized)), ProcessAllSections(false) {}
93
94void RTDyldObjectLinkingLayer2::emit(MaterializationResponsibility R,
95 VModuleKey K,
96 std::unique_ptr<MemoryBuffer> O) {
Lang Hames4caa2f72018-05-23 21:27:01 +000097 assert(O && "Object must not be null");
Lang Hames373f4622018-05-21 23:45:40 +000098
99 auto &ES = getExecutionSession();
100
101 auto ObjFile = object::ObjectFile::createObjectFile(*O);
102 if (!ObjFile) {
103 getExecutionSession().reportError(ObjFile.takeError());
104 R.failMaterialization();
105 }
106
Lang Hamesfd0c1e712018-07-20 18:31:50 +0000107 auto MemoryManager = GetMemoryManager(K);
Lang Hames373f4622018-05-21 23:45:40 +0000108
Reid Kleckner7ed83592018-07-20 20:20:45 +0000109 VSOSearchOrderResolver Resolver(ES, R);
Lang Hamesfd0c1e712018-07-20 18:31:50 +0000110 auto RTDyld = llvm::make_unique<RuntimeDyld>(*MemoryManager, Resolver);
Lang Hames373f4622018-05-21 23:45:40 +0000111 RTDyld->setProcessAllSections(ProcessAllSections);
112
113 {
114 std::lock_guard<std::mutex> Lock(RTDyldLayerMutex);
115
116 assert(!ActiveRTDylds.count(K) &&
117 "An active RTDyld already exists for this key?");
118 ActiveRTDylds[K] = RTDyld.get();
119
120 assert(!MemMgrs.count(K) &&
121 "A memory manager already exists for this key?");
Lang Hamesfd0c1e712018-07-20 18:31:50 +0000122 MemMgrs[K] = std::move(MemoryManager);
Lang Hames373f4622018-05-21 23:45:40 +0000123 }
124
125 auto Info = RTDyld->loadObject(**ObjFile);
126
127 {
Lang Hames68c9b8d2018-06-18 18:01:43 +0000128 std::set<StringRef> InternalSymbols;
129 for (auto &Sym : (*ObjFile)->symbols()) {
130 if (!(Sym.getFlags() & object::BasicSymbolRef::SF_Global)) {
131 if (auto SymName = Sym.getName())
132 InternalSymbols.insert(*SymName);
133 else {
134 ES.reportError(SymName.takeError());
135 R.failMaterialization();
136 return;
137 }
138 }
139 }
140
Lang Hames373f4622018-05-21 23:45:40 +0000141 SymbolMap Symbols;
142 for (auto &KV : RTDyld->getSymbolTable())
Lang Hames68c9b8d2018-06-18 18:01:43 +0000143 if (!InternalSymbols.count(KV.first))
144 Symbols[ES.getSymbolStringPool().intern(KV.first)] = KV.second;
145
Lang Hames373f4622018-05-21 23:45:40 +0000146 R.resolve(Symbols);
147 }
148
149 if (NotifyLoaded)
150 NotifyLoaded(K, **ObjFile, *Info);
151
152 RTDyld->finalizeWithMemoryManagerLocking();
153
154 {
155 std::lock_guard<std::mutex> Lock(RTDyldLayerMutex);
156 ActiveRTDylds.erase(K);
157 }
158
159 if (RTDyld->hasError()) {
160 ES.reportError(make_error<StringError>(RTDyld->getErrorString(),
161 inconvertibleErrorCode()));
162 R.failMaterialization();
Lang Hames68c9b8d2018-06-18 18:01:43 +0000163 return;
Lang Hames373f4622018-05-21 23:45:40 +0000164 }
165
166 R.finalize();
167
168 if (NotifyFinalized)
169 NotifyFinalized(K);
170}
171
172void RTDyldObjectLinkingLayer2::mapSectionAddress(
173 VModuleKey K, const void *LocalAddress, JITTargetAddress TargetAddr) const {
174 std::lock_guard<std::mutex> Lock(RTDyldLayerMutex);
175 auto ActiveRTDyldItr = ActiveRTDylds.find(K);
176
177 assert(ActiveRTDyldItr != ActiveRTDylds.end() &&
178 "No active RTDyld instance found for key");
179 ActiveRTDyldItr->second->mapSectionAddress(LocalAddress, TargetAddr);
180}
181
182} // End namespace orc.
183} // End namespace llvm.