1//===--- SimpleRemoteEPCUtils.h - Utils for Simple Remote EPC ---*- 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// Message definitions and other utilities for SimpleRemoteEPC and
10// SimpleRemoteEPCServer.
11//
12//===----------------------------------------------------------------------===//
13
14#ifndef LLVM_EXECUTIONENGINE_ORC_SHARED_SIMPLEREMOTEEPCUTILS_H
15#define LLVM_EXECUTIONENGINE_ORC_SHARED_SIMPLEREMOTEEPCUTILS_H
16
17#include "llvm/ADT/ArrayRef.h"
18#include "llvm/ADT/SmallVector.h"
19#include "llvm/ADT/StringMap.h"
20#include "llvm/ExecutionEngine/Orc/Shared/ExecutorAddress.h"
21#include "llvm/ExecutionEngine/Orc/Shared/SimplePackedSerialization.h"
22#include "llvm/Support/Error.h"
23
24#include <atomic>
25#include <mutex>
26#include <string>
27#include <thread>
28
29namespace llvm {
30namespace orc {
31
32namespace SimpleRemoteEPCDefaultBootstrapSymbolNames {
33extern const char *ExecutorSessionObjectName;
34extern const char *DispatchFnName;
35} // end namespace SimpleRemoteEPCDefaultBootstrapSymbolNames
36
37enum class SimpleRemoteEPCOpcode : uint8_t {
38 Setup,
39 Hangup,
40 Result,
41 CallWrapper,
42 LastOpC = CallWrapper
43};
44
45struct SimpleRemoteEPCExecutorInfo {
46 std::string TargetTriple;
47 uint64_t PageSize;
48 StringMap<std::vector<char>> BootstrapMap;
49 StringMap<ExecutorAddr> BootstrapSymbols;
50};
51
52using SimpleRemoteEPCArgBytesVector = SmallVector<char, 128>;
53
54class SimpleRemoteEPCTransportClient {
55public:
56 enum HandleMessageAction { ContinueSession, EndSession };
57
58 virtual ~SimpleRemoteEPCTransportClient();
59
60 /// Handle receipt of a message.
61 ///
62 /// Returns an Error if the message cannot be handled, 'EndSession' if the
63 /// client will not accept any further messages, and 'ContinueSession'
64 /// otherwise.
65 virtual Expected<HandleMessageAction>
66 handleMessage(SimpleRemoteEPCOpcode OpC, uint64_t SeqNo, ExecutorAddr TagAddr,
67 SimpleRemoteEPCArgBytesVector ArgBytes) = 0;
68
69 /// Handle a disconnection from the underlying transport. No further messages
70 /// should be sent to handleMessage after this is called.
71 /// Err may contain an Error value indicating unexpected disconnection. This
72 /// allows clients to log such errors, but no attempt should be made at
73 /// recovery (which should be handled inside the transport class, if it is
74 /// supported at all).
75 virtual void handleDisconnect(Error Err) = 0;
76};
77
78class SimpleRemoteEPCTransport {
79public:
80 virtual ~SimpleRemoteEPCTransport();
81
82 /// Called during setup of the client to indicate that the client is ready
83 /// to receive messages.
84 ///
85 /// Transport objects should not access the client until this method is
86 /// called.
87 virtual Error start() = 0;
88
89 /// Send a SimpleRemoteEPC message.
90 ///
91 /// This function may be called concurrently. Subclasses should implement
92 /// locking if required for the underlying transport.
93 virtual Error sendMessage(SimpleRemoteEPCOpcode OpC, uint64_t SeqNo,
94 ExecutorAddr TagAddr, ArrayRef<char> ArgBytes) = 0;
95
96 /// Trigger disconnection from the transport. The implementation should
97 /// respond by calling handleDisconnect on the client once disconnection
98 /// is complete. May be called more than once and from different threads.
99 virtual void disconnect() = 0;
100};
101
102/// Uses read/write on FileDescriptors for transport.
103class FDSimpleRemoteEPCTransport : public SimpleRemoteEPCTransport {
104public:
105 /// Create a FDSimpleRemoteEPCTransport using the given FDs for
106 /// reading (InFD) and writing (OutFD).
107 static Expected<std::unique_ptr<FDSimpleRemoteEPCTransport>>
108 Create(SimpleRemoteEPCTransportClient &C, int InFD, int OutFD);
109
110 /// Create a FDSimpleRemoteEPCTransport using the given FD for both
111 /// reading and writing.
112 static Expected<std::unique_ptr<FDSimpleRemoteEPCTransport>>
113 Create(SimpleRemoteEPCTransportClient &C, int FD) {
114 return Create(C, InFD: FD, OutFD: FD);
115 }
116
117 ~FDSimpleRemoteEPCTransport() override;
118
119 Error start() override;
120
121 Error sendMessage(SimpleRemoteEPCOpcode OpC, uint64_t SeqNo,
122 ExecutorAddr TagAddr, ArrayRef<char> ArgBytes) override;
123
124 void disconnect() override;
125
126private:
127 FDSimpleRemoteEPCTransport(SimpleRemoteEPCTransportClient &C, int InFD,
128 int OutFD)
129 : C(C), InFD(InFD), OutFD(OutFD) {}
130
131 Error readBytes(char *Dst, size_t Size, bool *IsEOF = nullptr);
132 int writeBytes(const char *Src, size_t Size);
133 void listenLoop();
134
135 std::mutex M;
136 SimpleRemoteEPCTransportClient &C;
137 std::thread ListenerThread;
138 int InFD, OutFD;
139 std::atomic<bool> Disconnected{false};
140};
141
142struct RemoteSymbolLookupSetElement {
143 std::string Name;
144 bool Required;
145};
146
147using RemoteSymbolLookupSet = std::vector<RemoteSymbolLookupSetElement>;
148
149struct RemoteSymbolLookup {
150 uint64_t H;
151 RemoteSymbolLookupSet Symbols;
152};
153
154namespace shared {
155
156using SPSRemoteSymbolLookupSetElement = SPSTuple<SPSString, bool>;
157
158using SPSRemoteSymbolLookupSet = SPSSequence<SPSRemoteSymbolLookupSetElement>;
159
160using SPSRemoteSymbolLookup = SPSTuple<uint64_t, SPSRemoteSymbolLookupSet>;
161
162/// Tuple containing target triple, page size, and bootstrap symbols.
163using SPSSimpleRemoteEPCExecutorInfo =
164 SPSTuple<SPSString, uint64_t,
165 SPSSequence<SPSTuple<SPSString, SPSSequence<char>>>,
166 SPSSequence<SPSTuple<SPSString, SPSExecutorAddr>>>;
167
168template <>
169class SPSSerializationTraits<SPSRemoteSymbolLookupSetElement,
170 RemoteSymbolLookupSetElement> {
171public:
172 static size_t size(const RemoteSymbolLookupSetElement &V) {
173 return SPSArgList<SPSString, bool>::size(Arg: V.Name, Args: V.Required);
174 }
175
176 static size_t serialize(SPSOutputBuffer &OB,
177 const RemoteSymbolLookupSetElement &V) {
178 return SPSArgList<SPSString, bool>::serialize(OB, Arg: V.Name, Args: V.Required);
179 }
180
181 static size_t deserialize(SPSInputBuffer &IB,
182 RemoteSymbolLookupSetElement &V) {
183 return SPSArgList<SPSString, bool>::deserialize(IB, Arg&: V.Name, Args&: V.Required);
184 }
185};
186
187template <>
188class SPSSerializationTraits<SPSRemoteSymbolLookup, RemoteSymbolLookup> {
189public:
190 static size_t size(const RemoteSymbolLookup &V) {
191 return SPSArgList<uint64_t, SPSRemoteSymbolLookupSet>::size(Arg: V.H, Args: V.Symbols);
192 }
193
194 static size_t serialize(SPSOutputBuffer &OB, const RemoteSymbolLookup &V) {
195 return SPSArgList<uint64_t, SPSRemoteSymbolLookupSet>::serialize(OB, Arg: V.H,
196 Args: V.Symbols);
197 }
198
199 static size_t deserialize(SPSInputBuffer &IB, RemoteSymbolLookup &V) {
200 return SPSArgList<uint64_t, SPSRemoteSymbolLookupSet>::deserialize(
201 IB, Arg&: V.H, Args&: V.Symbols);
202 }
203};
204
205template <>
206class SPSSerializationTraits<SPSSimpleRemoteEPCExecutorInfo,
207 SimpleRemoteEPCExecutorInfo> {
208public:
209 static size_t size(const SimpleRemoteEPCExecutorInfo &SI) {
210 return SPSSimpleRemoteEPCExecutorInfo::AsArgList ::size(
211 Arg: SI.TargetTriple, Args: SI.PageSize, Args: SI.BootstrapMap, Args: SI.BootstrapSymbols);
212 }
213
214 static bool serialize(SPSOutputBuffer &OB,
215 const SimpleRemoteEPCExecutorInfo &SI) {
216 return SPSSimpleRemoteEPCExecutorInfo::AsArgList ::serialize(
217 OB, Arg: SI.TargetTriple, Args: SI.PageSize, Args: SI.BootstrapMap, Args: SI.BootstrapSymbols);
218 }
219
220 static bool deserialize(SPSInputBuffer &IB, SimpleRemoteEPCExecutorInfo &SI) {
221 return SPSSimpleRemoteEPCExecutorInfo::AsArgList ::deserialize(
222 IB, Arg&: SI.TargetTriple, Args&: SI.PageSize, Args&: SI.BootstrapMap, Args&: SI.BootstrapSymbols);
223 }
224};
225
226using SPSLoadDylibSignature = SPSExpected<SPSExecutorAddr>(SPSExecutorAddr,
227 SPSString, uint64_t);
228
229using SPSLookupSymbolsSignature =
230 SPSExpected<SPSSequence<SPSSequence<SPSExecutorAddr>>>(
231 SPSExecutorAddr, SPSSequence<SPSRemoteSymbolLookup>);
232
233} // end namespace shared
234} // end namespace orc
235} // end namespace llvm
236
237#endif // LLVM_EXECUTIONENGINE_ORC_SHARED_SIMPLEREMOTEEPCUTILS_H
238

source code of llvm/include/llvm/ExecutionEngine/Orc/Shared/SimpleRemoteEPCUtils.h