OrcRemoteTargetRPCAPI.h 12 KB

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