1#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 ~LLIChildTarget(); // OS-specific destructor 15 void initialize(); 16 LLIMessageType waitForIncomingMessage(); 17 void handleMessage(LLIMessageType messageType); 18 19private: 20 // Incoming message handlers 21 void handleAllocateSpace(); 22 void handleLoadSection(bool IsCode); 23 void handleExecute(); 24 void handleTerminate(); 25 26 // Outgoing message handlers 27 void sendChildActive(); 28 void sendAllocationResult(uint64_t Addr); 29 void sendLoadComplete(); 30 void sendExecutionComplete(uint64_t Result); 31 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); 40 41 // Store a map of allocated buffers to sizes. 42 typedef std::map<uint64_t, uint32_t> AllocMapType; 43 AllocMapType m_AllocatedBufferMap; 44 45 // Communication handles (OS-specific) 46 void *ConnectionData; 47}; 48 49int main() { 50 LLIChildTarget ThisChild; 51 ThisChild.initialize(); 52 LLIMessageType MsgType; 53 do { 54 MsgType = ThisChild.waitForIncomingMessage(); 55 ThisChild.handleMessage(MsgType); 56 } while (MsgType != LLI_Terminate && 57 MsgType != LLI_Error); 58 return 0; 59} 60 61// Public methods 62void LLIChildTarget::initialize() { 63 initializeConnection(); 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 handleTerminate(); 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. 100 uint32_t DataSize; 101 int rc = ReadBytes(&DataSize, 4); 102 assert(rc == 4); 103 assert(DataSize == 8); 104 105 // Read the message arguments. 106 uint32_t Alignment; 107 uint32_t AllocSize; 108 rc = ReadBytes(&Alignment, 4); 109 assert(rc == 4); 110 rc = ReadBytes(&AllocSize, 4); 111 assert(rc == 4); 112 113 // Allocate the memory. 114 uint64_t Addr = allocate(Alignment, AllocSize); 115 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); 124 assert(rc == 4); 125 126 // Read the target load address. 127 uint64_t Addr; 128 rc = ReadBytes(&Addr, 8); 129 assert(rc == 8); 130 131 size_t BufferSize = DataSize - 8; 132 133 // FIXME: Verify that this is in allocated space 134 135 // Read section data into previously allocated buffer 136 rc = ReadBytes((void*)Addr, DataSize - 8); 137 assert(rc == (int)(BufferSize)); 138 139 // If IsCode, mark memory executable 140 if (IsCode) 141 makeSectionExecutable(Addr, BufferSize); 142 143 // Send MarkLoadComplete message. 144 sendLoadComplete(); 145} 146 147void LLIChildTarget::handleExecute() { 148 // Read the message data size. 149 uint32_t DataSize; 150 int rc = ReadBytes(&DataSize, 4); 151 assert(rc == 4); 152 assert(DataSize == 8); 153 154 // Read the target address. 155 uint64_t Addr; 156 rc = ReadBytes(&Addr, 8); 157 assert(rc == 8); 158 159 // Call function 160 int Result; 161 int (*fn)(void) = (int(*)(void))Addr; 162 Result = fn(); 163 164 // Send ExecutionResult message. 165 sendExecutionComplete((int64_t)Result); 166} 167 168void 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); 174 } 175 m_AllocatedBufferMap.clear(); 176} 177 178// Outgoing message handlers 179void LLIChildTarget::sendChildActive() { 180 // Write the message type. 181 uint32_t MsgType = (uint32_t)LLI_ChildActive; 182 int rc = WriteBytes(&MsgType, 4); 183 assert(rc == 4); 184 185 // Write the data size. 186 uint32_t DataSize = 0; 187 rc = WriteBytes(&DataSize, 4); 188 assert(rc == 4); 189} 190 191void LLIChildTarget::sendAllocationResult(uint64_t Addr) { 192 // Write the message type. 193 uint32_t MsgType = (uint32_t)LLI_AllocationResult; 194 int rc = WriteBytes(&MsgType, 4); 195 assert(rc == 4); 196 197 // Write the data size. 198 uint32_t DataSize = 8; 199 rc = WriteBytes(&DataSize, 4); 200 assert(rc == 4); 201 202 // Write the allocated address. 203 rc = WriteBytes(&Addr, 8); 204 assert(rc == 8); 205} 206 207void LLIChildTarget::sendLoadComplete() { 208 // Write the message type. 209 uint32_t MsgType = (uint32_t)LLI_LoadComplete; 210 int rc = WriteBytes(&MsgType, 4); 211 assert(rc == 4); 212 213 // Write the data size. 214 uint32_t DataSize = 0; 215 rc = WriteBytes(&DataSize, 4); 216 assert(rc == 4); 217} 218 219void LLIChildTarget::sendExecutionComplete(uint64_t Result) { 220 // Write the message type. 221 uint32_t MsgType = (uint32_t)LLI_ExecutionResult; 222 int rc = WriteBytes(&MsgType, 4); 223 assert(rc == 4); 224 225 226 // Write the data size. 227 uint32_t DataSize = 8; 228 rc = WriteBytes(&DataSize, 4); 229 assert(rc == 4); 230 231 // Write the result. 232 rc = WriteBytes(&Result, 8); 233 assert(rc == 8); 234} 235 236#ifdef LLVM_ON_UNIX 237#include "Unix/ChildTarget.inc" 238#endif 239 240#ifdef LLVM_ON_WIN32 241#include "Windows/ChildTarget.inc" 242#endif 243