Home | History | Annotate | Download | only in Orc
      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 = "")
     37     : ResourceId(std::move(ResourceId)),
     38       ResourceDescription(std::move(ResourceDescription)) {}
     39 
     40   std::error_code convertToErrorCode() const override {
     41     return orcError(OrcErrorCode::UnknownResourceHandle);
     42   }
     43 
     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;
     62   DirectBufferWriter(const char *Src, JITTargetAddress Dst, uint64_t Size)
     63       : Src(Src), Dst(Dst), Size(Size) {}
     64 
     65   const char *getSrc() const { return Src; }
     66   JITTargetAddress getDst() const { return Dst; }
     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:
     82   static const char *getName() { return "JITSymbolFlags"; }
     83 };
     84 
     85 template <typename ChannelT>
     86 class SerializationTraits<ChannelT, JITSymbolFlags> {
     87 public:
     88 
     89   static Error serialize(ChannelT &C, const JITSymbolFlags &Flags) {
     90     return serializeSeq(C, static_cast<JITSymbolFlags::UnderlyingType>(Flags),
     91                         Flags.getTargetFlags());
     92   }
     93 
     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:
    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:
    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 
    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;
    149   explicit ResourceIdMgr(ResourceId FirstValidId)
    150     : NextId(std::move(FirstValidId)) {}
    151 
    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 
    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:
    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:
    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:
    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:
    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:
    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:
    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:
    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:
    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:
    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:
    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:
    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:
    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:
    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:
    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:
    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:
    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:
    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:
    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:
    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:
    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:
    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.
    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