OrcRemoteTargetRPCAPI.h 12 KB

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