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