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
30namespace llvm {
31namespace orc {
32namespace tpctypes {
33
34struct 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
49struct SegFinalizeRequest {
50 RemoteAllocGroup RAG;
51 ExecutorAddr Addr;
52 uint64_t Size;
53 ArrayRef<char> Content;
54};
55
56struct FinalizeRequest {
57 std::vector<SegFinalizeRequest> Segments;
58 shared::AllocActions Actions;
59};
60
61struct SharedMemorySegFinalizeRequest {
62 RemoteAllocGroup RAG;
63 ExecutorAddr Addr;
64 uint64_t Size;
65};
66
67struct SharedMemoryFinalizeRequest {
68 std::vector<SharedMemorySegFinalizeRequest> Segments;
69 shared::AllocActions Actions;
70};
71
72template <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.
81using UInt8Write = UIntWrite<uint8_t>;
82
83/// Describes a write to a uint16_t.
84using UInt16Write = UIntWrite<uint16_t>;
85
86/// Describes a write to a uint32_t.
87using UInt32Write = UIntWrite<uint32_t>;
88
89/// Describes a write to a uint64_t.
90using UInt64Write = UIntWrite<uint64_t>;
91
92/// Describes a write to a buffer.
93/// For use with TargetProcessControl::MemoryAccess objects.
94struct 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.
105struct 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.
115using DylibHandle = ExecutorAddr;
116
117using LookupResult = std::vector<ExecutorSymbolDef>;
118
119} // end namespace tpctypes
120
121namespace shared {
122
123class SPSRemoteAllocGroup;
124
125using SPSSegFinalizeRequest =
126 SPSTuple<SPSRemoteAllocGroup, SPSExecutorAddr, uint64_t, SPSSequence<char>>;
127
128using SPSFinalizeRequest = SPSTuple<SPSSequence<SPSSegFinalizeRequest>,
129 SPSSequence<SPSAllocActionCallPair>>;
130
131using SPSSharedMemorySegFinalizeRequest =
132 SPSTuple<SPSRemoteAllocGroup, SPSExecutorAddr, uint64_t>;
133
134using SPSSharedMemoryFinalizeRequest =
135 SPSTuple<SPSSequence<SPSSharedMemorySegFinalizeRequest>,
136 SPSSequence<SPSAllocActionCallPair>>;
137
138template <typename T>
139using SPSMemoryAccessUIntWrite = SPSTuple<SPSExecutorAddr, T>;
140
141using SPSMemoryAccessUInt8Write = SPSMemoryAccessUIntWrite<uint8_t>;
142using SPSMemoryAccessUInt16Write = SPSMemoryAccessUIntWrite<uint16_t>;
143using SPSMemoryAccessUInt32Write = SPSMemoryAccessUIntWrite<uint32_t>;
144using SPSMemoryAccessUInt64Write = SPSMemoryAccessUIntWrite<uint64_t>;
145
146using SPSMemoryAccessBufferWrite = SPSTuple<SPSExecutorAddr, SPSSequence<char>>;
147using SPSMemoryAccessPointerWrite = SPSTuple<SPSExecutorAddr, SPSExecutorAddr>;
148
149template <>
150class 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
158public:
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
195template <>
196class SPSSerializationTraits<SPSSegFinalizeRequest,
197 tpctypes::SegFinalizeRequest> {
198 using SFRAL = SPSSegFinalizeRequest::AsArgList;
199
200public:
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
216template <>
217class SPSSerializationTraits<SPSFinalizeRequest, tpctypes::FinalizeRequest> {
218 using FRAL = SPSFinalizeRequest::AsArgList;
219
220public:
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
235template <>
236class SPSSerializationTraits<SPSSharedMemorySegFinalizeRequest,
237 tpctypes::SharedMemorySegFinalizeRequest> {
238 using SFRAL = SPSSharedMemorySegFinalizeRequest::AsArgList;
239
240public:
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
256template <>
257class SPSSerializationTraits<SPSSharedMemoryFinalizeRequest,
258 tpctypes::SharedMemoryFinalizeRequest> {
259 using FRAL = SPSSharedMemoryFinalizeRequest::AsArgList;
260
261public:
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
277template <typename T>
278class SPSSerializationTraits<SPSMemoryAccessUIntWrite<T>,
279 tpctypes::UIntWrite<T>> {
280public:
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
296template <>
297class SPSSerializationTraits<SPSMemoryAccessBufferWrite,
298 tpctypes::BufferWrite> {
299public:
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
317template <>
318class SPSSerializationTraits<SPSMemoryAccessPointerWrite,
319 tpctypes::PointerWrite> {
320public:
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

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