• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 VSOSearchOrderResolver : public JITSymbolResolver {
18 public:
VSOSearchOrderResolver(MaterializationResponsibility & MR)19   VSOSearchOrderResolver(MaterializationResponsibility &MR) : MR(MR) {}
20 
lookup(const LookupSet & Symbols)21   Expected<LookupResult> lookup(const LookupSet &Symbols) {
22     auto &ES = MR.getTargetVSO().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.getTargetVSO().withSearchOrderDo([&](const VSOList &VSOs) {
34           return ES.lookup(VSOs, 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 
lookupFlags(const LookupSet & Symbols)47   Expected<LookupFlagsResult> lookupFlags(const LookupSet &Symbols) {
48     auto &ES = MR.getTargetVSO().getExecutionSession();
49 
50     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");
62       InternedResult = VSOs.front()->lookupFlags(InternedSymbols);
63     });
64 
65     LookupFlagsResult Result;
66     for (auto &KV : InternedResult)
67       Result[*KV.first] = std::move(KV.second);
68 
69     return Result;
70   }
71 
72 private:
73   MaterializationResponsibility &MR;
74 };
75 
76 } // end anonymous namespace
77 
78 namespace llvm {
79 namespace orc {
80 
RTDyldObjectLinkingLayer2(ExecutionSession & ES,GetMemoryManagerFunction GetMemoryManager,NotifyLoadedFunction NotifyLoaded,NotifyFinalizedFunction NotifyFinalized)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) {}
87 
emit(MaterializationResponsibility R,VModuleKey K,std::unique_ptr<MemoryBuffer> O)88 void RTDyldObjectLinkingLayer2::emit(MaterializationResponsibility R,
89                                      VModuleKey K,
90                                      std::unique_ptr<MemoryBuffer> O) {
91   assert(O && "Object must not be null");
92 
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 
101   auto MemoryManager = GetMemoryManager(K);
102 
103   VSOSearchOrderResolver Resolver(R);
104   auto RTDyld = llvm::make_unique<RuntimeDyld>(*MemoryManager, Resolver);
105   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?");
116     MemMgrs[K] = std::move(MemoryManager);
117   }
118 
119   auto Info = RTDyld->loadObject(**ObjFile);
120 
121   {
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);
127         else {
128           ES.reportError(SymName.takeError());
129           R.failMaterialization();
130           return;
131         }
132       }
133     }
134 
135     SymbolMap Symbols;
136     for (auto &KV : RTDyld->getSymbolTable())
137       if (!InternalSymbols.count(KV.first))
138         Symbols[ES.getSymbolStringPool().intern(KV.first)] = KV.second;
139 
140     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();
157     return;
158   }
159 
160   R.finalize();
161 
162   if (NotifyFinalized)
163     NotifyFinalized(K);
164 }
165 
mapSectionAddress(VModuleKey K,const void * LocalAddress,JITTargetAddress TargetAddr) const166 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);
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.
178