1 //===---- RemoteTargetExternal.cpp - LLVM out-of-process JIT execution ----===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 // 10 // Implementation of the RemoteTargetExternal class which executes JITed code 11 // in a separate process from where it was built. 12 // 13 //===----------------------------------------------------------------------===// 14 15 #include "llvm/Config/config.h" 16 17 #include "RemoteTarget.h" 18 #include "RemoteTargetExternal.h" 19 20 #include "llvm/ADT/StringRef.h" 21 #include "llvm/Support/DataTypes.h" 22 #include "llvm/Support/Memory.h" 23 #include "llvm/Support/Program.h" 24 #include "llvm/Support/raw_ostream.h" 25 #include <string> 26 27 using namespace llvm; 28 29 bool RemoteTargetExternal::allocateSpace(size_t Size, unsigned Alignment, 30 uint64_t &Address) { 31 SendAllocateSpace(Alignment, Size); 32 Receive(LLI_AllocationResult, Address); 33 return false; 34 } 35 36 bool RemoteTargetExternal::loadData(uint64_t Address, const void *Data, size_t Size) { 37 SendLoadSection(Address, Data, (uint32_t)Size, false); 38 Receive(LLI_LoadComplete); 39 return false; 40 } 41 42 bool RemoteTargetExternal::loadCode(uint64_t Address, const void *Data, size_t Size) { 43 SendLoadSection(Address, Data, (uint32_t)Size, true); 44 Receive(LLI_LoadComplete); 45 return false; 46 } 47 48 bool RemoteTargetExternal::executeCode(uint64_t Address, int &RetVal) { 49 SendExecute(Address); 50 51 Receive(LLI_ExecutionResult, RetVal); 52 return false; 53 } 54 55 void RemoteTargetExternal::stop() { 56 SendTerminate(); 57 Wait(); 58 } 59 60 void RemoteTargetExternal::SendAllocateSpace(uint32_t Alignment, uint32_t Size) { 61 int rc; 62 uint32_t MsgType = (uint32_t)LLI_AllocateSpace; 63 rc = WriteBytes(&MsgType, 4); 64 assert(rc == 4 && "Error writing message type."); 65 66 uint32_t DataSize = 8; 67 rc = WriteBytes(&DataSize, 4); 68 assert(rc == 4 && "Error writing data size."); 69 70 rc = WriteBytes(&Alignment, 4); 71 assert(rc == 4 && "Error writing alignment data."); 72 73 rc = WriteBytes(&Size, 4); 74 assert(rc == 4 && "Error writing size data."); 75 } 76 77 void RemoteTargetExternal::SendLoadSection(uint64_t Addr, 78 const void *Data, 79 uint32_t Size, 80 bool IsCode) { 81 int rc; 82 uint32_t MsgType = IsCode ? LLI_LoadCodeSection : LLI_LoadDataSection; 83 rc = WriteBytes(&MsgType, 4); 84 assert(rc == 4 && "Error writing message type."); 85 86 uint32_t DataSize = Size + 8; 87 rc = WriteBytes(&DataSize, 4); 88 assert(rc == 4 && "Error writing data size."); 89 90 rc = WriteBytes(&Addr, 8); 91 assert(rc == 8 && "Error writing data."); 92 93 rc = WriteBytes(Data, Size); 94 assert(rc == (int)Size && "Error writing data."); 95 } 96 97 void RemoteTargetExternal::SendExecute(uint64_t Addr) { 98 int rc; 99 uint32_t MsgType = (uint32_t)LLI_Execute; 100 rc = WriteBytes(&MsgType, 4); 101 assert(rc == 4 && "Error writing message type."); 102 103 uint32_t DataSize = 8; 104 rc = WriteBytes(&DataSize, 4); 105 assert(rc == 4 && "Error writing data size."); 106 107 rc = WriteBytes(&Addr, 8); 108 assert(rc == 8 && "Error writing data."); 109 } 110 111 void RemoteTargetExternal::SendTerminate() { 112 int rc; 113 uint32_t MsgType = (uint32_t)LLI_Terminate; 114 rc = WriteBytes(&MsgType, 4); 115 assert(rc == 4 && "Error writing message type."); 116 117 // No data or data size is sent with Terminate 118 } 119 120 121 void RemoteTargetExternal::Receive(LLIMessageType ExpectedMsgType) { 122 int rc; 123 uint32_t MsgType; 124 rc = ReadBytes(&MsgType, 4); 125 assert(rc == 4 && "Error reading message type."); 126 assert(MsgType == (uint32_t)ExpectedMsgType && "Error: received unexpected message type."); 127 128 uint32_t DataSize; 129 rc = ReadBytes(&DataSize, 4); 130 assert(rc == 4 && "Error reading data size."); 131 assert(DataSize == 0 && "Error: unexpected data size."); 132 } 133 134 void RemoteTargetExternal::Receive(LLIMessageType ExpectedMsgType, int &Data) { 135 uint64_t Temp; 136 Receive(ExpectedMsgType, Temp); 137 Data = (int)(int64_t)Temp; 138 } 139 140 void RemoteTargetExternal::Receive(LLIMessageType ExpectedMsgType, uint64_t &Data) { 141 int rc; 142 uint32_t MsgType; 143 rc = ReadBytes(&MsgType, 4); 144 assert(rc == 4 && "Error reading message type."); 145 assert(MsgType == (uint32_t)ExpectedMsgType && "Error: received unexpected message type."); 146 147 uint32_t DataSize; 148 rc = ReadBytes(&DataSize, 4); 149 assert(rc == 4 && "Error reading data size."); 150 assert(DataSize == 8 && "Error: unexpected data size."); 151 152 rc = ReadBytes(&Data, 8); 153 assert(DataSize == 8 && "Error: unexpected data."); 154 } 155 156 #ifdef LLVM_ON_UNIX 157 #include "Unix/RemoteTargetExternal.inc" 158 #endif 159 160 #ifdef LLVM_ON_WIN32 161 #include "Windows/RemoteTargetExternal.inc" 162 #endif 163