xref: /aosp_15_r20/external/llvm/lib/ExecutionEngine/Orc/OrcMCJITReplacement.h (revision 9880d6810fe72a1726cb53787c6711e909410d58)
1*9880d681SAndroid Build Coastguard Worker //===---- OrcMCJITReplacement.h - Orc based MCJIT replacement ---*- C++ -*-===//
2*9880d681SAndroid Build Coastguard Worker //
3*9880d681SAndroid Build Coastguard Worker //                     The LLVM Compiler Infrastructure
4*9880d681SAndroid Build Coastguard Worker //
5*9880d681SAndroid Build Coastguard Worker // This file is distributed under the University of Illinois Open Source
6*9880d681SAndroid Build Coastguard Worker // License. See LICENSE.TXT for details.
7*9880d681SAndroid Build Coastguard Worker //
8*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
9*9880d681SAndroid Build Coastguard Worker //
10*9880d681SAndroid Build Coastguard Worker // Orc based MCJIT replacement.
11*9880d681SAndroid Build Coastguard Worker //
12*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
13*9880d681SAndroid Build Coastguard Worker 
14*9880d681SAndroid Build Coastguard Worker #ifndef LLVM_LIB_EXECUTIONENGINE_ORC_ORCMCJITREPLACEMENT_H
15*9880d681SAndroid Build Coastguard Worker #define LLVM_LIB_EXECUTIONENGINE_ORC_ORCMCJITREPLACEMENT_H
16*9880d681SAndroid Build Coastguard Worker 
17*9880d681SAndroid Build Coastguard Worker #include "llvm/ExecutionEngine/ExecutionEngine.h"
18*9880d681SAndroid Build Coastguard Worker #include "llvm/ExecutionEngine/Orc/CompileUtils.h"
19*9880d681SAndroid Build Coastguard Worker #include "llvm/ExecutionEngine/Orc/IRCompileLayer.h"
20*9880d681SAndroid Build Coastguard Worker #include "llvm/ExecutionEngine/Orc/LazyEmittingLayer.h"
21*9880d681SAndroid Build Coastguard Worker #include "llvm/ExecutionEngine/Orc/ObjectLinkingLayer.h"
22*9880d681SAndroid Build Coastguard Worker #include "llvm/Object/Archive.h"
23*9880d681SAndroid Build Coastguard Worker 
24*9880d681SAndroid Build Coastguard Worker namespace llvm {
25*9880d681SAndroid Build Coastguard Worker namespace orc {
26*9880d681SAndroid Build Coastguard Worker 
27*9880d681SAndroid Build Coastguard Worker class OrcMCJITReplacement : public ExecutionEngine {
28*9880d681SAndroid Build Coastguard Worker 
29*9880d681SAndroid Build Coastguard Worker   // OrcMCJITReplacement needs to do a little extra book-keeping to ensure that
30*9880d681SAndroid Build Coastguard Worker   // Orc's automatic finalization doesn't kick in earlier than MCJIT clients are
31*9880d681SAndroid Build Coastguard Worker   // expecting - see finalizeMemory.
32*9880d681SAndroid Build Coastguard Worker   class MCJITReplacementMemMgr : public MCJITMemoryManager {
33*9880d681SAndroid Build Coastguard Worker   public:
MCJITReplacementMemMgr(OrcMCJITReplacement & M,std::shared_ptr<MCJITMemoryManager> ClientMM)34*9880d681SAndroid Build Coastguard Worker     MCJITReplacementMemMgr(OrcMCJITReplacement &M,
35*9880d681SAndroid Build Coastguard Worker                            std::shared_ptr<MCJITMemoryManager> ClientMM)
36*9880d681SAndroid Build Coastguard Worker       : M(M), ClientMM(std::move(ClientMM)) {}
37*9880d681SAndroid Build Coastguard Worker 
allocateCodeSection(uintptr_t Size,unsigned Alignment,unsigned SectionID,StringRef SectionName)38*9880d681SAndroid Build Coastguard Worker     uint8_t *allocateCodeSection(uintptr_t Size, unsigned Alignment,
39*9880d681SAndroid Build Coastguard Worker                                  unsigned SectionID,
40*9880d681SAndroid Build Coastguard Worker                                  StringRef SectionName) override {
41*9880d681SAndroid Build Coastguard Worker       uint8_t *Addr =
42*9880d681SAndroid Build Coastguard Worker           ClientMM->allocateCodeSection(Size, Alignment, SectionID,
43*9880d681SAndroid Build Coastguard Worker                                         SectionName);
44*9880d681SAndroid Build Coastguard Worker       M.SectionsAllocatedSinceLastLoad.insert(Addr);
45*9880d681SAndroid Build Coastguard Worker       return Addr;
46*9880d681SAndroid Build Coastguard Worker     }
47*9880d681SAndroid Build Coastguard Worker 
allocateDataSection(uintptr_t Size,unsigned Alignment,unsigned SectionID,StringRef SectionName,bool IsReadOnly)48*9880d681SAndroid Build Coastguard Worker     uint8_t *allocateDataSection(uintptr_t Size, unsigned Alignment,
49*9880d681SAndroid Build Coastguard Worker                                  unsigned SectionID, StringRef SectionName,
50*9880d681SAndroid Build Coastguard Worker                                  bool IsReadOnly) override {
51*9880d681SAndroid Build Coastguard Worker       uint8_t *Addr = ClientMM->allocateDataSection(Size, Alignment, SectionID,
52*9880d681SAndroid Build Coastguard Worker                                                     SectionName, IsReadOnly);
53*9880d681SAndroid Build Coastguard Worker       M.SectionsAllocatedSinceLastLoad.insert(Addr);
54*9880d681SAndroid Build Coastguard Worker       return Addr;
55*9880d681SAndroid Build Coastguard Worker     }
56*9880d681SAndroid Build Coastguard Worker 
reserveAllocationSpace(uintptr_t CodeSize,uint32_t CodeAlign,uintptr_t RODataSize,uint32_t RODataAlign,uintptr_t RWDataSize,uint32_t RWDataAlign)57*9880d681SAndroid Build Coastguard Worker     void reserveAllocationSpace(uintptr_t CodeSize, uint32_t CodeAlign,
58*9880d681SAndroid Build Coastguard Worker                                 uintptr_t RODataSize, uint32_t RODataAlign,
59*9880d681SAndroid Build Coastguard Worker                                 uintptr_t RWDataSize,
60*9880d681SAndroid Build Coastguard Worker                                 uint32_t RWDataAlign) override {
61*9880d681SAndroid Build Coastguard Worker       return ClientMM->reserveAllocationSpace(CodeSize, CodeAlign,
62*9880d681SAndroid Build Coastguard Worker                                               RODataSize, RODataAlign,
63*9880d681SAndroid Build Coastguard Worker                                               RWDataSize, RWDataAlign);
64*9880d681SAndroid Build Coastguard Worker     }
65*9880d681SAndroid Build Coastguard Worker 
needsToReserveAllocationSpace()66*9880d681SAndroid Build Coastguard Worker     bool needsToReserveAllocationSpace() override {
67*9880d681SAndroid Build Coastguard Worker       return ClientMM->needsToReserveAllocationSpace();
68*9880d681SAndroid Build Coastguard Worker     }
69*9880d681SAndroid Build Coastguard Worker 
registerEHFrames(uint8_t * Addr,uint64_t LoadAddr,size_t Size)70*9880d681SAndroid Build Coastguard Worker     void registerEHFrames(uint8_t *Addr, uint64_t LoadAddr,
71*9880d681SAndroid Build Coastguard Worker                           size_t Size) override {
72*9880d681SAndroid Build Coastguard Worker       return ClientMM->registerEHFrames(Addr, LoadAddr, Size);
73*9880d681SAndroid Build Coastguard Worker     }
74*9880d681SAndroid Build Coastguard Worker 
deregisterEHFrames(uint8_t * Addr,uint64_t LoadAddr,size_t Size)75*9880d681SAndroid Build Coastguard Worker     void deregisterEHFrames(uint8_t *Addr, uint64_t LoadAddr,
76*9880d681SAndroid Build Coastguard Worker                             size_t Size) override {
77*9880d681SAndroid Build Coastguard Worker       return ClientMM->deregisterEHFrames(Addr, LoadAddr, Size);
78*9880d681SAndroid Build Coastguard Worker     }
79*9880d681SAndroid Build Coastguard Worker 
notifyObjectLoaded(RuntimeDyld & RTDyld,const object::ObjectFile & O)80*9880d681SAndroid Build Coastguard Worker     void notifyObjectLoaded(RuntimeDyld &RTDyld,
81*9880d681SAndroid Build Coastguard Worker                             const object::ObjectFile &O) override {
82*9880d681SAndroid Build Coastguard Worker       return ClientMM->notifyObjectLoaded(RTDyld, O);
83*9880d681SAndroid Build Coastguard Worker     }
84*9880d681SAndroid Build Coastguard Worker 
notifyObjectLoaded(ExecutionEngine * EE,const object::ObjectFile & O)85*9880d681SAndroid Build Coastguard Worker     void notifyObjectLoaded(ExecutionEngine *EE,
86*9880d681SAndroid Build Coastguard Worker                             const object::ObjectFile &O) override {
87*9880d681SAndroid Build Coastguard Worker       return ClientMM->notifyObjectLoaded(EE, O);
88*9880d681SAndroid Build Coastguard Worker     }
89*9880d681SAndroid Build Coastguard Worker 
90*9880d681SAndroid Build Coastguard Worker     bool finalizeMemory(std::string *ErrMsg = nullptr) override {
91*9880d681SAndroid Build Coastguard Worker       // Each set of objects loaded will be finalized exactly once, but since
92*9880d681SAndroid Build Coastguard Worker       // symbol lookup during relocation may recursively trigger the
93*9880d681SAndroid Build Coastguard Worker       // loading/relocation of other modules, and since we're forwarding all
94*9880d681SAndroid Build Coastguard Worker       // finalizeMemory calls to a single underlying memory manager, we need to
95*9880d681SAndroid Build Coastguard Worker       // defer forwarding the call on until all necessary objects have been
96*9880d681SAndroid Build Coastguard Worker       // loaded. Otherwise, during the relocation of a leaf object, we will end
97*9880d681SAndroid Build Coastguard Worker       // up finalizing memory, causing a crash further up the stack when we
98*9880d681SAndroid Build Coastguard Worker       // attempt to apply relocations to finalized memory.
99*9880d681SAndroid Build Coastguard Worker       // To avoid finalizing too early, look at how many objects have been
100*9880d681SAndroid Build Coastguard Worker       // loaded but not yet finalized. This is a bit of a hack that relies on
101*9880d681SAndroid Build Coastguard Worker       // the fact that we're lazily emitting object files: The only way you can
102*9880d681SAndroid Build Coastguard Worker       // get more than one set of objects loaded but not yet finalized is if
103*9880d681SAndroid Build Coastguard Worker       // they were loaded during relocation of another set.
104*9880d681SAndroid Build Coastguard Worker       if (M.UnfinalizedSections.size() == 1)
105*9880d681SAndroid Build Coastguard Worker         return ClientMM->finalizeMemory(ErrMsg);
106*9880d681SAndroid Build Coastguard Worker       return false;
107*9880d681SAndroid Build Coastguard Worker     }
108*9880d681SAndroid Build Coastguard Worker 
109*9880d681SAndroid Build Coastguard Worker   private:
110*9880d681SAndroid Build Coastguard Worker     OrcMCJITReplacement &M;
111*9880d681SAndroid Build Coastguard Worker     std::shared_ptr<MCJITMemoryManager> ClientMM;
112*9880d681SAndroid Build Coastguard Worker   };
113*9880d681SAndroid Build Coastguard Worker 
114*9880d681SAndroid Build Coastguard Worker   class LinkingResolver : public RuntimeDyld::SymbolResolver {
115*9880d681SAndroid Build Coastguard Worker   public:
LinkingResolver(OrcMCJITReplacement & M)116*9880d681SAndroid Build Coastguard Worker     LinkingResolver(OrcMCJITReplacement &M) : M(M) {}
117*9880d681SAndroid Build Coastguard Worker 
findSymbol(const std::string & Name)118*9880d681SAndroid Build Coastguard Worker     RuntimeDyld::SymbolInfo findSymbol(const std::string &Name) override {
119*9880d681SAndroid Build Coastguard Worker       return M.findMangledSymbol(Name);
120*9880d681SAndroid Build Coastguard Worker     }
121*9880d681SAndroid Build Coastguard Worker 
122*9880d681SAndroid Build Coastguard Worker     RuntimeDyld::SymbolInfo
findSymbolInLogicalDylib(const std::string & Name)123*9880d681SAndroid Build Coastguard Worker     findSymbolInLogicalDylib(const std::string &Name) override {
124*9880d681SAndroid Build Coastguard Worker       return M.ClientResolver->findSymbol(Name);
125*9880d681SAndroid Build Coastguard Worker     }
126*9880d681SAndroid Build Coastguard Worker 
127*9880d681SAndroid Build Coastguard Worker   private:
128*9880d681SAndroid Build Coastguard Worker     OrcMCJITReplacement &M;
129*9880d681SAndroid Build Coastguard Worker   };
130*9880d681SAndroid Build Coastguard Worker 
131*9880d681SAndroid Build Coastguard Worker private:
132*9880d681SAndroid Build Coastguard Worker 
133*9880d681SAndroid Build Coastguard Worker   static ExecutionEngine *
createOrcMCJITReplacement(std::string * ErrorMsg,std::shared_ptr<MCJITMemoryManager> MemMgr,std::shared_ptr<RuntimeDyld::SymbolResolver> Resolver,std::unique_ptr<TargetMachine> TM)134*9880d681SAndroid Build Coastguard Worker   createOrcMCJITReplacement(std::string *ErrorMsg,
135*9880d681SAndroid Build Coastguard Worker                             std::shared_ptr<MCJITMemoryManager> MemMgr,
136*9880d681SAndroid Build Coastguard Worker                             std::shared_ptr<RuntimeDyld::SymbolResolver> Resolver,
137*9880d681SAndroid Build Coastguard Worker                             std::unique_ptr<TargetMachine> TM) {
138*9880d681SAndroid Build Coastguard Worker     return new OrcMCJITReplacement(std::move(MemMgr), std::move(Resolver),
139*9880d681SAndroid Build Coastguard Worker                                    std::move(TM));
140*9880d681SAndroid Build Coastguard Worker   }
141*9880d681SAndroid Build Coastguard Worker 
142*9880d681SAndroid Build Coastguard Worker public:
Register()143*9880d681SAndroid Build Coastguard Worker   static void Register() {
144*9880d681SAndroid Build Coastguard Worker     OrcMCJITReplacementCtor = createOrcMCJITReplacement;
145*9880d681SAndroid Build Coastguard Worker   }
146*9880d681SAndroid Build Coastguard Worker 
OrcMCJITReplacement(std::shared_ptr<MCJITMemoryManager> MemMgr,std::shared_ptr<RuntimeDyld::SymbolResolver> ClientResolver,std::unique_ptr<TargetMachine> TM)147*9880d681SAndroid Build Coastguard Worker   OrcMCJITReplacement(
148*9880d681SAndroid Build Coastguard Worker       std::shared_ptr<MCJITMemoryManager> MemMgr,
149*9880d681SAndroid Build Coastguard Worker       std::shared_ptr<RuntimeDyld::SymbolResolver> ClientResolver,
150*9880d681SAndroid Build Coastguard Worker       std::unique_ptr<TargetMachine> TM)
151*9880d681SAndroid Build Coastguard Worker       : ExecutionEngine(TM->createDataLayout()), TM(std::move(TM)),
152*9880d681SAndroid Build Coastguard Worker         MemMgr(*this, std::move(MemMgr)), Resolver(*this),
153*9880d681SAndroid Build Coastguard Worker         ClientResolver(std::move(ClientResolver)), NotifyObjectLoaded(*this),
154*9880d681SAndroid Build Coastguard Worker         NotifyFinalized(*this),
155*9880d681SAndroid Build Coastguard Worker         ObjectLayer(NotifyObjectLoaded, NotifyFinalized),
156*9880d681SAndroid Build Coastguard Worker         CompileLayer(ObjectLayer, SimpleCompiler(*this->TM)),
157*9880d681SAndroid Build Coastguard Worker         LazyEmitLayer(CompileLayer) {}
158*9880d681SAndroid Build Coastguard Worker 
addModule(std::unique_ptr<Module> M)159*9880d681SAndroid Build Coastguard Worker   void addModule(std::unique_ptr<Module> M) override {
160*9880d681SAndroid Build Coastguard Worker 
161*9880d681SAndroid Build Coastguard Worker     // If this module doesn't have a DataLayout attached then attach the
162*9880d681SAndroid Build Coastguard Worker     // default.
163*9880d681SAndroid Build Coastguard Worker     if (M->getDataLayout().isDefault()) {
164*9880d681SAndroid Build Coastguard Worker       M->setDataLayout(getDataLayout());
165*9880d681SAndroid Build Coastguard Worker     } else {
166*9880d681SAndroid Build Coastguard Worker       assert(M->getDataLayout() == getDataLayout() && "DataLayout Mismatch");
167*9880d681SAndroid Build Coastguard Worker     }
168*9880d681SAndroid Build Coastguard Worker     Modules.push_back(std::move(M));
169*9880d681SAndroid Build Coastguard Worker     std::vector<Module *> Ms;
170*9880d681SAndroid Build Coastguard Worker     Ms.push_back(&*Modules.back());
171*9880d681SAndroid Build Coastguard Worker     LazyEmitLayer.addModuleSet(std::move(Ms), &MemMgr, &Resolver);
172*9880d681SAndroid Build Coastguard Worker   }
173*9880d681SAndroid Build Coastguard Worker 
addObjectFile(std::unique_ptr<object::ObjectFile> O)174*9880d681SAndroid Build Coastguard Worker   void addObjectFile(std::unique_ptr<object::ObjectFile> O) override {
175*9880d681SAndroid Build Coastguard Worker     std::vector<std::unique_ptr<object::ObjectFile>> Objs;
176*9880d681SAndroid Build Coastguard Worker     Objs.push_back(std::move(O));
177*9880d681SAndroid Build Coastguard Worker     ObjectLayer.addObjectSet(std::move(Objs), &MemMgr, &Resolver);
178*9880d681SAndroid Build Coastguard Worker   }
179*9880d681SAndroid Build Coastguard Worker 
addObjectFile(object::OwningBinary<object::ObjectFile> O)180*9880d681SAndroid Build Coastguard Worker   void addObjectFile(object::OwningBinary<object::ObjectFile> O) override {
181*9880d681SAndroid Build Coastguard Worker     std::vector<std::unique_ptr<object::OwningBinary<object::ObjectFile>>> Objs;
182*9880d681SAndroid Build Coastguard Worker     Objs.push_back(
183*9880d681SAndroid Build Coastguard Worker       llvm::make_unique<object::OwningBinary<object::ObjectFile>>(
184*9880d681SAndroid Build Coastguard Worker         std::move(O)));
185*9880d681SAndroid Build Coastguard Worker     ObjectLayer.addObjectSet(std::move(Objs), &MemMgr, &Resolver);
186*9880d681SAndroid Build Coastguard Worker   }
187*9880d681SAndroid Build Coastguard Worker 
addArchive(object::OwningBinary<object::Archive> A)188*9880d681SAndroid Build Coastguard Worker   void addArchive(object::OwningBinary<object::Archive> A) override {
189*9880d681SAndroid Build Coastguard Worker     Archives.push_back(std::move(A));
190*9880d681SAndroid Build Coastguard Worker   }
191*9880d681SAndroid Build Coastguard Worker 
getSymbolAddress(StringRef Name)192*9880d681SAndroid Build Coastguard Worker   uint64_t getSymbolAddress(StringRef Name) {
193*9880d681SAndroid Build Coastguard Worker     return findSymbol(Name).getAddress();
194*9880d681SAndroid Build Coastguard Worker   }
195*9880d681SAndroid Build Coastguard Worker 
findSymbol(StringRef Name)196*9880d681SAndroid Build Coastguard Worker   RuntimeDyld::SymbolInfo findSymbol(StringRef Name) {
197*9880d681SAndroid Build Coastguard Worker     return findMangledSymbol(Mangle(Name));
198*9880d681SAndroid Build Coastguard Worker   }
199*9880d681SAndroid Build Coastguard Worker 
finalizeObject()200*9880d681SAndroid Build Coastguard Worker   void finalizeObject() override {
201*9880d681SAndroid Build Coastguard Worker     // This is deprecated - Aim to remove in ExecutionEngine.
202*9880d681SAndroid Build Coastguard Worker     // REMOVE IF POSSIBLE - Doesn't make sense for New JIT.
203*9880d681SAndroid Build Coastguard Worker   }
204*9880d681SAndroid Build Coastguard Worker 
mapSectionAddress(const void * LocalAddress,uint64_t TargetAddress)205*9880d681SAndroid Build Coastguard Worker   void mapSectionAddress(const void *LocalAddress,
206*9880d681SAndroid Build Coastguard Worker                          uint64_t TargetAddress) override {
207*9880d681SAndroid Build Coastguard Worker     for (auto &P : UnfinalizedSections)
208*9880d681SAndroid Build Coastguard Worker       if (P.second.count(LocalAddress))
209*9880d681SAndroid Build Coastguard Worker         ObjectLayer.mapSectionAddress(P.first, LocalAddress, TargetAddress);
210*9880d681SAndroid Build Coastguard Worker   }
211*9880d681SAndroid Build Coastguard Worker 
getGlobalValueAddress(const std::string & Name)212*9880d681SAndroid Build Coastguard Worker   uint64_t getGlobalValueAddress(const std::string &Name) override {
213*9880d681SAndroid Build Coastguard Worker     return getSymbolAddress(Name);
214*9880d681SAndroid Build Coastguard Worker   }
215*9880d681SAndroid Build Coastguard Worker 
getFunctionAddress(const std::string & Name)216*9880d681SAndroid Build Coastguard Worker   uint64_t getFunctionAddress(const std::string &Name) override {
217*9880d681SAndroid Build Coastguard Worker     return getSymbolAddress(Name);
218*9880d681SAndroid Build Coastguard Worker   }
219*9880d681SAndroid Build Coastguard Worker 
getPointerToFunction(Function * F)220*9880d681SAndroid Build Coastguard Worker   void *getPointerToFunction(Function *F) override {
221*9880d681SAndroid Build Coastguard Worker     uint64_t FAddr = getSymbolAddress(F->getName());
222*9880d681SAndroid Build Coastguard Worker     return reinterpret_cast<void *>(static_cast<uintptr_t>(FAddr));
223*9880d681SAndroid Build Coastguard Worker   }
224*9880d681SAndroid Build Coastguard Worker 
225*9880d681SAndroid Build Coastguard Worker   void *getPointerToNamedFunction(StringRef Name,
226*9880d681SAndroid Build Coastguard Worker                                   bool AbortOnFailure = true) override {
227*9880d681SAndroid Build Coastguard Worker     uint64_t Addr = getSymbolAddress(Name);
228*9880d681SAndroid Build Coastguard Worker     if (!Addr && AbortOnFailure)
229*9880d681SAndroid Build Coastguard Worker       llvm_unreachable("Missing symbol!");
230*9880d681SAndroid Build Coastguard Worker     return reinterpret_cast<void *>(static_cast<uintptr_t>(Addr));
231*9880d681SAndroid Build Coastguard Worker   }
232*9880d681SAndroid Build Coastguard Worker 
233*9880d681SAndroid Build Coastguard Worker   GenericValue runFunction(Function *F,
234*9880d681SAndroid Build Coastguard Worker                            ArrayRef<GenericValue> ArgValues) override;
235*9880d681SAndroid Build Coastguard Worker 
setObjectCache(ObjectCache * NewCache)236*9880d681SAndroid Build Coastguard Worker   void setObjectCache(ObjectCache *NewCache) override {
237*9880d681SAndroid Build Coastguard Worker     CompileLayer.setObjectCache(NewCache);
238*9880d681SAndroid Build Coastguard Worker   }
239*9880d681SAndroid Build Coastguard Worker 
setProcessAllSections(bool ProcessAllSections)240*9880d681SAndroid Build Coastguard Worker   void setProcessAllSections(bool ProcessAllSections) override {
241*9880d681SAndroid Build Coastguard Worker     ObjectLayer.setProcessAllSections(ProcessAllSections);
242*9880d681SAndroid Build Coastguard Worker   }
243*9880d681SAndroid Build Coastguard Worker 
244*9880d681SAndroid Build Coastguard Worker private:
245*9880d681SAndroid Build Coastguard Worker 
findMangledSymbol(StringRef Name)246*9880d681SAndroid Build Coastguard Worker   RuntimeDyld::SymbolInfo findMangledSymbol(StringRef Name) {
247*9880d681SAndroid Build Coastguard Worker     if (auto Sym = LazyEmitLayer.findSymbol(Name, false))
248*9880d681SAndroid Build Coastguard Worker       return Sym.toRuntimeDyldSymbol();
249*9880d681SAndroid Build Coastguard Worker     if (auto Sym = ClientResolver->findSymbol(Name))
250*9880d681SAndroid Build Coastguard Worker       return Sym;
251*9880d681SAndroid Build Coastguard Worker     if (auto Sym = scanArchives(Name))
252*9880d681SAndroid Build Coastguard Worker       return Sym.toRuntimeDyldSymbol();
253*9880d681SAndroid Build Coastguard Worker 
254*9880d681SAndroid Build Coastguard Worker     return nullptr;
255*9880d681SAndroid Build Coastguard Worker   }
256*9880d681SAndroid Build Coastguard Worker 
scanArchives(StringRef Name)257*9880d681SAndroid Build Coastguard Worker   JITSymbol scanArchives(StringRef Name) {
258*9880d681SAndroid Build Coastguard Worker     for (object::OwningBinary<object::Archive> &OB : Archives) {
259*9880d681SAndroid Build Coastguard Worker       object::Archive *A = OB.getBinary();
260*9880d681SAndroid Build Coastguard Worker       // Look for our symbols in each Archive
261*9880d681SAndroid Build Coastguard Worker       auto OptionalChildOrErr = A->findSym(Name);
262*9880d681SAndroid Build Coastguard Worker       if (!OptionalChildOrErr)
263*9880d681SAndroid Build Coastguard Worker         report_fatal_error(OptionalChildOrErr.takeError());
264*9880d681SAndroid Build Coastguard Worker       auto &OptionalChild = *OptionalChildOrErr;
265*9880d681SAndroid Build Coastguard Worker       if (OptionalChild) {
266*9880d681SAndroid Build Coastguard Worker         // FIXME: Support nested archives?
267*9880d681SAndroid Build Coastguard Worker         Expected<std::unique_ptr<object::Binary>> ChildBinOrErr =
268*9880d681SAndroid Build Coastguard Worker             OptionalChild->getAsBinary();
269*9880d681SAndroid Build Coastguard Worker         if (!ChildBinOrErr) {
270*9880d681SAndroid Build Coastguard Worker           // TODO: Actually report errors helpfully.
271*9880d681SAndroid Build Coastguard Worker           consumeError(ChildBinOrErr.takeError());
272*9880d681SAndroid Build Coastguard Worker           continue;
273*9880d681SAndroid Build Coastguard Worker         }
274*9880d681SAndroid Build Coastguard Worker         std::unique_ptr<object::Binary> &ChildBin = ChildBinOrErr.get();
275*9880d681SAndroid Build Coastguard Worker         if (ChildBin->isObject()) {
276*9880d681SAndroid Build Coastguard Worker           std::vector<std::unique_ptr<object::ObjectFile>> ObjSet;
277*9880d681SAndroid Build Coastguard Worker           ObjSet.push_back(std::unique_ptr<object::ObjectFile>(
278*9880d681SAndroid Build Coastguard Worker               static_cast<object::ObjectFile *>(ChildBin.release())));
279*9880d681SAndroid Build Coastguard Worker           ObjectLayer.addObjectSet(std::move(ObjSet), &MemMgr, &Resolver);
280*9880d681SAndroid Build Coastguard Worker           if (auto Sym = ObjectLayer.findSymbol(Name, true))
281*9880d681SAndroid Build Coastguard Worker             return Sym;
282*9880d681SAndroid Build Coastguard Worker         }
283*9880d681SAndroid Build Coastguard Worker       }
284*9880d681SAndroid Build Coastguard Worker     }
285*9880d681SAndroid Build Coastguard Worker     return nullptr;
286*9880d681SAndroid Build Coastguard Worker   }
287*9880d681SAndroid Build Coastguard Worker 
288*9880d681SAndroid Build Coastguard Worker   class NotifyObjectLoadedT {
289*9880d681SAndroid Build Coastguard Worker   public:
290*9880d681SAndroid Build Coastguard Worker     typedef std::vector<std::unique_ptr<RuntimeDyld::LoadedObjectInfo>>
291*9880d681SAndroid Build Coastguard Worker         LoadedObjInfoListT;
292*9880d681SAndroid Build Coastguard Worker 
NotifyObjectLoadedT(OrcMCJITReplacement & M)293*9880d681SAndroid Build Coastguard Worker     NotifyObjectLoadedT(OrcMCJITReplacement &M) : M(M) {}
294*9880d681SAndroid Build Coastguard Worker 
295*9880d681SAndroid Build Coastguard Worker     template <typename ObjListT>
operator()296*9880d681SAndroid Build Coastguard Worker     void operator()(ObjectLinkingLayerBase::ObjSetHandleT H,
297*9880d681SAndroid Build Coastguard Worker                     const ObjListT &Objects,
298*9880d681SAndroid Build Coastguard Worker                     const LoadedObjInfoListT &Infos) const {
299*9880d681SAndroid Build Coastguard Worker       M.UnfinalizedSections[H] = std::move(M.SectionsAllocatedSinceLastLoad);
300*9880d681SAndroid Build Coastguard Worker       M.SectionsAllocatedSinceLastLoad = SectionAddrSet();
301*9880d681SAndroid Build Coastguard Worker       assert(Objects.size() == Infos.size() &&
302*9880d681SAndroid Build Coastguard Worker              "Incorrect number of Infos for Objects.");
303*9880d681SAndroid Build Coastguard Worker       for (unsigned I = 0; I < Objects.size(); ++I)
304*9880d681SAndroid Build Coastguard Worker         M.MemMgr.notifyObjectLoaded(&M, getObject(*Objects[I]));
305*9880d681SAndroid Build Coastguard Worker     }
306*9880d681SAndroid Build Coastguard Worker 
307*9880d681SAndroid Build Coastguard Worker   private:
308*9880d681SAndroid Build Coastguard Worker 
getObject(const object::ObjectFile & Obj)309*9880d681SAndroid Build Coastguard Worker     static const object::ObjectFile& getObject(const object::ObjectFile &Obj) {
310*9880d681SAndroid Build Coastguard Worker       return Obj;
311*9880d681SAndroid Build Coastguard Worker     }
312*9880d681SAndroid Build Coastguard Worker 
313*9880d681SAndroid Build Coastguard Worker     template <typename ObjT>
314*9880d681SAndroid Build Coastguard Worker     static const object::ObjectFile&
getObject(const object::OwningBinary<ObjT> & Obj)315*9880d681SAndroid Build Coastguard Worker     getObject(const object::OwningBinary<ObjT> &Obj) {
316*9880d681SAndroid Build Coastguard Worker       return *Obj.getBinary();
317*9880d681SAndroid Build Coastguard Worker     }
318*9880d681SAndroid Build Coastguard Worker 
319*9880d681SAndroid Build Coastguard Worker     OrcMCJITReplacement &M;
320*9880d681SAndroid Build Coastguard Worker   };
321*9880d681SAndroid Build Coastguard Worker 
322*9880d681SAndroid Build Coastguard Worker   class NotifyFinalizedT {
323*9880d681SAndroid Build Coastguard Worker   public:
NotifyFinalizedT(OrcMCJITReplacement & M)324*9880d681SAndroid Build Coastguard Worker     NotifyFinalizedT(OrcMCJITReplacement &M) : M(M) {}
operator()325*9880d681SAndroid Build Coastguard Worker     void operator()(ObjectLinkingLayerBase::ObjSetHandleT H) {
326*9880d681SAndroid Build Coastguard Worker       M.UnfinalizedSections.erase(H);
327*9880d681SAndroid Build Coastguard Worker     }
328*9880d681SAndroid Build Coastguard Worker 
329*9880d681SAndroid Build Coastguard Worker   private:
330*9880d681SAndroid Build Coastguard Worker     OrcMCJITReplacement &M;
331*9880d681SAndroid Build Coastguard Worker   };
332*9880d681SAndroid Build Coastguard Worker 
Mangle(StringRef Name)333*9880d681SAndroid Build Coastguard Worker   std::string Mangle(StringRef Name) {
334*9880d681SAndroid Build Coastguard Worker     std::string MangledName;
335*9880d681SAndroid Build Coastguard Worker     {
336*9880d681SAndroid Build Coastguard Worker       raw_string_ostream MangledNameStream(MangledName);
337*9880d681SAndroid Build Coastguard Worker       Mang.getNameWithPrefix(MangledNameStream, Name, getDataLayout());
338*9880d681SAndroid Build Coastguard Worker     }
339*9880d681SAndroid Build Coastguard Worker     return MangledName;
340*9880d681SAndroid Build Coastguard Worker   }
341*9880d681SAndroid Build Coastguard Worker 
342*9880d681SAndroid Build Coastguard Worker   typedef ObjectLinkingLayer<NotifyObjectLoadedT> ObjectLayerT;
343*9880d681SAndroid Build Coastguard Worker   typedef IRCompileLayer<ObjectLayerT> CompileLayerT;
344*9880d681SAndroid Build Coastguard Worker   typedef LazyEmittingLayer<CompileLayerT> LazyEmitLayerT;
345*9880d681SAndroid Build Coastguard Worker 
346*9880d681SAndroid Build Coastguard Worker   std::unique_ptr<TargetMachine> TM;
347*9880d681SAndroid Build Coastguard Worker   MCJITReplacementMemMgr MemMgr;
348*9880d681SAndroid Build Coastguard Worker   LinkingResolver Resolver;
349*9880d681SAndroid Build Coastguard Worker   std::shared_ptr<RuntimeDyld::SymbolResolver> ClientResolver;
350*9880d681SAndroid Build Coastguard Worker   Mangler Mang;
351*9880d681SAndroid Build Coastguard Worker 
352*9880d681SAndroid Build Coastguard Worker   NotifyObjectLoadedT NotifyObjectLoaded;
353*9880d681SAndroid Build Coastguard Worker   NotifyFinalizedT NotifyFinalized;
354*9880d681SAndroid Build Coastguard Worker 
355*9880d681SAndroid Build Coastguard Worker   ObjectLayerT ObjectLayer;
356*9880d681SAndroid Build Coastguard Worker   CompileLayerT CompileLayer;
357*9880d681SAndroid Build Coastguard Worker   LazyEmitLayerT LazyEmitLayer;
358*9880d681SAndroid Build Coastguard Worker 
359*9880d681SAndroid Build Coastguard Worker   // We need to store ObjLayerT::ObjSetHandles for each of the object sets
360*9880d681SAndroid Build Coastguard Worker   // that have been emitted but not yet finalized so that we can forward the
361*9880d681SAndroid Build Coastguard Worker   // mapSectionAddress calls appropriately.
362*9880d681SAndroid Build Coastguard Worker   typedef std::set<const void *> SectionAddrSet;
363*9880d681SAndroid Build Coastguard Worker   struct ObjSetHandleCompare {
operatorObjSetHandleCompare364*9880d681SAndroid Build Coastguard Worker     bool operator()(ObjectLayerT::ObjSetHandleT H1,
365*9880d681SAndroid Build Coastguard Worker                     ObjectLayerT::ObjSetHandleT H2) const {
366*9880d681SAndroid Build Coastguard Worker       return &*H1 < &*H2;
367*9880d681SAndroid Build Coastguard Worker     }
368*9880d681SAndroid Build Coastguard Worker   };
369*9880d681SAndroid Build Coastguard Worker   SectionAddrSet SectionsAllocatedSinceLastLoad;
370*9880d681SAndroid Build Coastguard Worker   std::map<ObjectLayerT::ObjSetHandleT, SectionAddrSet, ObjSetHandleCompare>
371*9880d681SAndroid Build Coastguard Worker       UnfinalizedSections;
372*9880d681SAndroid Build Coastguard Worker 
373*9880d681SAndroid Build Coastguard Worker   std::vector<object::OwningBinary<object::Archive>> Archives;
374*9880d681SAndroid Build Coastguard Worker };
375*9880d681SAndroid Build Coastguard Worker 
376*9880d681SAndroid Build Coastguard Worker } // End namespace orc.
377*9880d681SAndroid Build Coastguard Worker } // End namespace llvm.
378*9880d681SAndroid Build Coastguard Worker 
379*9880d681SAndroid Build Coastguard Worker #endif // LLVM_LIB_EXECUTIONENGINE_ORC_MCJITREPLACEMENT_H
380