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/MemoryFlags.h"
23 #include "llvm/ExecutionEngine/Orc/Shared/SimplePackedSerialization.h"
24 #include "llvm/ExecutionEngine/Orc/Shared/WrapperFunctionUtils.h"
25 #include "llvm/Support/Memory.h"
26 
27 #include <vector>
28 
29 namespace llvm {
30 namespace orc {
31 namespace tpctypes {
32 
33 struct SegFinalizeRequest {
34   AllocGroup AG;
35   ExecutorAddr Addr;
36   uint64_t Size;
37   ArrayRef<char> Content;
38 };
39 
40 struct FinalizeRequest {
41   std::vector<SegFinalizeRequest> Segments;
42   shared::AllocActions Actions;
43 };
44 
45 struct SharedMemorySegFinalizeRequest {
46   AllocGroup AG;
47   ExecutorAddr Addr;
48   uint64_t Size;
49 };
50 
51 struct SharedMemoryFinalizeRequest {
52   std::vector<SharedMemorySegFinalizeRequest> Segments;
53   shared::AllocActions Actions;
54 };
55 
56 template <typename T> struct UIntWrite {
57   UIntWrite() = default;
UIntWriteUIntWrite58   UIntWrite(ExecutorAddr Addr, T Value) : Addr(Addr), Value(Value) {}
59 
60   ExecutorAddr Addr;
61   T Value = 0;
62 };
63 
64 /// Describes a write to a uint8_t.
65 using UInt8Write = UIntWrite<uint8_t>;
66 
67 /// Describes a write to a uint16_t.
68 using UInt16Write = UIntWrite<uint16_t>;
69 
70 /// Describes a write to a uint32_t.
71 using UInt32Write = UIntWrite<uint32_t>;
72 
73 /// Describes a write to a uint64_t.
74 using UInt64Write = UIntWrite<uint64_t>;
75 
76 /// Describes a write to a buffer.
77 /// For use with TargetProcessControl::MemoryAccess objects.
78 struct BufferWrite {
79   BufferWrite() = default;
BufferWriteBufferWrite80   BufferWrite(ExecutorAddr Addr, StringRef Buffer)
81       : Addr(Addr), Buffer(Buffer) {}
82 
83   ExecutorAddr Addr;
84   StringRef Buffer;
85 };
86 
87 /// A handle used to represent a loaded dylib in the target process.
88 using DylibHandle = ExecutorAddr;
89 
90 using LookupResult = std::vector<ExecutorAddr>;
91 
92 } // end namespace tpctypes
93 
94 namespace shared {
95 
96 class SPSAllocGroup {};
97 
98 using SPSSegFinalizeRequest =
99     SPSTuple<SPSAllocGroup, SPSExecutorAddr, uint64_t, SPSSequence<char>>;
100 
101 using SPSFinalizeRequest = SPSTuple<SPSSequence<SPSSegFinalizeRequest>,
102                                     SPSSequence<SPSAllocActionCallPair>>;
103 
104 using SPSSharedMemorySegFinalizeRequest =
105     SPSTuple<SPSAllocGroup, SPSExecutorAddr, uint64_t>;
106 
107 using SPSSharedMemoryFinalizeRequest =
108     SPSTuple<SPSSequence<SPSSharedMemorySegFinalizeRequest>,
109              SPSSequence<SPSAllocActionCallPair>>;
110 
111 template <typename T>
112 using SPSMemoryAccessUIntWrite = SPSTuple<SPSExecutorAddr, T>;
113 
114 using SPSMemoryAccessUInt8Write = SPSMemoryAccessUIntWrite<uint8_t>;
115 using SPSMemoryAccessUInt16Write = SPSMemoryAccessUIntWrite<uint16_t>;
116 using SPSMemoryAccessUInt32Write = SPSMemoryAccessUIntWrite<uint32_t>;
117 using SPSMemoryAccessUInt64Write = SPSMemoryAccessUIntWrite<uint64_t>;
118 
119 using SPSMemoryAccessBufferWrite = SPSTuple<SPSExecutorAddr, SPSSequence<char>>;
120 
121 template <> class SPSSerializationTraits<SPSAllocGroup, AllocGroup> {
122   enum WireBits {
123     ReadBit = 1 << 0,
124     WriteBit = 1 << 1,
125     ExecBit = 1 << 2,
126     FinalizeBit = 1 << 3
127   };
128 
129 public:
size(const AllocGroup & AG)130   static size_t size(const AllocGroup &AG) {
131     // All AllocGroup values encode to the same size.
132     return SPSArgList<uint8_t>::size(uint8_t(0));
133   }
134 
serialize(SPSOutputBuffer & OB,const AllocGroup & AG)135   static bool serialize(SPSOutputBuffer &OB, const AllocGroup &AG) {
136     uint8_t WireValue = 0;
137     if ((AG.getMemProt() & MemProt::Read) != MemProt::None)
138       WireValue |= ReadBit;
139     if ((AG.getMemProt() & MemProt::Write) != MemProt::None)
140       WireValue |= WriteBit;
141     if ((AG.getMemProt() & MemProt::Exec) != MemProt::None)
142       WireValue |= ExecBit;
143     if (AG.getMemDeallocPolicy() == MemDeallocPolicy::Finalize)
144       WireValue |= FinalizeBit;
145     return SPSArgList<uint8_t>::serialize(OB, WireValue);
146   }
147 
deserialize(SPSInputBuffer & IB,AllocGroup & AG)148   static bool deserialize(SPSInputBuffer &IB, AllocGroup &AG) {
149     uint8_t Val;
150     if (!SPSArgList<uint8_t>::deserialize(IB, Val))
151       return false;
152     MemProt MP = MemProt::None;
153     if (Val & ReadBit)
154       MP |= MemProt::Read;
155     if (Val & WriteBit)
156       MP |= MemProt::Write;
157     if (Val & ExecBit)
158       MP |= MemProt::Exec;
159     MemDeallocPolicy MDP = (Val & FinalizeBit) ? MemDeallocPolicy::Finalize
160                                                : MemDeallocPolicy::Standard;
161     AG = AllocGroup(MP, MDP);
162     return true;
163   }
164 };
165 
166 template <>
167 class SPSSerializationTraits<SPSSegFinalizeRequest,
168                              tpctypes::SegFinalizeRequest> {
169   using SFRAL = SPSSegFinalizeRequest::AsArgList;
170 
171 public:
size(const tpctypes::SegFinalizeRequest & SFR)172   static size_t size(const tpctypes::SegFinalizeRequest &SFR) {
173     return SFRAL::size(SFR.AG, SFR.Addr, SFR.Size, SFR.Content);
174   }
175 
serialize(SPSOutputBuffer & OB,const tpctypes::SegFinalizeRequest & SFR)176   static bool serialize(SPSOutputBuffer &OB,
177                         const tpctypes::SegFinalizeRequest &SFR) {
178     return SFRAL::serialize(OB, SFR.AG, SFR.Addr, SFR.Size, SFR.Content);
179   }
180 
deserialize(SPSInputBuffer & IB,tpctypes::SegFinalizeRequest & SFR)181   static bool deserialize(SPSInputBuffer &IB,
182                           tpctypes::SegFinalizeRequest &SFR) {
183     return SFRAL::deserialize(IB, SFR.AG, SFR.Addr, SFR.Size, SFR.Content);
184   }
185 };
186 
187 template <>
188 class SPSSerializationTraits<SPSFinalizeRequest, tpctypes::FinalizeRequest> {
189   using FRAL = SPSFinalizeRequest::AsArgList;
190 
191 public:
size(const tpctypes::FinalizeRequest & FR)192   static size_t size(const tpctypes::FinalizeRequest &FR) {
193     return FRAL::size(FR.Segments, FR.Actions);
194   }
195 
serialize(SPSOutputBuffer & OB,const tpctypes::FinalizeRequest & FR)196   static bool serialize(SPSOutputBuffer &OB,
197                         const tpctypes::FinalizeRequest &FR) {
198     return FRAL::serialize(OB, FR.Segments, FR.Actions);
199   }
200 
deserialize(SPSInputBuffer & IB,tpctypes::FinalizeRequest & FR)201   static bool deserialize(SPSInputBuffer &IB, tpctypes::FinalizeRequest &FR) {
202     return FRAL::deserialize(IB, FR.Segments, FR.Actions);
203   }
204 };
205 
206 template <>
207 class SPSSerializationTraits<SPSSharedMemorySegFinalizeRequest,
208                              tpctypes::SharedMemorySegFinalizeRequest> {
209   using SFRAL = SPSSharedMemorySegFinalizeRequest::AsArgList;
210 
211 public:
size(const tpctypes::SharedMemorySegFinalizeRequest & SFR)212   static size_t size(const tpctypes::SharedMemorySegFinalizeRequest &SFR) {
213     return SFRAL::size(SFR.AG, SFR.Addr, SFR.Size);
214   }
215 
serialize(SPSOutputBuffer & OB,const tpctypes::SharedMemorySegFinalizeRequest & SFR)216   static bool serialize(SPSOutputBuffer &OB,
217                         const tpctypes::SharedMemorySegFinalizeRequest &SFR) {
218     return SFRAL::serialize(OB, SFR.AG, SFR.Addr, SFR.Size);
219   }
220 
deserialize(SPSInputBuffer & IB,tpctypes::SharedMemorySegFinalizeRequest & SFR)221   static bool deserialize(SPSInputBuffer &IB,
222                           tpctypes::SharedMemorySegFinalizeRequest &SFR) {
223     return SFRAL::deserialize(IB, SFR.AG, SFR.Addr, SFR.Size);
224   }
225 };
226 
227 template <>
228 class SPSSerializationTraits<SPSSharedMemoryFinalizeRequest,
229                              tpctypes::SharedMemoryFinalizeRequest> {
230   using FRAL = SPSSharedMemoryFinalizeRequest::AsArgList;
231 
232 public:
size(const tpctypes::SharedMemoryFinalizeRequest & FR)233   static size_t size(const tpctypes::SharedMemoryFinalizeRequest &FR) {
234     return FRAL::size(FR.Segments, FR.Actions);
235   }
236 
serialize(SPSOutputBuffer & OB,const tpctypes::SharedMemoryFinalizeRequest & FR)237   static bool serialize(SPSOutputBuffer &OB,
238                         const tpctypes::SharedMemoryFinalizeRequest &FR) {
239     return FRAL::serialize(OB, FR.Segments, FR.Actions);
240   }
241 
deserialize(SPSInputBuffer & IB,tpctypes::SharedMemoryFinalizeRequest & FR)242   static bool deserialize(SPSInputBuffer &IB,
243                           tpctypes::SharedMemoryFinalizeRequest &FR) {
244     return FRAL::deserialize(IB, FR.Segments, FR.Actions);
245   }
246 };
247 
248 template <typename T>
249 class SPSSerializationTraits<SPSMemoryAccessUIntWrite<T>,
250                              tpctypes::UIntWrite<T>> {
251 public:
size(const tpctypes::UIntWrite<T> & W)252   static size_t size(const tpctypes::UIntWrite<T> &W) {
253     return SPSTuple<SPSExecutorAddr, T>::AsArgList::size(W.Addr, W.Value);
254   }
255 
serialize(SPSOutputBuffer & OB,const tpctypes::UIntWrite<T> & W)256   static bool serialize(SPSOutputBuffer &OB, const tpctypes::UIntWrite<T> &W) {
257     return SPSTuple<SPSExecutorAddr, T>::AsArgList::serialize(OB, W.Addr,
258                                                               W.Value);
259   }
260 
deserialize(SPSInputBuffer & IB,tpctypes::UIntWrite<T> & W)261   static bool deserialize(SPSInputBuffer &IB, tpctypes::UIntWrite<T> &W) {
262     return SPSTuple<SPSExecutorAddr, T>::AsArgList::deserialize(IB, W.Addr,
263                                                                 W.Value);
264   }
265 };
266 
267 template <>
268 class SPSSerializationTraits<SPSMemoryAccessBufferWrite,
269                              tpctypes::BufferWrite> {
270 public:
size(const tpctypes::BufferWrite & W)271   static size_t size(const tpctypes::BufferWrite &W) {
272     return SPSTuple<SPSExecutorAddr, SPSSequence<char>>::AsArgList::size(
273         W.Addr, W.Buffer);
274   }
275 
serialize(SPSOutputBuffer & OB,const tpctypes::BufferWrite & W)276   static bool serialize(SPSOutputBuffer &OB, const tpctypes::BufferWrite &W) {
277     return SPSTuple<SPSExecutorAddr, SPSSequence<char>>::AsArgList ::serialize(
278         OB, W.Addr, W.Buffer);
279   }
280 
deserialize(SPSInputBuffer & IB,tpctypes::BufferWrite & W)281   static bool deserialize(SPSInputBuffer &IB, tpctypes::BufferWrite &W) {
282     return SPSTuple<SPSExecutorAddr,
283                     SPSSequence<char>>::AsArgList ::deserialize(IB, W.Addr,
284                                                                 W.Buffer);
285   }
286 };
287 
288 } // end namespace shared
289 } // end namespace orc
290 } // end namespace llvm
291 
292 #endif // LLVM_EXECUTIONENGINE_ORC_SHARED_TARGETPROCESSCONTROLTYPES_H
293