]> git.proxmox.com Git - rustc.git/blame - src/llvm/tools/lli/ChildTarget/ChildTarget.cpp
Imported Upstream version 1.0.0+dfsg1
[rustc.git] / src / llvm / tools / lli / ChildTarget / ChildTarget.cpp
CommitLineData
1a4d82fc
JJ
1#include "llvm/Config/config.h"
2#include "../RPCChannel.h"
3#include "../RemoteTarget.h"
4#include "../RemoteTargetMessage.h"
5#include "llvm/Support/Memory.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:
16 void initialize();
17 LLIMessageType waitForIncomingMessage();
18 void handleMessage(LLIMessageType messageType);
19 RemoteTarget *RT;
20 RPCChannel RPC;
21
22private:
23 // Incoming message handlers
24 void handleAllocateSpace();
25 void handleLoadSection(bool IsCode);
26 void handleExecute();
27
28 // Outgoing message handlers
29 void sendChildActive();
30 void sendAllocationResult(uint64_t Addr);
31 void sendLoadStatus(uint32_t Status);
32 void sendExecutionComplete(int Result);
33
34 // OS-specific functions
35 void initializeConnection();
36 int WriteBytes(const void *Data, size_t Size) {
37 return RPC.WriteBytes(Data, Size) ? Size : -1;
38 }
39 int ReadBytes(void *Data, size_t Size) {
40 return RPC.ReadBytes(Data, Size) ? Size : -1;
41 }
42
43 // Communication handles (OS-specific)
44 void *ConnectionData;
45};
46
47int main() {
48 LLIChildTarget ThisChild;
49 ThisChild.RT = new RemoteTarget();
50 ThisChild.initialize();
51 LLIMessageType MsgType;
52 do {
53 MsgType = ThisChild.waitForIncomingMessage();
54 ThisChild.handleMessage(MsgType);
55 } while (MsgType != LLI_Terminate &&
56 MsgType != LLI_Error);
57 delete ThisChild.RT;
58 return 0;
59}
60
61// Public methods
62void LLIChildTarget::initialize() {
63 RPC.createClient();
64 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:
89 RT->stop();
90 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.
85aaf69f 100 uint32_t DataSize = 0;
1a4d82fc
JJ
101 int rc = ReadBytes(&DataSize, 4);
102 (void)rc;
103 assert(rc == 4);
104 assert(DataSize == 8);
105
106 // Read the message arguments.
85aaf69f
SL
107 uint32_t Alignment = 0;
108 uint32_t AllocSize = 0;
1a4d82fc
JJ
109 rc = ReadBytes(&Alignment, 4);
110 assert(rc == 4);
111 rc = ReadBytes(&AllocSize, 4);
112 assert(rc == 4);
113
114 // Allocate the memory.
115 uint64_t Addr;
116 RT->allocateSpace(AllocSize, Alignment, Addr);
117
118 // Send AllocationResult message.
119 sendAllocationResult(Addr);
120}
121
122void LLIChildTarget::handleLoadSection(bool IsCode) {
123 // Read the message data size.
85aaf69f 124 uint32_t DataSize = 0;
1a4d82fc
JJ
125 int rc = ReadBytes(&DataSize, 4);
126 (void)rc;
127 assert(rc == 4);
128
129 // Read the target load address.
85aaf69f 130 uint64_t Addr = 0;
1a4d82fc
JJ
131 rc = ReadBytes(&Addr, 8);
132 assert(rc == 8);
133 size_t BufferSize = DataSize - 8;
134
135 if (!RT->isAllocatedMemory(Addr, BufferSize))
136 return sendLoadStatus(LLI_Status_NotAllocated);
137
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);
142
143 // If IsCode, mark memory executable
144 if (IsCode)
145 sys::Memory::InvalidateInstructionCache((void *)Addr, BufferSize);
146
147 // Send MarkLoadComplete message.
148 sendLoadStatus(LLI_Status_Success);
149}
150
151void LLIChildTarget::handleExecute() {
152 // Read the message data size.
85aaf69f 153 uint32_t DataSize = 0;
1a4d82fc
JJ
154 int rc = ReadBytes(&DataSize, 4);
155 (void)rc;
156 assert(rc == 4);
157 assert(DataSize == 8);
158
159 // Read the target address.
85aaf69f 160 uint64_t Addr = 0;
1a4d82fc
JJ
161 rc = ReadBytes(&Addr, 8);
162 assert(rc == 8);
163
164 // Call function
165 int32_t Result = -1;
166 RT->executeCode(Addr, Result);
167
168 // Send ExecutionResult message.
169 sendExecutionComplete(Result);
170}
171
172// 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);
177 (void)rc;
178 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);
190 (void)rc;
191 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
203void LLIChildTarget::sendLoadStatus(uint32_t Status) {
204 // Write the message type.
205 uint32_t MsgType = (uint32_t)LLI_LoadResult;
206 int rc = WriteBytes(&MsgType, 4);
207 (void)rc;
208 assert(rc == 4);
209
210 // Write the data size.
211 uint32_t DataSize = 4;
212 rc = WriteBytes(&DataSize, 4);
213 assert(rc == 4);
214
215 // Write the result.
216 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);
236}
237
238#ifdef LLVM_ON_UNIX
239#include "../Unix/RPCChannel.inc"
240#endif
241
242#ifdef LLVM_ON_WIN32
243#include "../Windows/RPCChannel.inc"
244#endif