aboutsummaryrefslogtreecommitdiffstats
path: root/tools/lli/ChildTarget/ChildTarget.cpp
diff options
context:
space:
mode:
authorStephen Hines <srhines@google.com>2014-02-11 20:01:10 -0800
committerStephen Hines <srhines@google.com>2014-02-11 20:01:10 -0800
commitce9904c6ea8fd669978a8eefb854b330eb9828ff (patch)
tree2418ee2e96ea220977c8fb74959192036ab5b133 /tools/lli/ChildTarget/ChildTarget.cpp
parentc27b10b198c1d9e9b51f2303994313ec2778edd7 (diff)
parentdbb832b83351cec97b025b61c26536ef50c3181c (diff)
downloadexternal_llvm-ce9904c6ea8fd669978a8eefb854b330eb9828ff.zip
external_llvm-ce9904c6ea8fd669978a8eefb854b330eb9828ff.tar.gz
external_llvm-ce9904c6ea8fd669978a8eefb854b330eb9828ff.tar.bz2
Merge remote-tracking branch 'upstream/release_34' into merge-20140211
Conflicts: lib/Linker/LinkModules.cpp lib/Support/Unix/Signals.inc Change-Id: Ia54f291fa5dc828052d2412736e8495c1282aa64
Diffstat (limited to 'tools/lli/ChildTarget/ChildTarget.cpp')
-rw-r--r--tools/lli/ChildTarget/ChildTarget.cpp242
1 files changed, 242 insertions, 0 deletions
diff --git a/tools/lli/ChildTarget/ChildTarget.cpp b/tools/lli/ChildTarget/ChildTarget.cpp
new file mode 100644
index 0000000..55fcae9
--- /dev/null
+++ b/tools/lli/ChildTarget/ChildTarget.cpp
@@ -0,0 +1,242 @@
+#include "llvm/Config/config.h"
+
+#include "../RemoteTargetMessage.h"
+#include <assert.h>
+#include <map>
+#include <stdint.h>
+#include <string>
+#include <vector>
+
+using namespace llvm;
+
+class LLIChildTarget {
+public:
+ ~LLIChildTarget(); // OS-specific destructor
+ void initialize();
+ LLIMessageType waitForIncomingMessage();
+ void handleMessage(LLIMessageType messageType);
+
+private:
+ // Incoming message handlers
+ void handleAllocateSpace();
+ void handleLoadSection(bool IsCode);
+ void handleExecute();
+ void handleTerminate();
+
+ // Outgoing message handlers
+ void sendChildActive();
+ void sendAllocationResult(uint64_t Addr);
+ void sendLoadComplete();
+ void sendExecutionComplete(uint64_t Result);
+
+ // OS-specific functions
+ void initializeConnection();
+ int WriteBytes(const void *Data, size_t Size);
+ int ReadBytes(void *Data, size_t Size);
+ uint64_t allocate(uint32_t Alignment, uint32_t Size);
+ void makeSectionExecutable(uint64_t Addr, uint32_t Size);
+ void InvalidateInstructionCache(const void *Addr, size_t Len);
+ void releaseMemory(uint64_t Addr, uint32_t Size);
+
+ // Store a map of allocated buffers to sizes.
+ typedef std::map<uint64_t, uint32_t> AllocMapType;
+ AllocMapType m_AllocatedBufferMap;
+
+ // Communication handles (OS-specific)
+ void *ConnectionData;
+};
+
+int main() {
+ LLIChildTarget ThisChild;
+ ThisChild.initialize();
+ LLIMessageType MsgType;
+ do {
+ MsgType = ThisChild.waitForIncomingMessage();
+ ThisChild.handleMessage(MsgType);
+ } while (MsgType != LLI_Terminate &&
+ MsgType != LLI_Error);
+ return 0;
+}
+
+// Public methods
+void LLIChildTarget::initialize() {
+ initializeConnection();
+ sendChildActive();
+}
+
+LLIMessageType LLIChildTarget::waitForIncomingMessage() {
+ int32_t MsgType = -1;
+ if (ReadBytes(&MsgType, 4) > 0)
+ return (LLIMessageType)MsgType;
+ return LLI_Error;
+}
+
+void LLIChildTarget::handleMessage(LLIMessageType messageType) {
+ switch (messageType) {
+ case LLI_AllocateSpace:
+ handleAllocateSpace();
+ break;
+ case LLI_LoadCodeSection:
+ handleLoadSection(true);
+ break;
+ case LLI_LoadDataSection:
+ handleLoadSection(false);
+ break;
+ case LLI_Execute:
+ handleExecute();
+ break;
+ case LLI_Terminate:
+ handleTerminate();
+ break;
+ default:
+ // FIXME: Handle error!
+ break;
+ }
+}
+
+// Incoming message handlers
+void LLIChildTarget::handleAllocateSpace() {
+ // Read and verify the message data size.
+ uint32_t DataSize;
+ int rc = ReadBytes(&DataSize, 4);
+ assert(rc == 4);
+ assert(DataSize == 8);
+
+ // Read the message arguments.
+ uint32_t Alignment;
+ uint32_t AllocSize;
+ rc = ReadBytes(&Alignment, 4);
+ assert(rc == 4);
+ rc = ReadBytes(&AllocSize, 4);
+ assert(rc == 4);
+
+ // Allocate the memory.
+ uint64_t Addr = allocate(Alignment, AllocSize);
+
+ // Send AllocationResult message.
+ sendAllocationResult(Addr);
+}
+
+void LLIChildTarget::handleLoadSection(bool IsCode) {
+ // Read the message data size.
+ uint32_t DataSize;
+ int rc = ReadBytes(&DataSize, 4);
+ assert(rc == 4);
+
+ // Read the target load address.
+ uint64_t Addr;
+ rc = ReadBytes(&Addr, 8);
+ assert(rc == 8);
+
+ size_t BufferSize = DataSize - 8;
+
+ // FIXME: Verify that this is in allocated space
+
+ // Read section data into previously allocated buffer
+ rc = ReadBytes((void*)Addr, DataSize - 8);
+ assert(rc == (int)(BufferSize));
+
+ // If IsCode, mark memory executable
+ if (IsCode)
+ makeSectionExecutable(Addr, BufferSize);
+
+ // Send MarkLoadComplete message.
+ sendLoadComplete();
+}
+
+void LLIChildTarget::handleExecute() {
+ // Read the message data size.
+ uint32_t DataSize;
+ int rc = ReadBytes(&DataSize, 4);
+ assert(rc == 4);
+ assert(DataSize == 8);
+
+ // Read the target address.
+ uint64_t Addr;
+ rc = ReadBytes(&Addr, 8);
+ assert(rc == 8);
+
+ // Call function
+ int Result;
+ int (*fn)(void) = (int(*)(void))Addr;
+ Result = fn();
+
+ // Send ExecutionResult message.
+ sendExecutionComplete((int64_t)Result);
+}
+
+void LLIChildTarget::handleTerminate() {
+ // Release all allocated memory
+ AllocMapType::iterator Begin = m_AllocatedBufferMap.begin();
+ AllocMapType::iterator End = m_AllocatedBufferMap.end();
+ for (AllocMapType::iterator It = Begin; It != End; ++It) {
+ releaseMemory(It->first, It->second);
+ }
+ m_AllocatedBufferMap.clear();
+}
+
+// Outgoing message handlers
+void LLIChildTarget::sendChildActive() {
+ // Write the message type.
+ uint32_t MsgType = (uint32_t)LLI_ChildActive;
+ int rc = WriteBytes(&MsgType, 4);
+ assert(rc == 4);
+
+ // Write the data size.
+ uint32_t DataSize = 0;
+ rc = WriteBytes(&DataSize, 4);
+ assert(rc == 4);
+}
+
+void LLIChildTarget::sendAllocationResult(uint64_t Addr) {
+ // Write the message type.
+ uint32_t MsgType = (uint32_t)LLI_AllocationResult;
+ int rc = WriteBytes(&MsgType, 4);
+ assert(rc == 4);
+
+ // Write the data size.
+ uint32_t DataSize = 8;
+ rc = WriteBytes(&DataSize, 4);
+ assert(rc == 4);
+
+ // Write the allocated address.
+ rc = WriteBytes(&Addr, 8);
+ assert(rc == 8);
+}
+
+void LLIChildTarget::sendLoadComplete() {
+ // Write the message type.
+ uint32_t MsgType = (uint32_t)LLI_LoadComplete;
+ int rc = WriteBytes(&MsgType, 4);
+ assert(rc == 4);
+
+ // Write the data size.
+ uint32_t DataSize = 0;
+ rc = WriteBytes(&DataSize, 4);
+ assert(rc == 4);
+}
+
+void LLIChildTarget::sendExecutionComplete(uint64_t Result) {
+ // Write the message type.
+ uint32_t MsgType = (uint32_t)LLI_ExecutionResult;
+ int rc = WriteBytes(&MsgType, 4);
+ assert(rc == 4);
+
+
+ // Write the data size.
+ uint32_t DataSize = 8;
+ rc = WriteBytes(&DataSize, 4);
+ assert(rc == 4);
+
+ // Write the result.
+ rc = WriteBytes(&Result, 8);
+ assert(rc == 8);
+}
+
+#ifdef LLVM_ON_UNIX
+#include "Unix/ChildTarget.inc"
+#endif
+
+#ifdef LLVM_ON_WIN32
+#include "Windows/ChildTarget.inc"
+#endif