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