summaryrefslogtreecommitdiff
path: root/include/llvm/ExecutionEngine/Orc/OrcRemoteTargetServer.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/llvm/ExecutionEngine/Orc/OrcRemoteTargetServer.h')
-rw-r--r--include/llvm/ExecutionEngine/Orc/OrcRemoteTargetServer.h233
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;