1 //===-- 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 
12 namespace {
13 
14 using namespace llvm;
15 using namespace llvm::orc;
16 
17 class JITDylibSearchOrderResolver : public JITSymbolResolver {
18 public:
19   JITDylibSearchOrderResolver(MaterializationResponsibility &MR) : MR(MR) {}
20 
21   Expected<LookupResult> lookup(const LookupSet &Symbols) {
22     auto &ES = MR.getTargetJITDylib().getExecutionSession();
23     SymbolNameSet InternedSymbols;
24 
25     for (auto &S : Symbols)
26       InternedSymbols.insert(ES.getSymbolStringPool().intern(S));
27 
28     auto RegisterDependencies = [&](const SymbolDependenceMap &Deps) {
29       MR.addDependenciesForAll(Deps);
30     };
31 
32     auto InternedResult =
33         MR.getTargetJITDylib().withSearchOrderDo([&](const JITDylibList &JDs) {
34           return ES.lookup(JDs, InternedSymbols, RegisterDependencies, false);
35         });
36 
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<LookupSet> getResponsibilitySet(const LookupSet &Symbols) {
48     LookupSet Result;
49 
50     for (auto &KV : MR.getSymbols()) {
51       if (Symbols.count(*KV.first))
52         Result.insert(*KV.first);
53     }
54 
55     return Result;
56   }
57 
58 private:
59   MaterializationResponsibility &MR;
60 };
61 
62 } // end anonymous namespace
63 
64 namespace llvm {
65 namespace orc {
66 
67 RTDyldObjectLinkingLayer2::RTDyldObjectLinkingLayer2(
68     ExecutionSession &ES, GetMemoryManagerFunction GetMemoryManager,
69     NotifyLoadedFunction NotifyLoaded, NotifyEmittedFunction NotifyEmitted)
70     : ObjectLayer(ES), GetMemoryManager(GetMemoryManager),
71       NotifyLoaded(std::move(NotifyLoaded)),
72       NotifyEmitted(std::move(NotifyEmitted)) {}
73 
74 void RTDyldObjectLinkingLayer2::emit(MaterializationResponsibility R,
75                                      VModuleKey K,
76                                      std::unique_ptr<MemoryBuffer> O) {
77   assert(O && "Object must not be null");
78 
79   auto &ES = getExecutionSession();
80 
81   auto ObjFile = object::ObjectFile::createObjectFile(*O);
82   if (!ObjFile) {
83     getExecutionSession().reportError(ObjFile.takeError());
84     R.failMaterialization();
85   }
86 
87   auto MemoryManager = GetMemoryManager(K);
88 
89   JITDylibSearchOrderResolver Resolver(R);
90   auto RTDyld = llvm::make_unique<RuntimeDyld>(*MemoryManager, Resolver);
91   RTDyld->setProcessAllSections(ProcessAllSections);
92 
93   {
94     std::lock_guard<std::mutex> Lock(RTDyldLayerMutex);
95 
96     assert(!ActiveRTDylds.count(K) &&
97            "An active RTDyld already exists for this key?");
98     ActiveRTDylds[K] = RTDyld.get();
99 
100     assert(!MemMgrs.count(K) &&
101            "A memory manager already exists for this key?");
102     MemMgrs[K] = std::move(MemoryManager);
103   }
104 
105   auto Info = RTDyld->loadObject(**ObjFile);
106 
107   {
108     std::set<StringRef> InternalSymbols;
109     for (auto &Sym : (*ObjFile)->symbols()) {
110       if (!(Sym.getFlags() & object::BasicSymbolRef::SF_Global)) {
111         if (auto SymName = Sym.getName())
112           InternalSymbols.insert(*SymName);
113         else {
114           ES.reportError(SymName.takeError());
115           R.failMaterialization();
116           return;
117         }
118       }
119     }
120 
121     SymbolFlagsMap ExtraSymbolsToClaim;
122     SymbolMap Symbols;
123     for (auto &KV : RTDyld->getSymbolTable()) {
124       // Scan the symbols and add them to the Symbols map for resolution.
125 
126       // We never claim internal symbols.
127       if (InternalSymbols.count(KV.first))
128         continue;
129 
130       auto InternedName = ES.getSymbolStringPool().intern(KV.first);
131       auto Flags = KV.second.getFlags();
132 
133       // Override object flags and claim responsibility for symbols if
134       // requested.
135       if (OverrideObjectFlags || AutoClaimObjectSymbols) {
136         auto I = R.getSymbols().find(InternedName);
137 
138         if (OverrideObjectFlags && I != R.getSymbols().end())
139           Flags = JITSymbolFlags::stripTransientFlags(I->second);
140         else if (AutoClaimObjectSymbols && I == R.getSymbols().end())
141           ExtraSymbolsToClaim[InternedName] = Flags;
142       }
143 
144       Symbols[InternedName] = JITEvaluatedSymbol(KV.second.getAddress(), Flags);
145     }
146 
147     if (!ExtraSymbolsToClaim.empty())
148       if (auto Err = R.defineMaterializing(ExtraSymbolsToClaim)) {
149         ES.reportError(std::move(Err));
150         R.failMaterialization();
151         return;
152       }
153 
154     R.resolve(Symbols);
155   }
156 
157   if (NotifyLoaded)
158     NotifyLoaded(K, **ObjFile, *Info);
159 
160   RTDyld->finalizeWithMemoryManagerLocking();
161 
162   {
163     std::lock_guard<std::mutex> Lock(RTDyldLayerMutex);
164     ActiveRTDylds.erase(K);
165   }
166 
167   if (RTDyld->hasError()) {
168     ES.reportError(make_error<StringError>(RTDyld->getErrorString(),
169                                            inconvertibleErrorCode()));
170     R.failMaterialization();
171     return;
172   }
173 
174   R.emit();
175 
176   if (NotifyEmitted)
177     NotifyEmitted(K);
178 }
179 
180 void RTDyldObjectLinkingLayer2::mapSectionAddress(
181     VModuleKey K, const void *LocalAddress, JITTargetAddress TargetAddr) const {
182   std::lock_guard<std::mutex> Lock(RTDyldLayerMutex);
183   auto ActiveRTDyldItr = ActiveRTDylds.find(K);
184 
185   assert(ActiveRTDyldItr != ActiveRTDylds.end() &&
186          "No active RTDyld instance found for key");
187   ActiveRTDyldItr->second->mapSectionAddress(LocalAddress, TargetAddr);
188 }
189 
190 } // End namespace orc.
191 } // End namespace llvm.
192