summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--llvm/include/llvm/ExecutionEngine/Orc/OrcRemoteTargetClient.h31
-rw-r--r--llvm/include/llvm/ExecutionEngine/Orc/OrcRemoteTargetRPCAPI.h10
-rw-r--r--llvm/include/llvm/ExecutionEngine/Orc/OrcRemoteTargetServer.h34
-rw-r--r--llvm/include/llvm/ExecutionEngine/RTDyldMemoryManager.h15
-rw-r--r--llvm/lib/ExecutionEngine/Orc/OrcRemoteTargetRPCAPI.cpp4
-rw-r--r--llvm/lib/ExecutionEngine/RuntimeDyld/RTDyldMemoryManager.cpp20
-rw-r--r--llvm/test/ExecutionEngine/MCJIT/remote/eh.ll32
-rw-r--r--llvm/test/ExecutionEngine/OrcMCJIT/remote/eh.ll32
-rw-r--r--llvm/tools/lli/ChildTarget/ChildTarget.cpp10
9 files changed, 168 insertions, 20 deletions
diff --git a/llvm/include/llvm/ExecutionEngine/Orc/OrcRemoteTargetClient.h b/llvm/include/llvm/ExecutionEngine/Orc/OrcRemoteTargetClient.h
index 08a9dd218e4..defae248dba 100644
--- a/llvm/include/llvm/ExecutionEngine/Orc/OrcRemoteTargetClient.h
+++ b/llvm/include/llvm/ExecutionEngine/Orc/OrcRemoteTargetClient.h
@@ -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.
@@ -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) {
diff --git a/llvm/include/llvm/ExecutionEngine/Orc/OrcRemoteTargetRPCAPI.h b/llvm/include/llvm/ExecutionEngine/Orc/OrcRemoteTargetRPCAPI.h
index 96dc2425102..3a8dbf000a6 100644
--- a/llvm/include/llvm/ExecutionEngine/Orc/OrcRemoteTargetRPCAPI.h
+++ b/llvm/include/llvm/ExecutionEngine/Orc/OrcRemoteTargetRPCAPI.h
@@ -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;
diff --git a/llvm/include/llvm/ExecutionEngine/Orc/OrcRemoteTargetServer.h b/llvm/include/llvm/ExecutionEngine/Orc/OrcRemoteTargetServer.h
index 5247661e49c..969b5cc2e4d 100644
--- a/llvm/include/llvm/ExecutionEngine/Orc/OrcRemoteTargetServer.h
+++ b/llvm/include/llvm/ExecutionEngine/Orc/OrcRemoteTargetServer.h
@@ -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;
diff --git a/llvm/include/llvm/ExecutionEngine/RTDyldMemoryManager.h b/llvm/include/llvm/ExecutionEngine/RTDyldMemoryManager.h
index c5006962550..a6871663657 100644
--- a/llvm/include/llvm/ExecutionEngine/RTDyldMemoryManager.h
+++ b/llvm/include/llvm/ExecutionEngine/RTDyldMemoryManager.h
@@ -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.
diff --git a/llvm/lib/ExecutionEngine/Orc/OrcRemoteTargetRPCAPI.cpp b/llvm/lib/ExecutionEngine/Orc/OrcRemoteTargetRPCAPI.cpp
index 064633b4e49..d17723f0fc1 100644
--- a/llvm/lib/ExecutionEngine/Orc/OrcRemoteTargetRPCAPI.cpp
+++ b/llvm/lib/ExecutionEngine/Orc/OrcRemoteTargetRPCAPI.cpp
@@ -33,6 +33,8 @@ const char *OrcRemoteTargetRPCAPI::getJITProcIdName(JITProcId Id) {
return "CreateRemoteAllocator";
case CreateIndirectStubsOwnerId:
return "CreateIndirectStubsOwner";
+ case DeregisterEHFramesId:
+ return "DeregisterEHFrames";
case DestroyRemoteAllocatorId:
return "DestroyRemoteAllocator";
case DestroyIndirectStubsOwnerId:
@@ -59,6 +61,8 @@ const char *OrcRemoteTargetRPCAPI::getJITProcIdName(JITProcId Id) {
return "ReadMem";
case ReadMemResponseId:
return "ReadMemResponse";
+ case RegisterEHFramesId:
+ return "RegisterEHFrames";
case ReserveMemId:
return "ReserveMem";
case ReserveMemResponseId:
diff --git a/llvm/lib/ExecutionEngine/RuntimeDyld/RTDyldMemoryManager.cpp b/llvm/lib/ExecutionEngine/RuntimeDyld/RTDyldMemoryManager.cpp
index ecd99004bad..a9f8ab7bb88 100644
--- a/llvm/lib/ExecutionEngine/RuntimeDyld/RTDyldMemoryManager.cpp
+++ b/llvm/lib/ExecutionEngine/RuntimeDyld/RTDyldMemoryManager.cpp
@@ -94,9 +94,8 @@ static const char *processFDE(const char *Entry, bool isDeregister) {
// 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::registerEHFrames(uint8_t *Addr,
} 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::deregisterEHFrames(uint8_t *Addr,
#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::registerEHFrames(uint8_t *Addr,
__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);
}
diff --git a/llvm/test/ExecutionEngine/MCJIT/remote/eh.ll b/llvm/test/ExecutionEngine/MCJIT/remote/eh.ll
new file mode 100644
index 00000000000..f772e1c03e6
--- /dev/null
+++ b/llvm/test/ExecutionEngine/MCJIT/remote/eh.ll
@@ -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*)
+
+@_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
+}
diff --git a/llvm/test/ExecutionEngine/OrcMCJIT/remote/eh.ll b/llvm/test/ExecutionEngine/OrcMCJIT/remote/eh.ll
new file mode 100644
index 00000000000..f772e1c03e6
--- /dev/null
+++ b/llvm/test/ExecutionEngine/OrcMCJIT/remote/eh.ll
@@ -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*)
+
+@_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
+}
diff --git a/llvm/tools/lli/ChildTarget/ChildTarget.cpp b/llvm/tools/lli/ChildTarget/ChildTarget.cpp
index 0b75e20f83e..93925d6aa87 100644
--- a/llvm/tools/lli/ChildTarget/ChildTarget.cpp
+++ b/llvm/tools/lli/ChildTarget/ChildTarget.cpp
@@ -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;
OpenPOWER on IntegriCloud