blob: bc0da0f9a730e2abf12410eeaf0e07077ec1c53f [file] [log] [blame]
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01001//===- OrcRemoteTargetRPCAPI.h - Orc Remote-target RPC API ------*- C++ -*-===//
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// This file defines the Orc remote-target RPC API. It should not be used
11// directly, but is used by the RemoteTargetClient and RemoteTargetServer
12// classes.
13//
14//===----------------------------------------------------------------------===//
15
16#ifndef LLVM_EXECUTIONENGINE_ORC_ORCREMOTETARGETRPCAPI_H
17#define LLVM_EXECUTIONENGINE_ORC_ORCREMOTETARGETRPCAPI_H
18
19#include "llvm/ExecutionEngine/JITSymbol.h"
20#include "llvm/ExecutionEngine/Orc/RPCUtils.h"
21#include "llvm/ExecutionEngine/Orc/RawByteChannel.h"
22
23namespace llvm {
24namespace orc {
25
26namespace remote {
27
28/// Template error for missing resources.
29template <typename ResourceIdT>
30class ResourceNotFound
31 : public ErrorInfo<ResourceNotFound<ResourceIdT>> {
32public:
33 static char ID;
34
35 ResourceNotFound(ResourceIdT ResourceId,
36 std::string ResourceDescription = "")
37 : ResourceId(std::move(ResourceId)),
38 ResourceDescription(std::move(ResourceDescription)) {}
39
40 std::error_code convertToErrorCode() const override {
41 return orcError(OrcErrorCode::UnknownResourceHandle);
42 }
43
44 void log(raw_ostream &OS) const override {
45 OS << (ResourceDescription.empty()
46 ? "Remote resource with id "
47 : ResourceDescription)
48 << " " << ResourceId << " not found";
49 }
50
51private:
52 ResourceIdT ResourceId;
53 std::string ResourceDescription;
54};
55
56template <typename ResourceIdT>
57char ResourceNotFound<ResourceIdT>::ID = 0;
58
59class DirectBufferWriter {
60public:
61 DirectBufferWriter() = default;
62 DirectBufferWriter(const char *Src, JITTargetAddress Dst, uint64_t Size)
63 : Src(Src), Dst(Dst), Size(Size) {}
64
65 const char *getSrc() const { return Src; }
66 JITTargetAddress getDst() const { return Dst; }
67 uint64_t getSize() const { return Size; }
68
69private:
70 const char *Src;
71 JITTargetAddress Dst;
72 uint64_t Size;
73};
74
75} // end namespace remote
76
77namespace rpc {
78
79template <>
80class RPCTypeName<JITSymbolFlags> {
81public:
82 static const char *getName() { return "JITSymbolFlags"; }
83};
84
85template <typename ChannelT>
86class SerializationTraits<ChannelT, JITSymbolFlags> {
87public:
88
89 static Error serialize(ChannelT &C, const JITSymbolFlags &Flags) {
90 return serializeSeq(C, static_cast<JITSymbolFlags::UnderlyingType>(Flags),
91 Flags.getTargetFlags());
92 }
93
94 static Error deserialize(ChannelT &C, JITSymbolFlags &Flags) {
95 JITSymbolFlags::UnderlyingType JITFlags;
96 JITSymbolFlags::TargetFlagsType TargetFlags;
97 if (auto Err = deserializeSeq(C, JITFlags, TargetFlags))
98 return Err;
99 Flags = JITSymbolFlags(static_cast<JITSymbolFlags::FlagNames>(JITFlags),
100 TargetFlags);
101 return Error::success();
102 }
103};
104
105template <> class RPCTypeName<remote::DirectBufferWriter> {
106public:
107 static const char *getName() { return "DirectBufferWriter"; }
108};
109
110template <typename ChannelT>
111class SerializationTraits<
112 ChannelT, remote::DirectBufferWriter, remote::DirectBufferWriter,
113 typename std::enable_if<
114 std::is_base_of<RawByteChannel, ChannelT>::value>::type> {
115public:
116 static Error serialize(ChannelT &C, const remote::DirectBufferWriter &DBW) {
117 if (auto EC = serializeSeq(C, DBW.getDst()))
118 return EC;
119 if (auto EC = serializeSeq(C, DBW.getSize()))
120 return EC;
121 return C.appendBytes(DBW.getSrc(), DBW.getSize());
122 }
123
124 static Error deserialize(ChannelT &C, remote::DirectBufferWriter &DBW) {
125 JITTargetAddress Dst;
126 if (auto EC = deserializeSeq(C, Dst))
127 return EC;
128 uint64_t Size;
129 if (auto EC = deserializeSeq(C, Size))
130 return EC;
131 char *Addr = reinterpret_cast<char *>(static_cast<uintptr_t>(Dst));
132
133 DBW = remote::DirectBufferWriter(nullptr, Dst, Size);
134
135 return C.readBytes(Addr, Size);
136 }
137};
138
139} // end namespace rpc
140
141namespace remote {
142
143class ResourceIdMgr {
144public:
145 using ResourceId = uint64_t;
146 static const ResourceId InvalidId = ~0U;
147
148 ResourceIdMgr() = default;
149 explicit ResourceIdMgr(ResourceId FirstValidId)
150 : NextId(std::move(FirstValidId)) {}
151
152 ResourceId getNext() {
153 if (!FreeIds.empty()) {
154 ResourceId I = FreeIds.back();
155 FreeIds.pop_back();
156 return I;
157 }
158 assert(NextId + 1 != ~0ULL && "All ids allocated");
159 return NextId++;
160 }
161
162 void release(ResourceId I) { FreeIds.push_back(I); }
163
164private:
165 ResourceId NextId = 1;
166 std::vector<ResourceId> FreeIds;
167};
168
169/// Registers EH frames on the remote.
170namespace eh {
171
172 /// Registers EH frames on the remote.
173 class RegisterEHFrames
174 : public rpc::Function<RegisterEHFrames,
175 void(JITTargetAddress Addr, uint32_t Size)> {
176 public:
177 static const char *getName() { return "RegisterEHFrames"; }
178 };
179
180 /// Deregisters EH frames on the remote.
181 class DeregisterEHFrames
182 : public rpc::Function<DeregisterEHFrames,
183 void(JITTargetAddress Addr, uint32_t Size)> {
184 public:
185 static const char *getName() { return "DeregisterEHFrames"; }
186 };
187
188} // end namespace eh
189
190/// RPC functions for executing remote code.
191namespace exec {
192
193 /// Call an 'int32_t()'-type function on the remote, returns the called
194 /// function's return value.
195 class CallIntVoid
196 : public rpc::Function<CallIntVoid, int32_t(JITTargetAddress Addr)> {
197 public:
198 static const char *getName() { return "CallIntVoid"; }
199 };
200
201 /// Call an 'int32_t(int32_t, char**)'-type function on the remote, returns the
202 /// called function's return value.
203 class CallMain
204 : public rpc::Function<CallMain, int32_t(JITTargetAddress Addr,
205 std::vector<std::string> Args)> {
206 public:
207 static const char *getName() { return "CallMain"; }
208 };
209
210 /// Calls a 'void()'-type function on the remote, returns when the called
211 /// function completes.
212 class CallVoidVoid
213 : public rpc::Function<CallVoidVoid, void(JITTargetAddress FnAddr)> {
214 public:
215 static const char *getName() { return "CallVoidVoid"; }
216 };
217
218} // end namespace exec
219
220/// RPC functions for remote memory management / inspection / modification.
221namespace mem {
222
223 /// Creates a memory allocator on the remote.
224 class CreateRemoteAllocator
225 : public rpc::Function<CreateRemoteAllocator,
226 void(ResourceIdMgr::ResourceId AllocatorID)> {
227 public:
228 static const char *getName() { return "CreateRemoteAllocator"; }
229 };
230
231 /// Destroys a remote allocator, freeing any memory allocated by it.
232 class DestroyRemoteAllocator
233 : public rpc::Function<DestroyRemoteAllocator,
234 void(ResourceIdMgr::ResourceId AllocatorID)> {
235 public:
236 static const char *getName() { return "DestroyRemoteAllocator"; }
237 };
238
239 /// Read a remote memory block.
240 class ReadMem
241 : public rpc::Function<ReadMem, std::vector<uint8_t>(JITTargetAddress Src,
242 uint64_t Size)> {
243 public:
244 static const char *getName() { return "ReadMem"; }
245 };
246
247 /// Reserve a block of memory on the remote via the given allocator.
248 class ReserveMem
249 : public rpc::Function<ReserveMem,
250 JITTargetAddress(ResourceIdMgr::ResourceId AllocID,
251 uint64_t Size, uint32_t Align)> {
252 public:
253 static const char *getName() { return "ReserveMem"; }
254 };
255
256 /// Set the memory protection on a memory block.
257 class SetProtections
258 : public rpc::Function<SetProtections,
259 void(ResourceIdMgr::ResourceId AllocID,
260 JITTargetAddress Dst, uint32_t ProtFlags)> {
261 public:
262 static const char *getName() { return "SetProtections"; }
263 };
264
265 /// Write to a remote memory block.
266 class WriteMem
267 : public rpc::Function<WriteMem, void(remote::DirectBufferWriter DB)> {
268 public:
269 static const char *getName() { return "WriteMem"; }
270 };
271
272 /// Write to a remote pointer.
273 class WritePtr : public rpc::Function<WritePtr, void(JITTargetAddress Dst,
274 JITTargetAddress Val)> {
275 public:
276 static const char *getName() { return "WritePtr"; }
277 };
278
279} // end namespace mem
280
281/// RPC functions for remote stub and trampoline management.
282namespace stubs {
283
284 /// Creates an indirect stub owner on the remote.
285 class CreateIndirectStubsOwner
286 : public rpc::Function<CreateIndirectStubsOwner,
287 void(ResourceIdMgr::ResourceId StubOwnerID)> {
288 public:
289 static const char *getName() { return "CreateIndirectStubsOwner"; }
290 };
291
292 /// RPC function for destroying an indirect stubs owner.
293 class DestroyIndirectStubsOwner
294 : public rpc::Function<DestroyIndirectStubsOwner,
295 void(ResourceIdMgr::ResourceId StubsOwnerID)> {
296 public:
297 static const char *getName() { return "DestroyIndirectStubsOwner"; }
298 };
299
300 /// EmitIndirectStubs result is (StubsBase, PtrsBase, NumStubsEmitted).
301 class EmitIndirectStubs
302 : public rpc::Function<
303 EmitIndirectStubs,
304 std::tuple<JITTargetAddress, JITTargetAddress, uint32_t>(
305 ResourceIdMgr::ResourceId StubsOwnerID,
306 uint32_t NumStubsRequired)> {
307 public:
308 static const char *getName() { return "EmitIndirectStubs"; }
309 };
310
311 /// RPC function to emit the resolver block and return its address.
312 class EmitResolverBlock : public rpc::Function<EmitResolverBlock, void()> {
313 public:
314 static const char *getName() { return "EmitResolverBlock"; }
315 };
316
317 /// EmitTrampolineBlock result is (BlockAddr, NumTrampolines).
318 class EmitTrampolineBlock
319 : public rpc::Function<EmitTrampolineBlock,
320 std::tuple<JITTargetAddress, uint32_t>()> {
321 public:
322 static const char *getName() { return "EmitTrampolineBlock"; }
323 };
324
325} // end namespace stubs
326
327/// Miscelaneous RPC functions for dealing with remotes.
328namespace utils {
329
330 /// GetRemoteInfo result is (Triple, PointerSize, PageSize, TrampolineSize,
331 /// IndirectStubsSize).
332 class GetRemoteInfo
333 : public rpc::Function<
334 GetRemoteInfo,
335 std::tuple<std::string, uint32_t, uint32_t, uint32_t, uint32_t>()> {
336 public:
337 static const char *getName() { return "GetRemoteInfo"; }
338 };
339
340 /// Get the address of a remote symbol.
341 class GetSymbolAddress
342 : public rpc::Function<GetSymbolAddress,
343 JITTargetAddress(std::string SymbolName)> {
344 public:
345 static const char *getName() { return "GetSymbolAddress"; }
346 };
347
348 /// Request that the host execute a compile callback.
349 class RequestCompile
350 : public rpc::Function<
351 RequestCompile, JITTargetAddress(JITTargetAddress TrampolineAddr)> {
352 public:
353 static const char *getName() { return "RequestCompile"; }
354 };
355
356 /// Notify the remote and terminate the session.
357 class TerminateSession : public rpc::Function<TerminateSession, void()> {
358 public:
359 static const char *getName() { return "TerminateSession"; }
360 };
361
362} // namespace utils
363
364class OrcRemoteTargetRPCAPI
365 : public rpc::SingleThreadedRPCEndpoint<rpc::RawByteChannel> {
366public:
367 // FIXME: Remove constructors once MSVC supports synthesizing move-ops.
368 OrcRemoteTargetRPCAPI(rpc::RawByteChannel &C)
369 : rpc::SingleThreadedRPCEndpoint<rpc::RawByteChannel>(C, true) {}
370};
371
372} // end namespace remote
373
374} // end namespace orc
375} // end namespace llvm
376
377#endif // LLVM_EXECUTIONENGINE_ORC_ORCREMOTETARGETRPCAPI_H