1 | //===--- TargetProcessControlTypes.h -- Shared Core/TPC types ---*- 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 | // TargetProcessControl types that are used by both the Orc and |
10 | // OrcTargetProcess libraries. |
11 | // |
12 | //===----------------------------------------------------------------------===// |
13 | |
14 | #ifndef LLVM_EXECUTIONENGINE_ORC_SHARED_TARGETPROCESSCONTROLTYPES_H |
15 | #define LLVM_EXECUTIONENGINE_ORC_SHARED_TARGETPROCESSCONTROLTYPES_H |
16 | |
17 | #include "llvm/ADT/ArrayRef.h" |
18 | #include "llvm/ADT/StringRef.h" |
19 | #include "llvm/ExecutionEngine/JITSymbol.h" |
20 | #include "llvm/ExecutionEngine/Orc/Shared/AllocationActions.h" |
21 | #include "llvm/ExecutionEngine/Orc/Shared/ExecutorAddress.h" |
22 | #include "llvm/ExecutionEngine/Orc/Shared/ExecutorSymbolDef.h" |
23 | #include "llvm/ExecutionEngine/Orc/Shared/MemoryFlags.h" |
24 | #include "llvm/ExecutionEngine/Orc/Shared/SimplePackedSerialization.h" |
25 | #include "llvm/ExecutionEngine/Orc/Shared/WrapperFunctionUtils.h" |
26 | #include "llvm/Support/Memory.h" |
27 | |
28 | #include <vector> |
29 | |
30 | namespace llvm { |
31 | namespace orc { |
32 | namespace tpctypes { |
33 | |
34 | struct RemoteAllocGroup { |
35 | RemoteAllocGroup() = default; |
36 | RemoteAllocGroup(MemProt Prot) : Prot(Prot) {} |
37 | RemoteAllocGroup(MemProt Prot, bool FinalizeLifetime) |
38 | : Prot(Prot), FinalizeLifetime(FinalizeLifetime) {} |
39 | RemoteAllocGroup(const AllocGroup &AG) : Prot(AG.getMemProt()) { |
40 | assert(AG.getMemLifetime() != orc::MemLifetime::NoAlloc && |
41 | "Cannot use no-alloc memory in a remote alloc request" ); |
42 | FinalizeLifetime = AG.getMemLifetime() == orc::MemLifetime::Finalize; |
43 | } |
44 | |
45 | MemProt Prot; |
46 | bool FinalizeLifetime = false; |
47 | }; |
48 | |
49 | struct SegFinalizeRequest { |
50 | RemoteAllocGroup RAG; |
51 | ExecutorAddr Addr; |
52 | uint64_t Size; |
53 | ArrayRef<char> Content; |
54 | }; |
55 | |
56 | struct FinalizeRequest { |
57 | std::vector<SegFinalizeRequest> Segments; |
58 | shared::AllocActions Actions; |
59 | }; |
60 | |
61 | struct SharedMemorySegFinalizeRequest { |
62 | RemoteAllocGroup RAG; |
63 | ExecutorAddr Addr; |
64 | uint64_t Size; |
65 | }; |
66 | |
67 | struct SharedMemoryFinalizeRequest { |
68 | std::vector<SharedMemorySegFinalizeRequest> Segments; |
69 | shared::AllocActions Actions; |
70 | }; |
71 | |
72 | template <typename T> struct UIntWrite { |
73 | UIntWrite() = default; |
74 | UIntWrite(ExecutorAddr Addr, T Value) : Addr(Addr), Value(Value) {} |
75 | |
76 | ExecutorAddr Addr; |
77 | T Value = 0; |
78 | }; |
79 | |
80 | /// Describes a write to a uint8_t. |
81 | using UInt8Write = UIntWrite<uint8_t>; |
82 | |
83 | /// Describes a write to a uint16_t. |
84 | using UInt16Write = UIntWrite<uint16_t>; |
85 | |
86 | /// Describes a write to a uint32_t. |
87 | using UInt32Write = UIntWrite<uint32_t>; |
88 | |
89 | /// Describes a write to a uint64_t. |
90 | using UInt64Write = UIntWrite<uint64_t>; |
91 | |
92 | /// Describes a write to a buffer. |
93 | /// For use with TargetProcessControl::MemoryAccess objects. |
94 | struct BufferWrite { |
95 | BufferWrite() = default; |
96 | BufferWrite(ExecutorAddr Addr, StringRef Buffer) |
97 | : Addr(Addr), Buffer(Buffer) {} |
98 | |
99 | ExecutorAddr Addr; |
100 | StringRef Buffer; |
101 | }; |
102 | |
103 | /// Describes a write to a pointer. |
104 | /// For use with TargetProcessControl::MemoryAccess objects. |
105 | struct PointerWrite { |
106 | PointerWrite() = default; |
107 | PointerWrite(ExecutorAddr Addr, ExecutorAddr Value) |
108 | : Addr(Addr), Value(Value) {} |
109 | |
110 | ExecutorAddr Addr; |
111 | ExecutorAddr Value; |
112 | }; |
113 | |
114 | /// A handle used to represent a loaded dylib in the target process. |
115 | using DylibHandle = ExecutorAddr; |
116 | |
117 | using LookupResult = std::vector<ExecutorSymbolDef>; |
118 | |
119 | } // end namespace tpctypes |
120 | |
121 | namespace shared { |
122 | |
123 | class SPSRemoteAllocGroup; |
124 | |
125 | using SPSSegFinalizeRequest = |
126 | SPSTuple<SPSRemoteAllocGroup, SPSExecutorAddr, uint64_t, SPSSequence<char>>; |
127 | |
128 | using SPSFinalizeRequest = SPSTuple<SPSSequence<SPSSegFinalizeRequest>, |
129 | SPSSequence<SPSAllocActionCallPair>>; |
130 | |
131 | using SPSSharedMemorySegFinalizeRequest = |
132 | SPSTuple<SPSRemoteAllocGroup, SPSExecutorAddr, uint64_t>; |
133 | |
134 | using SPSSharedMemoryFinalizeRequest = |
135 | SPSTuple<SPSSequence<SPSSharedMemorySegFinalizeRequest>, |
136 | SPSSequence<SPSAllocActionCallPair>>; |
137 | |
138 | template <typename T> |
139 | using SPSMemoryAccessUIntWrite = SPSTuple<SPSExecutorAddr, T>; |
140 | |
141 | using SPSMemoryAccessUInt8Write = SPSMemoryAccessUIntWrite<uint8_t>; |
142 | using SPSMemoryAccessUInt16Write = SPSMemoryAccessUIntWrite<uint16_t>; |
143 | using SPSMemoryAccessUInt32Write = SPSMemoryAccessUIntWrite<uint32_t>; |
144 | using SPSMemoryAccessUInt64Write = SPSMemoryAccessUIntWrite<uint64_t>; |
145 | |
146 | using SPSMemoryAccessBufferWrite = SPSTuple<SPSExecutorAddr, SPSSequence<char>>; |
147 | using SPSMemoryAccessPointerWrite = SPSTuple<SPSExecutorAddr, SPSExecutorAddr>; |
148 | |
149 | template <> |
150 | class SPSSerializationTraits<SPSRemoteAllocGroup, tpctypes::RemoteAllocGroup> { |
151 | enum WireBits { |
152 | ReadBit = 1 << 0, |
153 | WriteBit = 1 << 1, |
154 | ExecBit = 1 << 2, |
155 | FinalizeBit = 1 << 3 |
156 | }; |
157 | |
158 | public: |
159 | static size_t size(const tpctypes::RemoteAllocGroup &RAG) { |
160 | // All AllocGroup values encode to the same size. |
161 | return SPSArgList<uint8_t>::size(Arg: uint8_t(0)); |
162 | } |
163 | |
164 | static bool serialize(SPSOutputBuffer &OB, |
165 | const tpctypes::RemoteAllocGroup &RAG) { |
166 | uint8_t WireValue = 0; |
167 | if ((RAG.Prot & MemProt::Read) != MemProt::None) |
168 | WireValue |= ReadBit; |
169 | if ((RAG.Prot & MemProt::Write) != MemProt::None) |
170 | WireValue |= WriteBit; |
171 | if ((RAG.Prot & MemProt::Exec) != MemProt::None) |
172 | WireValue |= ExecBit; |
173 | if (RAG.FinalizeLifetime) |
174 | WireValue |= FinalizeBit; |
175 | return SPSArgList<uint8_t>::serialize(OB, Arg: WireValue); |
176 | } |
177 | |
178 | static bool deserialize(SPSInputBuffer &IB, tpctypes::RemoteAllocGroup &RAG) { |
179 | uint8_t Val; |
180 | if (!SPSArgList<uint8_t>::deserialize(IB, Arg&: Val)) |
181 | return false; |
182 | MemProt MP = MemProt::None; |
183 | if (Val & ReadBit) |
184 | MP |= MemProt::Read; |
185 | if (Val & WriteBit) |
186 | MP |= MemProt::Write; |
187 | if (Val & ExecBit) |
188 | MP |= MemProt::Exec; |
189 | bool FinalizeLifetime = (Val & FinalizeBit) ? true : false; |
190 | RAG = {MP, FinalizeLifetime}; |
191 | return true; |
192 | } |
193 | }; |
194 | |
195 | template <> |
196 | class SPSSerializationTraits<SPSSegFinalizeRequest, |
197 | tpctypes::SegFinalizeRequest> { |
198 | using SFRAL = SPSSegFinalizeRequest::AsArgList; |
199 | |
200 | public: |
201 | static size_t size(const tpctypes::SegFinalizeRequest &SFR) { |
202 | return SFRAL::size(Arg: SFR.RAG, Args: SFR.Addr, Args: SFR.Size, Args: SFR.Content); |
203 | } |
204 | |
205 | static bool serialize(SPSOutputBuffer &OB, |
206 | const tpctypes::SegFinalizeRequest &SFR) { |
207 | return SFRAL::serialize(OB, Arg: SFR.RAG, Args: SFR.Addr, Args: SFR.Size, Args: SFR.Content); |
208 | } |
209 | |
210 | static bool deserialize(SPSInputBuffer &IB, |
211 | tpctypes::SegFinalizeRequest &SFR) { |
212 | return SFRAL::deserialize(IB, Arg&: SFR.RAG, Args&: SFR.Addr, Args&: SFR.Size, Args&: SFR.Content); |
213 | } |
214 | }; |
215 | |
216 | template <> |
217 | class SPSSerializationTraits<SPSFinalizeRequest, tpctypes::FinalizeRequest> { |
218 | using FRAL = SPSFinalizeRequest::AsArgList; |
219 | |
220 | public: |
221 | static size_t size(const tpctypes::FinalizeRequest &FR) { |
222 | return FRAL::size(Arg: FR.Segments, Args: FR.Actions); |
223 | } |
224 | |
225 | static bool serialize(SPSOutputBuffer &OB, |
226 | const tpctypes::FinalizeRequest &FR) { |
227 | return FRAL::serialize(OB, Arg: FR.Segments, Args: FR.Actions); |
228 | } |
229 | |
230 | static bool deserialize(SPSInputBuffer &IB, tpctypes::FinalizeRequest &FR) { |
231 | return FRAL::deserialize(IB, Arg&: FR.Segments, Args&: FR.Actions); |
232 | } |
233 | }; |
234 | |
235 | template <> |
236 | class SPSSerializationTraits<SPSSharedMemorySegFinalizeRequest, |
237 | tpctypes::SharedMemorySegFinalizeRequest> { |
238 | using SFRAL = SPSSharedMemorySegFinalizeRequest::AsArgList; |
239 | |
240 | public: |
241 | static size_t size(const tpctypes::SharedMemorySegFinalizeRequest &SFR) { |
242 | return SFRAL::size(Arg: SFR.RAG, Args: SFR.Addr, Args: SFR.Size); |
243 | } |
244 | |
245 | static bool serialize(SPSOutputBuffer &OB, |
246 | const tpctypes::SharedMemorySegFinalizeRequest &SFR) { |
247 | return SFRAL::serialize(OB, Arg: SFR.RAG, Args: SFR.Addr, Args: SFR.Size); |
248 | } |
249 | |
250 | static bool deserialize(SPSInputBuffer &IB, |
251 | tpctypes::SharedMemorySegFinalizeRequest &SFR) { |
252 | return SFRAL::deserialize(IB, Arg&: SFR.RAG, Args&: SFR.Addr, Args&: SFR.Size); |
253 | } |
254 | }; |
255 | |
256 | template <> |
257 | class SPSSerializationTraits<SPSSharedMemoryFinalizeRequest, |
258 | tpctypes::SharedMemoryFinalizeRequest> { |
259 | using FRAL = SPSSharedMemoryFinalizeRequest::AsArgList; |
260 | |
261 | public: |
262 | static size_t size(const tpctypes::SharedMemoryFinalizeRequest &FR) { |
263 | return FRAL::size(Arg: FR.Segments, Args: FR.Actions); |
264 | } |
265 | |
266 | static bool serialize(SPSOutputBuffer &OB, |
267 | const tpctypes::SharedMemoryFinalizeRequest &FR) { |
268 | return FRAL::serialize(OB, Arg: FR.Segments, Args: FR.Actions); |
269 | } |
270 | |
271 | static bool deserialize(SPSInputBuffer &IB, |
272 | tpctypes::SharedMemoryFinalizeRequest &FR) { |
273 | return FRAL::deserialize(IB, Arg&: FR.Segments, Args&: FR.Actions); |
274 | } |
275 | }; |
276 | |
277 | template <typename T> |
278 | class SPSSerializationTraits<SPSMemoryAccessUIntWrite<T>, |
279 | tpctypes::UIntWrite<T>> { |
280 | public: |
281 | static size_t size(const tpctypes::UIntWrite<T> &W) { |
282 | return SPSTuple<SPSExecutorAddr, T>::AsArgList::size(W.Addr, W.Value); |
283 | } |
284 | |
285 | static bool serialize(SPSOutputBuffer &OB, const tpctypes::UIntWrite<T> &W) { |
286 | return SPSTuple<SPSExecutorAddr, T>::AsArgList::serialize(OB, W.Addr, |
287 | W.Value); |
288 | } |
289 | |
290 | static bool deserialize(SPSInputBuffer &IB, tpctypes::UIntWrite<T> &W) { |
291 | return SPSTuple<SPSExecutorAddr, T>::AsArgList::deserialize(IB, W.Addr, |
292 | W.Value); |
293 | } |
294 | }; |
295 | |
296 | template <> |
297 | class SPSSerializationTraits<SPSMemoryAccessBufferWrite, |
298 | tpctypes::BufferWrite> { |
299 | public: |
300 | static size_t size(const tpctypes::BufferWrite &W) { |
301 | return SPSTuple<SPSExecutorAddr, SPSSequence<char>>::AsArgList::size( |
302 | Arg: W.Addr, Args: W.Buffer); |
303 | } |
304 | |
305 | static bool serialize(SPSOutputBuffer &OB, const tpctypes::BufferWrite &W) { |
306 | return SPSTuple<SPSExecutorAddr, SPSSequence<char>>::AsArgList ::serialize( |
307 | OB, Arg: W.Addr, Args: W.Buffer); |
308 | } |
309 | |
310 | static bool deserialize(SPSInputBuffer &IB, tpctypes::BufferWrite &W) { |
311 | return SPSTuple<SPSExecutorAddr, |
312 | SPSSequence<char>>::AsArgList ::deserialize(IB, Arg&: W.Addr, |
313 | Args&: W.Buffer); |
314 | } |
315 | }; |
316 | |
317 | template <> |
318 | class SPSSerializationTraits<SPSMemoryAccessPointerWrite, |
319 | tpctypes::PointerWrite> { |
320 | public: |
321 | static size_t size(const tpctypes::PointerWrite &W) { |
322 | return SPSTuple<SPSExecutorAddr, SPSExecutorAddr>::AsArgList::size(Arg: W.Addr, |
323 | Args: W.Value); |
324 | } |
325 | |
326 | static bool serialize(SPSOutputBuffer &OB, const tpctypes::PointerWrite &W) { |
327 | return SPSTuple<SPSExecutorAddr, SPSExecutorAddr>::AsArgList::serialize( |
328 | OB, Arg: W.Addr, Args: W.Value); |
329 | } |
330 | |
331 | static bool deserialize(SPSInputBuffer &IB, tpctypes::PointerWrite &W) { |
332 | return SPSTuple<SPSExecutorAddr, SPSExecutorAddr>::AsArgList::deserialize( |
333 | IB, Arg&: W.Addr, Args&: W.Value); |
334 | } |
335 | }; |
336 | |
337 | } // end namespace shared |
338 | } // end namespace orc |
339 | } // end namespace llvm |
340 | |
341 | #endif // LLVM_EXECUTIONENGINE_ORC_SHARED_TARGETPROCESSCONTROLTYPES_H |
342 | |