diff options
Diffstat (limited to 'include/llvm/ExecutionEngine/Orc/OrcRemoteTargetServer.h')
-rw-r--r-- | include/llvm/ExecutionEngine/Orc/OrcRemoteTargetServer.h | 233 |
1 files changed, 126 insertions, 107 deletions
diff --git a/include/llvm/ExecutionEngine/Orc/OrcRemoteTargetServer.h b/include/llvm/ExecutionEngine/Orc/OrcRemoteTargetServer.h index 5247661e49cee..bf4299c69b24b 100644 --- a/include/llvm/ExecutionEngine/Orc/OrcRemoteTargetServer.h +++ b/include/llvm/ExecutionEngine/Orc/OrcRemoteTargetServer.h @@ -35,17 +35,31 @@ public: typedef std::function<TargetAddress(const std::string &Name)> SymbolLookupFtor; - OrcRemoteTargetServer(ChannelT &Channel, SymbolLookupFtor SymbolLookup) - : Channel(Channel), SymbolLookup(std::move(SymbolLookup)) {} + typedef std::function<void(uint8_t *Addr, uint32_t Size)> + EHFrameRegistrationFtor; - std::error_code getNextProcId(JITProcId &Id) { - return deserialize(Channel, Id); - } + OrcRemoteTargetServer(ChannelT &Channel, SymbolLookupFtor SymbolLookup, + EHFrameRegistrationFtor EHFramesRegister, + EHFrameRegistrationFtor EHFramesDeregister) + : Channel(Channel), SymbolLookup(std::move(SymbolLookup)), + EHFramesRegister(std::move(EHFramesRegister)), + EHFramesDeregister(std::move(EHFramesDeregister)) {} + + // FIXME: Remove move/copy ops once MSVC supports synthesizing move ops. + OrcRemoteTargetServer(const OrcRemoteTargetServer &) = delete; + OrcRemoteTargetServer &operator=(const OrcRemoteTargetServer &) = delete; + + OrcRemoteTargetServer(OrcRemoteTargetServer &&Other) + : Channel(Other.Channel), SymbolLookup(std::move(Other.SymbolLookup)), + EHFramesRegister(std::move(Other.EHFramesRegister)), + EHFramesDeregister(std::move(Other.EHFramesDeregister)) {} + + OrcRemoteTargetServer &operator=(OrcRemoteTargetServer &&) = delete; - std::error_code handleKnownProcedure(JITProcId Id) { + Error handleKnownFunction(JITFuncId Id) { typedef OrcRemoteTargetServer ThisT; - DEBUG(dbgs() << "Handling known proc: " << getJITProcIdName(Id) << "\n"); + DEBUG(dbgs() << "Handling known proc: " << getJITFuncIdName(Id) << "\n"); switch (Id) { case CallIntVoidId: @@ -60,6 +74,9 @@ public: case CreateIndirectStubsOwnerId: return handle<CreateIndirectStubsOwner>( Channel, *this, &ThisT::handleCreateIndirectStubsOwner); + case DeregisterEHFramesId: + return handle<DeregisterEHFrames>(Channel, *this, + &ThisT::handleDeregisterEHFrames); case DestroyRemoteAllocatorId: return handle<DestroyRemoteAllocator>( Channel, *this, &ThisT::handleDestroyRemoteAllocator); @@ -82,6 +99,9 @@ public: return handle<GetRemoteInfo>(Channel, *this, &ThisT::handleGetRemoteInfo); case ReadMemId: return handle<ReadMem>(Channel, *this, &ThisT::handleReadMem); + case RegisterEHFramesId: + return handle<RegisterEHFrames>(Channel, *this, + &ThisT::handleRegisterEHFrames); case ReserveMemId: return handle<ReserveMem>(Channel, *this, &ThisT::handleReserveMem); case SetProtectionsId: @@ -98,27 +118,16 @@ public: llvm_unreachable("Unhandled JIT RPC procedure Id."); } - std::error_code requestCompile(TargetAddress &CompiledFnAddr, - TargetAddress TrampolineAddr) { - if (auto EC = call<RequestCompile>(Channel, TrampolineAddr)) - return EC; - - while (1) { - JITProcId Id = InvalidId; - if (auto EC = getNextProcId(Id)) - return EC; - - switch (Id) { - case RequestCompileResponseId: - return handle<RequestCompileResponse>(Channel, - readArgs(CompiledFnAddr)); - default: - if (auto EC = handleKnownProcedure(Id)) - return EC; - } - } + Expected<TargetAddress> requestCompile(TargetAddress TrampolineAddr) { + auto Listen = [&](RPCChannel &C, uint32_t Id) { + return handleKnownFunction(static_cast<JITFuncId>(Id)); + }; + + return callSTHandling<RequestCompile>(Channel, Listen, TrampolineAddr); + } - llvm_unreachable("Fell through request-compile command loop."); + Error handleTerminateSession() { + return handle<TerminateSession>(Channel, []() { return Error::success(); }); } private: @@ -135,60 +144,56 @@ private: sys::Memory::releaseMappedMemory(Alloc.second); } - std::error_code allocate(void *&Addr, size_t Size, uint32_t Align) { + Error allocate(void *&Addr, size_t Size, uint32_t Align) { std::error_code EC; sys::MemoryBlock MB = sys::Memory::allocateMappedMemory( Size, nullptr, sys::Memory::MF_READ | sys::Memory::MF_WRITE, EC); if (EC) - return EC; + return errorCodeToError(EC); Addr = MB.base(); assert(Allocs.find(MB.base()) == Allocs.end() && "Duplicate alloc"); Allocs[MB.base()] = std::move(MB); - return std::error_code(); + return Error::success(); } - std::error_code setProtections(void *block, unsigned Flags) { + Error setProtections(void *block, unsigned Flags) { auto I = Allocs.find(block); if (I == Allocs.end()) return orcError(OrcErrorCode::RemoteMProtectAddrUnrecognized); - return sys::Memory::protectMappedMemory(I->second, Flags); + return errorCodeToError( + sys::Memory::protectMappedMemory(I->second, Flags)); } private: std::map<void *, sys::MemoryBlock> Allocs; }; - static std::error_code doNothing() { return std::error_code(); } + static Error doNothing() { return Error::success(); } static TargetAddress reenter(void *JITTargetAddr, void *TrampolineAddr) { - TargetAddress CompiledFnAddr = 0; - auto T = static_cast<OrcRemoteTargetServer *>(JITTargetAddr); - auto EC = T->requestCompile( - CompiledFnAddr, static_cast<TargetAddress>( - reinterpret_cast<uintptr_t>(TrampolineAddr))); - assert(!EC && "Compile request failed"); - (void)EC; - return CompiledFnAddr; + auto AddrOrErr = T->requestCompile(static_cast<TargetAddress>( + reinterpret_cast<uintptr_t>(TrampolineAddr))); + // FIXME: Allow customizable failure substitution functions. + assert(AddrOrErr && "Compile request failed"); + return *AddrOrErr; } - std::error_code handleCallIntVoid(TargetAddress Addr) { + Expected<int32_t> handleCallIntVoid(TargetAddress Addr) { typedef int (*IntVoidFnTy)(); IntVoidFnTy Fn = reinterpret_cast<IntVoidFnTy>(static_cast<uintptr_t>(Addr)); - DEBUG(dbgs() << " Calling " - << reinterpret_cast<void *>(reinterpret_cast<intptr_t>(Fn)) - << "\n"); + DEBUG(dbgs() << " Calling " << format("0x%016x", Addr) << "\n"); int Result = Fn(); DEBUG(dbgs() << " Result = " << Result << "\n"); - return call<CallIntVoidResponse>(Channel, Result); + return Result; } - std::error_code handleCallMain(TargetAddress Addr, - std::vector<std::string> Args) { + Expected<int32_t> handleCallMain(TargetAddress Addr, + std::vector<std::string> Args) { typedef int (*MainFnTy)(int, const char *[]); MainFnTy Fn = reinterpret_cast<MainFnTy>(static_cast<uintptr_t>(Addr)); @@ -199,63 +204,71 @@ private: for (auto &Arg : Args) ArgV[Idx++] = Arg.c_str(); - DEBUG(dbgs() << " Calling " << reinterpret_cast<void *>(Fn) << "\n"); + DEBUG(dbgs() << " Calling " << format("0x%016x", Addr) << "\n"); int Result = Fn(ArgC, ArgV.get()); DEBUG(dbgs() << " Result = " << Result << "\n"); - return call<CallMainResponse>(Channel, Result); + return Result; } - std::error_code handleCallVoidVoid(TargetAddress Addr) { + Error handleCallVoidVoid(TargetAddress Addr) { typedef void (*VoidVoidFnTy)(); VoidVoidFnTy Fn = reinterpret_cast<VoidVoidFnTy>(static_cast<uintptr_t>(Addr)); - DEBUG(dbgs() << " Calling " << reinterpret_cast<void *>(Fn) << "\n"); + DEBUG(dbgs() << " Calling " << format("0x%016x", Addr) << "\n"); Fn(); DEBUG(dbgs() << " Complete.\n"); - return call<CallVoidVoidResponse>(Channel); + return Error::success(); } - std::error_code handleCreateRemoteAllocator(ResourceIdMgr::ResourceId Id) { + Error handleCreateRemoteAllocator(ResourceIdMgr::ResourceId Id) { auto I = Allocators.find(Id); if (I != Allocators.end()) return orcError(OrcErrorCode::RemoteAllocatorIdAlreadyInUse); DEBUG(dbgs() << " Created allocator " << Id << "\n"); Allocators[Id] = Allocator(); - return std::error_code(); + return Error::success(); } - std::error_code handleCreateIndirectStubsOwner(ResourceIdMgr::ResourceId Id) { + Error handleCreateIndirectStubsOwner(ResourceIdMgr::ResourceId Id) { auto I = IndirectStubsOwners.find(Id); if (I != IndirectStubsOwners.end()) return orcError(OrcErrorCode::RemoteIndirectStubsOwnerIdAlreadyInUse); DEBUG(dbgs() << " Create indirect stubs owner " << Id << "\n"); IndirectStubsOwners[Id] = ISBlockOwnerList(); - return std::error_code(); + return Error::success(); + } + + Error handleDeregisterEHFrames(TargetAddress TAddr, uint32_t Size) { + uint8_t *Addr = reinterpret_cast<uint8_t *>(static_cast<uintptr_t>(TAddr)); + DEBUG(dbgs() << " Registering EH frames at " << format("0x%016x", TAddr) + << ", Size = " << Size << " bytes\n"); + EHFramesDeregister(Addr, Size); + return Error::success(); } - std::error_code handleDestroyRemoteAllocator(ResourceIdMgr::ResourceId Id) { + Error handleDestroyRemoteAllocator(ResourceIdMgr::ResourceId Id) { auto I = Allocators.find(Id); if (I == Allocators.end()) return orcError(OrcErrorCode::RemoteAllocatorDoesNotExist); Allocators.erase(I); DEBUG(dbgs() << " Destroyed allocator " << Id << "\n"); - return std::error_code(); + return Error::success(); } - std::error_code - handleDestroyIndirectStubsOwner(ResourceIdMgr::ResourceId Id) { + Error handleDestroyIndirectStubsOwner(ResourceIdMgr::ResourceId Id) { auto I = IndirectStubsOwners.find(Id); if (I == IndirectStubsOwners.end()) return orcError(OrcErrorCode::RemoteIndirectStubsOwnerDoesNotExist); IndirectStubsOwners.erase(I); - return std::error_code(); + return Error::success(); } - std::error_code handleEmitIndirectStubs(ResourceIdMgr::ResourceId Id, - uint32_t NumStubsRequired) { + Expected<std::tuple<TargetAddress, TargetAddress, uint32_t>> + handleEmitIndirectStubs(ResourceIdMgr::ResourceId Id, + uint32_t NumStubsRequired) { DEBUG(dbgs() << " ISMgr " << Id << " request " << NumStubsRequired << " stubs.\n"); @@ -264,9 +277,9 @@ private: return orcError(OrcErrorCode::RemoteIndirectStubsOwnerDoesNotExist); typename TargetT::IndirectStubsInfo IS; - if (auto EC = + if (auto Err = TargetT::emitIndirectStubsBlock(IS, NumStubsRequired, nullptr)) - return EC; + return std::move(Err); TargetAddress StubsBase = static_cast<TargetAddress>(reinterpret_cast<uintptr_t>(IS.getStub(0))); @@ -277,36 +290,35 @@ private: auto &BlockList = StubOwnerItr->second; BlockList.push_back(std::move(IS)); - return call<EmitIndirectStubsResponse>(Channel, StubsBase, PtrsBase, - NumStubsEmitted); + return std::make_tuple(StubsBase, PtrsBase, NumStubsEmitted); } - std::error_code handleEmitResolverBlock() { + Error handleEmitResolverBlock() { std::error_code EC; ResolverBlock = sys::OwningMemoryBlock(sys::Memory::allocateMappedMemory( TargetT::ResolverCodeSize, nullptr, sys::Memory::MF_READ | sys::Memory::MF_WRITE, EC)); if (EC) - return EC; + return errorCodeToError(EC); TargetT::writeResolverCode(static_cast<uint8_t *>(ResolverBlock.base()), &reenter, this); - return sys::Memory::protectMappedMemory(ResolverBlock.getMemoryBlock(), - sys::Memory::MF_READ | - sys::Memory::MF_EXEC); + return errorCodeToError(sys::Memory::protectMappedMemory( + ResolverBlock.getMemoryBlock(), + sys::Memory::MF_READ | sys::Memory::MF_EXEC)); } - std::error_code handleEmitTrampolineBlock() { + Expected<std::tuple<TargetAddress, uint32_t>> handleEmitTrampolineBlock() { std::error_code EC; auto TrampolineBlock = sys::OwningMemoryBlock(sys::Memory::allocateMappedMemory( sys::Process::getPageSize(), nullptr, sys::Memory::MF_READ | sys::Memory::MF_WRITE, EC)); if (EC) - return EC; + return errorCodeToError(EC); - unsigned NumTrampolines = + uint32_t NumTrampolines = (sys::Process::getPageSize() - TargetT::PointerSize) / TargetT::TrampolineSize; @@ -320,20 +332,21 @@ private: TrampolineBlocks.push_back(std::move(TrampolineBlock)); - return call<EmitTrampolineBlockResponse>( - Channel, - static_cast<TargetAddress>(reinterpret_cast<uintptr_t>(TrampolineMem)), - NumTrampolines); + auto TrampolineBaseAddr = + static_cast<TargetAddress>(reinterpret_cast<uintptr_t>(TrampolineMem)); + + return std::make_tuple(TrampolineBaseAddr, NumTrampolines); } - std::error_code handleGetSymbolAddress(const std::string &Name) { + Expected<TargetAddress> handleGetSymbolAddress(const std::string &Name) { TargetAddress Addr = SymbolLookup(Name); DEBUG(dbgs() << " Symbol '" << Name << "' = " << format("0x%016x", Addr) << "\n"); - return call<GetSymbolAddressResponse>(Channel, Addr); + return Addr; } - std::error_code handleGetRemoteInfo() { + Expected<std::tuple<std::string, uint32_t, uint32_t, uint32_t, uint32_t>> + handleGetRemoteInfo() { std::string ProcessTriple = sys::getProcessTriple(); uint32_t PointerSize = TargetT::PointerSize; uint32_t PageSize = sys::Process::getPageSize(); @@ -345,35 +358,41 @@ private: << " page size = " << PageSize << "\n" << " trampoline size = " << TrampolineSize << "\n" << " indirect stub size = " << IndirectStubSize << "\n"); - return call<GetRemoteInfoResponse>(Channel, ProcessTriple, PointerSize, - PageSize, TrampolineSize, - IndirectStubSize); + return std::make_tuple(ProcessTriple, PointerSize, PageSize, TrampolineSize, + IndirectStubSize); } - std::error_code handleReadMem(TargetAddress RSrc, uint64_t Size) { + Expected<std::vector<char>> handleReadMem(TargetAddress RSrc, uint64_t Size) { char *Src = reinterpret_cast<char *>(static_cast<uintptr_t>(RSrc)); DEBUG(dbgs() << " Reading " << Size << " bytes from " - << static_cast<void *>(Src) << "\n"); + << format("0x%016x", RSrc) << "\n"); - if (auto EC = call<ReadMemResponse>(Channel)) - return EC; + std::vector<char> Buffer; + Buffer.resize(Size); + for (char *P = Src; Size != 0; --Size) + Buffer.push_back(*P++); - if (auto EC = Channel.appendBytes(Src, Size)) - return EC; + return Buffer; + } - return Channel.send(); + Error handleRegisterEHFrames(TargetAddress TAddr, uint32_t Size) { + uint8_t *Addr = reinterpret_cast<uint8_t *>(static_cast<uintptr_t>(TAddr)); + DEBUG(dbgs() << " Registering EH frames at " << format("0x%016x", TAddr) + << ", Size = " << Size << " bytes\n"); + EHFramesRegister(Addr, Size); + return Error::success(); } - std::error_code handleReserveMem(ResourceIdMgr::ResourceId Id, uint64_t Size, - uint32_t Align) { + Expected<TargetAddress> handleReserveMem(ResourceIdMgr::ResourceId Id, + uint64_t Size, uint32_t Align) { auto I = Allocators.find(Id); if (I == Allocators.end()) return orcError(OrcErrorCode::RemoteAllocatorDoesNotExist); auto &Allocator = I->second; void *LocalAllocAddr = nullptr; - if (auto EC = Allocator.allocate(LocalAllocAddr, Size, Align)) - return EC; + if (auto Err = Allocator.allocate(LocalAllocAddr, Size, Align)) + return std::move(Err); DEBUG(dbgs() << " Allocator " << Id << " reserved " << LocalAllocAddr << " (" << Size << " bytes, alignment " << Align << ")\n"); @@ -381,11 +400,11 @@ private: TargetAddress AllocAddr = static_cast<TargetAddress>(reinterpret_cast<uintptr_t>(LocalAllocAddr)); - return call<ReserveMemResponse>(Channel, AllocAddr); + return AllocAddr; } - std::error_code handleSetProtections(ResourceIdMgr::ResourceId Id, - TargetAddress Addr, uint32_t Flags) { + Error handleSetProtections(ResourceIdMgr::ResourceId Id, TargetAddress Addr, + uint32_t Flags) { auto I = Allocators.find(Id); if (I == Allocators.end()) return orcError(OrcErrorCode::RemoteAllocatorDoesNotExist); @@ -398,24 +417,24 @@ private: return Allocator.setProtections(LocalAddr, Flags); } - std::error_code handleWriteMem(TargetAddress RDst, uint64_t Size) { - char *Dst = reinterpret_cast<char *>(static_cast<uintptr_t>(RDst)); - DEBUG(dbgs() << " Writing " << Size << " bytes to " - << format("0x%016x", RDst) << "\n"); - return Channel.readBytes(Dst, Size); + Error handleWriteMem(DirectBufferWriter DBW) { + DEBUG(dbgs() << " Writing " << DBW.getSize() << " bytes to " + << format("0x%016x", DBW.getDst()) << "\n"); + return Error::success(); } - std::error_code handleWritePtr(TargetAddress Addr, TargetAddress PtrVal) { + Error handleWritePtr(TargetAddress Addr, TargetAddress PtrVal) { DEBUG(dbgs() << " Writing pointer *" << format("0x%016x", Addr) << " = " << format("0x%016x", PtrVal) << "\n"); uintptr_t *Ptr = reinterpret_cast<uintptr_t *>(static_cast<uintptr_t>(Addr)); *Ptr = static_cast<uintptr_t>(PtrVal); - return std::error_code(); + return Error::success(); } ChannelT &Channel; SymbolLookupFtor SymbolLookup; + EHFrameRegistrationFtor EHFramesRegister, EHFramesDeregister; std::map<ResourceIdMgr::ResourceId, Allocator> Allocators; typedef std::vector<typename TargetT::IndirectStubsInfo> ISBlockOwnerList; std::map<ResourceIdMgr::ResourceId, ISBlockOwnerList> IndirectStubsOwners; |