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