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