1706f03a35db7029b2dbd2925552eb0d0472dcbb4Jim Grosbach//===- RemoteTarget.h - LLVM Remote process JIT execution ----------------===//
2706f03a35db7029b2dbd2925552eb0d0472dcbb4Jim Grosbach//
3706f03a35db7029b2dbd2925552eb0d0472dcbb4Jim Grosbach//                     The LLVM Compiler Infrastructure
4706f03a35db7029b2dbd2925552eb0d0472dcbb4Jim Grosbach//
5706f03a35db7029b2dbd2925552eb0d0472dcbb4Jim Grosbach// This file is distributed under the University of Illinois Open Source
6706f03a35db7029b2dbd2925552eb0d0472dcbb4Jim Grosbach// License. See LICENSE.TXT for details.
7706f03a35db7029b2dbd2925552eb0d0472dcbb4Jim Grosbach//
8706f03a35db7029b2dbd2925552eb0d0472dcbb4Jim Grosbach//===----------------------------------------------------------------------===//
9706f03a35db7029b2dbd2925552eb0d0472dcbb4Jim Grosbach//
10706f03a35db7029b2dbd2925552eb0d0472dcbb4Jim Grosbach// Definition of the RemoteTarget class which executes JITed code in a
11706f03a35db7029b2dbd2925552eb0d0472dcbb4Jim Grosbach// separate address range from where it was built.
12706f03a35db7029b2dbd2925552eb0d0472dcbb4Jim Grosbach//
13706f03a35db7029b2dbd2925552eb0d0472dcbb4Jim Grosbach//===----------------------------------------------------------------------===//
14706f03a35db7029b2dbd2925552eb0d0472dcbb4Jim Grosbach
15706f03a35db7029b2dbd2925552eb0d0472dcbb4Jim Grosbach#ifndef REMOTEPROCESS_H
16706f03a35db7029b2dbd2925552eb0d0472dcbb4Jim Grosbach#define REMOTEPROCESS_H
17706f03a35db7029b2dbd2925552eb0d0472dcbb4Jim Grosbach
18dbf545719a22bf03403c1d0137ae0f5726f36de3Craig Topper#include "llvm/ADT/SmallVector.h"
19f010c464a11444733ec67e31aace8bcebeaf2588Chandler Carruth#include "llvm/ADT/StringRef.h"
20dbf545719a22bf03403c1d0137ae0f5726f36de3Craig Topper#include "llvm/Support/DataTypes.h"
21dbf545719a22bf03403c1d0137ae0f5726f36de3Craig Topper#include "llvm/Support/Memory.h"
22706f03a35db7029b2dbd2925552eb0d0472dcbb4Jim Grosbach#include <stdlib.h>
23706f03a35db7029b2dbd2925552eb0d0472dcbb4Jim Grosbach#include <string>
24706f03a35db7029b2dbd2925552eb0d0472dcbb4Jim Grosbach
25706f03a35db7029b2dbd2925552eb0d0472dcbb4Jim Grosbachnamespace llvm {
26706f03a35db7029b2dbd2925552eb0d0472dcbb4Jim Grosbach
27706f03a35db7029b2dbd2925552eb0d0472dcbb4Jim Grosbachclass RemoteTarget {
28706f03a35db7029b2dbd2925552eb0d0472dcbb4Jim Grosbach  std::string ErrorMsg;
29706f03a35db7029b2dbd2925552eb0d0472dcbb4Jim Grosbach  bool IsRunning;
30706f03a35db7029b2dbd2925552eb0d0472dcbb4Jim Grosbach
31706f03a35db7029b2dbd2925552eb0d0472dcbb4Jim Grosbach  SmallVector<sys::MemoryBlock, 16> Allocations;
32706f03a35db7029b2dbd2925552eb0d0472dcbb4Jim Grosbach
33706f03a35db7029b2dbd2925552eb0d0472dcbb4Jim Grosbachpublic:
34706f03a35db7029b2dbd2925552eb0d0472dcbb4Jim Grosbach  StringRef getErrorMsg() const { return ErrorMsg; }
35706f03a35db7029b2dbd2925552eb0d0472dcbb4Jim Grosbach
36706f03a35db7029b2dbd2925552eb0d0472dcbb4Jim Grosbach  /// Allocate space in the remote target address space.
37706f03a35db7029b2dbd2925552eb0d0472dcbb4Jim Grosbach  ///
38706f03a35db7029b2dbd2925552eb0d0472dcbb4Jim Grosbach  /// @param      Size      Amount of space, in bytes, to allocate.
39706f03a35db7029b2dbd2925552eb0d0472dcbb4Jim Grosbach  /// @param      Alignment Required minimum alignment for allocated space.
40706f03a35db7029b2dbd2925552eb0d0472dcbb4Jim Grosbach  /// @param[out] Address   Remote address of the allocated memory.
41706f03a35db7029b2dbd2925552eb0d0472dcbb4Jim Grosbach  ///
42706f03a35db7029b2dbd2925552eb0d0472dcbb4Jim Grosbach  /// @returns False on success. On failure, ErrorMsg is updated with
43706f03a35db7029b2dbd2925552eb0d0472dcbb4Jim Grosbach  ///          descriptive text of the encountered error.
44706f03a35db7029b2dbd2925552eb0d0472dcbb4Jim Grosbach  bool allocateSpace(size_t Size, unsigned Alignment, uint64_t &Address);
45706f03a35db7029b2dbd2925552eb0d0472dcbb4Jim Grosbach
46706f03a35db7029b2dbd2925552eb0d0472dcbb4Jim Grosbach  /// Load data into the target address space.
47706f03a35db7029b2dbd2925552eb0d0472dcbb4Jim Grosbach  ///
48706f03a35db7029b2dbd2925552eb0d0472dcbb4Jim Grosbach  /// @param      Address   Destination address in the target process.
49706f03a35db7029b2dbd2925552eb0d0472dcbb4Jim Grosbach  /// @param      Data      Source address in the host process.
50706f03a35db7029b2dbd2925552eb0d0472dcbb4Jim Grosbach  /// @param      Size      Number of bytes to copy.
51706f03a35db7029b2dbd2925552eb0d0472dcbb4Jim Grosbach  ///
52706f03a35db7029b2dbd2925552eb0d0472dcbb4Jim Grosbach  /// @returns False on success. On failure, ErrorMsg is updated with
53706f03a35db7029b2dbd2925552eb0d0472dcbb4Jim Grosbach  ///          descriptive text of the encountered error.
54706f03a35db7029b2dbd2925552eb0d0472dcbb4Jim Grosbach  bool loadData(uint64_t Address, const void *Data, size_t Size);
55706f03a35db7029b2dbd2925552eb0d0472dcbb4Jim Grosbach
56706f03a35db7029b2dbd2925552eb0d0472dcbb4Jim Grosbach  /// Load code into the target address space and prepare it for execution.
57706f03a35db7029b2dbd2925552eb0d0472dcbb4Jim Grosbach  ///
58706f03a35db7029b2dbd2925552eb0d0472dcbb4Jim Grosbach  /// @param      Address   Destination address in the target process.
59706f03a35db7029b2dbd2925552eb0d0472dcbb4Jim Grosbach  /// @param      Data      Source address in the host process.
60706f03a35db7029b2dbd2925552eb0d0472dcbb4Jim Grosbach  /// @param      Size      Number of bytes to copy.
61706f03a35db7029b2dbd2925552eb0d0472dcbb4Jim Grosbach  ///
62706f03a35db7029b2dbd2925552eb0d0472dcbb4Jim Grosbach  /// @returns False on success. On failure, ErrorMsg is updated with
63706f03a35db7029b2dbd2925552eb0d0472dcbb4Jim Grosbach  ///          descriptive text of the encountered error.
64706f03a35db7029b2dbd2925552eb0d0472dcbb4Jim Grosbach  bool loadCode(uint64_t Address, const void *Data, size_t Size);
65706f03a35db7029b2dbd2925552eb0d0472dcbb4Jim Grosbach
66706f03a35db7029b2dbd2925552eb0d0472dcbb4Jim Grosbach  /// Execute code in the target process. The called function is required
67706f03a35db7029b2dbd2925552eb0d0472dcbb4Jim Grosbach  /// to be of signature int "(*)(void)".
68706f03a35db7029b2dbd2925552eb0d0472dcbb4Jim Grosbach  ///
69706f03a35db7029b2dbd2925552eb0d0472dcbb4Jim Grosbach  /// @param      Address   Address of the loaded function in the target
70706f03a35db7029b2dbd2925552eb0d0472dcbb4Jim Grosbach  ///                       process.
71706f03a35db7029b2dbd2925552eb0d0472dcbb4Jim Grosbach  /// @param[out] RetVal    The integer return value of the called function.
72706f03a35db7029b2dbd2925552eb0d0472dcbb4Jim Grosbach  ///
73706f03a35db7029b2dbd2925552eb0d0472dcbb4Jim Grosbach  /// @returns False on success. On failure, ErrorMsg is updated with
74706f03a35db7029b2dbd2925552eb0d0472dcbb4Jim Grosbach  ///          descriptive text of the encountered error.
75706f03a35db7029b2dbd2925552eb0d0472dcbb4Jim Grosbach  bool executeCode(uint64_t Address, int &RetVal);
76706f03a35db7029b2dbd2925552eb0d0472dcbb4Jim Grosbach
77706f03a35db7029b2dbd2925552eb0d0472dcbb4Jim Grosbach  /// Minimum alignment for memory permissions. Used to seperate code and
78706f03a35db7029b2dbd2925552eb0d0472dcbb4Jim Grosbach  /// data regions to make sure data doesn't get marked as code or vice
79706f03a35db7029b2dbd2925552eb0d0472dcbb4Jim Grosbach  /// versa.
80706f03a35db7029b2dbd2925552eb0d0472dcbb4Jim Grosbach  ///
81706f03a35db7029b2dbd2925552eb0d0472dcbb4Jim Grosbach  /// @returns Page alignment return value. Default of 4k.
82706f03a35db7029b2dbd2925552eb0d0472dcbb4Jim Grosbach  unsigned getPageAlignment() { return 4096; }
83706f03a35db7029b2dbd2925552eb0d0472dcbb4Jim Grosbach
84706f03a35db7029b2dbd2925552eb0d0472dcbb4Jim Grosbach  /// Start the remote process.
85706f03a35db7029b2dbd2925552eb0d0472dcbb4Jim Grosbach  void create();
86706f03a35db7029b2dbd2925552eb0d0472dcbb4Jim Grosbach
87706f03a35db7029b2dbd2925552eb0d0472dcbb4Jim Grosbach  /// Terminate the remote process.
88706f03a35db7029b2dbd2925552eb0d0472dcbb4Jim Grosbach  void stop();
89706f03a35db7029b2dbd2925552eb0d0472dcbb4Jim Grosbach
90706f03a35db7029b2dbd2925552eb0d0472dcbb4Jim Grosbach  RemoteTarget() : ErrorMsg(""), IsRunning(false) {}
91706f03a35db7029b2dbd2925552eb0d0472dcbb4Jim Grosbach  ~RemoteTarget() { if (IsRunning) stop(); }
92706f03a35db7029b2dbd2925552eb0d0472dcbb4Jim Grosbach
93706f03a35db7029b2dbd2925552eb0d0472dcbb4Jim Grosbachprivate:
94706f03a35db7029b2dbd2925552eb0d0472dcbb4Jim Grosbach  // Main processing function for the remote target process. Command messages
95706f03a35db7029b2dbd2925552eb0d0472dcbb4Jim Grosbach  // are received on file descriptor CmdFD and responses come back on OutFD.
96706f03a35db7029b2dbd2925552eb0d0472dcbb4Jim Grosbach  static void doRemoteTargeting(int CmdFD, int OutFD);
97706f03a35db7029b2dbd2925552eb0d0472dcbb4Jim Grosbach};
98706f03a35db7029b2dbd2925552eb0d0472dcbb4Jim Grosbach
99706f03a35db7029b2dbd2925552eb0d0472dcbb4Jim Grosbach} // end namespace llvm
100706f03a35db7029b2dbd2925552eb0d0472dcbb4Jim Grosbach
101706f03a35db7029b2dbd2925552eb0d0472dcbb4Jim Grosbach#endif
102