[llvm] r257816 - [Orc] Add support for EH-frame registration to the Orc Remote Target utility
David Blaikie via llvm-commits
llvm-commits at lists.llvm.org
Thu Jan 14 14:21:51 PST 2016
On Thu, Jan 14, 2016 at 2:02 PM, Lang Hames via llvm-commits <
llvm-commits at lists.llvm.org> wrote:
> Author: lhames
> Date: Thu Jan 14 16:02:03 2016
> New Revision: 257816
>
> URL: http://llvm.org/viewvc/llvm-project?rev=257816&view=rev
> Log:
> [Orc] Add support for EH-frame registration to the Orc Remote Target
> utility
> classes.
>
> OrcRemoteTargetClient::RCMemoryManager will now register EH frames with the
> server automatically. This allows remote-execution of code that uses
> exceptions.
>
>
> Added:
> llvm/trunk/test/ExecutionEngine/MCJIT/remote/eh.ll
> llvm/trunk/test/ExecutionEngine/OrcMCJIT/remote/eh.ll
> Modified:
> llvm/trunk/include/llvm/ExecutionEngine/Orc/OrcRemoteTargetClient.h
> llvm/trunk/include/llvm/ExecutionEngine/Orc/OrcRemoteTargetRPCAPI.h
> llvm/trunk/include/llvm/ExecutionEngine/Orc/OrcRemoteTargetServer.h
> llvm/trunk/include/llvm/ExecutionEngine/RTDyldMemoryManager.h
> llvm/trunk/lib/ExecutionEngine/Orc/OrcRemoteTargetRPCAPI.cpp
> llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RTDyldMemoryManager.cpp
> llvm/trunk/tools/lli/ChildTarget/ChildTarget.cpp
>
> Modified:
> llvm/trunk/include/llvm/ExecutionEngine/Orc/OrcRemoteTargetClient.h
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ExecutionEngine/Orc/OrcRemoteTargetClient.h?rev=257816&r1=257815&r2=257816&view=diff
>
> ==============================================================================
> --- llvm/trunk/include/llvm/ExecutionEngine/Orc/OrcRemoteTargetClient.h
> (original)
> +++ llvm/trunk/include/llvm/ExecutionEngine/Orc/OrcRemoteTargetClient.h
> Thu Jan 14 16:02:03 2016
> @@ -144,10 +144,18 @@ public:
> bool needsToReserveAllocationSpace() override { return true; }
>
> void registerEHFrames(uint8_t *Addr, uint64_t LoadAddr,
> - size_t Size) override {}
> + size_t Size) override {
> + UnfinalizedEHFrames.push_back(
> + std::make_pair(LoadAddr, static_cast<uint32_t>(Size)));
> + }
>
> - void deregisterEHFrames(uint8_t *addr, uint64_t LoadAddr,
> - size_t Size) override {}
> + void deregisterEHFrames(uint8_t *Addr, uint64_t LoadAddr,
> + size_t Size) override {
> + auto EC = Client.deregisterEHFrames(LoadAddr, Size);
> + // FIXME: Add error poll.
> + assert(!EC && "Failed to register remote EH frames.");
> + (void)EC;
> + }
>
> void notifyObjectLoaded(RuntimeDyld &Dyld,
> const object::ObjectFile &Obj) override {
> @@ -253,6 +261,14 @@ public:
> }
> Unfinalized.clear();
>
> + for (auto &EHFrame : UnfinalizedEHFrames) {
> + auto EC = Client.registerEHFrames(EHFrame.first, EHFrame.second);
> + // FIXME: Add error poll.
> + assert(!EC && "Failed to register remote EH frames.");
> + (void)EC;
> + }
> + UnfinalizedEHFrames.clear();
> +
> return false;
> }
>
> @@ -331,6 +347,7 @@ public:
> ResourceIdMgr::ResourceId Id;
> std::vector<ObjectAllocs> Unmapped;
> std::vector<ObjectAllocs> Unfinalized;
> + std::vector<std::pair<uint64_t, uint32_t>> UnfinalizedEHFrames;
> };
>
> /// Remote indirect stubs manager.ation list t
> @@ -620,6 +637,10 @@ private:
> RemoteTrampolineSize, RemoteIndirectStubSize));
> }
>
> + std::error_code deregisterEHFrames(TargetAddress Addr, uint32_t Size) {
> + return call<RegisterEHFrames>(Channel, Addr, Size);
> + }
> +
> void destroyRemoteAllocator(ResourceIdMgr::ResourceId Id) {
> if (auto EC = call<DestroyRemoteAllocator>(Channel, Id)) {
> // FIXME: This will be triggered by a removeModuleSet call:
> Propagate
> @@ -716,6 +737,10 @@ private:
> return std::error_code();
> }
>
> + std::error_code registerEHFrames(TargetAddress &RAddr, uint32_t Size) {
> + return call<RegisterEHFrames>(Channel, RAddr, Size);
> + }
> +
> std::error_code reserveMem(TargetAddress &RemoteAddr,
> ResourceIdMgr::ResourceId Id, uint64_t Size,
> uint32_t Align) {
>
> Modified:
> llvm/trunk/include/llvm/ExecutionEngine/Orc/OrcRemoteTargetRPCAPI.h
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ExecutionEngine/Orc/OrcRemoteTargetRPCAPI.h?rev=257816&r1=257815&r2=257816&view=diff
>
> ==============================================================================
> --- llvm/trunk/include/llvm/ExecutionEngine/Orc/OrcRemoteTargetRPCAPI.h
> (original)
> +++ llvm/trunk/include/llvm/ExecutionEngine/Orc/OrcRemoteTargetRPCAPI.h
> Thu Jan 14 16:02:03 2016
> @@ -56,6 +56,7 @@ public:
> CallVoidVoidResponseId,
> CreateRemoteAllocatorId,
> CreateIndirectStubsOwnerId,
> + DeregisterEHFramesId,
> DestroyRemoteAllocatorId,
> DestroyIndirectStubsOwnerId,
> EmitIndirectStubsId,
> @@ -69,6 +70,7 @@ public:
> GetRemoteInfoResponseId,
> ReadMemId,
> ReadMemResponseId,
> + RegisterEHFramesId,
> ReserveMemId,
> ReserveMemResponseId,
> RequestCompileId,
> @@ -104,6 +106,10 @@ public:
> ResourceIdMgr::ResourceId /* StubsOwner ID */>
> CreateIndirectStubsOwner;
>
> + typedef Procedure<DeregisterEHFramesId, TargetAddress /* Addr */,
> + uint32_t /* Size */>
> + DeregisterEHFrames;
> +
> typedef Procedure<DestroyRemoteAllocatorId,
> ResourceIdMgr::ResourceId /* Allocator ID */>
> DestroyRemoteAllocator;
> @@ -150,6 +156,10 @@ public:
>
> typedef Procedure<ReadMemResponseId> ReadMemResponse;
>
> + typedef Procedure<RegisterEHFramesId, TargetAddress /* Addr */,
> + uint32_t /* Size */>
> + RegisterEHFrames;
> +
> typedef Procedure<ReserveMemId, ResourceIdMgr::ResourceId /* Id */,
> uint64_t /* Size */, uint32_t /* Align */>
> ReserveMem;
>
> Modified:
> llvm/trunk/include/llvm/ExecutionEngine/Orc/OrcRemoteTargetServer.h
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ExecutionEngine/Orc/OrcRemoteTargetServer.h?rev=257816&r1=257815&r2=257816&view=diff
>
> ==============================================================================
> --- llvm/trunk/include/llvm/ExecutionEngine/Orc/OrcRemoteTargetServer.h
> (original)
> +++ llvm/trunk/include/llvm/ExecutionEngine/Orc/OrcRemoteTargetServer.h
> Thu Jan 14 16:02:03 2016
> @@ -35,8 +35,15 @@ 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;
> +
> + OrcRemoteTargetServer(ChannelT &Channel, SymbolLookupFtor SymbolLookup,
> + EHFrameRegistrationFtor EHFramesRegister,
> + EHFrameRegistrationFtor EHFramesDeregister)
> + : Channel(Channel), SymbolLookup(std::move(SymbolLookup)),
> + EHFramesRegister(std::move(EHFramesRegister)),
> + EHFramesDeregister(std::move(EHFramesDeregister)) {}
>
> std::error_code getNextProcId(JITProcId &Id) {
> return deserialize(Channel, Id);
> @@ -60,6 +67,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 +92,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:
> @@ -236,6 +249,14 @@ private:
> return std::error_code();
> }
>
> + std::error_code 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 std::error_code();
> + }
> +
> std::error_code handleDestroyRemoteAllocator(ResourceIdMgr::ResourceId
> Id) {
> auto I = Allocators.find(Id);
> if (I == Allocators.end())
> @@ -365,6 +386,14 @@ private:
> return Channel.send();
> }
>
> + std::error_code 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 std::error_code();
> + }
> +
> std::error_code handleReserveMem(ResourceIdMgr::ResourceId Id, uint64_t
> Size,
> uint32_t Align) {
> auto I = Allocators.find(Id);
> @@ -416,6 +445,7 @@ private:
>
> 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;
>
> Modified: llvm/trunk/include/llvm/ExecutionEngine/RTDyldMemoryManager.h
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ExecutionEngine/RTDyldMemoryManager.h?rev=257816&r1=257815&r2=257816&view=diff
>
> ==============================================================================
> --- llvm/trunk/include/llvm/ExecutionEngine/RTDyldMemoryManager.h
> (original)
> +++ llvm/trunk/include/llvm/ExecutionEngine/RTDyldMemoryManager.h Thu Jan
> 14 16:02:03 2016
> @@ -62,8 +62,19 @@ public:
> RTDyldMemoryManager() {}
> ~RTDyldMemoryManager() override;
>
> - void registerEHFrames(uint8_t *Addr, uint64_t LoadAddr, size_t Size)
> override;
> - void deregisterEHFrames(uint8_t *Addr, uint64_t LoadAddr, size_t Size)
> override;
> + /// Register EH frames in the current process.
> + static void registerEHFramesInProcess(uint8_t *Addr, size_t Size);
> +
> + /// Deregister EH frames in the current proces.
> + static void deregisterEHFramesInProcess(uint8_t *Addr, size_t Size);
> +
> + void registerEHFrames(uint8_t *Addr, uint64_t LoadAddr, size_t Size)
> override {
> + registerEHFramesInProcess(Addr, Size);
> + }
> +
> + void deregisterEHFrames(uint8_t *Addr, uint64_t LoadAddr, size_t Size)
> override {
> + registerEHFramesInProcess(Addr, Size);
> + }
>
> /// This method returns the address of the specified function or
> variable in
> /// the current process.
>
> Modified: llvm/trunk/lib/ExecutionEngine/Orc/OrcRemoteTargetRPCAPI.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/Orc/OrcRemoteTargetRPCAPI.cpp?rev=257816&r1=257815&r2=257816&view=diff
>
> ==============================================================================
> --- llvm/trunk/lib/ExecutionEngine/Orc/OrcRemoteTargetRPCAPI.cpp (original)
> +++ llvm/trunk/lib/ExecutionEngine/Orc/OrcRemoteTargetRPCAPI.cpp Thu Jan
> 14 16:02:03 2016
> @@ -33,6 +33,8 @@ const char *OrcRemoteTargetRPCAPI::getJI
> return "CreateRemoteAllocator";
> case CreateIndirectStubsOwnerId:
> return "CreateIndirectStubsOwner";
> + case DeregisterEHFramesId:
> + return "DeregisterEHFrames";
> case DestroyRemoteAllocatorId:
> return "DestroyRemoteAllocator";
> case DestroyIndirectStubsOwnerId:
> @@ -59,6 +61,8 @@ const char *OrcRemoteTargetRPCAPI::getJI
> return "ReadMem";
> case ReadMemResponseId:
> return "ReadMemResponse";
> + case RegisterEHFramesId:
> + return "RegisterEHFrames";
> case ReserveMemId:
> return "ReserveMem";
> case ReserveMemResponseId:
>
> Modified:
> llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RTDyldMemoryManager.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RTDyldMemoryManager.cpp?rev=257816&r1=257815&r2=257816&view=diff
>
> ==============================================================================
> --- llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RTDyldMemoryManager.cpp
> (original)
> +++ llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RTDyldMemoryManager.cpp Thu
> Jan 14 16:02:03 2016
> @@ -94,9 +94,8 @@ static const char *processFDE(const char
> // This implementation handles frame registration for local targets.
> // Memory managers for remote targets should re-implement this function
> // and use the LoadAddr parameter.
> -void RTDyldMemoryManager::registerEHFrames(uint8_t *Addr,
> - uint64_t LoadAddr,
> - size_t Size) {
> +void RTDyldMemoryManager::registerEHFramesInProcess(uint8_t *Addr,
> + size_t Size) {
> // On OS X OS X __register_frame takes a single FDE as an argument.
> // See http://lists.llvm.org/pipermail/llvm-dev/2013-April/061768.html
> const char *P = (const char *)Addr;
> @@ -106,9 +105,8 @@ void RTDyldMemoryManager::registerEHFram
> } while(P != End);
> }
>
> -void RTDyldMemoryManager::deregisterEHFrames(uint8_t *Addr,
> - uint64_t LoadAddr,
> - size_t Size) {
> +void RTDyldMemoryManager::deregisterEHFramesInProcess(uint8_t *Addr,
> + size_t Size) {
> const char *P = (const char *)Addr;
> const char *End = P + Size;
> do {
> @@ -118,9 +116,8 @@ void RTDyldMemoryManager::deregisterEHFr
>
> #else
>
> -void RTDyldMemoryManager::registerEHFrames(uint8_t *Addr,
> - uint64_t LoadAddr,
> - size_t Size) {
> +void RTDyldMemoryManager::registerEHFramesInProcess(uint8_t *Addr,
> + size_t Size) {
> // On Linux __register_frame takes a single argument:
> // a pointer to the start of the .eh_frame section.
>
> @@ -129,9 +126,8 @@ void RTDyldMemoryManager::registerEHFram
> __register_frame(Addr);
> }
>
> -void RTDyldMemoryManager::deregisterEHFrames(uint8_t *Addr,
> - uint64_t LoadAddr,
> - size_t Size) {
> +void RTDyldMemoryManager::deregisterEHFramesInProcess(uint8_t *Addr,
> + size_t Size) {
> __deregister_frame(Addr);
> }
>
>
> Added: llvm/trunk/test/ExecutionEngine/MCJIT/remote/eh.ll
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/test/ExecutionEngine/MCJIT/remote/eh.ll?rev=257816&view=auto
>
> ==============================================================================
> --- llvm/trunk/test/ExecutionEngine/MCJIT/remote/eh.ll (added)
> +++ llvm/trunk/test/ExecutionEngine/MCJIT/remote/eh.ll Thu Jan 14 16:02:03
> 2016
> @@ -0,0 +1,32 @@
> +; RUN: %lli -remote-mcjit -mcjit-remote-process=lli-child-target%exeext %s
> +; XFAIL: arm, cygwin, win32, mingw
> +declare i8* @__cxa_allocate_exception(i64)
> +declare void @__cxa_throw(i8*, i8*, i8*)
> +declare i32 @__gxx_personality_v0(...)
> +declare void @__cxa_end_catch()
> +declare i8* @__cxa_begin_catch(i8*)
> +
> + at _ZTIi = external constant i8*
> +
> +define void @throwException() {
> + %exception = tail call i8* @__cxa_allocate_exception(i64 4)
> + call void @__cxa_throw(i8* %exception, i8* bitcast (i8** @_ZTIi to
> i8*), i8* null)
> + unreachable
> +}
> +
> +define i32 @main() personality i8* bitcast (i32 (...)*
> @__gxx_personality_v0 to i8*) {
> +entry:
> + invoke void @throwException()
> + to label %try.cont unwind label %lpad
> +
> +lpad:
> + %p = landingpad { i8*, i32 }
> + catch i8* bitcast (i8** @_ZTIi to i8*)
> + %e = extractvalue { i8*, i32 } %p, 0
> + call i8* @__cxa_begin_catch(i8* %e)
> + call void @__cxa_end_catch()
> + br label %try.cont
> +
> +try.cont:
> + ret i32 0
> +}
>
> Added: llvm/trunk/test/ExecutionEngine/OrcMCJIT/remote/eh.ll
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/test/ExecutionEngine/OrcMCJIT/remote/eh.ll?rev=257816&view=auto
>
> ==============================================================================
> --- llvm/trunk/test/ExecutionEngine/OrcMCJIT/remote/eh.ll (added)
> +++ llvm/trunk/test/ExecutionEngine/OrcMCJIT/remote/eh.ll Thu Jan 14
> 16:02:03 2016
> @@ -0,0 +1,32 @@
> +; RUN: %lli -remote-mcjit -mcjit-remote-process=lli-child-target%exeext %s
>
Do these two tests actually verify any particular behavior? Perhaps the
catch block could return 0 and the non-exceptional exit could return
non-zero, then the zero exit (that lit will check) demonstrates that the
exception occurred and was handled correctly?
(semi-relatedly: How would these tests behave if the rest of the patch was
reverted? I guess it probably crashes somewhere in the EH runtime code?)
> +; XFAIL: arm, cygwin, win32, mingw
> +declare i8* @__cxa_allocate_exception(i64)
> +declare void @__cxa_throw(i8*, i8*, i8*)
> +declare i32 @__gxx_personality_v0(...)
> +declare void @__cxa_end_catch()
> +declare i8* @__cxa_begin_catch(i8*)
> +
> + at _ZTIi = external constant i8*
> +
> +define void @throwException() {
> + %exception = tail call i8* @__cxa_allocate_exception(i64 4)
> + call void @__cxa_throw(i8* %exception, i8* bitcast (i8** @_ZTIi to
> i8*), i8* null)
> + unreachable
> +}
> +
> +define i32 @main() personality i8* bitcast (i32 (...)*
> @__gxx_personality_v0 to i8*) {
> +entry:
> + invoke void @throwException()
> + to label %try.cont unwind label %lpad
> +
> +lpad:
> + %p = landingpad { i8*, i32 }
> + catch i8* bitcast (i8** @_ZTIi to i8*)
> + %e = extractvalue { i8*, i32 } %p, 0
> + call i8* @__cxa_begin_catch(i8* %e)
> + call void @__cxa_end_catch()
> + br label %try.cont
> +
> +try.cont:
> + ret i32 0
> +}
>
> Modified: llvm/trunk/tools/lli/ChildTarget/ChildTarget.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/lli/ChildTarget/ChildTarget.cpp?rev=257816&r1=257815&r2=257816&view=diff
>
> ==============================================================================
> --- llvm/trunk/tools/lli/ChildTarget/ChildTarget.cpp (original)
> +++ llvm/trunk/tools/lli/ChildTarget/ChildTarget.cpp Thu Jan 14 16:02:03
> 2016
> @@ -41,9 +41,17 @@ int main(int argc, char *argv[]) {
> return RTDyldMemoryManager::getSymbolAddressInProcess(Name);
> };
>
> + auto RegisterEHFrames = [](uint8_t *Addr, uint32_t Size) {
> + RTDyldMemoryManager::registerEHFramesInProcess(Addr, Size);
> + };
> +
> + auto DeregisterEHFrames = [](uint8_t *Addr, uint32_t Size) {
> + RTDyldMemoryManager::deregisterEHFramesInProcess(Addr, Size);
> + };
> +
> FDRPCChannel Channel(InFD, OutFD);
> typedef remote::OrcRemoteTargetServer<FDRPCChannel, HostOrcArch>
> JITServer;
> - JITServer Server(Channel, SymbolLookup);
> + JITServer Server(Channel, SymbolLookup, RegisterEHFrames,
> DeregisterEHFrames);
>
> while (1) {
> JITServer::JITProcId Id = JITServer::InvalidId;
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20160114/4259f64d/attachment.html>
More information about the llvm-commits
mailing list