10ab5c6c16b1b09d76c3ba2d70443b10bcc26169cAndrew Kaylor//===----- RemoteTargetExternal.h - LLVM out-of-process JIT execution -----===// 20ab5c6c16b1b09d76c3ba2d70443b10bcc26169cAndrew Kaylor// 30ab5c6c16b1b09d76c3ba2d70443b10bcc26169cAndrew Kaylor// The LLVM Compiler Infrastructure 40ab5c6c16b1b09d76c3ba2d70443b10bcc26169cAndrew Kaylor// 50ab5c6c16b1b09d76c3ba2d70443b10bcc26169cAndrew Kaylor// This file is distributed under the University of Illinois Open Source 60ab5c6c16b1b09d76c3ba2d70443b10bcc26169cAndrew Kaylor// License. See LICENSE.TXT for details. 70ab5c6c16b1b09d76c3ba2d70443b10bcc26169cAndrew Kaylor// 80ab5c6c16b1b09d76c3ba2d70443b10bcc26169cAndrew Kaylor//===----------------------------------------------------------------------===// 90ab5c6c16b1b09d76c3ba2d70443b10bcc26169cAndrew Kaylor// 100ab5c6c16b1b09d76c3ba2d70443b10bcc26169cAndrew Kaylor// Definition of the RemoteTargetExternal class which executes JITed code in a 110ab5c6c16b1b09d76c3ba2d70443b10bcc26169cAndrew Kaylor// separate process from where it was built. 120ab5c6c16b1b09d76c3ba2d70443b10bcc26169cAndrew Kaylor// 130ab5c6c16b1b09d76c3ba2d70443b10bcc26169cAndrew Kaylor//===----------------------------------------------------------------------===// 140ab5c6c16b1b09d76c3ba2d70443b10bcc26169cAndrew Kaylor 150ab5c6c16b1b09d76c3ba2d70443b10bcc26169cAndrew Kaylor#ifndef LLI_REMOTETARGETEXTERNAL_H 160ab5c6c16b1b09d76c3ba2d70443b10bcc26169cAndrew Kaylor#define LLI_REMOTETARGETEXTERNAL_H 170ab5c6c16b1b09d76c3ba2d70443b10bcc26169cAndrew Kaylor 1836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "RPCChannel.h" 1936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "RemoteTarget.h" 2036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "RemoteTargetMessage.h" 210ab5c6c16b1b09d76c3ba2d70443b10bcc26169cAndrew Kaylor#include "llvm/ADT/SmallVector.h" 220ab5c6c16b1b09d76c3ba2d70443b10bcc26169cAndrew Kaylor#include "llvm/ADT/StringRef.h" 2336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "llvm/Config/config.h" 240ab5c6c16b1b09d76c3ba2d70443b10bcc26169cAndrew Kaylor#include "llvm/Support/DataTypes.h" 250ab5c6c16b1b09d76c3ba2d70443b10bcc26169cAndrew Kaylor#include "llvm/Support/Memory.h" 260ab5c6c16b1b09d76c3ba2d70443b10bcc26169cAndrew Kaylor#include <stdlib.h> 270ab5c6c16b1b09d76c3ba2d70443b10bcc26169cAndrew Kaylor#include <string> 280ab5c6c16b1b09d76c3ba2d70443b10bcc26169cAndrew Kaylor 290ab5c6c16b1b09d76c3ba2d70443b10bcc26169cAndrew Kaylornamespace llvm { 300ab5c6c16b1b09d76c3ba2d70443b10bcc26169cAndrew Kaylor 310ab5c6c16b1b09d76c3ba2d70443b10bcc26169cAndrew Kaylorclass RemoteTargetExternal : public RemoteTarget { 3236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines RPCChannel RPC; 3336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 3436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines bool WriteBytes(const void *Data, size_t Size) { 3536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return RPC.WriteBytes(Data, Size); 3636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 3736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 3836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines bool ReadBytes(void *Data, size_t Size) { return RPC.ReadBytes(Data, Size); } 3936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 400ab5c6c16b1b09d76c3ba2d70443b10bcc26169cAndrew Kaylorpublic: 410ab5c6c16b1b09d76c3ba2d70443b10bcc26169cAndrew Kaylor /// Allocate space in the remote target address space. 420ab5c6c16b1b09d76c3ba2d70443b10bcc26169cAndrew Kaylor /// 430ab5c6c16b1b09d76c3ba2d70443b10bcc26169cAndrew Kaylor /// @param Size Amount of space, in bytes, to allocate. 440ab5c6c16b1b09d76c3ba2d70443b10bcc26169cAndrew Kaylor /// @param Alignment Required minimum alignment for allocated space. 450ab5c6c16b1b09d76c3ba2d70443b10bcc26169cAndrew Kaylor /// @param[out] Address Remote address of the allocated memory. 460ab5c6c16b1b09d76c3ba2d70443b10bcc26169cAndrew Kaylor /// 4736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines /// @returns True on success. On failure, ErrorMsg is updated with 480ab5c6c16b1b09d76c3ba2d70443b10bcc26169cAndrew Kaylor /// descriptive text of the encountered error. 4936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines bool allocateSpace(size_t Size, unsigned Alignment, 5036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines uint64_t &Address) override; 510ab5c6c16b1b09d76c3ba2d70443b10bcc26169cAndrew Kaylor 520ab5c6c16b1b09d76c3ba2d70443b10bcc26169cAndrew Kaylor /// Load data into the target address space. 530ab5c6c16b1b09d76c3ba2d70443b10bcc26169cAndrew Kaylor /// 540ab5c6c16b1b09d76c3ba2d70443b10bcc26169cAndrew Kaylor /// @param Address Destination address in the target process. 550ab5c6c16b1b09d76c3ba2d70443b10bcc26169cAndrew Kaylor /// @param Data Source address in the host process. 560ab5c6c16b1b09d76c3ba2d70443b10bcc26169cAndrew Kaylor /// @param Size Number of bytes to copy. 570ab5c6c16b1b09d76c3ba2d70443b10bcc26169cAndrew Kaylor /// 5836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines /// @returns True on success. On failure, ErrorMsg is updated with 590ab5c6c16b1b09d76c3ba2d70443b10bcc26169cAndrew Kaylor /// descriptive text of the encountered error. 6036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines bool loadData(uint64_t Address, const void *Data, size_t Size) override; 610ab5c6c16b1b09d76c3ba2d70443b10bcc26169cAndrew Kaylor 620ab5c6c16b1b09d76c3ba2d70443b10bcc26169cAndrew Kaylor /// Load code into the target address space and prepare it for execution. 630ab5c6c16b1b09d76c3ba2d70443b10bcc26169cAndrew Kaylor /// 640ab5c6c16b1b09d76c3ba2d70443b10bcc26169cAndrew Kaylor /// @param Address Destination address in the target process. 650ab5c6c16b1b09d76c3ba2d70443b10bcc26169cAndrew Kaylor /// @param Data Source address in the host process. 660ab5c6c16b1b09d76c3ba2d70443b10bcc26169cAndrew Kaylor /// @param Size Number of bytes to copy. 670ab5c6c16b1b09d76c3ba2d70443b10bcc26169cAndrew Kaylor /// 6836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines /// @returns True on success. On failure, ErrorMsg is updated with 690ab5c6c16b1b09d76c3ba2d70443b10bcc26169cAndrew Kaylor /// descriptive text of the encountered error. 7036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines bool loadCode(uint64_t Address, const void *Data, size_t Size) override; 710ab5c6c16b1b09d76c3ba2d70443b10bcc26169cAndrew Kaylor 720ab5c6c16b1b09d76c3ba2d70443b10bcc26169cAndrew Kaylor /// Execute code in the target process. The called function is required 730ab5c6c16b1b09d76c3ba2d70443b10bcc26169cAndrew Kaylor /// to be of signature int "(*)(void)". 740ab5c6c16b1b09d76c3ba2d70443b10bcc26169cAndrew Kaylor /// 750ab5c6c16b1b09d76c3ba2d70443b10bcc26169cAndrew Kaylor /// @param Address Address of the loaded function in the target 760ab5c6c16b1b09d76c3ba2d70443b10bcc26169cAndrew Kaylor /// process. 770ab5c6c16b1b09d76c3ba2d70443b10bcc26169cAndrew Kaylor /// @param[out] RetVal The integer return value of the called function. 780ab5c6c16b1b09d76c3ba2d70443b10bcc26169cAndrew Kaylor /// 7936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines /// @returns True on success. On failure, ErrorMsg is updated with 800ab5c6c16b1b09d76c3ba2d70443b10bcc26169cAndrew Kaylor /// descriptive text of the encountered error. 8136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines bool executeCode(uint64_t Address, int &RetVal) override; 820ab5c6c16b1b09d76c3ba2d70443b10bcc26169cAndrew Kaylor 8336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines /// Minimum alignment for memory permissions. Used to separate code and 840ab5c6c16b1b09d76c3ba2d70443b10bcc26169cAndrew Kaylor /// data regions to make sure data doesn't get marked as code or vice 850ab5c6c16b1b09d76c3ba2d70443b10bcc26169cAndrew Kaylor /// versa. 860ab5c6c16b1b09d76c3ba2d70443b10bcc26169cAndrew Kaylor /// 870ab5c6c16b1b09d76c3ba2d70443b10bcc26169cAndrew Kaylor /// @returns Page alignment return value. Default of 4k. 8836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines unsigned getPageAlignment() override { return 4096; } 8936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 9036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines bool create() override { 9136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines RPC.ChildName = ChildName; 9236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (!RPC.createServer()) 9336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return true; 940ab5c6c16b1b09d76c3ba2d70443b10bcc26169cAndrew Kaylor 9536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // We must get Ack from the client (blocking read) 9636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (!Receive(LLI_ChildActive)) { 9736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines ErrorMsg += ", (RPCChannel::create) - Stopping process!"; 9836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines stop(); 9936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return false; 10036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 10136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 10236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return true; 10336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 1040ab5c6c16b1b09d76c3ba2d70443b10bcc26169cAndrew Kaylor 1050ab5c6c16b1b09d76c3ba2d70443b10bcc26169cAndrew Kaylor /// Terminate the remote process. 10636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines void stop() override; 1070ab5c6c16b1b09d76c3ba2d70443b10bcc26169cAndrew Kaylor 1080ab5c6c16b1b09d76c3ba2d70443b10bcc26169cAndrew Kaylor RemoteTargetExternal(std::string &Name) : RemoteTarget(), ChildName(Name) {} 10936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines virtual ~RemoteTargetExternal() {} 1100ab5c6c16b1b09d76c3ba2d70443b10bcc26169cAndrew Kaylor 1110ab5c6c16b1b09d76c3ba2d70443b10bcc26169cAndrew Kaylorprivate: 1120ab5c6c16b1b09d76c3ba2d70443b10bcc26169cAndrew Kaylor std::string ChildName; 1130ab5c6c16b1b09d76c3ba2d70443b10bcc26169cAndrew Kaylor 11436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines bool SendAllocateSpace(uint32_t Alignment, uint32_t Size); 11536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines bool SendLoadSection(uint64_t Addr, 1160ab5c6c16b1b09d76c3ba2d70443b10bcc26169cAndrew Kaylor const void *Data, 1170ab5c6c16b1b09d76c3ba2d70443b10bcc26169cAndrew Kaylor uint32_t Size, 1180ab5c6c16b1b09d76c3ba2d70443b10bcc26169cAndrew Kaylor bool IsCode); 11936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines bool SendExecute(uint64_t Addr); 12036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines bool SendTerminate(); 12136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 12236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // High-level wrappers for receiving data 12336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines bool Receive(LLIMessageType Msg); 12436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines bool Receive(LLIMessageType Msg, int32_t &Data); 12536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines bool Receive(LLIMessageType Msg, uint64_t &Data); 12636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 12736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // Lower level target-independent read/write to deal with errors 12836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines bool ReceiveHeader(LLIMessageType Msg); 12936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines bool ReceivePayload(); 13036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines bool SendHeader(LLIMessageType Msg); 13136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines bool SendPayload(); 13236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 13336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // Functions to append/retrieve data from the payload 13436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines SmallVector<const void *, 2> SendData; 13536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines SmallVector<void *, 1> ReceiveData; // Future proof 13636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines SmallVector<int, 2> Sizes; 13736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines void AppendWrite(const void *Data, uint32_t Size); 13836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines void AppendRead(void *Data, uint32_t Size); 1390ab5c6c16b1b09d76c3ba2d70443b10bcc26169cAndrew Kaylor}; 1400ab5c6c16b1b09d76c3ba2d70443b10bcc26169cAndrew Kaylor 1410ab5c6c16b1b09d76c3ba2d70443b10bcc26169cAndrew Kaylor} // end namespace llvm 1420ab5c6c16b1b09d76c3ba2d70443b10bcc26169cAndrew Kaylor 1430ab5c6c16b1b09d76c3ba2d70443b10bcc26169cAndrew Kaylor#endif // LLI_REMOTETARGETEXTERNAL_H 144