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