1 #include "llvm/Config/config.h"
3 #include "../RemoteTargetMessage.h"
12 class LLIChildTarget {
14 ~LLIChildTarget(); // OS-specific destructor
16 LLIMessageType waitForIncomingMessage();
17 void handleMessage(LLIMessageType messageType);
20 // Incoming message handlers
21 void handleAllocateSpace();
22 void handleLoadSection(bool IsCode);
24 void handleTerminate();
26 // Outgoing message handlers
27 void sendChildActive();
28 void sendAllocationResult(uint64_t Addr);
29 void sendLoadComplete();
30 void sendExecutionComplete(uint64_t Result);
32 // OS-specific functions
33 void initializeConnection();
34 int WriteBytes(const void *Data, size_t Size);
35 int ReadBytes(void *Data, size_t Size);
36 uint64_t allocate(uint32_t Alignment, uint32_t Size);
37 void makeSectionExecutable(uint64_t Addr, uint32_t Size);
38 void InvalidateInstructionCache(const void *Addr, size_t Len);
39 void releaseMemory(uint64_t Addr, uint32_t Size);
41 // Store a map of allocated buffers to sizes.
42 typedef std::map<uint64_t, uint32_t> AllocMapType;
43 AllocMapType m_AllocatedBufferMap;
45 // Communication handles (OS-specific)
50 LLIChildTarget ThisChild;
51 ThisChild.initialize();
52 LLIMessageType MsgType;
54 MsgType = ThisChild.waitForIncomingMessage();
55 ThisChild.handleMessage(MsgType);
56 } while (MsgType != LLI_Terminate &&
57 MsgType != LLI_Error);
62 void LLIChildTarget::initialize() {
63 initializeConnection();
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);
103 assert(DataSize == 8);
105 // Read the message arguments.
108 rc = ReadBytes(&Alignment, 4);
110 rc = ReadBytes(&AllocSize, 4);
113 // Allocate the memory.
114 uint64_t Addr = allocate(Alignment, AllocSize);
116 // Send AllocationResult message.
117 sendAllocationResult(Addr);
120 void LLIChildTarget::handleLoadSection(bool IsCode) {
121 // Read the message data size.
123 int rc = ReadBytes(&DataSize, 4);
126 // Read the target load address.
128 rc = ReadBytes(&Addr, 8);
131 size_t BufferSize = DataSize - 8;
133 // FIXME: Verify that this is in allocated space
135 // Read section data into previously allocated buffer
136 rc = ReadBytes((void*)Addr, DataSize - 8);
137 assert(rc == (int)(BufferSize));
139 // If IsCode, mark memory executable
141 makeSectionExecutable(Addr, BufferSize);
143 // Send MarkLoadComplete message.
147 void LLIChildTarget::handleExecute() {
148 // Read the message data size.
150 int rc = ReadBytes(&DataSize, 4);
152 assert(DataSize == 8);
154 // Read the target address.
156 rc = ReadBytes(&Addr, 8);
161 int (*fn)(void) = (int(*)(void))Addr;
164 // Send ExecutionResult message.
165 sendExecutionComplete((int64_t)Result);
168 void LLIChildTarget::handleTerminate() {
169 // Release all allocated memory
170 AllocMapType::iterator Begin = m_AllocatedBufferMap.begin();
171 AllocMapType::iterator End = m_AllocatedBufferMap.end();
172 for (AllocMapType::iterator It = Begin; It != End; ++It) {
173 releaseMemory(It->first, It->second);
175 m_AllocatedBufferMap.clear();
178 // Outgoing message handlers
179 void LLIChildTarget::sendChildActive() {
180 // Write the message type.
181 uint32_t MsgType = (uint32_t)LLI_ChildActive;
182 int rc = WriteBytes(&MsgType, 4);
185 // Write the data size.
186 uint32_t DataSize = 0;
187 rc = WriteBytes(&DataSize, 4);
191 void LLIChildTarget::sendAllocationResult(uint64_t Addr) {
192 // Write the message type.
193 uint32_t MsgType = (uint32_t)LLI_AllocationResult;
194 int rc = WriteBytes(&MsgType, 4);
197 // Write the data size.
198 uint32_t DataSize = 8;
199 rc = WriteBytes(&DataSize, 4);
202 // Write the allocated address.
203 rc = WriteBytes(&Addr, 8);
207 void LLIChildTarget::sendLoadComplete() {
208 // Write the message type.
209 uint32_t MsgType = (uint32_t)LLI_LoadComplete;
210 int rc = WriteBytes(&MsgType, 4);
213 // Write the data size.
214 uint32_t DataSize = 0;
215 rc = WriteBytes(&DataSize, 4);
219 void LLIChildTarget::sendExecutionComplete(uint64_t Result) {
220 // Write the message type.
221 uint32_t MsgType = (uint32_t)LLI_ExecutionResult;
222 int rc = WriteBytes(&MsgType, 4);
226 // Write the data size.
227 uint32_t DataSize = 8;
228 rc = WriteBytes(&DataSize, 4);
232 rc = WriteBytes(&Result, 8);
237 #include "Unix/ChildTarget.inc"
241 #include "Windows/ChildTarget.inc"