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(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, WireValue);
176   }
177 
178   static bool deserialize(SPSInputBuffer &IB, tpctypes::RemoteAllocGroup &RAG) {
179     uint8_t Val;
180     if (!SPSArgList<uint8_t>::deserialize(IB, 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(SFR.RAG, SFR.Addr, SFR.Size, SFR.Content);
203   }
204 
205   static bool serialize(SPSOutputBuffer &OB,
206                         const tpctypes::SegFinalizeRequest &SFR) {
207     return SFRAL::serialize(OB, SFR.RAG, SFR.Addr, SFR.Size, SFR.Content);
208   }
209 
210   static bool deserialize(SPSInputBuffer &IB,
211                           tpctypes::SegFinalizeRequest &SFR) {
212     return SFRAL::deserialize(IB, SFR.RAG, SFR.Addr, SFR.Size, 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(FR.Segments, FR.Actions);
223   }
224 
225   static bool serialize(SPSOutputBuffer &OB,
226                         const tpctypes::FinalizeRequest &FR) {
227     return FRAL::serialize(OB, FR.Segments, FR.Actions);
228   }
229 
230   static bool deserialize(SPSInputBuffer &IB, tpctypes::FinalizeRequest &FR) {
231     return FRAL::deserialize(IB, FR.Segments, 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(SFR.RAG, SFR.Addr, SFR.Size);
243   }
244 
245   static bool serialize(SPSOutputBuffer &OB,
246                         const tpctypes::SharedMemorySegFinalizeRequest &SFR) {
247     return SFRAL::serialize(OB, SFR.RAG, SFR.Addr, SFR.Size);
248   }
249 
250   static bool deserialize(SPSInputBuffer &IB,
251                           tpctypes::SharedMemorySegFinalizeRequest &SFR) {
252     return SFRAL::deserialize(IB, SFR.RAG, SFR.Addr, 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(FR.Segments, FR.Actions);
264   }
265 
266   static bool serialize(SPSOutputBuffer &OB,
267                         const tpctypes::SharedMemoryFinalizeRequest &FR) {
268     return FRAL::serialize(OB, FR.Segments, FR.Actions);
269   }
270 
271   static bool deserialize(SPSInputBuffer &IB,
272                           tpctypes::SharedMemoryFinalizeRequest &FR) {
273     return FRAL::deserialize(IB, FR.Segments, 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         W.Addr, W.Buffer);
303   }
304 
305   static bool serialize(SPSOutputBuffer &OB, const tpctypes::BufferWrite &W) {
306     return SPSTuple<SPSExecutorAddr, SPSSequence<char>>::AsArgList ::serialize(
307         OB, W.Addr, W.Buffer);
308   }
309 
310   static bool deserialize(SPSInputBuffer &IB, tpctypes::BufferWrite &W) {
311     return SPSTuple<SPSExecutorAddr,
312                     SPSSequence<char>>::AsArgList ::deserialize(IB, W.Addr,
313                                                                 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(W.Addr,
323                                                                        W.Value);
324   }
325 
326   static bool serialize(SPSOutputBuffer &OB, const tpctypes::PointerWrite &W) {
327     return SPSTuple<SPSExecutorAddr, SPSExecutorAddr>::AsArgList::serialize(
328         OB, W.Addr, W.Value);
329   }
330 
331   static bool deserialize(SPSInputBuffer &IB, tpctypes::PointerWrite &W) {
332     return SPSTuple<SPSExecutorAddr, SPSExecutorAddr>::AsArgList::deserialize(
333         IB, W.Addr, 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