1 #include "llvm/Config/config.h"
2 #include "llvm/Support/Memory.h"
3 #include "../RPCChannel.h"
4 #include "../RemoteTarget.h"
5 #include "../RemoteTargetMessage.h"
14 class LLIChildTarget {
17 LLIMessageType waitForIncomingMessage();
18 void handleMessage(LLIMessageType messageType);
23 // Incoming message handlers
24 void handleAllocateSpace();
25 void handleLoadSection(bool IsCode);
28 // Outgoing message handlers
29 void sendChildActive();
30 void sendAllocationResult(uint64_t Addr);
31 void sendLoadStatus(uint32_t Status);
32 void sendExecutionComplete(int Result);
34 // OS-specific functions
35 void initializeConnection();
36 int WriteBytes(const void *Data, size_t Size) {
37 return RPC.WriteBytes(Data, Size) ? Size : -1;
39 int ReadBytes(void *Data, size_t Size) {
40 return RPC.ReadBytes(Data, Size) ? Size : -1;
43 // Communication handles (OS-specific)
48 LLIChildTarget ThisChild;
49 ThisChild.RT = new RemoteTarget();
50 ThisChild.initialize();
51 LLIMessageType MsgType;
53 MsgType = ThisChild.waitForIncomingMessage();
54 ThisChild.handleMessage(MsgType);
55 } while (MsgType != LLI_Terminate &&
56 MsgType != LLI_Error);
62 void LLIChildTarget::initialize() {
67 LLIMessageType LLIChildTarget::waitForIncomingMessage() {
69 if (ReadBytes(&MsgType, 4) > 0)
70 return (LLIMessageType)MsgType;
74 void LLIChildTarget::handleMessage(LLIMessageType messageType) {
75 switch (messageType) {
76 case LLI_AllocateSpace:
77 handleAllocateSpace();
79 case LLI_LoadCodeSection:
80 handleLoadSection(true);
82 case LLI_LoadDataSection:
83 handleLoadSection(false);
92 // FIXME: Handle error!
97 // Incoming message handlers
98 void LLIChildTarget::handleAllocateSpace() {
99 // Read and verify the message data size.
101 int rc = ReadBytes(&DataSize, 4);
104 assert(DataSize == 8);
106 // Read the message arguments.
109 rc = ReadBytes(&Alignment, 4);
111 rc = ReadBytes(&AllocSize, 4);
114 // Allocate the memory.
116 RT->allocateSpace(AllocSize, Alignment, Addr);
118 // Send AllocationResult message.
119 sendAllocationResult(Addr);
122 void LLIChildTarget::handleLoadSection(bool IsCode) {
123 // Read the message data size.
125 int rc = ReadBytes(&DataSize, 4);
129 // Read the target load address.
131 rc = ReadBytes(&Addr, 8);
133 size_t BufferSize = DataSize - 8;
135 if (!RT->isAllocatedMemory(Addr, BufferSize))
136 return sendLoadStatus(LLI_Status_NotAllocated);
138 // Read section data into previously allocated buffer
139 rc = ReadBytes((void*)Addr, BufferSize);
140 if (rc != (int)(BufferSize))
141 return sendLoadStatus(LLI_Status_IncompleteMsg);
143 // If IsCode, mark memory executable
145 sys::Memory::InvalidateInstructionCache((void *)Addr, BufferSize);
147 // Send MarkLoadComplete message.
148 sendLoadStatus(LLI_Status_Success);
151 void LLIChildTarget::handleExecute() {
152 // Read the message data size.
154 int rc = ReadBytes(&DataSize, 4);
157 assert(DataSize == 8);
159 // Read the target address.
161 rc = ReadBytes(&Addr, 8);
166 RT->executeCode(Addr, Result);
168 // Send ExecutionResult message.
169 sendExecutionComplete(Result);
172 // Outgoing message handlers
173 void LLIChildTarget::sendChildActive() {
174 // Write the message type.
175 uint32_t MsgType = (uint32_t)LLI_ChildActive;
176 int rc = WriteBytes(&MsgType, 4);
180 // Write the data size.
181 uint32_t DataSize = 0;
182 rc = WriteBytes(&DataSize, 4);
186 void LLIChildTarget::sendAllocationResult(uint64_t Addr) {
187 // Write the message type.
188 uint32_t MsgType = (uint32_t)LLI_AllocationResult;
189 int rc = WriteBytes(&MsgType, 4);
193 // Write the data size.
194 uint32_t DataSize = 8;
195 rc = WriteBytes(&DataSize, 4);
198 // Write the allocated address.
199 rc = WriteBytes(&Addr, 8);
203 void LLIChildTarget::sendLoadStatus(uint32_t Status) {
204 // Write the message type.
205 uint32_t MsgType = (uint32_t)LLI_LoadResult;
206 int rc = WriteBytes(&MsgType, 4);
210 // Write the data size.
211 uint32_t DataSize = 4;
212 rc = WriteBytes(&DataSize, 4);
216 rc = WriteBytes(&Status, 4);
220 void LLIChildTarget::sendExecutionComplete(int Result) {
221 // Write the message type.
222 uint32_t MsgType = (uint32_t)LLI_ExecutionResult;
223 int rc = WriteBytes(&MsgType, 4);
228 // Write the data size.
229 uint32_t DataSize = 4;
230 rc = WriteBytes(&DataSize, 4);
234 rc = WriteBytes(&Result, 4);
239 #include "../Unix/RPCChannel.inc"
243 #include "../Windows/RPCChannel.inc"