1259698Sdim#include "llvm/Config/config.h" 2259698Sdim 3259698Sdim#include "../RemoteTargetMessage.h" 4259698Sdim#include <assert.h> 5259698Sdim#include <map> 6259698Sdim#include <stdint.h> 7259698Sdim#include <string> 8259698Sdim#include <vector> 9259698Sdim 10259698Sdimusing namespace llvm; 11259698Sdim 12259698Sdimclass LLIChildTarget { 13259698Sdimpublic: 14259698Sdim ~LLIChildTarget(); // OS-specific destructor 15259698Sdim void initialize(); 16259698Sdim LLIMessageType waitForIncomingMessage(); 17259698Sdim void handleMessage(LLIMessageType messageType); 18259698Sdim 19259698Sdimprivate: 20259698Sdim // Incoming message handlers 21259698Sdim void handleAllocateSpace(); 22259698Sdim void handleLoadSection(bool IsCode); 23259698Sdim void handleExecute(); 24259698Sdim void handleTerminate(); 25259698Sdim 26259698Sdim // Outgoing message handlers 27259698Sdim void sendChildActive(); 28259698Sdim void sendAllocationResult(uint64_t Addr); 29259698Sdim void sendLoadComplete(); 30259698Sdim void sendExecutionComplete(uint64_t Result); 31259698Sdim 32259698Sdim // OS-specific functions 33259698Sdim void initializeConnection(); 34259698Sdim int WriteBytes(const void *Data, size_t Size); 35259698Sdim int ReadBytes(void *Data, size_t Size); 36259698Sdim uint64_t allocate(uint32_t Alignment, uint32_t Size); 37259698Sdim void makeSectionExecutable(uint64_t Addr, uint32_t Size); 38259698Sdim void InvalidateInstructionCache(const void *Addr, size_t Len); 39259698Sdim void releaseMemory(uint64_t Addr, uint32_t Size); 40259698Sdim 41259698Sdim // Store a map of allocated buffers to sizes. 42259698Sdim typedef std::map<uint64_t, uint32_t> AllocMapType; 43259698Sdim AllocMapType m_AllocatedBufferMap; 44259698Sdim 45259698Sdim // Communication handles (OS-specific) 46259698Sdim void *ConnectionData; 47259698Sdim}; 48259698Sdim 49259698Sdimint main() { 50259698Sdim LLIChildTarget ThisChild; 51259698Sdim ThisChild.initialize(); 52259698Sdim LLIMessageType MsgType; 53259698Sdim do { 54259698Sdim MsgType = ThisChild.waitForIncomingMessage(); 55259698Sdim ThisChild.handleMessage(MsgType); 56259698Sdim } while (MsgType != LLI_Terminate && 57259698Sdim MsgType != LLI_Error); 58259698Sdim return 0; 59259698Sdim} 60259698Sdim 61259698Sdim// Public methods 62259698Sdimvoid LLIChildTarget::initialize() { 63259698Sdim initializeConnection(); 64259698Sdim sendChildActive(); 65259698Sdim} 66259698Sdim 67259698SdimLLIMessageType LLIChildTarget::waitForIncomingMessage() { 68259698Sdim int32_t MsgType = -1; 69259698Sdim if (ReadBytes(&MsgType, 4) > 0) 70259698Sdim return (LLIMessageType)MsgType; 71259698Sdim return LLI_Error; 72259698Sdim} 73259698Sdim 74259698Sdimvoid LLIChildTarget::handleMessage(LLIMessageType messageType) { 75259698Sdim switch (messageType) { 76259698Sdim case LLI_AllocateSpace: 77259698Sdim handleAllocateSpace(); 78259698Sdim break; 79259698Sdim case LLI_LoadCodeSection: 80259698Sdim handleLoadSection(true); 81259698Sdim break; 82259698Sdim case LLI_LoadDataSection: 83259698Sdim handleLoadSection(false); 84259698Sdim break; 85259698Sdim case LLI_Execute: 86259698Sdim handleExecute(); 87259698Sdim break; 88259698Sdim case LLI_Terminate: 89259698Sdim handleTerminate(); 90259698Sdim break; 91259698Sdim default: 92259698Sdim // FIXME: Handle error! 93259698Sdim break; 94259698Sdim } 95259698Sdim} 96259698Sdim 97259698Sdim// Incoming message handlers 98259698Sdimvoid LLIChildTarget::handleAllocateSpace() { 99259698Sdim // Read and verify the message data size. 100259698Sdim uint32_t DataSize; 101259698Sdim int rc = ReadBytes(&DataSize, 4); 102259698Sdim assert(rc == 4); 103259698Sdim assert(DataSize == 8); 104259698Sdim 105259698Sdim // Read the message arguments. 106259698Sdim uint32_t Alignment; 107259698Sdim uint32_t AllocSize; 108259698Sdim rc = ReadBytes(&Alignment, 4); 109259698Sdim assert(rc == 4); 110259698Sdim rc = ReadBytes(&AllocSize, 4); 111259698Sdim assert(rc == 4); 112259698Sdim 113259698Sdim // Allocate the memory. 114259698Sdim uint64_t Addr = allocate(Alignment, AllocSize); 115259698Sdim 116259698Sdim // Send AllocationResult message. 117259698Sdim sendAllocationResult(Addr); 118259698Sdim} 119259698Sdim 120259698Sdimvoid LLIChildTarget::handleLoadSection(bool IsCode) { 121259698Sdim // Read the message data size. 122259698Sdim uint32_t DataSize; 123259698Sdim int rc = ReadBytes(&DataSize, 4); 124259698Sdim assert(rc == 4); 125259698Sdim 126259698Sdim // Read the target load address. 127259698Sdim uint64_t Addr; 128259698Sdim rc = ReadBytes(&Addr, 8); 129259698Sdim assert(rc == 8); 130259698Sdim 131259698Sdim size_t BufferSize = DataSize - 8; 132259698Sdim 133259698Sdim // FIXME: Verify that this is in allocated space 134259698Sdim 135259698Sdim // Read section data into previously allocated buffer 136259698Sdim rc = ReadBytes((void*)Addr, DataSize - 8); 137259698Sdim assert(rc == (int)(BufferSize)); 138259698Sdim 139259698Sdim // If IsCode, mark memory executable 140259698Sdim if (IsCode) 141259698Sdim makeSectionExecutable(Addr, BufferSize); 142259698Sdim 143259698Sdim // Send MarkLoadComplete message. 144259698Sdim sendLoadComplete(); 145259698Sdim} 146259698Sdim 147259698Sdimvoid LLIChildTarget::handleExecute() { 148259698Sdim // Read the message data size. 149259698Sdim uint32_t DataSize; 150259698Sdim int rc = ReadBytes(&DataSize, 4); 151259698Sdim assert(rc == 4); 152259698Sdim assert(DataSize == 8); 153259698Sdim 154259698Sdim // Read the target address. 155259698Sdim uint64_t Addr; 156259698Sdim rc = ReadBytes(&Addr, 8); 157259698Sdim assert(rc == 8); 158259698Sdim 159259698Sdim // Call function 160259698Sdim int Result; 161259698Sdim int (*fn)(void) = (int(*)(void))Addr; 162259698Sdim Result = fn(); 163259698Sdim 164259698Sdim // Send ExecutionResult message. 165259698Sdim sendExecutionComplete((int64_t)Result); 166259698Sdim} 167259698Sdim 168259698Sdimvoid LLIChildTarget::handleTerminate() { 169259698Sdim // Release all allocated memory 170259698Sdim AllocMapType::iterator Begin = m_AllocatedBufferMap.begin(); 171259698Sdim AllocMapType::iterator End = m_AllocatedBufferMap.end(); 172259698Sdim for (AllocMapType::iterator It = Begin; It != End; ++It) { 173259698Sdim releaseMemory(It->first, It->second); 174259698Sdim } 175259698Sdim m_AllocatedBufferMap.clear(); 176259698Sdim} 177259698Sdim 178259698Sdim// Outgoing message handlers 179259698Sdimvoid LLIChildTarget::sendChildActive() { 180259698Sdim // Write the message type. 181259698Sdim uint32_t MsgType = (uint32_t)LLI_ChildActive; 182259698Sdim int rc = WriteBytes(&MsgType, 4); 183259698Sdim assert(rc == 4); 184259698Sdim 185259698Sdim // Write the data size. 186259698Sdim uint32_t DataSize = 0; 187259698Sdim rc = WriteBytes(&DataSize, 4); 188259698Sdim assert(rc == 4); 189259698Sdim} 190259698Sdim 191259698Sdimvoid LLIChildTarget::sendAllocationResult(uint64_t Addr) { 192259698Sdim // Write the message type. 193259698Sdim uint32_t MsgType = (uint32_t)LLI_AllocationResult; 194259698Sdim int rc = WriteBytes(&MsgType, 4); 195259698Sdim assert(rc == 4); 196259698Sdim 197259698Sdim // Write the data size. 198259698Sdim uint32_t DataSize = 8; 199259698Sdim rc = WriteBytes(&DataSize, 4); 200259698Sdim assert(rc == 4); 201259698Sdim 202259698Sdim // Write the allocated address. 203259698Sdim rc = WriteBytes(&Addr, 8); 204259698Sdim assert(rc == 8); 205259698Sdim} 206259698Sdim 207259698Sdimvoid LLIChildTarget::sendLoadComplete() { 208259698Sdim // Write the message type. 209259698Sdim uint32_t MsgType = (uint32_t)LLI_LoadComplete; 210259698Sdim int rc = WriteBytes(&MsgType, 4); 211259698Sdim assert(rc == 4); 212259698Sdim 213259698Sdim // Write the data size. 214259698Sdim uint32_t DataSize = 0; 215259698Sdim rc = WriteBytes(&DataSize, 4); 216259698Sdim assert(rc == 4); 217259698Sdim} 218259698Sdim 219259698Sdimvoid LLIChildTarget::sendExecutionComplete(uint64_t Result) { 220259698Sdim // Write the message type. 221259698Sdim uint32_t MsgType = (uint32_t)LLI_ExecutionResult; 222259698Sdim int rc = WriteBytes(&MsgType, 4); 223259698Sdim assert(rc == 4); 224259698Sdim 225259698Sdim 226259698Sdim // Write the data size. 227259698Sdim uint32_t DataSize = 8; 228259698Sdim rc = WriteBytes(&DataSize, 4); 229259698Sdim assert(rc == 4); 230259698Sdim 231259698Sdim // Write the result. 232259698Sdim rc = WriteBytes(&Result, 8); 233259698Sdim assert(rc == 8); 234259698Sdim} 235259698Sdim 236259698Sdim#ifdef LLVM_ON_UNIX 237259698Sdim#include "Unix/ChildTarget.inc" 238259698Sdim#endif 239259698Sdim 240259698Sdim#ifdef LLVM_ON_WIN32 241259698Sdim#include "Windows/ChildTarget.inc" 242259698Sdim#endif 243