ReXGlue SDK
Loading...
Searching...
No Matches
mapped_ptr.h
Go to the documentation of this file.
1
13
14#pragma once
15
16#include <cstddef>
17#include <cstdint>
18#include <cstring>
19#include <string_view>
20#include <type_traits>
21
22#include <rex/platform.h>
23#include <rex/types.h>
24
25namespace rex::memory {
26
28template <typename T>
29class MappedPtr {
30 T* host_ptr_ = nullptr;
31 u32 guest_addr_ = 0;
32
33 public:
35 MappedPtr() = default;
36
37 MappedPtr(T* host_ptr, u32 guest_addr) : host_ptr_(host_ptr), guest_addr_(guest_addr) {}
38
40 MappedPtr(std::nullptr_t) {}
41
45 static MappedPtr FromHost(T* host_ptr) { return MappedPtr(host_ptr, 0); }
46
47 u32 GetGuestAddress() const { return guest_addr_; }
48
49 T* GetHostPtr() const { return host_ptr_; }
50
51 operator T*() const { return host_ptr_; }
52
53 T* operator->() const { return host_ptr_; }
54
55 T& operator*() const { return *host_ptr_; }
56
60 auto GetValue() const {
61 if constexpr (is_be_type_v<T>) {
62 return static_cast<T::value_type>(*host_ptr_);
63 } else {
64 return *host_ptr_;
65 }
66 }
67
68 explicit operator bool() const { return host_ptr_ != nullptr; }
69
70 explicit operator u32() const { return GetGuestAddress(); }
71
76 MappedPtr operator+(std::ptrdiff_t offset) const {
77 return MappedPtr(host_ptr_ + offset, guest_addr_ + static_cast<u32>(offset * sizeof(T)));
78 }
79
84 MappedPtr operator-(std::ptrdiff_t offset) const {
85 return MappedPtr(host_ptr_ - offset, guest_addr_ - static_cast<u32>(offset * sizeof(T)));
86 }
87
88 template <typename U>
89 U As() const {
90 return reinterpret_cast<U>(host_ptr_);
91 }
92
96 template <typename U>
97 rex::BE<U>* AsArray() const {
98 return reinterpret_cast<rex::BE<U>*>(host_ptr_);
99 }
100
104 void Zero() const {
105 if (host_ptr_) {
106 std::memset(host_ptr_, 0, sizeof(T));
107 }
108 }
109
111 void Zero(size_t size) const {
112 if (host_ptr_) {
113 std::memset(host_ptr_, 0, size);
114 }
115 }
116};
117
121template <>
122class MappedPtr<void> {
123 void* host_ptr_ = nullptr;
124 u32 guest_addr_ = 0;
125
126 public:
128 MappedPtr() = default;
129
130 MappedPtr(void* host_ptr, u32 guest_addr) : host_ptr_(host_ptr), guest_addr_(guest_addr) {}
131
133 MappedPtr(std::nullptr_t) {}
134
138 static MappedPtr FromHost(void* host_ptr) { return MappedPtr(host_ptr, 0); }
139
140 u32 GetGuestAddress() const { return guest_addr_; }
141
142 u32 GetValue() const { return guest_addr_; }
143
144 void* GetHostPtr() const { return host_ptr_; }
145
146 operator void*() const { return host_ptr_; }
147
151 operator u8*() const { return static_cast<u8*>(host_ptr_); }
152
153 explicit operator bool() const { return host_ptr_ != nullptr; }
154
155 explicit operator u32() const { return guest_addr_; }
156
162 template <std::integral IntType>
163 MappedPtr operator+(IntType offset) const {
164 return MappedPtr(static_cast<u8*>(host_ptr_) + static_cast<std::ptrdiff_t>(offset),
165 guest_addr_ + static_cast<u32>(offset));
166 }
167
173 template <std::integral IntType>
174 MappedPtr operator-(IntType offset) const {
175 return MappedPtr(static_cast<u8*>(host_ptr_) - static_cast<std::ptrdiff_t>(offset),
176 guest_addr_ - static_cast<u32>(offset));
177 }
178
179 template <typename U>
180 U As() const {
181 return reinterpret_cast<U>(host_ptr_);
182 }
183
187 template <typename U>
188 rex::BE<U>* AsArray() const {
189 return reinterpret_cast<rex::BE<U>*>(host_ptr_);
190 }
191
193 void Zero(size_t size) const {
194 if (host_ptr_) {
195 std::memset(host_ptr_, 0, size);
196 }
197 }
198};
199
203template <>
204class MappedPtr<char> {
205 char* host_ptr_ = nullptr;
206 u32 guest_addr_ = 0;
207
208 public:
210 MappedPtr() = default;
211
212 MappedPtr(char* host_ptr, u32 guest_addr) : host_ptr_(host_ptr), guest_addr_(guest_addr) {}
213
215 MappedPtr(std::nullptr_t) {}
216
217 u32 GetGuestAddress() const { return guest_addr_; }
218
219 char* GetHostPtr() const { return host_ptr_; }
220
221 operator char*() const { return host_ptr_; }
222
223 explicit operator bool() const { return host_ptr_ != nullptr; }
224
228 std::string_view GetValue() const {
229 return host_ptr_ ? std::string_view(host_ptr_) : std::string_view();
230 }
231
232 char* operator->() const { return host_ptr_; }
233
234 char& operator*() const { return *host_ptr_; }
235
240 MappedPtr operator+(std::ptrdiff_t offset) const {
241 return MappedPtr(host_ptr_ + offset, guest_addr_ + static_cast<u32>(offset));
242 }
243
248 MappedPtr operator-(std::ptrdiff_t offset) const {
249 return MappedPtr(host_ptr_ - offset, guest_addr_ - static_cast<u32>(offset));
250 }
251
252 char& operator[](size_t idx) const { return host_ptr_[idx]; }
253
254 template <typename U>
255 U As() const {
256 return reinterpret_cast<U>(host_ptr_);
257 }
258};
259
263template <>
264class MappedPtr<char16_t> {
265 char16_t* host_ptr_ = nullptr;
266 u32 guest_addr_ = 0;
267
268 public:
270 MappedPtr() = default;
271
272 MappedPtr(char16_t* host_ptr, u32 guest_addr) : host_ptr_(host_ptr), guest_addr_(guest_addr) {}
273
275 MappedPtr(std::nullptr_t) {}
276
277 u32 GetGuestAddress() const { return guest_addr_; }
278
279 char16_t* GetHostPtr() const { return host_ptr_; }
280
281 operator char16_t*() const { return host_ptr_; }
282
283 explicit operator bool() const { return host_ptr_ != nullptr; }
284
288 std::u16string_view GetValue() const {
289 return host_ptr_ ? std::u16string_view(host_ptr_) : std::u16string_view();
290 }
291
292 char16_t* operator->() const { return host_ptr_; }
293
294 char16_t& operator*() const { return *host_ptr_; }
295
300 MappedPtr operator+(std::ptrdiff_t offset) const {
301 return MappedPtr(host_ptr_ + offset, guest_addr_ + static_cast<u32>(offset * sizeof(char16_t)));
302 }
303
308 MappedPtr operator-(std::ptrdiff_t offset) const {
309 return MappedPtr(host_ptr_ - offset, guest_addr_ - static_cast<u32>(offset * sizeof(char16_t)));
310 }
311
312 char16_t& operator[](size_t idx) const { return host_ptr_[idx]; }
313
314 template <typename U>
315 U As() const {
316 return reinterpret_cast<U>(host_ptr_);
317 }
318};
319
320template <typename T>
321struct IsMappedPtr : std::false_type {};
322
323template <typename T>
324struct IsMappedPtr<MappedPtr<T>> : std::true_type {};
325
326template <typename T>
327inline constexpr bool is_mapped_ptr_v = IsMappedPtr<T>::value;
328
329template <typename T>
331
333template <typename T>
335 using type = T;
336};
337
338} // namespace rex::memory
339
340using MappedVoid = rex::memory::MappedPtr<void>;
341using MappedU8 = rex::memory::MappedPtr<rex::u8>;
347using MappedString = rex::memory::MappedPtr<char>;
348using MappedWString = rex::memory::MappedPtr<char16_t>;
349
350template <typename T>
351using GuestPtrT = rex::memory::MappedPtr<T>;
352
353namespace rex::memory::detail {
354
362#ifndef REX_PHYSICAL_OFFSET_IN_CODE
363#error "REX_PHYSICAL_OFFSET_IN_CODE is set by the CMake option of the same name"
364#endif
365inline constexpr bool kPhysicalOffsetInCode = static_cast<bool>(REX_PHYSICAL_OFFSET_IN_CODE);
366
371constexpr u32 PhysicalHostOffset(u32 guest_addr) noexcept {
372 return (kPhysicalOffsetInCode && guest_addr >= 0xE0000000u) ? 0x1000u : 0u;
373}
374
380constexpr u32 RemovePhysicalHostOffset(std::size_t host_offset) noexcept {
381 constexpr std::size_t kOffset = PhysicalHostOffset(0xE0000000u);
382 const bool shifted =
383 host_offset >= 0xE0000000u + kOffset && host_offset < 0x100000000ull + kOffset;
384 return static_cast<u32>(shifted ? host_offset - kOffset : host_offset);
385}
386
387} // namespace rex::memory::detail
388
389namespace rex::memory {
390
392template <typename T = u8*>
393inline T GuestPtr(u8* base, u32 guest_address) noexcept {
394 return reinterpret_cast<T>(base + guest_address + detail::PhysicalHostOffset(guest_address));
395}
396
403inline u32 HostPtrToGuest(const u8* base, const void* host_address) noexcept {
404 if (host_address == nullptr) {
405 return 0;
406 }
407 return detail::RemovePhysicalHostOffset(reinterpret_cast<std::size_t>(host_address) -
408 reinterpret_cast<std::size_t>(base));
409}
410
412class GuestMembase {
413 public:
414 constexpr GuestMembase() noexcept = default;
415
416 explicit constexpr GuestMembase(u8* base) noexcept : base_(base) {}
417
421 [[nodiscard]] constexpr u8* GetBase() const noexcept { return base_; }
422
424 template <typename T = u8*>
425 [[nodiscard]] T TranslateVirtual(u32 guest_address) const noexcept {
426 return GuestPtr<T>(base_, guest_address);
427 }
428
435 [[nodiscard]] u32 HostToGuestVirtual(const void* host_address) const noexcept {
436 return HostPtrToGuest(base_, host_address);
437 }
438
439 private:
440 u8* base_ = nullptr;
441};
442
443} // namespace rex::memory
u32 HostToGuestVirtual(const void *host_address) const noexcept
Definition mapped_ptr.h:435
constexpr u8 * GetBase() const noexcept
Definition mapped_ptr.h:421
T TranslateVirtual(u32 guest_address) const noexcept
Definition mapped_ptr.h:425
std::u16string_view GetValue() const
Definition mapped_ptr.h:288
MappedPtr(std::nullptr_t)
Definition mapped_ptr.h:275
MappedPtr operator+(std::ptrdiff_t offset) const
Definition mapped_ptr.h:300
MappedPtr operator-(std::ptrdiff_t offset) const
Definition mapped_ptr.h:308
std::string_view GetValue() const
Definition mapped_ptr.h:228
MappedPtr operator+(std::ptrdiff_t offset) const
Definition mapped_ptr.h:240
MappedPtr operator-(std::ptrdiff_t offset) const
Definition mapped_ptr.h:248
MappedPtr(std::nullptr_t)
Definition mapped_ptr.h:215
static MappedPtr FromHost(void *host_ptr)
Definition mapped_ptr.h:138
rex::BE< U > * AsArray() const
Definition mapped_ptr.h:188
MappedPtr operator+(IntType offset) const
Definition mapped_ptr.h:163
MappedPtr operator-(IntType offset) const
Definition mapped_ptr.h:174
void Zero(size_t size) const
Definition mapped_ptr.h:193
MappedPtr(std::nullptr_t)
Definition mapped_ptr.h:133
Definition mapped_ptr.h:29
MappedPtr operator+(std::ptrdiff_t offset) const
Definition mapped_ptr.h:76
auto GetValue() const
Definition mapped_ptr.h:60
void Zero(size_t size) const
Definition mapped_ptr.h:111
MappedPtr(std::nullptr_t)
Definition mapped_ptr.h:40
rex::BE< U > * AsArray() const
Definition mapped_ptr.h:97
static MappedPtr FromHost(T *host_ptr)
Definition mapped_ptr.h:45
MappedPtr operator-(std::ptrdiff_t offset) const
Definition mapped_ptr.h:84
void Zero() const
Definition mapped_ptr.h:104
Definition endian.h:27
T GuestPtr(u8 *base, u32 guest_address) noexcept
Definition mapped_ptr.h:393
u32 HostPtrToGuest(const u8 *base, const void *host_address) noexcept
Definition mapped_ptr.h:403
Platform flags, packing macros and export markers.
Definition mapped_ptr.h:321
Definition mapped_ptr.h:330
Integer types, byte order wrappers and size literals.