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 "RPCUtils.h"
20#include "RawByteChannel.h"
21#include "llvm/ExecutionEngine/JITSymbol.h"
22
23namespace llvm {
24namespace orc {
25namespace remote {
26
27class DirectBufferWriter {
28public:
29  DirectBufferWriter() = default;
30  DirectBufferWriter(const char *Src, JITTargetAddress Dst, uint64_t Size)
31      : Src(Src), Dst(Dst), Size(Size) {}
32
33  const char *getSrc() const { return Src; }
34  JITTargetAddress getDst() const { return Dst; }
35  uint64_t getSize() const { return Size; }
36
37private:
38  const char *Src;
39  JITTargetAddress Dst;
40  uint64_t Size;
41};
42
43} // end namespace remote
44
45namespace rpc {
46
47template <> class RPCTypeName<remote::DirectBufferWriter> {
48public:
49  static const char *getName() { return "DirectBufferWriter"; }
50};
51
52template <typename ChannelT>
53class SerializationTraits<
54    ChannelT, remote::DirectBufferWriter, remote::DirectBufferWriter,
55    typename std::enable_if<
56        std::is_base_of<RawByteChannel, ChannelT>::value>::type> {
57public:
58  static Error serialize(ChannelT &C, const remote::DirectBufferWriter &DBW) {
59    if (auto EC = serializeSeq(C, DBW.getDst()))
60      return EC;
61    if (auto EC = serializeSeq(C, DBW.getSize()))
62      return EC;
63    return C.appendBytes(DBW.getSrc(), DBW.getSize());
64  }
65
66  static Error deserialize(ChannelT &C, remote::DirectBufferWriter &DBW) {
67    JITTargetAddress Dst;
68    if (auto EC = deserializeSeq(C, Dst))
69      return EC;
70    uint64_t Size;
71    if (auto EC = deserializeSeq(C, Size))
72      return EC;
73    char *Addr = reinterpret_cast<char *>(static_cast<uintptr_t>(Dst));
74
75    DBW = remote::DirectBufferWriter(0, Dst, Size);
76
77    return C.readBytes(Addr, Size);
78  }
79};
80
81} // end namespace rpc
82
83namespace remote {
84
85class OrcRemoteTargetRPCAPI
86    : public rpc::SingleThreadedRPCEndpoint<rpc::RawByteChannel> {
87protected:
88  class ResourceIdMgr {
89  public:
90    typedef uint64_t ResourceId;
91    static const ResourceId InvalidId = ~0U;
92
93    ResourceId getNext() {
94      if (!FreeIds.empty()) {
95        ResourceId I = FreeIds.back();
96        FreeIds.pop_back();
97        return I;
98      }
99      return NextId++;
100    }
101    void release(ResourceId I) { FreeIds.push_back(I); }
102
103  private:
104    ResourceId NextId = 0;
105    std::vector<ResourceId> FreeIds;
106  };
107
108public:
109  // FIXME: Remove constructors once MSVC supports synthesizing move-ops.
110  OrcRemoteTargetRPCAPI(rpc::RawByteChannel &C)
111      : rpc::SingleThreadedRPCEndpoint<rpc::RawByteChannel>(C, true) {}
112
113  class CallIntVoid
114      : public rpc::Function<CallIntVoid, int32_t(JITTargetAddress Addr)> {
115  public:
116    static const char *getName() { return "CallIntVoid"; }
117  };
118
119  class CallMain
120      : public rpc::Function<CallMain, int32_t(JITTargetAddress Addr,
121                                               std::vector<std::string> Args)> {
122  public:
123    static const char *getName() { return "CallMain"; }
124  };
125
126  class CallVoidVoid
127      : public rpc::Function<CallVoidVoid, void(JITTargetAddress FnAddr)> {
128  public:
129    static const char *getName() { return "CallVoidVoid"; }
130  };
131
132  class CreateRemoteAllocator
133      : public rpc::Function<CreateRemoteAllocator,
134                             void(ResourceIdMgr::ResourceId AllocatorID)> {
135  public:
136    static const char *getName() { return "CreateRemoteAllocator"; }
137  };
138
139  class CreateIndirectStubsOwner
140      : public rpc::Function<CreateIndirectStubsOwner,
141                             void(ResourceIdMgr::ResourceId StubOwnerID)> {
142  public:
143    static const char *getName() { return "CreateIndirectStubsOwner"; }
144  };
145
146  class DeregisterEHFrames
147      : public rpc::Function<DeregisterEHFrames,
148                             void(JITTargetAddress Addr, uint32_t Size)> {
149  public:
150    static const char *getName() { return "DeregisterEHFrames"; }
151  };
152
153  class DestroyRemoteAllocator
154      : public rpc::Function<DestroyRemoteAllocator,
155                             void(ResourceIdMgr::ResourceId AllocatorID)> {
156  public:
157    static const char *getName() { return "DestroyRemoteAllocator"; }
158  };
159
160  class DestroyIndirectStubsOwner
161      : public rpc::Function<DestroyIndirectStubsOwner,
162                             void(ResourceIdMgr::ResourceId StubsOwnerID)> {
163  public:
164    static const char *getName() { return "DestroyIndirectStubsOwner"; }
165  };
166
167  /// EmitIndirectStubs result is (StubsBase, PtrsBase, NumStubsEmitted).
168  class EmitIndirectStubs
169      : public rpc::Function<
170            EmitIndirectStubs,
171            std::tuple<JITTargetAddress, JITTargetAddress, uint32_t>(
172                ResourceIdMgr::ResourceId StubsOwnerID,
173                uint32_t NumStubsRequired)> {
174  public:
175    static const char *getName() { return "EmitIndirectStubs"; }
176  };
177
178  class EmitResolverBlock : public rpc::Function<EmitResolverBlock, void()> {
179  public:
180    static const char *getName() { return "EmitResolverBlock"; }
181  };
182
183  /// EmitTrampolineBlock result is (BlockAddr, NumTrampolines).
184  class EmitTrampolineBlock
185      : public rpc::Function<EmitTrampolineBlock,
186                             std::tuple<JITTargetAddress, uint32_t>()> {
187  public:
188    static const char *getName() { return "EmitTrampolineBlock"; }
189  };
190
191  class GetSymbolAddress
192      : public rpc::Function<GetSymbolAddress,
193                             JITTargetAddress(std::string SymbolName)> {
194  public:
195    static const char *getName() { return "GetSymbolAddress"; }
196  };
197
198  /// GetRemoteInfo result is (Triple, PointerSize, PageSize, TrampolineSize,
199  ///                          IndirectStubsSize).
200  class GetRemoteInfo
201      : public rpc::Function<
202            GetRemoteInfo,
203            std::tuple<std::string, uint32_t, uint32_t, uint32_t, uint32_t>()> {
204  public:
205    static const char *getName() { return "GetRemoteInfo"; }
206  };
207
208  class ReadMem
209      : public rpc::Function<ReadMem, std::vector<uint8_t>(JITTargetAddress Src,
210                                                           uint64_t Size)> {
211  public:
212    static const char *getName() { return "ReadMem"; }
213  };
214
215  class RegisterEHFrames
216      : public rpc::Function<RegisterEHFrames,
217                             void(JITTargetAddress Addr, uint32_t Size)> {
218  public:
219    static const char *getName() { return "RegisterEHFrames"; }
220  };
221
222  class ReserveMem
223      : public rpc::Function<ReserveMem,
224                             JITTargetAddress(ResourceIdMgr::ResourceId AllocID,
225                                              uint64_t Size, uint32_t Align)> {
226  public:
227    static const char *getName() { return "ReserveMem"; }
228  };
229
230  class RequestCompile
231      : public rpc::Function<
232            RequestCompile, JITTargetAddress(JITTargetAddress TrampolineAddr)> {
233  public:
234    static const char *getName() { return "RequestCompile"; }
235  };
236
237  class SetProtections
238      : public rpc::Function<SetProtections,
239                             void(ResourceIdMgr::ResourceId AllocID,
240                                  JITTargetAddress Dst, uint32_t ProtFlags)> {
241  public:
242    static const char *getName() { return "SetProtections"; }
243  };
244
245  class TerminateSession : public rpc::Function<TerminateSession, void()> {
246  public:
247    static const char *getName() { return "TerminateSession"; }
248  };
249
250  class WriteMem
251      : public rpc::Function<WriteMem, void(remote::DirectBufferWriter DB)> {
252  public:
253    static const char *getName() { return "WriteMem"; }
254  };
255
256  class WritePtr : public rpc::Function<WritePtr, void(JITTargetAddress Dst,
257                                                       JITTargetAddress Val)> {
258  public:
259    static const char *getName() { return "WritePtr"; }
260  };
261};
262
263} // end namespace remote
264} // end namespace orc
265} // end namespace llvm
266
267#endif
268