summaryrefslogtreecommitdiff
path: root/tools/lli/RemoteTargetExternal.cpp
diff options
context:
space:
mode:
authorRenato Golin <renato.golin@linaro.org>2014-01-14 22:43:43 +0000
committerRenato Golin <renato.golin@linaro.org>2014-01-14 22:43:43 +0000
commit83ece7a4993edb295e71841bd51b298219186c4c (patch)
tree396a100a569c18057afe5c1ed288cabf65a2c0c0 /tools/lli/RemoteTargetExternal.cpp
parent0445dc203b0e4001a153d9af4bd75f5242401d06 (diff)
downloadllvm-83ece7a4993edb295e71841bd51b298219186c4c.tar.gz
llvm-83ece7a4993edb295e71841bd51b298219186c4c.tar.bz2
llvm-83ece7a4993edb295e71841bd51b298219186c4c.tar.xz
Sanitize MCJIT remote execution
MCJIT remote execution (ChildTarget+RemoteTargetExternal) protocol was in dire need of refactoring. It was fail-prone, had no error reporting and implemented the same message logic on every single function. This patch rectifies it, and makes it work on ARM, where it was randomly failing. Other architectures shall profit from this change as well, making their buildbots and releases more reliable. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@199261 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'tools/lli/RemoteTargetExternal.cpp')
-rw-r--r--tools/lli/RemoteTargetExternal.cpp331
1 files changed, 245 insertions, 86 deletions
diff --git a/tools/lli/RemoteTargetExternal.cpp b/tools/lli/RemoteTargetExternal.cpp
index 809488c9e3..3bf7bf4e3b 100644
--- a/tools/lli/RemoteTargetExternal.cpp
+++ b/tools/lli/RemoteTargetExternal.cpp
@@ -17,6 +17,8 @@
#include "RemoteTargetExternal.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/DataTypes.h"
+#include "llvm/Support/Debug.h"
+#include "llvm/Support/Format.h"
#include "llvm/Support/Memory.h"
#include "llvm/Support/Program.h"
#include "llvm/Support/raw_ostream.h"
@@ -26,28 +28,85 @@ using namespace llvm;
bool RemoteTargetExternal::allocateSpace(size_t Size, unsigned Alignment,
uint64_t &Address) {
- SendAllocateSpace(Alignment, Size);
- Receive(LLI_AllocationResult, Address);
- return false;
+ DEBUG(dbgs() << "Message [allocate space] size: " << Size <<
+ ", align: " << Alignment << "\n");
+ if (!SendAllocateSpace(Alignment, Size)) {
+ ErrorMsg += ", (RemoteTargetExternal::allocateSpace)";
+ return false;
+ }
+ if (!Receive(LLI_AllocationResult, Address)) {
+ ErrorMsg += ", (RemoteTargetExternal::allocateSpace)";
+ return false;
+ }
+ if (Address == 0) {
+ ErrorMsg += "failed allocation, (RemoteTargetExternal::allocateSpace)";
+ return false;
+ }
+ DEBUG(dbgs() << "Message [allocate space] addr: 0x" <<
+ format("%llx", Address) << "\n");
+ return true;
}
bool RemoteTargetExternal::loadData(uint64_t Address, const void *Data, size_t Size) {
- SendLoadSection(Address, Data, (uint32_t)Size, false);
- Receive(LLI_LoadComplete);
- return false;
+ DEBUG(dbgs() << "Message [load data] addr: 0x" << format("%llx", Address) <<
+ ", size: " << Size << "\n");
+ if (!SendLoadSection(Address, Data, (uint32_t)Size, false)) {
+ ErrorMsg += ", (RemoteTargetExternal::loadData)";
+ return false;
+ }
+ int Status = LLI_Status_Success;
+ if (!Receive(LLI_LoadResult, Status)) {
+ ErrorMsg += ", (RemoteTargetExternal::loadData)";
+ return false;
+ }
+ if (Status == LLI_Status_IncompleteMsg) {
+ ErrorMsg += "incomplete load data, (RemoteTargetExternal::loadData)";
+ return false;
+ }
+ if (Status == LLI_Status_NotAllocated) {
+ ErrorMsg += "data memory not allocated, (RemoteTargetExternal::loadData)";
+ return false;
+ }
+ DEBUG(dbgs() << "Message [load data] complete\n");
+ return true;
}
bool RemoteTargetExternal::loadCode(uint64_t Address, const void *Data, size_t Size) {
- SendLoadSection(Address, Data, (uint32_t)Size, true);
- Receive(LLI_LoadComplete);
- return false;
+ DEBUG(dbgs() << "Message [load code] addr: 0x" << format("%llx", Address) <<
+ ", size: " << Size << "\n");
+ if (!SendLoadSection(Address, Data, (uint32_t)Size, true)) {
+ ErrorMsg += ", (RemoteTargetExternal::loadCode)";
+ return false;
+ }
+ int Status = LLI_Status_Success;
+ if (!Receive(LLI_LoadResult, Status)) {
+ ErrorMsg += ", (RemoteTargetExternal::loadCode)";
+ return false;
+ }
+ if (Status == LLI_Status_IncompleteMsg) {
+ ErrorMsg += "incomplete load data, (RemoteTargetExternal::loadData)";
+ return false;
+ }
+ if (Status == LLI_Status_NotAllocated) {
+ ErrorMsg += "data memory not allocated, (RemoteTargetExternal::loadData)";
+ return false;
+ }
+ DEBUG(dbgs() << "Message [load code] complete\n");
+ return true;
}
-bool RemoteTargetExternal::executeCode(uint64_t Address, int &RetVal) {
- SendExecute(Address);
-
- Receive(LLI_ExecutionResult, RetVal);
- return false;
+bool RemoteTargetExternal::executeCode(uint64_t Address, int32_t &RetVal) {
+ DEBUG(dbgs() << "Message [exectue code] addr: " << Address << "\n");
+ if (!SendExecute(Address)) {
+ ErrorMsg += ", (RemoteTargetExternal::executeCode)";
+ return false;
+ }
+ if (!Receive(LLI_ExecutionResult, RetVal)) {
+ ErrorMsg += ", (RemoteTargetExternal::executeCode)";
+ return false;
+ }
+ DEBUG(dbgs() << "Message [exectue code] return: " << RetVal << "\n");
+ return true;
}
void RemoteTargetExternal::stop() {
@@ -55,106 +114,206 @@ void RemoteTargetExternal::stop() {
Wait();
}
-void RemoteTargetExternal::SendAllocateSpace(uint32_t Alignment, uint32_t Size) {
- int rc;
- (void)rc;
- uint32_t MsgType = (uint32_t)LLI_AllocateSpace;
- rc = WriteBytes(&MsgType, 4);
- assert(rc == 4 && "Error writing message type.");
-
- uint32_t DataSize = 8;
- rc = WriteBytes(&DataSize, 4);
- assert(rc == 4 && "Error writing data size.");
+bool RemoteTargetExternal::SendAllocateSpace(uint32_t Alignment, uint32_t Size) {
+ if (!SendHeader(LLI_AllocateSpace)) {
+ ErrorMsg += ", (RemoteTargetExternal::SendAllocateSpace)";
+ return false;
+ }
- rc = WriteBytes(&Alignment, 4);
- assert(rc == 4 && "Error writing alignment data.");
+ AppendWrite((const void *)&Alignment, 4);
+ AppendWrite((const void *)&Size, 4);
- rc = WriteBytes(&Size, 4);
- assert(rc == 4 && "Error writing size data.");
+ if (!SendPayload()) {
+ ErrorMsg += ", (RemoteTargetExternal::SendAllocateSpace)";
+ return false;
+ }
+ return true;
}
-void RemoteTargetExternal::SendLoadSection(uint64_t Addr,
+bool RemoteTargetExternal::SendLoadSection(uint64_t Addr,
const void *Data,
uint32_t Size,
bool IsCode) {
- int rc;
- (void)rc;
- uint32_t MsgType = IsCode ? LLI_LoadCodeSection : LLI_LoadDataSection;
- rc = WriteBytes(&MsgType, 4);
- assert(rc == 4 && "Error writing message type.");
-
- uint32_t DataSize = Size + 8;
- rc = WriteBytes(&DataSize, 4);
- assert(rc == 4 && "Error writing data size.");
+ LLIMessageType MsgType = IsCode ? LLI_LoadCodeSection : LLI_LoadDataSection;
+ if (!SendHeader(MsgType)) {
+ ErrorMsg += ", (RemoteTargetExternal::SendLoadSection)";
+ return false;
+ }
- rc = WriteBytes(&Addr, 8);
- assert(rc == 8 && "Error writing data.");
+ AppendWrite((const void *)&Addr, 8);
+ AppendWrite(Data, Size);
- rc = WriteBytes(Data, Size);
- assert(rc == (int)Size && "Error writing data.");
+ if (!SendPayload()) {
+ ErrorMsg += ", (RemoteTargetExternal::SendLoadSection)";
+ return false;
+ }
+ return true;
}
-void RemoteTargetExternal::SendExecute(uint64_t Addr) {
- int rc;
- (void)rc;
- uint32_t MsgType = (uint32_t)LLI_Execute;
- rc = WriteBytes(&MsgType, 4);
- assert(rc == 4 && "Error writing message type.");
+bool RemoteTargetExternal::SendExecute(uint64_t Addr) {
+ if (!SendHeader(LLI_Execute)) {
+ ErrorMsg += ", (RemoteTargetExternal::SendExecute)";
+ return false;
+ }
- uint32_t DataSize = 8;
- rc = WriteBytes(&DataSize, 4);
- assert(rc == 4 && "Error writing data size.");
+ AppendWrite((const void *)&Addr, 8);
- rc = WriteBytes(&Addr, 8);
- assert(rc == 8 && "Error writing data.");
+ if (!SendPayload()) {
+ ErrorMsg += ", (RemoteTargetExternal::SendExecute)";
+ return false;
+ }
+ return true;
}
-void RemoteTargetExternal::SendTerminate() {
- int rc;
- (void)rc;
- uint32_t MsgType = (uint32_t)LLI_Terminate;
- rc = WriteBytes(&MsgType, 4);
- assert(rc == 4 && "Error writing message type.");
-
+bool RemoteTargetExternal::SendTerminate() {
+ return SendHeader(LLI_Terminate);
// No data or data size is sent with Terminate
}
+bool RemoteTargetExternal::Receive(LLIMessageType Msg) {
+ if (!ReceiveHeader(Msg))
+ return false;
+ int Unused;
+ AppendRead(&Unused, 0);
+ if (!ReceivePayload())
+ return false;
+ ReceiveData.clear();
+ Sizes.clear();
+ return true;
+}
+
+bool RemoteTargetExternal::Receive(LLIMessageType Msg, int32_t &Data) {
+ if (!ReceiveHeader(Msg))
+ return false;
+ AppendRead(&Data, 4);
+ if (!ReceivePayload())
+ return false;
+ ReceiveData.clear();
+ Sizes.clear();
+ return true;
+}
+
+bool RemoteTargetExternal::Receive(LLIMessageType Msg, uint64_t &Data) {
+ if (!ReceiveHeader(Msg))
+ return false;
+ AppendRead(&Data, 8);
+ if (!ReceivePayload())
+ return false;
+ ReceiveData.clear();
+ Sizes.clear();
+ return true;
+}
-void RemoteTargetExternal::Receive(LLIMessageType ExpectedMsgType) {
- int rc;
- (void)rc;
+bool RemoteTargetExternal::ReceiveHeader(LLIMessageType ExpectedMsgType) {
+ assert(ReceiveData.empty() && Sizes.empty() &&
+ "Payload vector not empty to receive header");
+
+ // Message header, with type to follow
uint32_t MsgType;
- rc = ReadBytes(&MsgType, 4);
- assert(rc == 4 && "Error reading message type.");
- assert(MsgType == (uint32_t)ExpectedMsgType && "Error: received unexpected message type.");
+ if (!ReadBytes(&MsgType, 4)) {
+ ErrorMsg += ", (RemoteTargetExternal::ReceiveHeader)";
+ return false;
+ }
+ if (MsgType != (uint32_t)ExpectedMsgType) {
+ ErrorMsg = "received unexpected message type";
+ ErrorMsg += ". Expecting: ";
+ ErrorMsg += ExpectedMsgType;
+ ErrorMsg += ", Got: ";
+ ErrorMsg += MsgType;
+ return false;
+ }
+ return true;
+}
+
+bool RemoteTargetExternal::ReceivePayload() {
+ assert(!ReceiveData.empty() &&
+ "Payload vector empty to receive");
+ assert(ReceiveData.size() == Sizes.size() &&
+ "Unexpected mismatch between data and size");
+ uint32_t TotalSize = 0;
+ for (int I=0, E=Sizes.size(); I < E; I++)
+ TotalSize += Sizes[I];
+
+ // Payload size header
uint32_t DataSize;
- rc = ReadBytes(&DataSize, 4);
- assert(rc == 4 && "Error reading data size.");
- assert(DataSize == 0 && "Error: unexpected data size.");
+ if (!ReadBytes(&DataSize, 4)) {
+ ErrorMsg += ", invalid data size";
+ return false;
+ }
+ if (DataSize != TotalSize) {
+ ErrorMsg = "unexpected data size";
+ ErrorMsg += ". Expecting: ";
+ ErrorMsg += TotalSize;
+ ErrorMsg += ", Got: ";
+ ErrorMsg += DataSize;
+ return false;
+ }
+ if (DataSize == 0)
+ return true;
+
+ // Payload itself
+ for (int I=0, E=Sizes.size(); I < E; I++) {
+ if (!ReadBytes(ReceiveData[I], Sizes[I])) {
+ ErrorMsg = "unexpected data while reading message";
+ return false;
+ }
+ }
+
+ return true;
}
-void RemoteTargetExternal::Receive(LLIMessageType ExpectedMsgType, int &Data) {
- uint64_t Temp;
- Receive(ExpectedMsgType, Temp);
- Data = (int)(int64_t)Temp;
+bool RemoteTargetExternal::SendHeader(LLIMessageType MsgType) {
+ assert(SendData.empty() && Sizes.empty() &&
+ "Payload vector not empty to send header");
+
+ // Message header, with type to follow
+ if (!WriteBytes(&MsgType, 4)) {
+ ErrorMsg += ", (RemoteTargetExternal::SendHeader)";
+ return false;
+ }
+ return true;
}
-void RemoteTargetExternal::Receive(LLIMessageType ExpectedMsgType, uint64_t &Data) {
- int rc;
- (void)rc;
- uint32_t MsgType;
- rc = ReadBytes(&MsgType, 4);
- assert(rc == 4 && "Error reading message type.");
- assert(MsgType == (uint32_t)ExpectedMsgType && "Error: received unexpected message type.");
+bool RemoteTargetExternal::SendPayload() {
+ assert(!SendData.empty() && !Sizes.empty() &&
+ "Payload vector empty to send");
+ assert(SendData.size() == Sizes.size() &&
+ "Unexpected mismatch between data and size");
- uint32_t DataSize;
- rc = ReadBytes(&DataSize, 4);
- assert(rc == 4 && "Error reading data size.");
- assert(DataSize == 8 && "Error: unexpected data size.");
+ uint32_t TotalSize = 0;
+ for (int I=0, E=Sizes.size(); I < E; I++)
+ TotalSize += Sizes[I];
+
+ // Payload size header
+ if (!WriteBytes(&TotalSize, 4)) {
+ ErrorMsg += ", invalid data size";
+ return false;
+ }
+ if (TotalSize == 0)
+ return true;
+
+ // Payload itself
+ for (int I=0, E=Sizes.size(); I < E; I++) {
+ if (!WriteBytes(SendData[I], Sizes[I])) {
+ ErrorMsg = "unexpected data while writing message";
+ return false;
+ }
+ }
+
+ SendData.clear();
+ Sizes.clear();
+ return true;
+}
+
+void RemoteTargetExternal::AppendWrite(const void *Data, uint32_t Size) {
+ SendData.push_back(Data);
+ Sizes.push_back(Size);
+}
- rc = ReadBytes(&Data, 8);
- assert(DataSize == 8 && "Error: unexpected data.");
+void RemoteTargetExternal::AppendRead(void *Data, uint32_t Size) {
+ ReceiveData.push_back(Data);
+ Sizes.push_back(Size);
}
#ifdef LLVM_ON_UNIX