blob: 1e3000da46adf5f2b1b3bf1ee65681605f498d8f [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) {
37 return RPC.WriteBytes(Data, Size);
38 }
39 int ReadBytes(void *Data, size_t Size) { return RPC.ReadBytes(Data, Size); }
Andrew Kaylorc2ebf3f2013-10-02 17:12:36 +000040
41 // Communication handles (OS-specific)
42 void *ConnectionData;
43};
44
45int main() {
46 LLIChildTarget ThisChild;
Alp Tokere2641f12014-01-23 11:04:42 +000047 ThisChild.RT = new RemoteTarget();
Andrew Kaylorc2ebf3f2013-10-02 17:12:36 +000048 ThisChild.initialize();
49 LLIMessageType MsgType;
50 do {
51 MsgType = ThisChild.waitForIncomingMessage();
52 ThisChild.handleMessage(MsgType);
53 } while (MsgType != LLI_Terminate &&
54 MsgType != LLI_Error);
Alp Tokere2641f12014-01-23 11:04:42 +000055 delete ThisChild.RT;
Andrew Kaylorc2ebf3f2013-10-02 17:12:36 +000056 return 0;
57}
58
59// Public methods
60void LLIChildTarget::initialize() {
Alp Toker632c6cd2014-01-23 22:19:45 +000061 RPC.createClient();
Andrew Kaylorc2ebf3f2013-10-02 17:12:36 +000062 sendChildActive();
63}
64
65LLIMessageType LLIChildTarget::waitForIncomingMessage() {
66 int32_t MsgType = -1;
67 if (ReadBytes(&MsgType, 4) > 0)
68 return (LLIMessageType)MsgType;
69 return LLI_Error;
70}
71
72void LLIChildTarget::handleMessage(LLIMessageType messageType) {
73 switch (messageType) {
74 case LLI_AllocateSpace:
75 handleAllocateSpace();
76 break;
77 case LLI_LoadCodeSection:
78 handleLoadSection(true);
79 break;
80 case LLI_LoadDataSection:
81 handleLoadSection(false);
82 break;
83 case LLI_Execute:
84 handleExecute();
85 break;
86 case LLI_Terminate:
Alp Tokere2641f12014-01-23 11:04:42 +000087 RT->stop();
Andrew Kaylorc2ebf3f2013-10-02 17:12:36 +000088 break;
89 default:
90 // FIXME: Handle error!
91 break;
92 }
93}
94
95// Incoming message handlers
96void LLIChildTarget::handleAllocateSpace() {
97 // Read and verify the message data size.
98 uint32_t DataSize;
99 int rc = ReadBytes(&DataSize, 4);
Matt Arsenaultc44a3ff2013-12-05 19:37:36 +0000100 (void)rc;
Andrew Kaylorc2ebf3f2013-10-02 17:12:36 +0000101 assert(rc == 4);
102 assert(DataSize == 8);
103
104 // Read the message arguments.
105 uint32_t Alignment;
106 uint32_t AllocSize;
107 rc = ReadBytes(&Alignment, 4);
108 assert(rc == 4);
109 rc = ReadBytes(&AllocSize, 4);
110 assert(rc == 4);
111
112 // Allocate the memory.
Alp Tokere2641f12014-01-23 11:04:42 +0000113 uint64_t Addr;
114 RT->allocateSpace(AllocSize, Alignment, Addr);
Andrew Kaylorc2ebf3f2013-10-02 17:12:36 +0000115
116 // Send AllocationResult message.
117 sendAllocationResult(Addr);
118}
119
120void LLIChildTarget::handleLoadSection(bool IsCode) {
121 // Read the message data size.
122 uint32_t DataSize;
123 int rc = ReadBytes(&DataSize, 4);
Renato Golin695895c2014-01-14 22:43:43 +0000124 (void)rc;
Andrew Kaylorc2ebf3f2013-10-02 17:12:36 +0000125 assert(rc == 4);
126
127 // Read the target load address.
128 uint64_t Addr;
129 rc = ReadBytes(&Addr, 8);
130 assert(rc == 8);
Andrew Kaylorc2ebf3f2013-10-02 17:12:36 +0000131 size_t BufferSize = DataSize - 8;
132
Alp Tokere2641f12014-01-23 11:04:42 +0000133 if (!RT->isAllocatedMemory(Addr, BufferSize))
Renato Golin695895c2014-01-14 22:43:43 +0000134 return sendLoadStatus(LLI_Status_NotAllocated);
Andrew Kaylorc2ebf3f2013-10-02 17:12:36 +0000135
136 // Read section data into previously allocated buffer
Renato Golin695895c2014-01-14 22:43:43 +0000137 rc = ReadBytes((void*)Addr, BufferSize);
138 if (rc != (int)(BufferSize))
139 return sendLoadStatus(LLI_Status_IncompleteMsg);
Andrew Kaylorc2ebf3f2013-10-02 17:12:36 +0000140
141 // If IsCode, mark memory executable
142 if (IsCode)
Alp Tokere2641f12014-01-23 11:04:42 +0000143 sys::Memory::InvalidateInstructionCache((void *)Addr, BufferSize);
Andrew Kaylorc2ebf3f2013-10-02 17:12:36 +0000144
145 // Send MarkLoadComplete message.
Renato Golin695895c2014-01-14 22:43:43 +0000146 sendLoadStatus(LLI_Status_Success);
Andrew Kaylorc2ebf3f2013-10-02 17:12:36 +0000147}
148
149void LLIChildTarget::handleExecute() {
150 // Read the message data size.
151 uint32_t DataSize;
152 int rc = ReadBytes(&DataSize, 4);
Renato Golin695895c2014-01-14 22:43:43 +0000153 (void)rc;
Andrew Kaylorc2ebf3f2013-10-02 17:12:36 +0000154 assert(rc == 4);
155 assert(DataSize == 8);
156
157 // Read the target address.
158 uint64_t Addr;
159 rc = ReadBytes(&Addr, 8);
160 assert(rc == 8);
161
162 // Call function
Alp Tokere2641f12014-01-23 11:04:42 +0000163 int32_t Result = -1;
164 RT->executeCode(Addr, Result);
Andrew Kaylorc2ebf3f2013-10-02 17:12:36 +0000165
166 // Send ExecutionResult message.
Renato Golin695895c2014-01-14 22:43:43 +0000167 sendExecutionComplete(Result);
Andrew Kaylorc2ebf3f2013-10-02 17:12:36 +0000168}
169
Andrew Kaylorc2ebf3f2013-10-02 17:12:36 +0000170// Outgoing message handlers
171void LLIChildTarget::sendChildActive() {
172 // Write the message type.
173 uint32_t MsgType = (uint32_t)LLI_ChildActive;
174 int rc = WriteBytes(&MsgType, 4);
Renato Golin695895c2014-01-14 22:43:43 +0000175 (void)rc;
Andrew Kaylorc2ebf3f2013-10-02 17:12:36 +0000176 assert(rc == 4);
177
178 // Write the data size.
179 uint32_t DataSize = 0;
180 rc = WriteBytes(&DataSize, 4);
181 assert(rc == 4);
182}
183
184void LLIChildTarget::sendAllocationResult(uint64_t Addr) {
185 // Write the message type.
186 uint32_t MsgType = (uint32_t)LLI_AllocationResult;
187 int rc = WriteBytes(&MsgType, 4);
Renato Golin695895c2014-01-14 22:43:43 +0000188 (void)rc;
Andrew Kaylorc2ebf3f2013-10-02 17:12:36 +0000189 assert(rc == 4);
190
191 // Write the data size.
192 uint32_t DataSize = 8;
193 rc = WriteBytes(&DataSize, 4);
194 assert(rc == 4);
195
196 // Write the allocated address.
197 rc = WriteBytes(&Addr, 8);
198 assert(rc == 8);
199}
200
Renato Golin695895c2014-01-14 22:43:43 +0000201void LLIChildTarget::sendLoadStatus(uint32_t Status) {
Andrew Kaylorc2ebf3f2013-10-02 17:12:36 +0000202 // Write the message type.
Renato Golin695895c2014-01-14 22:43:43 +0000203 uint32_t MsgType = (uint32_t)LLI_LoadResult;
Andrew Kaylorc2ebf3f2013-10-02 17:12:36 +0000204 int rc = WriteBytes(&MsgType, 4);
Renato Golin695895c2014-01-14 22:43:43 +0000205 (void)rc;
Andrew Kaylorc2ebf3f2013-10-02 17:12:36 +0000206 assert(rc == 4);
207
208 // Write the data size.
Renato Golin695895c2014-01-14 22:43:43 +0000209 uint32_t DataSize = 4;
Andrew Kaylorc2ebf3f2013-10-02 17:12:36 +0000210 rc = WriteBytes(&DataSize, 4);
211 assert(rc == 4);
212
213 // Write the result.
Renato Golin695895c2014-01-14 22:43:43 +0000214 rc = WriteBytes(&Status, 4);
215 assert(rc == 4);
216}
217
218void LLIChildTarget::sendExecutionComplete(int Result) {
219 // Write the message type.
220 uint32_t MsgType = (uint32_t)LLI_ExecutionResult;
221 int rc = WriteBytes(&MsgType, 4);
222 (void)rc;
223 assert(rc == 4);
224
225
226 // Write the data size.
227 uint32_t DataSize = 4;
228 rc = WriteBytes(&DataSize, 4);
229 assert(rc == 4);
230
231 // Write the result.
232 rc = WriteBytes(&Result, 4);
233 assert(rc == 4);
Andrew Kaylorc2ebf3f2013-10-02 17:12:36 +0000234}
235
236#ifdef LLVM_ON_UNIX
Alp Toker632c6cd2014-01-23 22:19:45 +0000237#include "../Unix/RPCChannel.inc"
Andrew Kaylorc2ebf3f2013-10-02 17:12:36 +0000238#endif
239
240#ifdef LLVM_ON_WIN32
Alp Toker632c6cd2014-01-23 22:19:45 +0000241#include "../Windows/RPCChannel.inc"
Andrew Kaylorc2ebf3f2013-10-02 17:12:36 +0000242#endif