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 21 #include <vector> 22 23 namespace llvm { 24 namespace orc { 25 namespace tpctypes { 26 27 template <typename T> struct UIntWrite { 28 UIntWrite() = default; UIntWriteUIntWrite29 UIntWrite(JITTargetAddress Address, T Value) 30 : Address(Address), Value(Value) {} 31 32 JITTargetAddress Address = 0; 33 T Value = 0; 34 }; 35 36 /// Describes a write to a uint8_t. 37 using UInt8Write = UIntWrite<uint8_t>; 38 39 /// Describes a write to a uint16_t. 40 using UInt16Write = UIntWrite<uint16_t>; 41 42 /// Describes a write to a uint32_t. 43 using UInt32Write = UIntWrite<uint32_t>; 44 45 /// Describes a write to a uint64_t. 46 using UInt64Write = UIntWrite<uint64_t>; 47 48 /// Describes a write to a buffer. 49 /// For use with TargetProcessControl::MemoryAccess objects. 50 struct BufferWrite { 51 BufferWrite() = default; BufferWriteBufferWrite52 BufferWrite(JITTargetAddress Address, StringRef Buffer) 53 : Address(Address), Buffer(Buffer) {} 54 55 JITTargetAddress Address = 0; 56 StringRef Buffer; 57 }; 58 59 /// A handle used to represent a loaded dylib in the target process. 60 using DylibHandle = JITTargetAddress; 61 62 using LookupResult = std::vector<JITTargetAddress>; 63 64 /// Either a uint8_t array or a uint8_t*. 65 union CWrapperFunctionResultData { 66 uint8_t Value[8]; 67 uint8_t *ValuePtr; 68 }; 69 70 /// C ABI compatible wrapper function result. 71 /// 72 /// This can be safely returned from extern "C" functions, but should be used 73 /// to construct a WrapperFunctionResult for safety. 74 struct CWrapperFunctionResult { 75 uint64_t Size; 76 CWrapperFunctionResultData Data; 77 void (*Destroy)(CWrapperFunctionResultData Data, uint64_t Size); 78 }; 79 80 /// C++ wrapper function result: Same as CWrapperFunctionResult but 81 /// auto-releases memory. 82 class WrapperFunctionResult { 83 public: 84 /// Create a default WrapperFunctionResult. WrapperFunctionResult()85 WrapperFunctionResult() { zeroInit(R); } 86 87 /// Create a WrapperFunctionResult from a CWrapperFunctionResult. This 88 /// instance takes ownership of the result object and will automatically 89 /// call the Destroy member upon destruction. WrapperFunctionResult(CWrapperFunctionResult R)90 WrapperFunctionResult(CWrapperFunctionResult R) : R(R) {} 91 92 WrapperFunctionResult(const WrapperFunctionResult &) = delete; 93 WrapperFunctionResult &operator=(const WrapperFunctionResult &) = delete; 94 WrapperFunctionResult(WrapperFunctionResult && Other)95 WrapperFunctionResult(WrapperFunctionResult &&Other) { 96 zeroInit(R); 97 std::swap(R, Other.R); 98 } 99 100 WrapperFunctionResult &operator=(WrapperFunctionResult &&Other) { 101 CWrapperFunctionResult Tmp; 102 zeroInit(Tmp); 103 std::swap(Tmp, Other.R); 104 std::swap(R, Tmp); 105 return *this; 106 } 107 ~WrapperFunctionResult()108 ~WrapperFunctionResult() { 109 if (R.Destroy) 110 R.Destroy(R.Data, R.Size); 111 } 112 113 /// Relinquish ownership of and return the CWrapperFunctionResult. release()114 CWrapperFunctionResult release() { 115 CWrapperFunctionResult Tmp; 116 zeroInit(Tmp); 117 std::swap(R, Tmp); 118 return Tmp; 119 } 120 121 /// Get an ArrayRef covering the data in the result. getData()122 ArrayRef<uint8_t> getData() const { 123 if (R.Size <= 8) 124 return ArrayRef<uint8_t>(R.Data.Value, R.Size); 125 return ArrayRef<uint8_t>(R.Data.ValuePtr, R.Size); 126 } 127 128 /// Create a WrapperFunctionResult from the given integer, provided its 129 /// size is no greater than 64 bits. 130 template <typename T, 131 typename _ = std::enable_if_t<std::is_integral<T>::value && 132 sizeof(T) <= sizeof(uint64_t)>> from(T Value)133 static WrapperFunctionResult from(T Value) { 134 CWrapperFunctionResult R; 135 R.Size = sizeof(T); 136 memcpy(&R.Data.Value, Value, R.Size); 137 R.Destroy = nullptr; 138 return R; 139 } 140 141 /// Create a WrapperFunctionResult from the given string. 142 static WrapperFunctionResult from(StringRef S); 143 144 /// Always free Data.ValuePtr by calling free on it. 145 static void destroyWithFree(CWrapperFunctionResultData Data, uint64_t Size); 146 147 /// Always free Data.ValuePtr by calling delete[] on it. 148 static void destroyWithDeleteArray(CWrapperFunctionResultData Data, 149 uint64_t Size); 150 151 private: zeroInit(CWrapperFunctionResult & R)152 static void zeroInit(CWrapperFunctionResult &R) { 153 R.Size = 0; 154 R.Data.ValuePtr = nullptr; 155 R.Destroy = nullptr; 156 } 157 158 CWrapperFunctionResult R; 159 }; 160 161 } // end namespace tpctypes 162 } // end namespace orc 163 } // end namespace llvm 164 165 #endif // LLVM_EXECUTIONENGINE_ORC_SHARED_TARGETPROCESSCONTROLTYPES_H 166