blob: a59209a160c3044bf3b15f889fe46fc13dede745 [file] [log] [blame]
Andrew Kaylorc2ebf3f2013-10-02 17:12:36 +00001#include "llvm/Config/config.h"
2
3#include "../RemoteTargetMessage.h"
4#include <assert.h>
5#include <map>
6#include <stdint.h>
7#include <string>
8#include <vector>
9
10using namespace llvm;
11
12class LLIChildTarget {
13public:
14 void initialize();
15 LLIMessageType waitForIncomingMessage();
16 void handleMessage(LLIMessageType messageType);
17
18private:
19 // Incoming message handlers
20 void handleAllocateSpace();
21 void handleLoadSection(bool IsCode);
22 void handleExecute();
23 void handleTerminate();
24
25 // Outgoing message handlers
26 void sendChildActive();
27 void sendAllocationResult(uint64_t Addr);
28 void sendLoadComplete();
29 void sendExecutionComplete(uint64_t Result);
30
31 // OS-specific functions
32 void initializeConnection();
33 int WriteBytes(const void *Data, size_t Size);
34 int ReadBytes(void *Data, size_t Size);
35 uint64_t allocate(uint32_t Alignment, uint32_t Size);
36 void makeSectionExecutable(uint64_t Addr, uint32_t Size);
37 void InvalidateInstructionCache(const void *Addr, size_t Len);
38 void releaseMemory(uint64_t Addr, uint32_t Size);
39
40 // Store a map of allocated buffers to sizes.
41 typedef std::map<uint64_t, uint32_t> AllocMapType;
42 AllocMapType m_AllocatedBufferMap;
43
44 // Communication handles (OS-specific)
45 void *ConnectionData;
46};
47
48int main() {
49 LLIChildTarget ThisChild;
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 return 0;
58}
59
60// Public methods
61void LLIChildTarget::initialize() {
62 initializeConnection();
63 sendChildActive();
64}
65
66LLIMessageType LLIChildTarget::waitForIncomingMessage() {
67 int32_t MsgType = -1;
68 if (ReadBytes(&MsgType, 4) > 0)
69 return (LLIMessageType)MsgType;
70 return LLI_Error;
71}
72
73void LLIChildTarget::handleMessage(LLIMessageType messageType) {
74 switch (messageType) {
75 case LLI_AllocateSpace:
76 handleAllocateSpace();
77 break;
78 case LLI_LoadCodeSection:
79 handleLoadSection(true);
80 break;
81 case LLI_LoadDataSection:
82 handleLoadSection(false);
83 break;
84 case LLI_Execute:
85 handleExecute();
86 break;
87 case LLI_Terminate:
88 handleTerminate();
89 break;
90 default:
91 // FIXME: Handle error!
92 break;
93 }
94}
95
96// Incoming message handlers
97void LLIChildTarget::handleAllocateSpace() {
98 // Read and verify the message data size.
99 uint32_t DataSize;
100 int rc = ReadBytes(&DataSize, 4);
101 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.
113 uint64_t Addr = allocate(Alignment, AllocSize);
114
115 // Send AllocationResult message.
116 sendAllocationResult(Addr);
117}
118
119void LLIChildTarget::handleLoadSection(bool IsCode) {
120 // Read the message data size.
121 uint32_t DataSize;
122 int rc = ReadBytes(&DataSize, 4);
123 assert(rc == 4);
124
125 // Read the target load address.
126 uint64_t Addr;
127 rc = ReadBytes(&Addr, 8);
128 assert(rc == 8);
129
130 size_t BufferSize = DataSize - 8;
131
132 // FIXME: Verify that this is in allocated space
133
134 // Read section data into previously allocated buffer
135 rc = ReadBytes((void*)Addr, DataSize - 8);
136 assert(rc == (int)(BufferSize));
137
138 // If IsCode, mark memory executable
139 if (IsCode)
140 makeSectionExecutable(Addr, BufferSize);
141
142 // Send MarkLoadComplete message.
143 sendLoadComplete();
144}
145
146void LLIChildTarget::handleExecute() {
147 // Read the message data size.
148 uint32_t DataSize;
149 int rc = ReadBytes(&DataSize, 4);
150 assert(rc == 4);
151 assert(DataSize == 8);
152
153 // Read the target address.
154 uint64_t Addr;
155 rc = ReadBytes(&Addr, 8);
156 assert(rc == 8);
157
158 // Call function
159 int Result;
160 int (*fn)(void) = (int(*)(void))Addr;
161 Result = fn();
162
163 // Send ExecutionResult message.
164 sendExecutionComplete((int64_t)Result);
165}
166
167void LLIChildTarget::handleTerminate() {
168 // Release all allocated memory
169 AllocMapType::iterator Begin = m_AllocatedBufferMap.begin();
170 AllocMapType::iterator End = m_AllocatedBufferMap.end();
171 for (AllocMapType::iterator It = Begin; It != End; ++It) {
172 releaseMemory(It->first, It->second);
173 }
174 m_AllocatedBufferMap.clear();
175}
176
177// Outgoing message handlers
178void LLIChildTarget::sendChildActive() {
179 // Write the message type.
180 uint32_t MsgType = (uint32_t)LLI_ChildActive;
181 int rc = WriteBytes(&MsgType, 4);
182 assert(rc == 4);
183
184 // Write the data size.
185 uint32_t DataSize = 0;
186 rc = WriteBytes(&DataSize, 4);
187 assert(rc == 4);
188}
189
190void LLIChildTarget::sendAllocationResult(uint64_t Addr) {
191 // Write the message type.
192 uint32_t MsgType = (uint32_t)LLI_AllocationResult;
193 int rc = WriteBytes(&MsgType, 4);
194 assert(rc == 4);
195
196 // Write the data size.
197 uint32_t DataSize = 8;
198 rc = WriteBytes(&DataSize, 4);
199 assert(rc == 4);
200
201 // Write the allocated address.
202 rc = WriteBytes(&Addr, 8);
203 assert(rc == 8);
204}
205
206void LLIChildTarget::sendLoadComplete() {
207 // Write the message type.
208 uint32_t MsgType = (uint32_t)LLI_LoadComplete;
209 int rc = WriteBytes(&MsgType, 4);
210 assert(rc == 4);
211
212 // Write the data size.
213 uint32_t DataSize = 0;
214 rc = WriteBytes(&DataSize, 4);
215 assert(rc == 4);
216}
217
218void LLIChildTarget::sendExecutionComplete(uint64_t Result) {
219 // Write the message type.
220 uint32_t MsgType = (uint32_t)LLI_ExecutionResult;
221 int rc = WriteBytes(&MsgType, 4);
222 assert(rc == 4);
223
224
225 // Write the data size.
226 uint32_t DataSize = 8;
227 rc = WriteBytes(&DataSize, 4);
228 assert(rc == 4);
229
230 // Write the result.
231 rc = WriteBytes(&Result, 8);
232 assert(rc == 8);
233}
234
235#ifdef LLVM_ON_UNIX
236#include "Unix/ChildTarget.inc"
237#endif
238
239#ifdef LLVM_ON_WIN32
240#include "Windows/ChildTarget.inc"
241#endif