1 //===----- RemoteTargetExternal.h - 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 // Definition of the RemoteTargetExternal class which executes JITed code in a 11 // separate process from where it was built. 12 // 13 //===----------------------------------------------------------------------===// 14 15 #ifndef LLVM_TOOLS_LLI_REMOTETARGETEXTERNAL_H 16 #define LLVM_TOOLS_LLI_REMOTETARGETEXTERNAL_H 17 18 #include "RPCChannel.h" 19 #include "RemoteTarget.h" 20 #include "RemoteTargetMessage.h" 21 #include "llvm/ADT/SmallVector.h" 22 #include "llvm/ADT/StringRef.h" 23 #include "llvm/Config/config.h" 24 #include "llvm/Support/DataTypes.h" 25 #include "llvm/Support/Memory.h" 26 #include <stdlib.h> 27 #include <string> 28 29 namespace llvm { 30 31 class RemoteTargetExternal : public RemoteTarget { 32 RPCChannel RPC; 33 34 bool WriteBytes(const void *Data, size_t Size) { 35 return RPC.WriteBytes(Data, Size); 36 } 37 38 bool ReadBytes(void *Data, size_t Size) { return RPC.ReadBytes(Data, Size); } 39 40 public: 41 /// Allocate space in the remote target address space. 42 /// 43 /// @param Size Amount of space, in bytes, to allocate. 44 /// @param Alignment Required minimum alignment for allocated space. 45 /// @param[out] Address Remote address of the allocated memory. 46 /// 47 /// @returns True on success. On failure, ErrorMsg is updated with 48 /// descriptive text of the encountered error. 49 bool allocateSpace(size_t Size, unsigned Alignment, 50 uint64_t &Address) override; 51 52 /// Load data into the target address space. 53 /// 54 /// @param Address Destination address in the target process. 55 /// @param Data Source address in the host process. 56 /// @param Size Number of bytes to copy. 57 /// 58 /// @returns True on success. On failure, ErrorMsg is updated with 59 /// descriptive text of the encountered error. 60 bool loadData(uint64_t Address, const void *Data, size_t Size) override; 61 62 /// Load code into the target address space and prepare it for execution. 63 /// 64 /// @param Address Destination address in the target process. 65 /// @param Data Source address in the host process. 66 /// @param Size Number of bytes to copy. 67 /// 68 /// @returns True on success. On failure, ErrorMsg is updated with 69 /// descriptive text of the encountered error. 70 bool loadCode(uint64_t Address, const void *Data, size_t Size) override; 71 72 /// Execute code in the target process. The called function is required 73 /// to be of signature int "(*)(void)". 74 /// 75 /// @param Address Address of the loaded function in the target 76 /// process. 77 /// @param[out] RetVal The integer return value of the called function. 78 /// 79 /// @returns True on success. On failure, ErrorMsg is updated with 80 /// descriptive text of the encountered error. 81 bool executeCode(uint64_t Address, int &RetVal) override; 82 83 /// Minimum alignment for memory permissions. Used to separate code and 84 /// data regions to make sure data doesn't get marked as code or vice 85 /// versa. 86 /// 87 /// @returns Page alignment return value. Default of 4k. 88 unsigned getPageAlignment() override { return 4096; } 89 90 bool create() override { 91 RPC.ChildName = ChildName; 92 if (!RPC.createServer()) 93 return true; 94 95 // We must get Ack from the client (blocking read) 96 if (!Receive(LLI_ChildActive)) { 97 ErrorMsg += ", (RPCChannel::create) - Stopping process!"; 98 stop(); 99 return false; 100 } 101 102 return true; 103 } 104 105 /// Terminate the remote process. 106 void stop() override; 107 108 RemoteTargetExternal(std::string &Name) : RemoteTarget(), ChildName(Name) {} 109 ~RemoteTargetExternal() override {} 110 111 private: 112 std::string ChildName; 113 114 bool SendAllocateSpace(uint32_t Alignment, uint32_t Size); 115 bool SendLoadSection(uint64_t Addr, 116 const void *Data, 117 uint32_t Size, 118 bool IsCode); 119 bool SendExecute(uint64_t Addr); 120 bool SendTerminate(); 121 122 // High-level wrappers for receiving data 123 bool Receive(LLIMessageType Msg); 124 bool Receive(LLIMessageType Msg, int32_t &Data); 125 bool Receive(LLIMessageType Msg, uint64_t &Data); 126 127 // Lower level target-independent read/write to deal with errors 128 bool ReceiveHeader(LLIMessageType Msg); 129 bool ReceivePayload(); 130 bool SendHeader(LLIMessageType Msg); 131 bool SendPayload(); 132 133 // Functions to append/retrieve data from the payload 134 SmallVector<const void *, 2> SendData; 135 SmallVector<void *, 1> ReceiveData; // Future proof 136 SmallVector<int, 2> Sizes; 137 void AppendWrite(const void *Data, uint32_t Size); 138 void AppendRead(void *Data, uint32_t Size); 139 }; 140 141 } // end namespace llvm 142 143 #endif 144