1 //===------ ExecutorAddress.h - Executing process address -------*- 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 // Represents an address in the executing program. 10 // 11 //===----------------------------------------------------------------------===// 12 13 #ifndef LLVM_EXECUTIONENGINE_ORC_SHARED_EXECUTORADDRESS_H 14 #define LLVM_EXECUTIONENGINE_ORC_SHARED_EXECUTORADDRESS_H 15 16 #include "llvm/ExecutionEngine/Orc/Shared/SimplePackedSerialization.h" 17 18 #include <cassert> 19 #include <type_traits> 20 21 namespace llvm { 22 namespace orc { 23 24 /// Represents the difference between two addresses in the executor process. 25 class ExecutorAddrDiff { 26 public: 27 ExecutorAddrDiff() = default; 28 explicit ExecutorAddrDiff(uint64_t Value) : Value(Value) {} 29 30 uint64_t getValue() const { return Value; } 31 32 private: 33 int64_t Value = 0; 34 }; 35 36 /// Represents an address in the executor process. 37 class ExecutorAddress { 38 public: 39 ExecutorAddress() = default; 40 explicit ExecutorAddress(uint64_t Addr) : Addr(Addr) {} 41 42 /// Create an ExecutorAddress from the given pointer. 43 /// Warning: This should only be used when JITing in-process. 44 template <typename T> static ExecutorAddress fromPtr(T *Value) { 45 return ExecutorAddress( 46 static_cast<uint64_t>(reinterpret_cast<uintptr_t>(Value))); 47 } 48 49 /// Cast this ExecutorAddress to a pointer of the given type. 50 /// Warning: This should only be esude when JITing in-process. 51 template <typename T> T toPtr() const { 52 static_assert(std::is_pointer<T>::value, "T must be a pointer type"); 53 uintptr_t IntPtr = static_cast<uintptr_t>(Addr); 54 assert(IntPtr == Addr && 55 "JITTargetAddress value out of range for uintptr_t"); 56 return reinterpret_cast<T>(IntPtr); 57 } 58 59 uint64_t getValue() const { return Addr; } 60 void setValue(uint64_t Addr) { this->Addr = Addr; } 61 bool isNull() const { return Addr == 0; } 62 63 explicit operator bool() const { return Addr != 0; } 64 65 friend bool operator==(const ExecutorAddress &LHS, 66 const ExecutorAddress &RHS) { 67 return LHS.Addr == RHS.Addr; 68 } 69 70 friend bool operator!=(const ExecutorAddress &LHS, 71 const ExecutorAddress &RHS) { 72 return LHS.Addr != RHS.Addr; 73 } 74 75 friend bool operator<(const ExecutorAddress &LHS, 76 const ExecutorAddress &RHS) { 77 return LHS.Addr < RHS.Addr; 78 } 79 80 friend bool operator<=(const ExecutorAddress &LHS, 81 const ExecutorAddress &RHS) { 82 return LHS.Addr <= RHS.Addr; 83 } 84 85 friend bool operator>(const ExecutorAddress &LHS, 86 const ExecutorAddress &RHS) { 87 return LHS.Addr > RHS.Addr; 88 } 89 90 friend bool operator>=(const ExecutorAddress &LHS, 91 const ExecutorAddress &RHS) { 92 return LHS.Addr >= RHS.Addr; 93 } 94 95 ExecutorAddress &operator++() { 96 ++Addr; 97 return *this; 98 } 99 ExecutorAddress &operator--() { 100 --Addr; 101 return *this; 102 } 103 ExecutorAddress operator++(int) { return ExecutorAddress(Addr++); } 104 ExecutorAddress operator--(int) { return ExecutorAddress(Addr++); } 105 106 ExecutorAddress &operator+=(const ExecutorAddrDiff Delta) { 107 Addr += Delta.getValue(); 108 return *this; 109 } 110 111 ExecutorAddress &operator-=(const ExecutorAddrDiff Delta) { 112 Addr -= Delta.getValue(); 113 return *this; 114 } 115 116 private: 117 uint64_t Addr = 0; 118 }; 119 120 /// Subtracting two addresses yields an offset. 121 inline ExecutorAddrDiff operator-(const ExecutorAddress &LHS, 122 const ExecutorAddress &RHS) { 123 return ExecutorAddrDiff(LHS.getValue() - RHS.getValue()); 124 } 125 126 /// Adding an offset and an address yields an address. 127 inline ExecutorAddress operator+(const ExecutorAddress &LHS, 128 const ExecutorAddrDiff &RHS) { 129 return ExecutorAddress(LHS.getValue() + RHS.getValue()); 130 } 131 132 /// Adding an address and an offset yields an address. 133 inline ExecutorAddress operator+(const ExecutorAddrDiff &LHS, 134 const ExecutorAddress &RHS) { 135 return ExecutorAddress(LHS.getValue() + RHS.getValue()); 136 } 137 138 /// Represents an address range in the exceutor process. 139 struct ExecutorAddressRange { 140 ExecutorAddressRange() = default; 141 ExecutorAddressRange(ExecutorAddress StartAddress, ExecutorAddress EndAddress) 142 : StartAddress(StartAddress), EndAddress(EndAddress) {} 143 144 bool empty() const { return StartAddress == EndAddress; } 145 ExecutorAddrDiff size() const { return EndAddress - StartAddress; } 146 147 ExecutorAddress StartAddress; 148 ExecutorAddress EndAddress; 149 }; 150 151 namespace shared { 152 153 /// SPS serializatior for ExecutorAddress. 154 template <> class SPSSerializationTraits<SPSExecutorAddress, ExecutorAddress> { 155 public: 156 static size_t size(const ExecutorAddress &EA) { 157 return SPSArgList<uint64_t>::size(EA.getValue()); 158 } 159 160 static bool serialize(SPSOutputBuffer &BOB, const ExecutorAddress &EA) { 161 return SPSArgList<uint64_t>::serialize(BOB, EA.getValue()); 162 } 163 164 static bool deserialize(SPSInputBuffer &BIB, ExecutorAddress &EA) { 165 uint64_t Tmp; 166 if (!SPSArgList<uint64_t>::deserialize(BIB, Tmp)) 167 return false; 168 EA = ExecutorAddress(Tmp); 169 return true; 170 } 171 }; 172 173 using SPSExecutorAddressRange = 174 SPSTuple<SPSExecutorAddress, SPSExecutorAddress>; 175 176 /// Serialization traits for address ranges. 177 template <> 178 class SPSSerializationTraits<SPSExecutorAddressRange, ExecutorAddressRange> { 179 public: 180 static size_t size(const ExecutorAddressRange &Value) { 181 return SPSArgList<SPSExecutorAddress, SPSExecutorAddress>::size( 182 Value.StartAddress, Value.EndAddress); 183 } 184 185 static bool serialize(SPSOutputBuffer &BOB, 186 const ExecutorAddressRange &Value) { 187 return SPSArgList<SPSExecutorAddress, SPSExecutorAddress>::serialize( 188 BOB, Value.StartAddress, Value.EndAddress); 189 } 190 191 static bool deserialize(SPSInputBuffer &BIB, ExecutorAddressRange &Value) { 192 return SPSArgList<SPSExecutorAddress, SPSExecutorAddress>::deserialize( 193 BIB, Value.StartAddress, Value.EndAddress); 194 } 195 }; 196 197 using SPSExecutorAddressRangeSequence = SPSSequence<SPSExecutorAddressRange>; 198 199 } // End namespace shared. 200 } // End namespace orc. 201 } // End namespace llvm. 202 203 #endif // LLVM_EXECUTIONENGINE_ORC_SHARED_EXECUTORADDRESS_H 204