1*9880d681SAndroid Build Coastguard Worker //===-- RemoteJITUtils.h - Utilities for remote-JITing with LLI -*- 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 // Utilities for remote-JITing with LLI. 11*9880d681SAndroid Build Coastguard Worker // 12*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===// 13*9880d681SAndroid Build Coastguard Worker 14*9880d681SAndroid Build Coastguard Worker #ifndef LLVM_TOOLS_LLI_REMOTEJITUTILS_H 15*9880d681SAndroid Build Coastguard Worker #define LLVM_TOOLS_LLI_REMOTEJITUTILS_H 16*9880d681SAndroid Build Coastguard Worker 17*9880d681SAndroid Build Coastguard Worker #include "llvm/ExecutionEngine/Orc/RPCChannel.h" 18*9880d681SAndroid Build Coastguard Worker #include "llvm/ExecutionEngine/RTDyldMemoryManager.h" 19*9880d681SAndroid Build Coastguard Worker #include <mutex> 20*9880d681SAndroid Build Coastguard Worker 21*9880d681SAndroid Build Coastguard Worker #if !defined(_MSC_VER) && !defined(__MINGW32__) 22*9880d681SAndroid Build Coastguard Worker #include <unistd.h> 23*9880d681SAndroid Build Coastguard Worker #else 24*9880d681SAndroid Build Coastguard Worker #include <io.h> 25*9880d681SAndroid Build Coastguard Worker #endif 26*9880d681SAndroid Build Coastguard Worker 27*9880d681SAndroid Build Coastguard Worker /// RPC channel that reads from and writes from file descriptors. 28*9880d681SAndroid Build Coastguard Worker class FDRPCChannel final : public llvm::orc::remote::RPCChannel { 29*9880d681SAndroid Build Coastguard Worker public: FDRPCChannel(int InFD,int OutFD)30*9880d681SAndroid Build Coastguard Worker FDRPCChannel(int InFD, int OutFD) : InFD(InFD), OutFD(OutFD) {} 31*9880d681SAndroid Build Coastguard Worker readBytes(char * Dst,unsigned Size)32*9880d681SAndroid Build Coastguard Worker llvm::Error readBytes(char *Dst, unsigned Size) override { 33*9880d681SAndroid Build Coastguard Worker assert(Dst && "Attempt to read into null."); 34*9880d681SAndroid Build Coastguard Worker ssize_t Completed = 0; 35*9880d681SAndroid Build Coastguard Worker while (Completed < static_cast<ssize_t>(Size)) { 36*9880d681SAndroid Build Coastguard Worker ssize_t Read = ::read(InFD, Dst + Completed, Size - Completed); 37*9880d681SAndroid Build Coastguard Worker if (Read <= 0) { 38*9880d681SAndroid Build Coastguard Worker auto ErrNo = errno; 39*9880d681SAndroid Build Coastguard Worker if (ErrNo == EAGAIN || ErrNo == EINTR) 40*9880d681SAndroid Build Coastguard Worker continue; 41*9880d681SAndroid Build Coastguard Worker else 42*9880d681SAndroid Build Coastguard Worker return llvm::errorCodeToError( 43*9880d681SAndroid Build Coastguard Worker std::error_code(errno, std::generic_category())); 44*9880d681SAndroid Build Coastguard Worker } 45*9880d681SAndroid Build Coastguard Worker Completed += Read; 46*9880d681SAndroid Build Coastguard Worker } 47*9880d681SAndroid Build Coastguard Worker return llvm::Error::success(); 48*9880d681SAndroid Build Coastguard Worker } 49*9880d681SAndroid Build Coastguard Worker appendBytes(const char * Src,unsigned Size)50*9880d681SAndroid Build Coastguard Worker llvm::Error appendBytes(const char *Src, unsigned Size) override { 51*9880d681SAndroid Build Coastguard Worker assert(Src && "Attempt to append from null."); 52*9880d681SAndroid Build Coastguard Worker ssize_t Completed = 0; 53*9880d681SAndroid Build Coastguard Worker while (Completed < static_cast<ssize_t>(Size)) { 54*9880d681SAndroid Build Coastguard Worker ssize_t Written = ::write(OutFD, Src + Completed, Size - Completed); 55*9880d681SAndroid Build Coastguard Worker if (Written < 0) { 56*9880d681SAndroid Build Coastguard Worker auto ErrNo = errno; 57*9880d681SAndroid Build Coastguard Worker if (ErrNo == EAGAIN || ErrNo == EINTR) 58*9880d681SAndroid Build Coastguard Worker continue; 59*9880d681SAndroid Build Coastguard Worker else 60*9880d681SAndroid Build Coastguard Worker return llvm::errorCodeToError( 61*9880d681SAndroid Build Coastguard Worker std::error_code(errno, std::generic_category())); 62*9880d681SAndroid Build Coastguard Worker } 63*9880d681SAndroid Build Coastguard Worker Completed += Written; 64*9880d681SAndroid Build Coastguard Worker } 65*9880d681SAndroid Build Coastguard Worker return llvm::Error::success(); 66*9880d681SAndroid Build Coastguard Worker } 67*9880d681SAndroid Build Coastguard Worker send()68*9880d681SAndroid Build Coastguard Worker llvm::Error send() override { return llvm::Error::success(); } 69*9880d681SAndroid Build Coastguard Worker 70*9880d681SAndroid Build Coastguard Worker private: 71*9880d681SAndroid Build Coastguard Worker int InFD, OutFD; 72*9880d681SAndroid Build Coastguard Worker }; 73*9880d681SAndroid Build Coastguard Worker 74*9880d681SAndroid Build Coastguard Worker // launch the remote process (see lli.cpp) and return a channel to it. 75*9880d681SAndroid Build Coastguard Worker std::unique_ptr<FDRPCChannel> launchRemote(); 76*9880d681SAndroid Build Coastguard Worker 77*9880d681SAndroid Build Coastguard Worker namespace llvm { 78*9880d681SAndroid Build Coastguard Worker 79*9880d681SAndroid Build Coastguard Worker // ForwardingMM - Adapter to connect MCJIT to Orc's Remote memory manager. 80*9880d681SAndroid Build Coastguard Worker class ForwardingMemoryManager : public llvm::RTDyldMemoryManager { 81*9880d681SAndroid Build Coastguard Worker public: setMemMgr(std::unique_ptr<RuntimeDyld::MemoryManager> MemMgr)82*9880d681SAndroid Build Coastguard Worker void setMemMgr(std::unique_ptr<RuntimeDyld::MemoryManager> MemMgr) { 83*9880d681SAndroid Build Coastguard Worker this->MemMgr = std::move(MemMgr); 84*9880d681SAndroid Build Coastguard Worker } 85*9880d681SAndroid Build Coastguard Worker setResolver(std::unique_ptr<RuntimeDyld::SymbolResolver> Resolver)86*9880d681SAndroid Build Coastguard Worker void setResolver(std::unique_ptr<RuntimeDyld::SymbolResolver> Resolver) { 87*9880d681SAndroid Build Coastguard Worker this->Resolver = std::move(Resolver); 88*9880d681SAndroid Build Coastguard Worker } 89*9880d681SAndroid Build Coastguard Worker allocateCodeSection(uintptr_t Size,unsigned Alignment,unsigned SectionID,StringRef SectionName)90*9880d681SAndroid Build Coastguard Worker uint8_t *allocateCodeSection(uintptr_t Size, unsigned Alignment, 91*9880d681SAndroid Build Coastguard Worker unsigned SectionID, 92*9880d681SAndroid Build Coastguard Worker StringRef SectionName) override { 93*9880d681SAndroid Build Coastguard Worker return MemMgr->allocateCodeSection(Size, Alignment, SectionID, SectionName); 94*9880d681SAndroid Build Coastguard Worker } 95*9880d681SAndroid Build Coastguard Worker allocateDataSection(uintptr_t Size,unsigned Alignment,unsigned SectionID,StringRef SectionName,bool IsReadOnly)96*9880d681SAndroid Build Coastguard Worker uint8_t *allocateDataSection(uintptr_t Size, unsigned Alignment, 97*9880d681SAndroid Build Coastguard Worker unsigned SectionID, StringRef SectionName, 98*9880d681SAndroid Build Coastguard Worker bool IsReadOnly) override { 99*9880d681SAndroid Build Coastguard Worker return MemMgr->allocateDataSection(Size, Alignment, SectionID, SectionName, 100*9880d681SAndroid Build Coastguard Worker IsReadOnly); 101*9880d681SAndroid Build Coastguard Worker } 102*9880d681SAndroid Build Coastguard Worker reserveAllocationSpace(uintptr_t CodeSize,uint32_t CodeAlign,uintptr_t RODataSize,uint32_t RODataAlign,uintptr_t RWDataSize,uint32_t RWDataAlign)103*9880d681SAndroid Build Coastguard Worker void reserveAllocationSpace(uintptr_t CodeSize, uint32_t CodeAlign, 104*9880d681SAndroid Build Coastguard Worker uintptr_t RODataSize, uint32_t RODataAlign, 105*9880d681SAndroid Build Coastguard Worker uintptr_t RWDataSize, 106*9880d681SAndroid Build Coastguard Worker uint32_t RWDataAlign) override { 107*9880d681SAndroid Build Coastguard Worker MemMgr->reserveAllocationSpace(CodeSize, CodeAlign, RODataSize, RODataAlign, 108*9880d681SAndroid Build Coastguard Worker RWDataSize, RWDataAlign); 109*9880d681SAndroid Build Coastguard Worker } 110*9880d681SAndroid Build Coastguard Worker needsToReserveAllocationSpace()111*9880d681SAndroid Build Coastguard Worker bool needsToReserveAllocationSpace() override { 112*9880d681SAndroid Build Coastguard Worker return MemMgr->needsToReserveAllocationSpace(); 113*9880d681SAndroid Build Coastguard Worker } 114*9880d681SAndroid Build Coastguard Worker registerEHFrames(uint8_t * Addr,uint64_t LoadAddr,size_t Size)115*9880d681SAndroid Build Coastguard Worker void registerEHFrames(uint8_t *Addr, uint64_t LoadAddr, 116*9880d681SAndroid Build Coastguard Worker size_t Size) override { 117*9880d681SAndroid Build Coastguard Worker MemMgr->registerEHFrames(Addr, LoadAddr, Size); 118*9880d681SAndroid Build Coastguard Worker } 119*9880d681SAndroid Build Coastguard Worker deregisterEHFrames(uint8_t * Addr,uint64_t LoadAddr,size_t Size)120*9880d681SAndroid Build Coastguard Worker void deregisterEHFrames(uint8_t *Addr, uint64_t LoadAddr, 121*9880d681SAndroid Build Coastguard Worker size_t Size) override { 122*9880d681SAndroid Build Coastguard Worker MemMgr->deregisterEHFrames(Addr, LoadAddr, Size); 123*9880d681SAndroid Build Coastguard Worker } 124*9880d681SAndroid Build Coastguard Worker 125*9880d681SAndroid Build Coastguard Worker bool finalizeMemory(std::string *ErrMsg = nullptr) override { 126*9880d681SAndroid Build Coastguard Worker return MemMgr->finalizeMemory(ErrMsg); 127*9880d681SAndroid Build Coastguard Worker } 128*9880d681SAndroid Build Coastguard Worker notifyObjectLoaded(RuntimeDyld & RTDyld,const object::ObjectFile & Obj)129*9880d681SAndroid Build Coastguard Worker void notifyObjectLoaded(RuntimeDyld &RTDyld, 130*9880d681SAndroid Build Coastguard Worker const object::ObjectFile &Obj) override { 131*9880d681SAndroid Build Coastguard Worker MemMgr->notifyObjectLoaded(RTDyld, Obj); 132*9880d681SAndroid Build Coastguard Worker } 133*9880d681SAndroid Build Coastguard Worker 134*9880d681SAndroid Build Coastguard Worker // Don't hide the sibling notifyObjectLoaded from RTDyldMemoryManager. 135*9880d681SAndroid Build Coastguard Worker using RTDyldMemoryManager::notifyObjectLoaded; 136*9880d681SAndroid Build Coastguard Worker findSymbol(const std::string & Name)137*9880d681SAndroid Build Coastguard Worker RuntimeDyld::SymbolInfo findSymbol(const std::string &Name) override { 138*9880d681SAndroid Build Coastguard Worker return Resolver->findSymbol(Name); 139*9880d681SAndroid Build Coastguard Worker } 140*9880d681SAndroid Build Coastguard Worker 141*9880d681SAndroid Build Coastguard Worker RuntimeDyld::SymbolInfo findSymbolInLogicalDylib(const std::string & Name)142*9880d681SAndroid Build Coastguard Worker findSymbolInLogicalDylib(const std::string &Name) override { 143*9880d681SAndroid Build Coastguard Worker return Resolver->findSymbolInLogicalDylib(Name); 144*9880d681SAndroid Build Coastguard Worker } 145*9880d681SAndroid Build Coastguard Worker 146*9880d681SAndroid Build Coastguard Worker private: 147*9880d681SAndroid Build Coastguard Worker std::unique_ptr<RuntimeDyld::MemoryManager> MemMgr; 148*9880d681SAndroid Build Coastguard Worker std::unique_ptr<RuntimeDyld::SymbolResolver> Resolver; 149*9880d681SAndroid Build Coastguard Worker }; 150*9880d681SAndroid Build Coastguard Worker } 151*9880d681SAndroid Build Coastguard Worker 152*9880d681SAndroid Build Coastguard Worker #endif 153