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