• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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   ResourceNotFound(ResourceIdT ResourceId,
36                    std::string ResourceDescription = "")
ResourceId(std::move (ResourceId))37     : ResourceId(std::move(ResourceId)),
38       ResourceDescription(std::move(ResourceDescription)) {}
39 
convertToErrorCode()40   std::error_code convertToErrorCode() const override {
41     return orcError(OrcErrorCode::UnknownResourceHandle);
42   }
43 
log(raw_ostream & OS)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 
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;
DirectBufferWriter(const char * Src,JITTargetAddress Dst,uint64_t Size)62   DirectBufferWriter(const char *Src, JITTargetAddress Dst, uint64_t Size)
63       : Src(Src), Dst(Dst), Size(Size) {}
64 
getSrc()65   const char *getSrc() const { return Src; }
getDst()66   JITTargetAddress getDst() const { return Dst; }
getSize()67   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:
getName()82   static const char *getName() { return "JITSymbolFlags"; }
83 };
84 
85 template <typename ChannelT>
86 class SerializationTraits<ChannelT, JITSymbolFlags> {
87 public:
88 
serialize(ChannelT & C,const JITSymbolFlags & Flags)89   static Error serialize(ChannelT &C, const JITSymbolFlags &Flags) {
90     return serializeSeq(C, static_cast<JITSymbolFlags::UnderlyingType>(Flags),
91                         Flags.getTargetFlags());
92   }
93 
deserialize(ChannelT & C,JITSymbolFlags & Flags)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 
105 template <> class RPCTypeName<remote::DirectBufferWriter> {
106 public:
getName()107   static const char *getName() { return "DirectBufferWriter"; }
108 };
109 
110 template <typename ChannelT>
111 class SerializationTraits<
112     ChannelT, remote::DirectBufferWriter, remote::DirectBufferWriter,
113     typename std::enable_if<
114         std::is_base_of<RawByteChannel, ChannelT>::value>::type> {
115 public:
serialize(ChannelT & C,const remote::DirectBufferWriter & DBW)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 
deserialize(ChannelT & C,remote::DirectBufferWriter & DBW)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 
141 namespace remote {
142 
143 class ResourceIdMgr {
144 public:
145   using ResourceId = uint64_t;
146   static const ResourceId InvalidId = ~0U;
147 
148   ResourceIdMgr() = default;
ResourceIdMgr(ResourceId FirstValidId)149   explicit ResourceIdMgr(ResourceId FirstValidId)
150     : NextId(std::move(FirstValidId)) {}
151 
getNext()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 
release(ResourceId I)162   void release(ResourceId I) { FreeIds.push_back(I); }
163 
164 private:
165   ResourceId NextId = 1;
166   std::vector<ResourceId> FreeIds;
167 };
168 
169 /// Registers EH frames on the remote.
170 namespace 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:
getName()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:
getName()185     static const char *getName() { return "DeregisterEHFrames"; }
186   };
187 
188 } // end namespace eh
189 
190 /// RPC functions for executing remote code.
191 namespace 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:
getName()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:
getName()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:
getName()215     static const char *getName() { return "CallVoidVoid"; }
216   };
217 
218 } // end namespace exec
219 
220 /// RPC functions for remote memory management / inspection / modification.
221 namespace 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:
getName()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:
getName()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:
getName()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:
getName()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:
getName()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:
getName()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:
getName()276     static const char *getName() { return "WritePtr"; }
277   };
278 
279 } // end namespace mem
280 
281 /// RPC functions for remote stub and trampoline management.
282 namespace 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:
getName()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:
getName()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:
getName()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:
getName()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:
getName()322     static const char *getName() { return "EmitTrampolineBlock"; }
323   };
324 
325 } // end namespace stubs
326 
327 /// Miscelaneous RPC functions for dealing with remotes.
328 namespace 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:
getName()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:
getName()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:
getName()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:
getName()359     static const char *getName() { return "TerminateSession"; }
360   };
361 
362 } // namespace utils
363 
364 class OrcRemoteTargetRPCAPI
365     : public rpc::SingleThreadedRPCEndpoint<rpc::RawByteChannel> {
366 public:
367   // FIXME: Remove constructors once MSVC supports synthesizing move-ops.
OrcRemoteTargetRPCAPI(rpc::RawByteChannel & C)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
378