1 //===-- RTDyldObjectLinkingLayer.cpp - RuntimeDyld backed ORC ObjectLayer -===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 #include "llvm/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.h"
15 using namespace llvm::orc;
17 class VSOSearchOrderResolver : public JITSymbolResolver {
19 VSOSearchOrderResolver(MaterializationResponsibility &MR) : MR(MR) {}
21 Expected<LookupResult> lookup(const LookupSet &Symbols) {
22 auto &ES = MR.getTargetVSO().getExecutionSession();
23 SymbolNameSet InternedSymbols;
25 for (auto &S : Symbols)
26 InternedSymbols.insert(ES.getSymbolStringPool().intern(S));
28 auto RegisterDependencies = [&](const SymbolDependenceMap &Deps) {
29 MR.addDependenciesForAll(Deps);
33 MR.getTargetVSO().withSearchOrderDo([&](const VSOList &VSOs) {
34 return ES.lookup(VSOs, InternedSymbols, RegisterDependencies, false);
38 return InternedResult.takeError();
41 for (auto &KV : *InternedResult)
42 Result[*KV.first] = std::move(KV.second);
47 Expected<LookupFlagsResult> lookupFlags(const LookupSet &Symbols) {
48 auto &ES = MR.getTargetVSO().getExecutionSession();
50 SymbolNameSet InternedSymbols;
52 for (auto &S : Symbols)
53 InternedSymbols.insert(ES.getSymbolStringPool().intern(S));
55 SymbolFlagsMap InternedResult;
56 MR.getTargetVSO().withSearchOrderDo([&](const VSOList &VSOs) {
57 // An empty search order is pathalogical, but allowed.
61 assert(VSOs.front() && "VSOList entry can not be null");
62 InternedResult = VSOs.front()->lookupFlags(InternedSymbols);
65 LookupFlagsResult Result;
66 for (auto &KV : InternedResult)
67 Result[*KV.first] = std::move(KV.second);
73 MaterializationResponsibility &MR;
76 } // end anonymous namespace
81 RTDyldObjectLinkingLayer2::RTDyldObjectLinkingLayer2(
82 ExecutionSession &ES, GetMemoryManagerFunction GetMemoryManager,
83 NotifyLoadedFunction NotifyLoaded, NotifyFinalizedFunction NotifyFinalized)
84 : ObjectLayer(ES), GetMemoryManager(GetMemoryManager),
85 NotifyLoaded(std::move(NotifyLoaded)),
86 NotifyFinalized(std::move(NotifyFinalized)), ProcessAllSections(false) {}
88 void RTDyldObjectLinkingLayer2::emit(MaterializationResponsibility R,
90 std::unique_ptr<MemoryBuffer> O) {
91 assert(O && "Object must not be null");
93 auto &ES = getExecutionSession();
95 auto ObjFile = object::ObjectFile::createObjectFile(*O);
97 getExecutionSession().reportError(ObjFile.takeError());
98 R.failMaterialization();
101 auto MemoryManager = GetMemoryManager(K);
103 VSOSearchOrderResolver Resolver(R);
104 auto RTDyld = llvm::make_unique<RuntimeDyld>(*MemoryManager, Resolver);
105 RTDyld->setProcessAllSections(ProcessAllSections);
108 std::lock_guard<std::mutex> Lock(RTDyldLayerMutex);
110 assert(!ActiveRTDylds.count(K) &&
111 "An active RTDyld already exists for this key?");
112 ActiveRTDylds[K] = RTDyld.get();
114 assert(!MemMgrs.count(K) &&
115 "A memory manager already exists for this key?");
116 MemMgrs[K] = std::move(MemoryManager);
119 auto Info = RTDyld->loadObject(**ObjFile);
122 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);
128 ES.reportError(SymName.takeError());
129 R.failMaterialization();
136 for (auto &KV : RTDyld->getSymbolTable())
137 if (!InternalSymbols.count(KV.first))
138 Symbols[ES.getSymbolStringPool().intern(KV.first)] = KV.second;
144 NotifyLoaded(K, **ObjFile, *Info);
146 RTDyld->finalizeWithMemoryManagerLocking();
149 std::lock_guard<std::mutex> Lock(RTDyldLayerMutex);
150 ActiveRTDylds.erase(K);
153 if (RTDyld->hasError()) {
154 ES.reportError(make_error<StringError>(RTDyld->getErrorString(),
155 inconvertibleErrorCode()));
156 R.failMaterialization();
166 void 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);
171 assert(ActiveRTDyldItr != ActiveRTDylds.end() &&
172 "No active RTDyld instance found for key");
173 ActiveRTDyldItr->second->mapSectionAddress(LocalAddress, TargetAddr);
176 } // End namespace orc.
177 } // End namespace llvm.