RemoteTargetExternal.cpp revision 263508
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
27using namespace llvm;
28
29bool 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
36bool 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
42bool 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
48bool RemoteTargetExternal::executeCode(uint64_t Address, int &RetVal) {
49  SendExecute(Address);
50
51  Receive(LLI_ExecutionResult, RetVal);
52  return false;
53}
54
55void RemoteTargetExternal::stop() {
56  SendTerminate();
57  Wait();
58}
59
60void 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
77void 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
97void 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
111void 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
121void 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
134void RemoteTargetExternal::Receive(LLIMessageType ExpectedMsgType, int &Data) {
135  uint64_t Temp;
136  Receive(ExpectedMsgType, Temp);
137  Data = (int)(int64_t)Temp;
138}
139
140void 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