blob: 4603496c982b9c8c192da22682b12352547b2f5f [file] [log] [blame]
Andrew Kaylorc2ebf3f2013-10-02 17:12:36 +00001#include "llvm/Config/config.h"
Alp Tokere2641f12014-01-23 11:04:42 +00002#include "llvm/Support/Memory.h"
Alp Toker632c6cd2014-01-23 22:19:45 +00003#include "../RPCChannel.h"
Alp Tokere2641f12014-01-23 11:04:42 +00004#include "../RemoteTarget.h"
Andrew Kaylorc2ebf3f2013-10-02 17:12:36 +00005#include "../RemoteTargetMessage.h"
6#include <assert.h>
7#include <map>
8#include <stdint.h>
9#include <string>
10#include <vector>
11
12using namespace llvm;
13
14class LLIChildTarget {
15public:
Andrew Kaylorc2ebf3f2013-10-02 17:12:36 +000016 void initialize();
17 LLIMessageType waitForIncomingMessage();
18 void handleMessage(LLIMessageType messageType);
Alp Tokere2641f12014-01-23 11:04:42 +000019 RemoteTarget *RT;
Alp Toker632c6cd2014-01-23 22:19:45 +000020 RPCChannel RPC;
Andrew Kaylorc2ebf3f2013-10-02 17:12:36 +000021
22private:
23 // Incoming message handlers
24 void handleAllocateSpace();
25 void handleLoadSection(bool IsCode);
26 void handleExecute();
Andrew Kaylorc2ebf3f2013-10-02 17:12:36 +000027
28 // Outgoing message handlers
29 void sendChildActive();
30 void sendAllocationResult(uint64_t Addr);
Renato Golin695895c2014-01-14 22:43:43 +000031 void sendLoadStatus(uint32_t Status);
32 void sendExecutionComplete(int Result);
Andrew Kaylorc2ebf3f2013-10-02 17:12:36 +000033
34 // OS-specific functions
35 void initializeConnection();
Alp Toker632c6cd2014-01-23 22:19:45 +000036 int WriteBytes(const void *Data, size_t Size) {
Alp Tokerad6aa472014-01-24 17:18:52 +000037 return RPC.WriteBytes(Data, Size) ? Size : -1;
Alp Toker632c6cd2014-01-23 22:19:45 +000038 }
Alp Tokerad6aa472014-01-24 17:18:52 +000039 int ReadBytes(void *Data, size_t Size) {
40 return RPC.ReadBytes(Data, Size) ? Size : -1;
41 }
Andrew Kaylorc2ebf3f2013-10-02 17:12:36 +000042
43 // Communication handles (OS-specific)
44 void *ConnectionData;
45};
46
47int main() {
48 LLIChildTarget ThisChild;
Alp Tokere2641f12014-01-23 11:04:42 +000049 ThisChild.RT = new RemoteTarget();
Andrew Kaylorc2ebf3f2013-10-02 17:12:36 +000050 ThisChild.initialize();
51 LLIMessageType MsgType;
52 do {
53 MsgType = ThisChild.waitForIncomingMessage();
54 ThisChild.handleMessage(MsgType);
55 } while (MsgType != LLI_Terminate &&
56 MsgType != LLI_Error);
Alp Tokere2641f12014-01-23 11:04:42 +000057 delete ThisChild.RT;
Andrew Kaylorc2ebf3f2013-10-02 17:12:36 +000058 return 0;
59}
60
61// Public methods
62void LLIChildTarget::initialize() {
Alp Toker632c6cd2014-01-23 22:19:45 +000063 RPC.createClient();
Andrew Kaylorc2ebf3f2013-10-02 17:12:36 +000064 sendChildActive();
65}
66
67LLIMessageType LLIChildTarget::waitForIncomingMessage() {
68 int32_t MsgType = -1;
69 if (ReadBytes(&MsgType, 4) > 0)
70 return (LLIMessageType)MsgType;
71 return LLI_Error;
72}
73
74void LLIChildTarget::handleMessage(LLIMessageType messageType) {
75 switch (messageType) {
76 case LLI_AllocateSpace:
77 handleAllocateSpace();
78 break;
79 case LLI_LoadCodeSection:
80 handleLoadSection(true);
81 break;
82 case LLI_LoadDataSection:
83 handleLoadSection(false);
84 break;
85 case LLI_Execute:
86 handleExecute();
87 break;
88 case LLI_Terminate:
Alp Tokere2641f12014-01-23 11:04:42 +000089 RT->stop();
Andrew Kaylorc2ebf3f2013-10-02 17:12:36 +000090 break;
91 default:
92 // FIXME: Handle error!
93 break;
94 }
95}
96
97// Incoming message handlers
98void LLIChildTarget::handleAllocateSpace() {
99 // Read and verify the message data size.
100 uint32_t DataSize;
101 int rc = ReadBytes(&DataSize, 4);
Matt Arsenaultc44a3ff2013-12-05 19:37:36 +0000102 (void)rc;
Andrew Kaylorc2ebf3f2013-10-02 17:12:36 +0000103 assert(rc == 4);
104 assert(DataSize == 8);
105
106 // Read the message arguments.
107 uint32_t Alignment;
108 uint32_t AllocSize;
109 rc = ReadBytes(&Alignment, 4);
110 assert(rc == 4);
111 rc = ReadBytes(&AllocSize, 4);
112 assert(rc == 4);
113
114 // Allocate the memory.
Alp Tokere2641f12014-01-23 11:04:42 +0000115 uint64_t Addr;
116 RT->allocateSpace(AllocSize, Alignment, Addr);
Andrew Kaylorc2ebf3f2013-10-02 17:12:36 +0000117
118 // Send AllocationResult message.
119 sendAllocationResult(Addr);
120}
121
122void LLIChildTarget::handleLoadSection(bool IsCode) {
123 // Read the message data size.
124 uint32_t DataSize;
125 int rc = ReadBytes(&DataSize, 4);
Renato Golin695895c2014-01-14 22:43:43 +0000126 (void)rc;
Andrew Kaylorc2ebf3f2013-10-02 17:12:36 +0000127 assert(rc == 4);
128
129 // Read the target load address.
130 uint64_t Addr;
131 rc = ReadBytes(&Addr, 8);
132 assert(rc == 8);
Andrew Kaylorc2ebf3f2013-10-02 17:12:36 +0000133 size_t BufferSize = DataSize - 8;
134
Alp Tokere2641f12014-01-23 11:04:42 +0000135 if (!RT->isAllocatedMemory(Addr, BufferSize))
Renato Golin695895c2014-01-14 22:43:43 +0000136 return sendLoadStatus(LLI_Status_NotAllocated);
Andrew Kaylorc2ebf3f2013-10-02 17:12:36 +0000137
138 // Read section data into previously allocated buffer
Renato Golin695895c2014-01-14 22:43:43 +0000139 rc = ReadBytes((void*)Addr, BufferSize);
140 if (rc != (int)(BufferSize))
141 return sendLoadStatus(LLI_Status_IncompleteMsg);
Andrew Kaylorc2ebf3f2013-10-02 17:12:36 +0000142
143 // If IsCode, mark memory executable
144 if (IsCode)
Alp Tokere2641f12014-01-23 11:04:42 +0000145 sys::Memory::InvalidateInstructionCache((void *)Addr, BufferSize);
Andrew Kaylorc2ebf3f2013-10-02 17:12:36 +0000146
147 // Send MarkLoadComplete message.
Renato Golin695895c2014-01-14 22:43:43 +0000148 sendLoadStatus(LLI_Status_Success);
Andrew Kaylorc2ebf3f2013-10-02 17:12:36 +0000149}
150
151void LLIChildTarget::handleExecute() {
152 // Read the message data size.
153 uint32_t DataSize;
154 int rc = ReadBytes(&DataSize, 4);
Renato Golin695895c2014-01-14 22:43:43 +0000155 (void)rc;
Andrew Kaylorc2ebf3f2013-10-02 17:12:36 +0000156 assert(rc == 4);
157 assert(DataSize == 8);
158
159 // Read the target address.
160 uint64_t Addr;
161 rc = ReadBytes(&Addr, 8);
162 assert(rc == 8);
163
164 // Call function
Alp Tokere2641f12014-01-23 11:04:42 +0000165 int32_t Result = -1;
166 RT->executeCode(Addr, Result);
Andrew Kaylorc2ebf3f2013-10-02 17:12:36 +0000167
168 // Send ExecutionResult message.
Renato Golin695895c2014-01-14 22:43:43 +0000169 sendExecutionComplete(Result);
Andrew Kaylorc2ebf3f2013-10-02 17:12:36 +0000170}
171
Andrew Kaylorc2ebf3f2013-10-02 17:12:36 +0000172// Outgoing message handlers
173void LLIChildTarget::sendChildActive() {
174 // Write the message type.
175 uint32_t MsgType = (uint32_t)LLI_ChildActive;
176 int rc = WriteBytes(&MsgType, 4);
Renato Golin695895c2014-01-14 22:43:43 +0000177 (void)rc;
Andrew Kaylorc2ebf3f2013-10-02 17:12:36 +0000178 assert(rc == 4);
179
180 // Write the data size.
181 uint32_t DataSize = 0;
182 rc = WriteBytes(&DataSize, 4);
183 assert(rc == 4);
184}
185
186void LLIChildTarget::sendAllocationResult(uint64_t Addr) {
187 // Write the message type.
188 uint32_t MsgType = (uint32_t)LLI_AllocationResult;
189 int rc = WriteBytes(&MsgType, 4);
Renato Golin695895c2014-01-14 22:43:43 +0000190 (void)rc;
Andrew Kaylorc2ebf3f2013-10-02 17:12:36 +0000191 assert(rc == 4);
192
193 // Write the data size.
194 uint32_t DataSize = 8;
195 rc = WriteBytes(&DataSize, 4);
196 assert(rc == 4);
197
198 // Write the allocated address.
199 rc = WriteBytes(&Addr, 8);
200 assert(rc == 8);
201}
202
Renato Golin695895c2014-01-14 22:43:43 +0000203void LLIChildTarget::sendLoadStatus(uint32_t Status) {
Andrew Kaylorc2ebf3f2013-10-02 17:12:36 +0000204 // Write the message type.
Renato Golin695895c2014-01-14 22:43:43 +0000205 uint32_t MsgType = (uint32_t)LLI_LoadResult;
Andrew Kaylorc2ebf3f2013-10-02 17:12:36 +0000206 int rc = WriteBytes(&MsgType, 4);
Renato Golin695895c2014-01-14 22:43:43 +0000207 (void)rc;
Andrew Kaylorc2ebf3f2013-10-02 17:12:36 +0000208 assert(rc == 4);
209
210 // Write the data size.
Renato Golin695895c2014-01-14 22:43:43 +0000211 uint32_t DataSize = 4;
Andrew Kaylorc2ebf3f2013-10-02 17:12:36 +0000212 rc = WriteBytes(&DataSize, 4);
213 assert(rc == 4);
214
215 // Write the result.
Renato Golin695895c2014-01-14 22:43:43 +0000216 rc = WriteBytes(&Status, 4);
217 assert(rc == 4);
218}
219
220void LLIChildTarget::sendExecutionComplete(int Result) {
221 // Write the message type.
222 uint32_t MsgType = (uint32_t)LLI_ExecutionResult;
223 int rc = WriteBytes(&MsgType, 4);
224 (void)rc;
225 assert(rc == 4);
226
227
228 // Write the data size.
229 uint32_t DataSize = 4;
230 rc = WriteBytes(&DataSize, 4);
231 assert(rc == 4);
232
233 // Write the result.
234 rc = WriteBytes(&Result, 4);
235 assert(rc == 4);
Andrew Kaylorc2ebf3f2013-10-02 17:12:36 +0000236}
237
238#ifdef LLVM_ON_UNIX
Alp Toker632c6cd2014-01-23 22:19:45 +0000239#include "../Unix/RPCChannel.inc"
Andrew Kaylorc2ebf3f2013-10-02 17:12:36 +0000240#endif
241
242#ifdef LLVM_ON_WIN32
Alp Toker632c6cd2014-01-23 22:19:45 +0000243#include "../Windows/RPCChannel.inc"
Andrew Kaylorc2ebf3f2013-10-02 17:12:36 +0000244#endif