xref: /freebsd-src/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/Shared/SimpleRemoteEPCUtils.h (revision 06c3fb2749bda94cb5201f81ffdb8fa6c3161b2e)
1349cc55cSDimitry Andric //===--- SimpleRemoteEPCUtils.h - Utils for Simple Remote EPC ---*- C++ -*-===//
2349cc55cSDimitry Andric //
3349cc55cSDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4349cc55cSDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
5349cc55cSDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6349cc55cSDimitry Andric //
7349cc55cSDimitry Andric //===----------------------------------------------------------------------===//
8349cc55cSDimitry Andric //
9349cc55cSDimitry Andric // Message definitions and other utilities for SimpleRemoteEPC and
10349cc55cSDimitry Andric // SimpleRemoteEPCServer.
11349cc55cSDimitry Andric //
12349cc55cSDimitry Andric //===----------------------------------------------------------------------===//
13349cc55cSDimitry Andric 
14349cc55cSDimitry Andric #ifndef LLVM_EXECUTIONENGINE_ORC_SHARED_SIMPLEREMOTEEPCUTILS_H
15349cc55cSDimitry Andric #define LLVM_EXECUTIONENGINE_ORC_SHARED_SIMPLEREMOTEEPCUTILS_H
16349cc55cSDimitry Andric 
17349cc55cSDimitry Andric #include "llvm/ADT/ArrayRef.h"
18349cc55cSDimitry Andric #include "llvm/ADT/SmallVector.h"
19349cc55cSDimitry Andric #include "llvm/ADT/StringMap.h"
20349cc55cSDimitry Andric #include "llvm/ExecutionEngine/Orc/Shared/ExecutorAddress.h"
21349cc55cSDimitry Andric #include "llvm/ExecutionEngine/Orc/Shared/SimplePackedSerialization.h"
22349cc55cSDimitry Andric #include "llvm/Support/Error.h"
23349cc55cSDimitry Andric 
24349cc55cSDimitry Andric #include <atomic>
25349cc55cSDimitry Andric #include <mutex>
26349cc55cSDimitry Andric #include <string>
27349cc55cSDimitry Andric #include <thread>
28349cc55cSDimitry Andric 
29349cc55cSDimitry Andric namespace llvm {
30349cc55cSDimitry Andric namespace orc {
31349cc55cSDimitry Andric 
32349cc55cSDimitry Andric namespace SimpleRemoteEPCDefaultBootstrapSymbolNames {
33349cc55cSDimitry Andric extern const char *ExecutorSessionObjectName;
34349cc55cSDimitry Andric extern const char *DispatchFnName;
35349cc55cSDimitry Andric } // end namespace SimpleRemoteEPCDefaultBootstrapSymbolNames
36349cc55cSDimitry Andric 
37349cc55cSDimitry Andric enum class SimpleRemoteEPCOpcode : uint8_t {
38349cc55cSDimitry Andric   Setup,
39349cc55cSDimitry Andric   Hangup,
40349cc55cSDimitry Andric   Result,
41349cc55cSDimitry Andric   CallWrapper,
42349cc55cSDimitry Andric   LastOpC = CallWrapper
43349cc55cSDimitry Andric };
44349cc55cSDimitry Andric 
45349cc55cSDimitry Andric struct SimpleRemoteEPCExecutorInfo {
46349cc55cSDimitry Andric   std::string TargetTriple;
47349cc55cSDimitry Andric   uint64_t PageSize;
48*06c3fb27SDimitry Andric   StringMap<std::vector<char>> BootstrapMap;
49349cc55cSDimitry Andric   StringMap<ExecutorAddr> BootstrapSymbols;
50349cc55cSDimitry Andric };
51349cc55cSDimitry Andric 
52349cc55cSDimitry Andric using SimpleRemoteEPCArgBytesVector = SmallVector<char, 128>;
53349cc55cSDimitry Andric 
54349cc55cSDimitry Andric class SimpleRemoteEPCTransportClient {
55349cc55cSDimitry Andric public:
56349cc55cSDimitry Andric   enum HandleMessageAction { ContinueSession, EndSession };
57349cc55cSDimitry Andric 
58349cc55cSDimitry Andric   virtual ~SimpleRemoteEPCTransportClient();
59349cc55cSDimitry Andric 
60349cc55cSDimitry Andric   /// Handle receipt of a message.
61349cc55cSDimitry Andric   ///
62349cc55cSDimitry Andric   /// Returns an Error if the message cannot be handled, 'EndSession' if the
63349cc55cSDimitry Andric   /// client will not accept any further messages, and 'ContinueSession'
64349cc55cSDimitry Andric   /// otherwise.
65349cc55cSDimitry Andric   virtual Expected<HandleMessageAction>
66349cc55cSDimitry Andric   handleMessage(SimpleRemoteEPCOpcode OpC, uint64_t SeqNo, ExecutorAddr TagAddr,
67349cc55cSDimitry Andric                 SimpleRemoteEPCArgBytesVector ArgBytes) = 0;
68349cc55cSDimitry Andric 
69349cc55cSDimitry Andric   /// Handle a disconnection from the underlying transport. No further messages
70349cc55cSDimitry Andric   /// should be sent to handleMessage after this is called.
71349cc55cSDimitry Andric   /// Err may contain an Error value indicating unexpected disconnection. This
72349cc55cSDimitry Andric   /// allows clients to log such errors, but no attempt should be made at
73349cc55cSDimitry Andric   /// recovery (which should be handled inside the transport class, if it is
74349cc55cSDimitry Andric   /// supported at all).
75349cc55cSDimitry Andric   virtual void handleDisconnect(Error Err) = 0;
76349cc55cSDimitry Andric };
77349cc55cSDimitry Andric 
78349cc55cSDimitry Andric class SimpleRemoteEPCTransport {
79349cc55cSDimitry Andric public:
80349cc55cSDimitry Andric   virtual ~SimpleRemoteEPCTransport();
81349cc55cSDimitry Andric 
82349cc55cSDimitry Andric   /// Called during setup of the client to indicate that the client is ready
83349cc55cSDimitry Andric   /// to receive messages.
84349cc55cSDimitry Andric   ///
85349cc55cSDimitry Andric   /// Transport objects should not access the client until this method is
86349cc55cSDimitry Andric   /// called.
87349cc55cSDimitry Andric   virtual Error start() = 0;
88349cc55cSDimitry Andric 
89349cc55cSDimitry Andric   /// Send a SimpleRemoteEPC message.
90349cc55cSDimitry Andric   ///
91349cc55cSDimitry Andric   /// This function may be called concurrently. Subclasses should implement
92349cc55cSDimitry Andric   /// locking if required for the underlying transport.
93349cc55cSDimitry Andric   virtual Error sendMessage(SimpleRemoteEPCOpcode OpC, uint64_t SeqNo,
94349cc55cSDimitry Andric                             ExecutorAddr TagAddr, ArrayRef<char> ArgBytes) = 0;
95349cc55cSDimitry Andric 
96349cc55cSDimitry Andric   /// Trigger disconnection from the transport. The implementation should
97349cc55cSDimitry Andric   /// respond by calling handleDisconnect on the client once disconnection
98349cc55cSDimitry Andric   /// is complete. May be called more than once and from different threads.
99349cc55cSDimitry Andric   virtual void disconnect() = 0;
100349cc55cSDimitry Andric };
101349cc55cSDimitry Andric 
102349cc55cSDimitry Andric /// Uses read/write on FileDescriptors for transport.
103349cc55cSDimitry Andric class FDSimpleRemoteEPCTransport : public SimpleRemoteEPCTransport {
104349cc55cSDimitry Andric public:
105349cc55cSDimitry Andric   /// Create a FDSimpleRemoteEPCTransport using the given FDs for
106349cc55cSDimitry Andric   /// reading (InFD) and writing (OutFD).
107349cc55cSDimitry Andric   static Expected<std::unique_ptr<FDSimpleRemoteEPCTransport>>
108349cc55cSDimitry Andric   Create(SimpleRemoteEPCTransportClient &C, int InFD, int OutFD);
109349cc55cSDimitry Andric 
110349cc55cSDimitry Andric   /// Create a FDSimpleRemoteEPCTransport using the given FD for both
111349cc55cSDimitry Andric   /// reading and writing.
112349cc55cSDimitry Andric   static Expected<std::unique_ptr<FDSimpleRemoteEPCTransport>>
Create(SimpleRemoteEPCTransportClient & C,int FD)113349cc55cSDimitry Andric   Create(SimpleRemoteEPCTransportClient &C, int FD) {
114349cc55cSDimitry Andric     return Create(C, FD, FD);
115349cc55cSDimitry Andric   }
116349cc55cSDimitry Andric 
117349cc55cSDimitry Andric   ~FDSimpleRemoteEPCTransport() override;
118349cc55cSDimitry Andric 
119349cc55cSDimitry Andric   Error start() override;
120349cc55cSDimitry Andric 
121349cc55cSDimitry Andric   Error sendMessage(SimpleRemoteEPCOpcode OpC, uint64_t SeqNo,
122349cc55cSDimitry Andric                     ExecutorAddr TagAddr, ArrayRef<char> ArgBytes) override;
123349cc55cSDimitry Andric 
124349cc55cSDimitry Andric   void disconnect() override;
125349cc55cSDimitry Andric 
126349cc55cSDimitry Andric private:
FDSimpleRemoteEPCTransport(SimpleRemoteEPCTransportClient & C,int InFD,int OutFD)127349cc55cSDimitry Andric   FDSimpleRemoteEPCTransport(SimpleRemoteEPCTransportClient &C, int InFD,
128349cc55cSDimitry Andric                              int OutFD)
129349cc55cSDimitry Andric       : C(C), InFD(InFD), OutFD(OutFD) {}
130349cc55cSDimitry Andric 
131349cc55cSDimitry Andric   Error readBytes(char *Dst, size_t Size, bool *IsEOF = nullptr);
132349cc55cSDimitry Andric   int writeBytes(const char *Src, size_t Size);
133349cc55cSDimitry Andric   void listenLoop();
134349cc55cSDimitry Andric 
135349cc55cSDimitry Andric   std::mutex M;
136349cc55cSDimitry Andric   SimpleRemoteEPCTransportClient &C;
137349cc55cSDimitry Andric   std::thread ListenerThread;
138349cc55cSDimitry Andric   int InFD, OutFD;
139349cc55cSDimitry Andric   std::atomic<bool> Disconnected{false};
140349cc55cSDimitry Andric };
141349cc55cSDimitry Andric 
142349cc55cSDimitry Andric struct RemoteSymbolLookupSetElement {
143349cc55cSDimitry Andric   std::string Name;
144349cc55cSDimitry Andric   bool Required;
145349cc55cSDimitry Andric };
146349cc55cSDimitry Andric 
147349cc55cSDimitry Andric using RemoteSymbolLookupSet = std::vector<RemoteSymbolLookupSetElement>;
148349cc55cSDimitry Andric 
149349cc55cSDimitry Andric struct RemoteSymbolLookup {
150349cc55cSDimitry Andric   uint64_t H;
151349cc55cSDimitry Andric   RemoteSymbolLookupSet Symbols;
152349cc55cSDimitry Andric };
153349cc55cSDimitry Andric 
154349cc55cSDimitry Andric namespace shared {
155349cc55cSDimitry Andric 
156349cc55cSDimitry Andric using SPSRemoteSymbolLookupSetElement = SPSTuple<SPSString, bool>;
157349cc55cSDimitry Andric 
158349cc55cSDimitry Andric using SPSRemoteSymbolLookupSet = SPSSequence<SPSRemoteSymbolLookupSetElement>;
159349cc55cSDimitry Andric 
160349cc55cSDimitry Andric using SPSRemoteSymbolLookup = SPSTuple<uint64_t, SPSRemoteSymbolLookupSet>;
161349cc55cSDimitry Andric 
162349cc55cSDimitry Andric /// Tuple containing target triple, page size, and bootstrap symbols.
163349cc55cSDimitry Andric using SPSSimpleRemoteEPCExecutorInfo =
164349cc55cSDimitry Andric     SPSTuple<SPSString, uint64_t,
165*06c3fb27SDimitry Andric              SPSSequence<SPSTuple<SPSString, SPSSequence<char>>>,
166349cc55cSDimitry Andric              SPSSequence<SPSTuple<SPSString, SPSExecutorAddr>>>;
167349cc55cSDimitry Andric 
168349cc55cSDimitry Andric template <>
169349cc55cSDimitry Andric class SPSSerializationTraits<SPSRemoteSymbolLookupSetElement,
170349cc55cSDimitry Andric                              RemoteSymbolLookupSetElement> {
171349cc55cSDimitry Andric public:
size(const RemoteSymbolLookupSetElement & V)172349cc55cSDimitry Andric   static size_t size(const RemoteSymbolLookupSetElement &V) {
173349cc55cSDimitry Andric     return SPSArgList<SPSString, bool>::size(V.Name, V.Required);
174349cc55cSDimitry Andric   }
175349cc55cSDimitry Andric 
serialize(SPSOutputBuffer & OB,const RemoteSymbolLookupSetElement & V)176349cc55cSDimitry Andric   static size_t serialize(SPSOutputBuffer &OB,
177349cc55cSDimitry Andric                           const RemoteSymbolLookupSetElement &V) {
178349cc55cSDimitry Andric     return SPSArgList<SPSString, bool>::serialize(OB, V.Name, V.Required);
179349cc55cSDimitry Andric   }
180349cc55cSDimitry Andric 
deserialize(SPSInputBuffer & IB,RemoteSymbolLookupSetElement & V)181349cc55cSDimitry Andric   static size_t deserialize(SPSInputBuffer &IB,
182349cc55cSDimitry Andric                             RemoteSymbolLookupSetElement &V) {
183349cc55cSDimitry Andric     return SPSArgList<SPSString, bool>::deserialize(IB, V.Name, V.Required);
184349cc55cSDimitry Andric   }
185349cc55cSDimitry Andric };
186349cc55cSDimitry Andric 
187349cc55cSDimitry Andric template <>
188349cc55cSDimitry Andric class SPSSerializationTraits<SPSRemoteSymbolLookup, RemoteSymbolLookup> {
189349cc55cSDimitry Andric public:
size(const RemoteSymbolLookup & V)190349cc55cSDimitry Andric   static size_t size(const RemoteSymbolLookup &V) {
191349cc55cSDimitry Andric     return SPSArgList<uint64_t, SPSRemoteSymbolLookupSet>::size(V.H, V.Symbols);
192349cc55cSDimitry Andric   }
193349cc55cSDimitry Andric 
serialize(SPSOutputBuffer & OB,const RemoteSymbolLookup & V)194349cc55cSDimitry Andric   static size_t serialize(SPSOutputBuffer &OB, const RemoteSymbolLookup &V) {
195349cc55cSDimitry Andric     return SPSArgList<uint64_t, SPSRemoteSymbolLookupSet>::serialize(OB, V.H,
196349cc55cSDimitry Andric                                                                      V.Symbols);
197349cc55cSDimitry Andric   }
198349cc55cSDimitry Andric 
deserialize(SPSInputBuffer & IB,RemoteSymbolLookup & V)199349cc55cSDimitry Andric   static size_t deserialize(SPSInputBuffer &IB, RemoteSymbolLookup &V) {
200349cc55cSDimitry Andric     return SPSArgList<uint64_t, SPSRemoteSymbolLookupSet>::deserialize(
201349cc55cSDimitry Andric         IB, V.H, V.Symbols);
202349cc55cSDimitry Andric   }
203349cc55cSDimitry Andric };
204349cc55cSDimitry Andric 
205349cc55cSDimitry Andric template <>
206349cc55cSDimitry Andric class SPSSerializationTraits<SPSSimpleRemoteEPCExecutorInfo,
207349cc55cSDimitry Andric                              SimpleRemoteEPCExecutorInfo> {
208349cc55cSDimitry Andric public:
size(const SimpleRemoteEPCExecutorInfo & SI)209349cc55cSDimitry Andric   static size_t size(const SimpleRemoteEPCExecutorInfo &SI) {
210349cc55cSDimitry Andric     return SPSSimpleRemoteEPCExecutorInfo::AsArgList ::size(
211*06c3fb27SDimitry Andric         SI.TargetTriple, SI.PageSize, SI.BootstrapMap, SI.BootstrapSymbols);
212349cc55cSDimitry Andric   }
213349cc55cSDimitry Andric 
serialize(SPSOutputBuffer & OB,const SimpleRemoteEPCExecutorInfo & SI)214349cc55cSDimitry Andric   static bool serialize(SPSOutputBuffer &OB,
215349cc55cSDimitry Andric                         const SimpleRemoteEPCExecutorInfo &SI) {
216349cc55cSDimitry Andric     return SPSSimpleRemoteEPCExecutorInfo::AsArgList ::serialize(
217*06c3fb27SDimitry Andric         OB, SI.TargetTriple, SI.PageSize, SI.BootstrapMap, SI.BootstrapSymbols);
218349cc55cSDimitry Andric   }
219349cc55cSDimitry Andric 
deserialize(SPSInputBuffer & IB,SimpleRemoteEPCExecutorInfo & SI)220349cc55cSDimitry Andric   static bool deserialize(SPSInputBuffer &IB, SimpleRemoteEPCExecutorInfo &SI) {
221349cc55cSDimitry Andric     return SPSSimpleRemoteEPCExecutorInfo::AsArgList ::deserialize(
222*06c3fb27SDimitry Andric         IB, SI.TargetTriple, SI.PageSize, SI.BootstrapMap, SI.BootstrapSymbols);
223349cc55cSDimitry Andric   }
224349cc55cSDimitry Andric };
225349cc55cSDimitry Andric 
226349cc55cSDimitry Andric using SPSLoadDylibSignature = SPSExpected<SPSExecutorAddr>(SPSExecutorAddr,
227349cc55cSDimitry Andric                                                            SPSString, uint64_t);
228349cc55cSDimitry Andric 
229349cc55cSDimitry Andric using SPSLookupSymbolsSignature =
230349cc55cSDimitry Andric     SPSExpected<SPSSequence<SPSSequence<SPSExecutorAddr>>>(
231349cc55cSDimitry Andric         SPSExecutorAddr, SPSSequence<SPSRemoteSymbolLookup>);
232349cc55cSDimitry Andric 
233349cc55cSDimitry Andric } // end namespace shared
234349cc55cSDimitry Andric } // end namespace orc
235349cc55cSDimitry Andric } // end namespace llvm
236349cc55cSDimitry Andric 
237349cc55cSDimitry Andric #endif // LLVM_EXECUTIONENGINE_ORC_SHARED_SIMPLEREMOTEEPCUTILS_H
238