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 RemoteAllocGroup { 34 RemoteAllocGroup() = default; 35 RemoteAllocGroup(MemProt Prot) : Prot(Prot) {} 36 RemoteAllocGroup(MemProt Prot, bool FinalizeLifetime) 37 : Prot(Prot), FinalizeLifetime(FinalizeLifetime) {} 38 RemoteAllocGroup(const AllocGroup &AG) : Prot(AG.getMemProt()) { 39 assert(AG.getMemLifetimePolicy() != orc::MemLifetimePolicy::NoAlloc && 40 "Cannot use no-alloc memory in a remote alloc request"); 41 FinalizeLifetime = 42 AG.getMemLifetimePolicy() == orc::MemLifetimePolicy::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 /// A handle used to represent a loaded dylib in the target process. 104 using DylibHandle = ExecutorAddr; 105 106 using LookupResult = std::vector<ExecutorAddr>; 107 108 } // end namespace tpctypes 109 110 namespace shared { 111 112 class SPSRemoteAllocGroup; 113 114 using SPSSegFinalizeRequest = 115 SPSTuple<SPSRemoteAllocGroup, SPSExecutorAddr, uint64_t, SPSSequence<char>>; 116 117 using SPSFinalizeRequest = SPSTuple<SPSSequence<SPSSegFinalizeRequest>, 118 SPSSequence<SPSAllocActionCallPair>>; 119 120 using SPSSharedMemorySegFinalizeRequest = 121 SPSTuple<SPSRemoteAllocGroup, SPSExecutorAddr, uint64_t>; 122 123 using SPSSharedMemoryFinalizeRequest = 124 SPSTuple<SPSSequence<SPSSharedMemorySegFinalizeRequest>, 125 SPSSequence<SPSAllocActionCallPair>>; 126 127 template <typename T> 128 using SPSMemoryAccessUIntWrite = SPSTuple<SPSExecutorAddr, T>; 129 130 using SPSMemoryAccessUInt8Write = SPSMemoryAccessUIntWrite<uint8_t>; 131 using SPSMemoryAccessUInt16Write = SPSMemoryAccessUIntWrite<uint16_t>; 132 using SPSMemoryAccessUInt32Write = SPSMemoryAccessUIntWrite<uint32_t>; 133 using SPSMemoryAccessUInt64Write = SPSMemoryAccessUIntWrite<uint64_t>; 134 135 using SPSMemoryAccessBufferWrite = SPSTuple<SPSExecutorAddr, SPSSequence<char>>; 136 137 template <> 138 class SPSSerializationTraits<SPSRemoteAllocGroup, tpctypes::RemoteAllocGroup> { 139 enum WireBits { 140 ReadBit = 1 << 0, 141 WriteBit = 1 << 1, 142 ExecBit = 1 << 2, 143 FinalizeBit = 1 << 3 144 }; 145 146 public: 147 static size_t size(const tpctypes::RemoteAllocGroup &RAG) { 148 // All AllocGroup values encode to the same size. 149 return SPSArgList<uint8_t>::size(uint8_t(0)); 150 } 151 152 static bool serialize(SPSOutputBuffer &OB, 153 const tpctypes::RemoteAllocGroup &RAG) { 154 uint8_t WireValue = 0; 155 if ((RAG.Prot & MemProt::Read) != MemProt::None) 156 WireValue |= ReadBit; 157 if ((RAG.Prot & MemProt::Write) != MemProt::None) 158 WireValue |= WriteBit; 159 if ((RAG.Prot & MemProt::Exec) != MemProt::None) 160 WireValue |= ExecBit; 161 if (RAG.FinalizeLifetime) 162 WireValue |= FinalizeBit; 163 return SPSArgList<uint8_t>::serialize(OB, WireValue); 164 } 165 166 static bool deserialize(SPSInputBuffer &IB, tpctypes::RemoteAllocGroup &RAG) { 167 uint8_t Val; 168 if (!SPSArgList<uint8_t>::deserialize(IB, Val)) 169 return false; 170 MemProt MP = MemProt::None; 171 if (Val & ReadBit) 172 MP |= MemProt::Read; 173 if (Val & WriteBit) 174 MP |= MemProt::Write; 175 if (Val & ExecBit) 176 MP |= MemProt::Exec; 177 bool FinalizeLifetime = (Val & FinalizeBit) ? true : false; 178 RAG = {MP, FinalizeLifetime}; 179 return true; 180 } 181 }; 182 183 template <> 184 class SPSSerializationTraits<SPSSegFinalizeRequest, 185 tpctypes::SegFinalizeRequest> { 186 using SFRAL = SPSSegFinalizeRequest::AsArgList; 187 188 public: 189 static size_t size(const tpctypes::SegFinalizeRequest &SFR) { 190 return SFRAL::size(SFR.RAG, SFR.Addr, SFR.Size, SFR.Content); 191 } 192 193 static bool serialize(SPSOutputBuffer &OB, 194 const tpctypes::SegFinalizeRequest &SFR) { 195 return SFRAL::serialize(OB, SFR.RAG, SFR.Addr, SFR.Size, SFR.Content); 196 } 197 198 static bool deserialize(SPSInputBuffer &IB, 199 tpctypes::SegFinalizeRequest &SFR) { 200 return SFRAL::deserialize(IB, SFR.RAG, SFR.Addr, SFR.Size, SFR.Content); 201 } 202 }; 203 204 template <> 205 class SPSSerializationTraits<SPSFinalizeRequest, tpctypes::FinalizeRequest> { 206 using FRAL = SPSFinalizeRequest::AsArgList; 207 208 public: 209 static size_t size(const tpctypes::FinalizeRequest &FR) { 210 return FRAL::size(FR.Segments, FR.Actions); 211 } 212 213 static bool serialize(SPSOutputBuffer &OB, 214 const tpctypes::FinalizeRequest &FR) { 215 return FRAL::serialize(OB, FR.Segments, FR.Actions); 216 } 217 218 static bool deserialize(SPSInputBuffer &IB, tpctypes::FinalizeRequest &FR) { 219 return FRAL::deserialize(IB, FR.Segments, FR.Actions); 220 } 221 }; 222 223 template <> 224 class SPSSerializationTraits<SPSSharedMemorySegFinalizeRequest, 225 tpctypes::SharedMemorySegFinalizeRequest> { 226 using SFRAL = SPSSharedMemorySegFinalizeRequest::AsArgList; 227 228 public: 229 static size_t size(const tpctypes::SharedMemorySegFinalizeRequest &SFR) { 230 return SFRAL::size(SFR.RAG, SFR.Addr, SFR.Size); 231 } 232 233 static bool serialize(SPSOutputBuffer &OB, 234 const tpctypes::SharedMemorySegFinalizeRequest &SFR) { 235 return SFRAL::serialize(OB, SFR.RAG, SFR.Addr, SFR.Size); 236 } 237 238 static bool deserialize(SPSInputBuffer &IB, 239 tpctypes::SharedMemorySegFinalizeRequest &SFR) { 240 return SFRAL::deserialize(IB, SFR.RAG, SFR.Addr, SFR.Size); 241 } 242 }; 243 244 template <> 245 class SPSSerializationTraits<SPSSharedMemoryFinalizeRequest, 246 tpctypes::SharedMemoryFinalizeRequest> { 247 using FRAL = SPSSharedMemoryFinalizeRequest::AsArgList; 248 249 public: 250 static size_t size(const tpctypes::SharedMemoryFinalizeRequest &FR) { 251 return FRAL::size(FR.Segments, FR.Actions); 252 } 253 254 static bool serialize(SPSOutputBuffer &OB, 255 const tpctypes::SharedMemoryFinalizeRequest &FR) { 256 return FRAL::serialize(OB, FR.Segments, FR.Actions); 257 } 258 259 static bool deserialize(SPSInputBuffer &IB, 260 tpctypes::SharedMemoryFinalizeRequest &FR) { 261 return FRAL::deserialize(IB, FR.Segments, FR.Actions); 262 } 263 }; 264 265 template <typename T> 266 class SPSSerializationTraits<SPSMemoryAccessUIntWrite<T>, 267 tpctypes::UIntWrite<T>> { 268 public: 269 static size_t size(const tpctypes::UIntWrite<T> &W) { 270 return SPSTuple<SPSExecutorAddr, T>::AsArgList::size(W.Addr, W.Value); 271 } 272 273 static bool serialize(SPSOutputBuffer &OB, const tpctypes::UIntWrite<T> &W) { 274 return SPSTuple<SPSExecutorAddr, T>::AsArgList::serialize(OB, W.Addr, 275 W.Value); 276 } 277 278 static bool deserialize(SPSInputBuffer &IB, tpctypes::UIntWrite<T> &W) { 279 return SPSTuple<SPSExecutorAddr, T>::AsArgList::deserialize(IB, W.Addr, 280 W.Value); 281 } 282 }; 283 284 template <> 285 class SPSSerializationTraits<SPSMemoryAccessBufferWrite, 286 tpctypes::BufferWrite> { 287 public: 288 static size_t size(const tpctypes::BufferWrite &W) { 289 return SPSTuple<SPSExecutorAddr, SPSSequence<char>>::AsArgList::size( 290 W.Addr, W.Buffer); 291 } 292 293 static bool serialize(SPSOutputBuffer &OB, const tpctypes::BufferWrite &W) { 294 return SPSTuple<SPSExecutorAddr, SPSSequence<char>>::AsArgList ::serialize( 295 OB, W.Addr, W.Buffer); 296 } 297 298 static bool deserialize(SPSInputBuffer &IB, tpctypes::BufferWrite &W) { 299 return SPSTuple<SPSExecutorAddr, 300 SPSSequence<char>>::AsArgList ::deserialize(IB, W.Addr, 301 W.Buffer); 302 } 303 }; 304 305 } // end namespace shared 306 } // end namespace orc 307 } // end namespace llvm 308 309 #endif // LLVM_EXECUTIONENGINE_ORC_SHARED_TARGETPROCESSCONTROLTYPES_H 310