1259698Sdim//===---- RemoteTargetExternal.cpp - LLVM out-of-process JIT execution ----===// 2259698Sdim// 3259698Sdim// The LLVM Compiler Infrastructure 4259698Sdim// 5259698Sdim// This file is distributed under the University of Illinois Open Source 6259698Sdim// License. See LICENSE.TXT for details. 7259698Sdim// 8259698Sdim//===----------------------------------------------------------------------===// 9259698Sdim// 10259698Sdim// Implementation of the RemoteTargetExternal class which executes JITed code 11259698Sdim// in a separate process from where it was built. 12259698Sdim// 13259698Sdim//===----------------------------------------------------------------------===// 14259698Sdim 15259698Sdim#include "llvm/Config/config.h" 16259698Sdim 17259698Sdim#include "RemoteTarget.h" 18259698Sdim#include "RemoteTargetExternal.h" 19259698Sdim 20259698Sdim#include "llvm/ADT/StringRef.h" 21259698Sdim#include "llvm/Support/DataTypes.h" 22259698Sdim#include "llvm/Support/Memory.h" 23259698Sdim#include "llvm/Support/Program.h" 24259698Sdim#include "llvm/Support/raw_ostream.h" 25259698Sdim#include <string> 26259698Sdim 27259698Sdimusing namespace llvm; 28259698Sdim 29259698Sdimbool RemoteTargetExternal::allocateSpace(size_t Size, unsigned Alignment, 30259698Sdim uint64_t &Address) { 31259698Sdim SendAllocateSpace(Alignment, Size); 32259698Sdim Receive(LLI_AllocationResult, Address); 33259698Sdim return false; 34259698Sdim} 35259698Sdim 36259698Sdimbool RemoteTargetExternal::loadData(uint64_t Address, const void *Data, size_t Size) { 37259698Sdim SendLoadSection(Address, Data, (uint32_t)Size, false); 38259698Sdim Receive(LLI_LoadComplete); 39259698Sdim return false; 40259698Sdim} 41259698Sdim 42259698Sdimbool RemoteTargetExternal::loadCode(uint64_t Address, const void *Data, size_t Size) { 43259698Sdim SendLoadSection(Address, Data, (uint32_t)Size, true); 44259698Sdim Receive(LLI_LoadComplete); 45259698Sdim return false; 46259698Sdim} 47259698Sdim 48259698Sdimbool RemoteTargetExternal::executeCode(uint64_t Address, int &RetVal) { 49259698Sdim SendExecute(Address); 50259698Sdim 51259698Sdim Receive(LLI_ExecutionResult, RetVal); 52259698Sdim return false; 53259698Sdim} 54259698Sdim 55259698Sdimvoid RemoteTargetExternal::stop() { 56259698Sdim SendTerminate(); 57259698Sdim Wait(); 58259698Sdim} 59259698Sdim 60259698Sdimvoid RemoteTargetExternal::SendAllocateSpace(uint32_t Alignment, uint32_t Size) { 61259698Sdim int rc; 62259698Sdim uint32_t MsgType = (uint32_t)LLI_AllocateSpace; 63259698Sdim rc = WriteBytes(&MsgType, 4); 64259698Sdim assert(rc == 4 && "Error writing message type."); 65259698Sdim 66259698Sdim uint32_t DataSize = 8; 67259698Sdim rc = WriteBytes(&DataSize, 4); 68259698Sdim assert(rc == 4 && "Error writing data size."); 69259698Sdim 70259698Sdim rc = WriteBytes(&Alignment, 4); 71259698Sdim assert(rc == 4 && "Error writing alignment data."); 72259698Sdim 73259698Sdim rc = WriteBytes(&Size, 4); 74259698Sdim assert(rc == 4 && "Error writing size data."); 75259698Sdim} 76259698Sdim 77259698Sdimvoid RemoteTargetExternal::SendLoadSection(uint64_t Addr, 78259698Sdim const void *Data, 79259698Sdim uint32_t Size, 80259698Sdim bool IsCode) { 81259698Sdim int rc; 82259698Sdim uint32_t MsgType = IsCode ? LLI_LoadCodeSection : LLI_LoadDataSection; 83259698Sdim rc = WriteBytes(&MsgType, 4); 84259698Sdim assert(rc == 4 && "Error writing message type."); 85259698Sdim 86259698Sdim uint32_t DataSize = Size + 8; 87259698Sdim rc = WriteBytes(&DataSize, 4); 88259698Sdim assert(rc == 4 && "Error writing data size."); 89259698Sdim 90259698Sdim rc = WriteBytes(&Addr, 8); 91259698Sdim assert(rc == 8 && "Error writing data."); 92259698Sdim 93259698Sdim rc = WriteBytes(Data, Size); 94259698Sdim assert(rc == (int)Size && "Error writing data."); 95259698Sdim} 96259698Sdim 97259698Sdimvoid RemoteTargetExternal::SendExecute(uint64_t Addr) { 98259698Sdim int rc; 99259698Sdim uint32_t MsgType = (uint32_t)LLI_Execute; 100259698Sdim rc = WriteBytes(&MsgType, 4); 101259698Sdim assert(rc == 4 && "Error writing message type."); 102259698Sdim 103259698Sdim uint32_t DataSize = 8; 104259698Sdim rc = WriteBytes(&DataSize, 4); 105259698Sdim assert(rc == 4 && "Error writing data size."); 106259698Sdim 107259698Sdim rc = WriteBytes(&Addr, 8); 108259698Sdim assert(rc == 8 && "Error writing data."); 109259698Sdim} 110259698Sdim 111259698Sdimvoid RemoteTargetExternal::SendTerminate() { 112259698Sdim int rc; 113259698Sdim uint32_t MsgType = (uint32_t)LLI_Terminate; 114259698Sdim rc = WriteBytes(&MsgType, 4); 115259698Sdim assert(rc == 4 && "Error writing message type."); 116259698Sdim 117259698Sdim // No data or data size is sent with Terminate 118259698Sdim} 119259698Sdim 120259698Sdim 121259698Sdimvoid RemoteTargetExternal::Receive(LLIMessageType ExpectedMsgType) { 122259698Sdim int rc; 123259698Sdim uint32_t MsgType; 124259698Sdim rc = ReadBytes(&MsgType, 4); 125259698Sdim assert(rc == 4 && "Error reading message type."); 126259698Sdim assert(MsgType == (uint32_t)ExpectedMsgType && "Error: received unexpected message type."); 127259698Sdim 128259698Sdim uint32_t DataSize; 129259698Sdim rc = ReadBytes(&DataSize, 4); 130259698Sdim assert(rc == 4 && "Error reading data size."); 131259698Sdim assert(DataSize == 0 && "Error: unexpected data size."); 132259698Sdim} 133259698Sdim 134259698Sdimvoid RemoteTargetExternal::Receive(LLIMessageType ExpectedMsgType, int &Data) { 135259698Sdim uint64_t Temp; 136259698Sdim Receive(ExpectedMsgType, Temp); 137259698Sdim Data = (int)(int64_t)Temp; 138259698Sdim} 139259698Sdim 140259698Sdimvoid RemoteTargetExternal::Receive(LLIMessageType ExpectedMsgType, uint64_t &Data) { 141259698Sdim int rc; 142259698Sdim uint32_t MsgType; 143259698Sdim rc = ReadBytes(&MsgType, 4); 144259698Sdim assert(rc == 4 && "Error reading message type."); 145259698Sdim assert(MsgType == (uint32_t)ExpectedMsgType && "Error: received unexpected message type."); 146259698Sdim 147259698Sdim uint32_t DataSize; 148259698Sdim rc = ReadBytes(&DataSize, 4); 149259698Sdim assert(rc == 4 && "Error reading data size."); 150259698Sdim assert(DataSize == 8 && "Error: unexpected data size."); 151259698Sdim 152259698Sdim rc = ReadBytes(&Data, 8); 153259698Sdim assert(DataSize == 8 && "Error: unexpected data."); 154259698Sdim} 155259698Sdim 156259698Sdim#ifdef LLVM_ON_UNIX 157259698Sdim#include "Unix/RemoteTargetExternal.inc" 158259698Sdim#endif 159259698Sdim 160259698Sdim#ifdef LLVM_ON_WIN32 161259698Sdim#include "Windows/RemoteTargetExternal.inc" 162259698Sdim#endif 163