Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-10 08:43:51

0001 //===--- SimpleRemoteEPCUtils.h - Utils for Simple Remote EPC ---*- C++ -*-===//
0002 //
0003 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
0004 // See https://llvm.org/LICENSE.txt for license information.
0005 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
0006 //
0007 //===----------------------------------------------------------------------===//
0008 //
0009 // Message definitions and other utilities for SimpleRemoteEPC and
0010 // SimpleRemoteEPCServer.
0011 //
0012 //===----------------------------------------------------------------------===//
0013 
0014 #ifndef LLVM_EXECUTIONENGINE_ORC_SHARED_SIMPLEREMOTEEPCUTILS_H
0015 #define LLVM_EXECUTIONENGINE_ORC_SHARED_SIMPLEREMOTEEPCUTILS_H
0016 
0017 #include "llvm/ADT/ArrayRef.h"
0018 #include "llvm/ADT/SmallVector.h"
0019 #include "llvm/ADT/StringMap.h"
0020 #include "llvm/ExecutionEngine/Orc/Shared/ExecutorAddress.h"
0021 #include "llvm/ExecutionEngine/Orc/Shared/SimplePackedSerialization.h"
0022 #include "llvm/Support/Error.h"
0023 
0024 #include <atomic>
0025 #include <mutex>
0026 #include <string>
0027 #include <thread>
0028 
0029 namespace llvm {
0030 namespace orc {
0031 
0032 namespace SimpleRemoteEPCDefaultBootstrapSymbolNames {
0033 extern const char *ExecutorSessionObjectName;
0034 extern const char *DispatchFnName;
0035 } // end namespace SimpleRemoteEPCDefaultBootstrapSymbolNames
0036 
0037 enum class SimpleRemoteEPCOpcode : uint8_t {
0038   Setup,
0039   Hangup,
0040   Result,
0041   CallWrapper,
0042   LastOpC = CallWrapper
0043 };
0044 
0045 struct SimpleRemoteEPCExecutorInfo {
0046   std::string TargetTriple;
0047   uint64_t PageSize;
0048   StringMap<std::vector<char>> BootstrapMap;
0049   StringMap<ExecutorAddr> BootstrapSymbols;
0050 };
0051 
0052 using SimpleRemoteEPCArgBytesVector = SmallVector<char, 128>;
0053 
0054 class SimpleRemoteEPCTransportClient {
0055 public:
0056   enum HandleMessageAction { ContinueSession, EndSession };
0057 
0058   virtual ~SimpleRemoteEPCTransportClient();
0059 
0060   /// Handle receipt of a message.
0061   ///
0062   /// Returns an Error if the message cannot be handled, 'EndSession' if the
0063   /// client will not accept any further messages, and 'ContinueSession'
0064   /// otherwise.
0065   virtual Expected<HandleMessageAction>
0066   handleMessage(SimpleRemoteEPCOpcode OpC, uint64_t SeqNo, ExecutorAddr TagAddr,
0067                 SimpleRemoteEPCArgBytesVector ArgBytes) = 0;
0068 
0069   /// Handle a disconnection from the underlying transport. No further messages
0070   /// should be sent to handleMessage after this is called.
0071   /// Err may contain an Error value indicating unexpected disconnection. This
0072   /// allows clients to log such errors, but no attempt should be made at
0073   /// recovery (which should be handled inside the transport class, if it is
0074   /// supported at all).
0075   virtual void handleDisconnect(Error Err) = 0;
0076 };
0077 
0078 class SimpleRemoteEPCTransport {
0079 public:
0080   virtual ~SimpleRemoteEPCTransport();
0081 
0082   /// Called during setup of the client to indicate that the client is ready
0083   /// to receive messages.
0084   ///
0085   /// Transport objects should not access the client until this method is
0086   /// called.
0087   virtual Error start() = 0;
0088 
0089   /// Send a SimpleRemoteEPC message.
0090   ///
0091   /// This function may be called concurrently. Subclasses should implement
0092   /// locking if required for the underlying transport.
0093   virtual Error sendMessage(SimpleRemoteEPCOpcode OpC, uint64_t SeqNo,
0094                             ExecutorAddr TagAddr, ArrayRef<char> ArgBytes) = 0;
0095 
0096   /// Trigger disconnection from the transport. The implementation should
0097   /// respond by calling handleDisconnect on the client once disconnection
0098   /// is complete. May be called more than once and from different threads.
0099   virtual void disconnect() = 0;
0100 };
0101 
0102 /// Uses read/write on FileDescriptors for transport.
0103 class FDSimpleRemoteEPCTransport : public SimpleRemoteEPCTransport {
0104 public:
0105   /// Create a FDSimpleRemoteEPCTransport using the given FDs for
0106   /// reading (InFD) and writing (OutFD).
0107   static Expected<std::unique_ptr<FDSimpleRemoteEPCTransport>>
0108   Create(SimpleRemoteEPCTransportClient &C, int InFD, int OutFD);
0109 
0110   /// Create a FDSimpleRemoteEPCTransport using the given FD for both
0111   /// reading and writing.
0112   static Expected<std::unique_ptr<FDSimpleRemoteEPCTransport>>
0113   Create(SimpleRemoteEPCTransportClient &C, int FD) {
0114     return Create(C, FD, FD);
0115   }
0116 
0117   ~FDSimpleRemoteEPCTransport() override;
0118 
0119   Error start() override;
0120 
0121   Error sendMessage(SimpleRemoteEPCOpcode OpC, uint64_t SeqNo,
0122                     ExecutorAddr TagAddr, ArrayRef<char> ArgBytes) override;
0123 
0124   void disconnect() override;
0125 
0126 private:
0127   FDSimpleRemoteEPCTransport(SimpleRemoteEPCTransportClient &C, int InFD,
0128                              int OutFD)
0129       : C(C), InFD(InFD), OutFD(OutFD) {}
0130 
0131   Error readBytes(char *Dst, size_t Size, bool *IsEOF = nullptr);
0132   int writeBytes(const char *Src, size_t Size);
0133   void listenLoop();
0134 
0135   std::mutex M;
0136   SimpleRemoteEPCTransportClient &C;
0137   std::thread ListenerThread;
0138   int InFD, OutFD;
0139   std::atomic<bool> Disconnected{false};
0140 };
0141 
0142 struct RemoteSymbolLookupSetElement {
0143   std::string Name;
0144   bool Required;
0145 };
0146 
0147 using RemoteSymbolLookupSet = std::vector<RemoteSymbolLookupSetElement>;
0148 
0149 struct RemoteSymbolLookup {
0150   uint64_t H;
0151   RemoteSymbolLookupSet Symbols;
0152 };
0153 
0154 namespace shared {
0155 
0156 using SPSRemoteSymbolLookupSetElement = SPSTuple<SPSString, bool>;
0157 
0158 using SPSRemoteSymbolLookupSet = SPSSequence<SPSRemoteSymbolLookupSetElement>;
0159 
0160 using SPSRemoteSymbolLookup = SPSTuple<uint64_t, SPSRemoteSymbolLookupSet>;
0161 
0162 /// Tuple containing target triple, page size, and bootstrap symbols.
0163 using SPSSimpleRemoteEPCExecutorInfo =
0164     SPSTuple<SPSString, uint64_t,
0165              SPSSequence<SPSTuple<SPSString, SPSSequence<char>>>,
0166              SPSSequence<SPSTuple<SPSString, SPSExecutorAddr>>>;
0167 
0168 template <>
0169 class SPSSerializationTraits<SPSRemoteSymbolLookupSetElement,
0170                              RemoteSymbolLookupSetElement> {
0171 public:
0172   static size_t size(const RemoteSymbolLookupSetElement &V) {
0173     return SPSArgList<SPSString, bool>::size(V.Name, V.Required);
0174   }
0175 
0176   static size_t serialize(SPSOutputBuffer &OB,
0177                           const RemoteSymbolLookupSetElement &V) {
0178     return SPSArgList<SPSString, bool>::serialize(OB, V.Name, V.Required);
0179   }
0180 
0181   static size_t deserialize(SPSInputBuffer &IB,
0182                             RemoteSymbolLookupSetElement &V) {
0183     return SPSArgList<SPSString, bool>::deserialize(IB, V.Name, V.Required);
0184   }
0185 };
0186 
0187 template <>
0188 class SPSSerializationTraits<SPSRemoteSymbolLookup, RemoteSymbolLookup> {
0189 public:
0190   static size_t size(const RemoteSymbolLookup &V) {
0191     return SPSArgList<uint64_t, SPSRemoteSymbolLookupSet>::size(V.H, V.Symbols);
0192   }
0193 
0194   static size_t serialize(SPSOutputBuffer &OB, const RemoteSymbolLookup &V) {
0195     return SPSArgList<uint64_t, SPSRemoteSymbolLookupSet>::serialize(OB, V.H,
0196                                                                      V.Symbols);
0197   }
0198 
0199   static size_t deserialize(SPSInputBuffer &IB, RemoteSymbolLookup &V) {
0200     return SPSArgList<uint64_t, SPSRemoteSymbolLookupSet>::deserialize(
0201         IB, V.H, V.Symbols);
0202   }
0203 };
0204 
0205 template <>
0206 class SPSSerializationTraits<SPSSimpleRemoteEPCExecutorInfo,
0207                              SimpleRemoteEPCExecutorInfo> {
0208 public:
0209   static size_t size(const SimpleRemoteEPCExecutorInfo &SI) {
0210     return SPSSimpleRemoteEPCExecutorInfo::AsArgList ::size(
0211         SI.TargetTriple, SI.PageSize, SI.BootstrapMap, SI.BootstrapSymbols);
0212   }
0213 
0214   static bool serialize(SPSOutputBuffer &OB,
0215                         const SimpleRemoteEPCExecutorInfo &SI) {
0216     return SPSSimpleRemoteEPCExecutorInfo::AsArgList ::serialize(
0217         OB, SI.TargetTriple, SI.PageSize, SI.BootstrapMap, SI.BootstrapSymbols);
0218   }
0219 
0220   static bool deserialize(SPSInputBuffer &IB, SimpleRemoteEPCExecutorInfo &SI) {
0221     return SPSSimpleRemoteEPCExecutorInfo::AsArgList ::deserialize(
0222         IB, SI.TargetTriple, SI.PageSize, SI.BootstrapMap, SI.BootstrapSymbols);
0223   }
0224 };
0225 
0226 using SPSLoadDylibSignature = SPSExpected<SPSExecutorAddr>(SPSExecutorAddr,
0227                                                            SPSString, uint64_t);
0228 
0229 using SPSLookupSymbolsSignature =
0230     SPSExpected<SPSSequence<SPSSequence<SPSExecutorAddr>>>(
0231         SPSExecutorAddr, SPSSequence<SPSRemoteSymbolLookup>);
0232 
0233 } // end namespace shared
0234 } // end namespace orc
0235 } // end namespace llvm
0236 
0237 #endif // LLVM_EXECUTIONENGINE_ORC_SHARED_SIMPLEREMOTEEPCUTILS_H