LLVM 20.0.0git
ExecutorAddress.h
Go to the documentation of this file.
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
17#include "llvm/ADT/identity.h"
21
22#include <cassert>
23#if __has_feature(ptrauth_calls)
24#include <ptrauth.h>
25#endif
26#include <type_traits>
27
28namespace llvm {
29namespace orc {
30
32
33/// Represents an address in the executor process.
35public:
36 /// A wrap/unwrap function that leaves pointers unmodified.
37 template <typename T> using rawPtr = llvm::identity<T *>;
38
39#if __has_feature(ptrauth_calls)
40 template <typename T> class PtrauthSignDefault {
41 public:
42 constexpr T *operator()(T *P) {
43 if (std::is_function_v<T>)
44 return ptrauth_sign_unauthenticated(P, ptrauth_key_function_pointer, 0);
45 else
46 return P;
47 }
48 };
49
50 template <typename T> class PtrauthStripDefault {
51 public:
52 constexpr T *operator()(T *P) {
53 return ptrauth_strip(P, ptrauth_key_function_pointer);
54 }
55 };
56
57 /// Default wrap function to use on this host.
58 template <typename T> using defaultWrap = PtrauthSignDefault<T>;
59
60 /// Default unwrap function to use on this host.
61 template <typename T> using defaultUnwrap = PtrauthStripDefault<T>;
62
63#else
64
65 /// Default wrap function to use on this host.
66 template <typename T> using defaultWrap = rawPtr<T>;
67
68 /// Default unwrap function to use on this host.
69 template <typename T> using defaultUnwrap = rawPtr<T>;
70
71#endif
72
73 /// Merges a tag into the raw address value:
74 /// P' = P | (TagValue << TagOffset).
75 class Tag {
76 public:
77 constexpr Tag(uintptr_t TagValue, uintptr_t TagOffset)
78 : TagMask(TagValue << TagOffset) {}
79
80 template <typename T> constexpr T *operator()(T *P) {
81 return reinterpret_cast<T *>(reinterpret_cast<uintptr_t>(P) | TagMask);
82 }
83
84 private:
85 uintptr_t TagMask;
86 };
87
88 /// Strips a tag of the given length from the given offset within the pointer:
89 /// P' = P & ~(((1 << TagLen) -1) << TagOffset)
90 class Untag {
91 public:
92 constexpr Untag(uintptr_t TagLen, uintptr_t TagOffset)
93 : UntagMask(~(((uintptr_t(1) << TagLen) - 1) << TagOffset)) {}
94
95 template <typename T> constexpr T *operator()(T *P) {
96 return reinterpret_cast<T *>(reinterpret_cast<uintptr_t>(P) & UntagMask);
97 }
98
99 private:
100 uintptr_t UntagMask;
101 };
102
103 ExecutorAddr() = default;
104
105 /// Create an ExecutorAddr from the given value.
106 explicit constexpr ExecutorAddr(uint64_t Addr) : Addr(Addr) {}
107
108 /// Create an ExecutorAddr from the given pointer.
109 /// Warning: This should only be used when JITing in-process.
110 template <typename T, typename UnwrapFn = defaultUnwrap<T>>
111 static ExecutorAddr fromPtr(T *Ptr, UnwrapFn &&Unwrap = UnwrapFn()) {
112 return ExecutorAddr(
113 static_cast<uint64_t>(reinterpret_cast<uintptr_t>(Unwrap(Ptr))));
114 }
115
116 /// Cast this ExecutorAddr to a pointer of the given type.
117 /// Warning: This should only be used when JITing in-process.
118 template <typename T, typename WrapFn = defaultWrap<std::remove_pointer_t<T>>>
119 std::enable_if_t<std::is_pointer<T>::value, T>
120 toPtr(WrapFn &&Wrap = WrapFn()) const {
121 uintptr_t IntPtr = static_cast<uintptr_t>(Addr);
122 assert(IntPtr == Addr && "ExecutorAddr value out of range for uintptr_t");
123 return Wrap(reinterpret_cast<T>(IntPtr));
124 }
125
126 /// Cast this ExecutorAddr to a pointer of the given function type.
127 /// Warning: This should only be used when JITing in-process.
128 template <typename T, typename WrapFn = defaultWrap<T>>
129 std::enable_if_t<std::is_function<T>::value, T *>
130 toPtr(WrapFn &&Wrap = WrapFn()) const {
131 uintptr_t IntPtr = static_cast<uintptr_t>(Addr);
132 assert(IntPtr == Addr && "ExecutorAddr value out of range for uintptr_t");
133 return Wrap(reinterpret_cast<T *>(IntPtr));
134 }
135
136 uint64_t getValue() const { return Addr; }
137 void setValue(uint64_t Addr) { this->Addr = Addr; }
138 bool isNull() const { return Addr == 0; }
139
140 explicit operator bool() const { return Addr != 0; }
141
142 friend bool operator==(const ExecutorAddr &LHS, const ExecutorAddr &RHS) {
143 return LHS.Addr == RHS.Addr;
144 }
145
146 friend bool operator!=(const ExecutorAddr &LHS, const ExecutorAddr &RHS) {
147 return LHS.Addr != RHS.Addr;
148 }
149
150 friend bool operator<(const ExecutorAddr &LHS, const ExecutorAddr &RHS) {
151 return LHS.Addr < RHS.Addr;
152 }
153
154 friend bool operator<=(const ExecutorAddr &LHS, const ExecutorAddr &RHS) {
155 return LHS.Addr <= RHS.Addr;
156 }
157
158 friend bool operator>(const ExecutorAddr &LHS, const ExecutorAddr &RHS) {
159 return LHS.Addr > RHS.Addr;
160 }
161
162 friend bool operator>=(const ExecutorAddr &LHS, const ExecutorAddr &RHS) {
163 return LHS.Addr >= RHS.Addr;
164 }
165
167 ++Addr;
168 return *this;
169 }
171 --Addr;
172 return *this;
173 }
174 ExecutorAddr operator++(int) { return ExecutorAddr(Addr++); }
175 ExecutorAddr operator--(int) { return ExecutorAddr(Addr--); }
176
178 Addr += Delta;
179 return *this;
180 }
181
183 Addr -= Delta;
184 return *this;
185 }
186
187private:
188 uint64_t Addr = 0;
189};
190
191/// Subtracting two addresses yields an offset.
193 const ExecutorAddr &RHS) {
194 return ExecutorAddrDiff(LHS.getValue() - RHS.getValue());
195}
196
197/// Adding an offset and an address yields an address.
199 const ExecutorAddrDiff &RHS) {
200 return ExecutorAddr(LHS.getValue() + RHS);
201}
202
203/// Adding an address and an offset yields an address.
205 const ExecutorAddr &RHS) {
206 return ExecutorAddr(LHS + RHS.getValue());
207}
208
209/// Subtracting an offset from an address yields an address.
211 const ExecutorAddrDiff &RHS) {
212 return ExecutorAddr(LHS.getValue() - RHS);
213}
214
215/// Taking the modulus of an address and a diff yields a diff.
217 const ExecutorAddrDiff &RHS) {
218 return ExecutorAddrDiff(LHS.getValue() % RHS);
219}
220
221/// Represents an address range in the exceutor process.
223 ExecutorAddrRange() = default;
225 : Start(Start), End(End) {}
227 : Start(Start), End(Start + Size) {}
228
229 bool empty() const { return Start == End; }
230 ExecutorAddrDiff size() const { return End - Start; }
231
232 friend bool operator==(const ExecutorAddrRange &LHS,
233 const ExecutorAddrRange &RHS) {
234 return LHS.Start == RHS.Start && LHS.End == RHS.End;
235 }
236 friend bool operator!=(const ExecutorAddrRange &LHS,
237 const ExecutorAddrRange &RHS) {
238 return !(LHS == RHS);
239 }
240 friend bool operator<(const ExecutorAddrRange &LHS,
241 const ExecutorAddrRange &RHS) {
242 return LHS.Start < RHS.Start ||
243 (LHS.Start == RHS.Start && LHS.End < RHS.End);
244 }
245 friend bool operator<=(const ExecutorAddrRange &LHS,
246 const ExecutorAddrRange &RHS) {
247 return LHS.Start < RHS.Start ||
248 (LHS.Start == RHS.Start && LHS.End <= RHS.End);
249 }
250 friend bool operator>(const ExecutorAddrRange &LHS,
251 const ExecutorAddrRange &RHS) {
252 return LHS.Start > RHS.Start ||
253 (LHS.Start == RHS.Start && LHS.End > RHS.End);
254 }
255 friend bool operator>=(const ExecutorAddrRange &LHS,
256 const ExecutorAddrRange &RHS) {
257 return LHS.Start > RHS.Start ||
258 (LHS.Start == RHS.Start && LHS.End >= RHS.End);
259 }
260
261 bool contains(ExecutorAddr Addr) const { return Start <= Addr && Addr < End; }
263 return !(Other.End <= Start || End <= Other.Start);
264 }
265
268};
269
271 return OS << formatv("{0:x}", A.getValue());
272}
273
275 return OS << formatv("{0:x} -- {1:x}", R.Start.getValue(), R.End.getValue());
276}
277
278namespace shared {
279
281
282/// SPS serializatior for ExecutorAddr.
284public:
285 static size_t size(const ExecutorAddr &EA) {
287 }
288
289 static bool serialize(SPSOutputBuffer &BOB, const ExecutorAddr &EA) {
291 }
292
293 static bool deserialize(SPSInputBuffer &BIB, ExecutorAddr &EA) {
294 uint64_t Tmp;
296 return false;
297 EA = ExecutorAddr(Tmp);
298 return true;
299 }
300};
301
303
304/// Serialization traits for address ranges.
305template <>
307public:
308 static size_t size(const ExecutorAddrRange &Value) {
310 Value.End);
311 }
312
315 BOB, Value.Start, Value.End);
316 }
317
320 BIB, Value.Start, Value.End);
321 }
322};
323
325
326} // End namespace shared.
327} // End namespace orc.
328
329// Provide DenseMapInfo for ExecutorAddrs.
330template <> struct DenseMapInfo<orc::ExecutorAddr> {
333 }
336 }
337
338 static unsigned getHashValue(const orc::ExecutorAddr &Addr) {
340 }
341
342 static bool isEqual(const orc::ExecutorAddr &LHS,
343 const orc::ExecutorAddr &RHS) {
344 return DenseMapInfo<uint64_t>::isEqual(LHS.getValue(), RHS.getValue());
345 }
346};
347
348} // End namespace llvm.
349
350#endif // LLVM_EXECUTIONENGINE_ORC_SHARED_EXECUTORADDRESS_H
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
This file defines DenseMapInfo traits for DenseMap.
uint64_t Addr
uint64_t Size
#define P(N)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
raw_pwrite_stream & OS
Value * RHS
Value * LHS
LLVM Value Representation.
Definition: Value.h:74
Merges a tag into the raw address value: P' = P | (TagValue << TagOffset).
constexpr Tag(uintptr_t TagValue, uintptr_t TagOffset)
constexpr T * operator()(T *P)
Strips a tag of the given length from the given offset within the pointer: P' = P & ~(((1 << TagLen) ...
constexpr Untag(uintptr_t TagLen, uintptr_t TagOffset)
constexpr T * operator()(T *P)
Represents an address in the executor process.
rawPtr< T > defaultWrap
Default wrap function to use on this host.
ExecutorAddr & operator++()
friend bool operator==(const ExecutorAddr &LHS, const ExecutorAddr &RHS)
ExecutorAddr operator--(int)
ExecutorAddr & operator-=(const ExecutorAddrDiff &Delta)
uint64_t getValue() const
void setValue(uint64_t Addr)
std::enable_if_t< std::is_function< T >::value, T * > toPtr(WrapFn &&Wrap=WrapFn()) const
Cast this ExecutorAddr to a pointer of the given function type.
ExecutorAddr operator++(int)
friend bool operator>(const ExecutorAddr &LHS, const ExecutorAddr &RHS)
static ExecutorAddr fromPtr(T *Ptr, UnwrapFn &&Unwrap=UnwrapFn())
Create an ExecutorAddr from the given pointer.
friend bool operator>=(const ExecutorAddr &LHS, const ExecutorAddr &RHS)
ExecutorAddr & operator--()
constexpr ExecutorAddr(uint64_t Addr)
Create an ExecutorAddr from the given value.
friend bool operator<=(const ExecutorAddr &LHS, const ExecutorAddr &RHS)
friend bool operator<(const ExecutorAddr &LHS, const ExecutorAddr &RHS)
ExecutorAddr & operator+=(const ExecutorAddrDiff &Delta)
rawPtr< T > defaultUnwrap
Default unwrap function to use on this host.
friend bool operator!=(const ExecutorAddr &LHS, const ExecutorAddr &RHS)
std::enable_if_t< std::is_pointer< T >::value, T > toPtr(WrapFn &&Wrap=WrapFn()) const
Cast this ExecutorAddr to a pointer of the given type.
A utility class for serializing to a blob from a variadic list.
Input char buffer with underflow check.
Output char buffer with overflow check.
static bool serialize(SPSOutputBuffer &BOB, const ExecutorAddrRange &Value)
static bool deserialize(SPSInputBuffer &BIB, ExecutorAddrRange &Value)
static bool serialize(SPSOutputBuffer &BOB, const ExecutorAddr &EA)
static bool deserialize(SPSInputBuffer &BIB, ExecutorAddr &EA)
Specialize to describe how to serialize/deserialize to/from the given concrete type.
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition: raw_ostream.h:52
ExecutorAddrDiff operator%(const ExecutorAddr &LHS, const ExecutorAddrDiff &RHS)
Taking the modulus of an address and a diff yields a diff.
ExecutorAddr operator+(const ExecutorAddr &LHS, const ExecutorAddrDiff &RHS)
Adding an offset and an address yields an address.
uint64_t ExecutorAddrDiff
raw_ostream & operator<<(raw_ostream &OS, const SymbolNameSet &Symbols)
Render a SymbolNameSet.
Definition: DebugUtils.cpp:140
ExecutorAddrDiff operator-(const ExecutorAddr &LHS, const ExecutorAddr &RHS)
Subtracting two addresses yields an offset.
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
auto formatv(bool Validate, const char *Fmt, Ts &&...Vals)
@ Other
Any other memory.
static unsigned getHashValue(const orc::ExecutorAddr &Addr)
static bool isEqual(const orc::ExecutorAddr &LHS, const orc::ExecutorAddr &RHS)
static orc::ExecutorAddr getTombstoneKey()
static orc::ExecutorAddr getEmptyKey()
An information struct used to provide DenseMap with the various necessary components for a given valu...
Definition: DenseMapInfo.h:52
Represents an address range in the exceutor process.
friend bool operator==(const ExecutorAddrRange &LHS, const ExecutorAddrRange &RHS)
bool overlaps(const ExecutorAddrRange &Other)
friend bool operator>=(const ExecutorAddrRange &LHS, const ExecutorAddrRange &RHS)
ExecutorAddrRange(ExecutorAddr Start, ExecutorAddr End)
friend bool operator!=(const ExecutorAddrRange &LHS, const ExecutorAddrRange &RHS)
friend bool operator<(const ExecutorAddrRange &LHS, const ExecutorAddrRange &RHS)
ExecutorAddrRange(ExecutorAddr Start, ExecutorAddrDiff Size)
ExecutorAddrDiff size() const
friend bool operator<=(const ExecutorAddrRange &LHS, const ExecutorAddrRange &RHS)
bool contains(ExecutorAddr Addr) const
friend bool operator>(const ExecutorAddrRange &LHS, const ExecutorAddrRange &RHS)