blob: 6edf616660e79e84427371fe5e47f59036f5da55 [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:
Lang Hamesa48d1082018-07-20 22:22:19 +000019 VSOSearchOrderResolver(MaterializationResponsibility &MR) : MR(MR) {}
Lang Hamesfd0c1e712018-07-20 18:31:50 +000020
21 Expected<LookupResult> lookup(const LookupSet &Symbols) {
Lang Hamesa48d1082018-07-20 22:22:19 +000022 auto &ES = MR.getTargetVSO().getExecutionSession();
Lang Hamesfd0c1e712018-07-20 18:31:50 +000023 SymbolNameSet InternedSymbols;
24
25 for (auto &S : Symbols)
26 InternedSymbols.insert(ES.getSymbolStringPool().intern(S));
27
Lang Hamesa48d1082018-07-20 22:22:19 +000028 auto RegisterDependencies = [&](const SymbolDependenceMap &Deps) {
29 MR.addDependencies(Deps);
Lang Hamesfd0c1e712018-07-20 18:31:50 +000030 };
31
Lang Hamesa48d1082018-07-20 22:22:19 +000032 auto InternedResult =
33 MR.getTargetVSO().withSearchOrderDo([&](const VSOList &VSOs) {
34 return ES.lookup(VSOs, InternedSymbols, RegisterDependencies, false);
35 });
Lang Hamesfd0c1e712018-07-20 18:31:50 +000036
37 if (!InternedResult)
38 return InternedResult.takeError();
39
40 LookupResult Result;
41 for (auto &KV : *InternedResult)
42 Result[*KV.first] = std::move(KV.second);
43
44 return Result;
45 }
46
47 Expected<LookupFlagsResult> lookupFlags(const LookupSet &Symbols) {
Lang Hamesa48d1082018-07-20 22:22:19 +000048 auto &ES = MR.getTargetVSO().getExecutionSession();
49
Lang Hamesfd0c1e712018-07-20 18:31:50 +000050 SymbolNameSet InternedSymbols;
51
52 for (auto &S : Symbols)
53 InternedSymbols.insert(ES.getSymbolStringPool().intern(S));
54
55 SymbolFlagsMap InternedResult;
56 MR.getTargetVSO().withSearchOrderDo([&](const VSOList &VSOs) {
57 // An empty search order is pathalogical, but allowed.
58 if (VSOs.empty())
59 return;
60
61 assert(VSOs.front() && "VSOList entry can not be null");
Lang Hamesd4df0f12018-07-20 18:31:52 +000062 InternedResult = VSOs.front()->lookupFlags(InternedSymbols);
Lang Hamesfd0c1e712018-07-20 18:31:50 +000063 });
64
65 LookupFlagsResult Result;
66 for (auto &KV : InternedResult)
67 Result[*KV.first] = std::move(KV.second);
68
69 return Result;
70 }
71
72private:
Lang Hamesfd0c1e712018-07-20 18:31:50 +000073 MaterializationResponsibility &MR;
74};
75
76} // end anonymous namespace
77
Lang Hames373f4622018-05-21 23:45:40 +000078namespace llvm {
79namespace orc {
80
81RTDyldObjectLinkingLayer2::RTDyldObjectLinkingLayer2(
Lang Hamesfd0c1e712018-07-20 18:31:50 +000082 ExecutionSession &ES, GetMemoryManagerFunction GetMemoryManager,
Lang Hames373f4622018-05-21 23:45:40 +000083 NotifyLoadedFunction NotifyLoaded, NotifyFinalizedFunction NotifyFinalized)
Lang Hamesfd0c1e712018-07-20 18:31:50 +000084 : ObjectLayer(ES), GetMemoryManager(GetMemoryManager),
Lang Hames373f4622018-05-21 23:45:40 +000085 NotifyLoaded(std::move(NotifyLoaded)),
86 NotifyFinalized(std::move(NotifyFinalized)), ProcessAllSections(false) {}
87
88void RTDyldObjectLinkingLayer2::emit(MaterializationResponsibility R,
89 VModuleKey K,
90 std::unique_ptr<MemoryBuffer> O) {
Lang Hames4caa2f72018-05-23 21:27:01 +000091 assert(O && "Object must not be null");
Lang Hames373f4622018-05-21 23:45:40 +000092
93 auto &ES = getExecutionSession();
94
95 auto ObjFile = object::ObjectFile::createObjectFile(*O);
96 if (!ObjFile) {
97 getExecutionSession().reportError(ObjFile.takeError());
98 R.failMaterialization();
99 }
100
Lang Hamesfd0c1e712018-07-20 18:31:50 +0000101 auto MemoryManager = GetMemoryManager(K);
Lang Hames373f4622018-05-21 23:45:40 +0000102
Lang Hamesa48d1082018-07-20 22:22:19 +0000103 VSOSearchOrderResolver Resolver(R);
Lang Hamesfd0c1e712018-07-20 18:31:50 +0000104 auto RTDyld = llvm::make_unique<RuntimeDyld>(*MemoryManager, Resolver);
Lang Hames373f4622018-05-21 23:45:40 +0000105 RTDyld->setProcessAllSections(ProcessAllSections);
106
107 {
108 std::lock_guard<std::mutex> Lock(RTDyldLayerMutex);
109
110 assert(!ActiveRTDylds.count(K) &&
111 "An active RTDyld already exists for this key?");
112 ActiveRTDylds[K] = RTDyld.get();
113
114 assert(!MemMgrs.count(K) &&
115 "A memory manager already exists for this key?");
Lang Hamesfd0c1e712018-07-20 18:31:50 +0000116 MemMgrs[K] = std::move(MemoryManager);
Lang Hames373f4622018-05-21 23:45:40 +0000117 }
118
119 auto Info = RTDyld->loadObject(**ObjFile);
120
121 {
Lang Hames68c9b8d2018-06-18 18:01:43 +0000122 std::set<StringRef> InternalSymbols;
123 for (auto &Sym : (*ObjFile)->symbols()) {
124 if (!(Sym.getFlags() & object::BasicSymbolRef::SF_Global)) {
125 if (auto SymName = Sym.getName())
126 InternalSymbols.insert(*SymName);
127 else {
128 ES.reportError(SymName.takeError());
129 R.failMaterialization();
130 return;
131 }
132 }
133 }
134
Lang Hames373f4622018-05-21 23:45:40 +0000135 SymbolMap Symbols;
136 for (auto &KV : RTDyld->getSymbolTable())
Lang Hames68c9b8d2018-06-18 18:01:43 +0000137 if (!InternalSymbols.count(KV.first))
138 Symbols[ES.getSymbolStringPool().intern(KV.first)] = KV.second;
139
Lang Hames373f4622018-05-21 23:45:40 +0000140 R.resolve(Symbols);
141 }
142
143 if (NotifyLoaded)
144 NotifyLoaded(K, **ObjFile, *Info);
145
146 RTDyld->finalizeWithMemoryManagerLocking();
147
148 {
149 std::lock_guard<std::mutex> Lock(RTDyldLayerMutex);
150 ActiveRTDylds.erase(K);
151 }
152
153 if (RTDyld->hasError()) {
154 ES.reportError(make_error<StringError>(RTDyld->getErrorString(),
155 inconvertibleErrorCode()));
156 R.failMaterialization();
Lang Hames68c9b8d2018-06-18 18:01:43 +0000157 return;
Lang Hames373f4622018-05-21 23:45:40 +0000158 }
159
160 R.finalize();
161
162 if (NotifyFinalized)
163 NotifyFinalized(K);
164}
165
166void RTDyldObjectLinkingLayer2::mapSectionAddress(
167 VModuleKey K, const void *LocalAddress, JITTargetAddress TargetAddr) const {
168 std::lock_guard<std::mutex> Lock(RTDyldLayerMutex);
169 auto ActiveRTDyldItr = ActiveRTDylds.find(K);
170
171 assert(ActiveRTDyldItr != ActiveRTDylds.end() &&
172 "No active RTDyld instance found for key");
173 ActiveRTDyldItr->second->mapSectionAddress(LocalAddress, TargetAddr);
174}
175
176} // End namespace orc.
177} // End namespace llvm.