ReXGlue SDK
Loading...
Searching...
No Matches
memory.h
Go to the documentation of this file.
1
11
12#pragma once
13
14#include <cstddef>
15#include <cstdint>
16#include <optional>
17#include <type_traits>
18
19#include <rex/types.h>
20#include <rex/assert.h>
22#include <rex/kernel/thread_state.h>
23#include <rex/kernel/heap.h>
24
25namespace rex::kernel {
26
28enum X_MEM : u32 {
29 kXMemCommit = 0x00001000,
30 kXMemReserve = 0x00002000,
31 kXMemDecommit = 0x00004000,
32 kXMemRelease = 0x00008000,
33 kXMemFree = 0x00010000,
34 kXMemPrivate = 0x00020000,
35 kXMemReset = 0x00080000,
36 kXMemTopDown = 0x00100000,
37 kXMemNoZero = 0x00800000,
38 kXMemLargePages = 0x20000000,
39 kXMemHeap = 0x40000000,
40 kXMem16MBPages = 0x80000000
41};
42
44enum X_PAGE : u16 {
45 kXPageNoAccess = 0x00000001,
46 kXPageReadOnly = 0x00000002,
47 kXPageReadWrite = 0x00000004,
48 kXPageWriteCopy = 0x00000008,
49 kXPageExecute = 0x00000010,
50 kXPageExecuteRead = 0x00000020,
53 0x00000080,
54 kXPageGuard = 0x00000100,
55 kXPageNoCache = 0x00000200,
57 0x00000400
58};
59
60} // namespace rex::kernel
61
62namespace rex::kernel {
63
64namespace detail {
65
67template <typename P, typename T>
68inline constexpr bool kIsHostPointerFor =
69 (std::is_pointer_v<P> || std::is_null_pointer_v<P>) && std::is_convertible_v<P, const T*>;
70
71} // namespace detail
72
74template <typename T>
75struct be_ptr {
76 be_u32 value;
77
78 operator u32() const { return value; }
79
83 u32 GetAddress() const { return value; }
84
85 explicit operator bool() const { return value != 0; }
86
92 T* GetHost() const {
93 if (value == 0) {
94 return nullptr;
95 }
96 auto* thread_state = rex::kernel::ThreadState::Get();
97 REX_ASSERT(thread_state != nullptr);
98 return rex::memory::GuestPtr<T*>(thread_state->GetAddressSpace()->GetVirtualMembase(), value);
99 }
100
108 T* TryGetHost() const {
109 auto* thread_state = rex::kernel::ThreadState::Get();
110 if (thread_state == nullptr || thread_state->GetAddressSpace() == nullptr) {
111 return nullptr;
112 }
113 return thread_state->GetAddressSpace()->TryTranslateVirtual<T*>(value);
114 }
115
121 T* GetHost(const rex::kernel::MemoryView& view) const {
122 return value == 0 ? nullptr : view.TranslateVirtual<T*>(value);
123 }
124
132 T* TryGetHost(const rex::kernel::MemoryView& view) const {
133 return view.TryTranslateVirtual<T*>(value);
134 }
135
136 T* operator->() const { return GetHost(); }
137
138 be_ptr& operator=(u32 v) {
139 value = v;
140 return *this;
141 }
142
149 template <typename P>
150 requires(detail::kIsHostPointerFor<P, T>)
151 be_ptr& operator=(P host_pointer) {
152 if constexpr (std::is_null_pointer_v<P>) {
153 value = 0;
154 } else {
155 if (host_pointer == nullptr) {
156 value = 0;
157 return *this;
158 }
159 auto* thread_state = rex::kernel::ThreadState::Get();
160 REX_ASSERT(thread_state != nullptr);
161 value = rex::memory::HostPtrToGuest(thread_state->GetAddressSpace()->GetVirtualMembase(),
162 reinterpret_cast<const void*>(host_pointer));
163 }
164 return *this;
165 }
166};
167
174template <typename T>
179
183 size_t size() const {
184 const u32 begin_address = first.GetAddress();
185 const u32 end_address = last.GetAddress();
186 return end_address > begin_address ? (end_address - begin_address) / sizeof(T) : 0;
187 }
188
189 bool empty() const { return size() == 0; }
190
196 const T* begin() const { return first.GetHost(); }
197
203 const T* end() const { return last.GetHost(); }
204
210 const T* begin(const rex::kernel::MemoryView& view) const { return first.GetHost(view); }
211
218 const T* end(const rex::kernel::MemoryView& view) const { return last.GetHost(view); }
219
225 const T& operator[](size_t index) const { return begin()[index]; }
226
228 u32 GetAddress(size_t index) const {
229 return index < size() ? first.GetAddress() + static_cast<u32>(index * sizeof(T)) : 0;
230 }
231
239 const T* TryAt(size_t index, const rex::kernel::MemoryView& view) const {
240 const u32 address = GetAddress(index);
241 const u64 last_byte = static_cast<u64>(address) + sizeof(T) - 1;
242 if (address == 0 || last_byte > 0xFFFFFFFFull) {
243 return nullptr;
244 }
245 const T* element = view.TryTranslateVirtual<const T*>(address);
246 if (element == nullptr ||
247 view.TryTranslateVirtual<const u8*>(static_cast<u32>(last_byte)) == nullptr) {
248 return nullptr;
249 }
250 return element;
251 }
252
261 std::optional<T> TryGet(size_t index, const rex::kernel::MemoryView& view) const
262 requires(rex::kernel::detail::GuestScalar<T>)
263 {
264 const u32 address = GetAddress(index);
265 if (address == 0) {
266 return std::nullopt;
267 }
268 return view.TryLoad<T>(address);
269 }
270
279 const T* TryAt(size_t index) const {
280 auto* thread_state = rex::kernel::ThreadState::Get();
281 if (thread_state == nullptr || thread_state->GetAddressSpace() == nullptr) {
282 return nullptr;
283 }
284 return TryAt(index, rex::kernel::MemoryView(*thread_state->GetAddressSpace()));
285 }
286};
287REX_STATIC_ASSERT_SIZE(GuestVector<u8>, 12);
288
289} // namespace rex::kernel
#define REX_ASSERT(cond,...)
Definition assert.h:84
Definition memory_view.h:38
T TryTranslateVirtual(u32 address, u32 required=kMemoryProtectRead) const
Definition memory_view.h:59
static ThreadState * Get()
Definition export.h:24
X_PAGE
Definition memory.h:44
@ kXPageNoCache
Definition memory.h:55
@ kXPageExecuteRead
Definition memory.h:50
@ kXPageGuard
Definition memory.h:54
@ kXPageNoAccess
Definition memory.h:45
@ kXPageExecute
Definition memory.h:49
@ kXPageExecuteReadWrite
Definition memory.h:51
@ kXPageWriteCombine
Definition memory.h:56
@ kXPageExecuteWriteCopy
Definition memory.h:52
@ kXPageWriteCopy
Definition memory.h:48
X_MEM
Definition memory.h:28
@ kXMemFree
Definition memory.h:33
@ kXMemRelease
Definition memory.h:32
@ kXMemDecommit
Definition memory.h:31
@ kXMemReset
Definition memory.h:35
@ kXMem16MBPages
Definition memory.h:40
@ kXMemLargePages
Definition memory.h:38
@ kXMemHeap
Definition memory.h:39
@ kXMemPrivate
Definition memory.h:34
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
Definition memory.h:175
size_t size() const
Definition memory.h:183
const T * begin() const
Definition memory.h:196
const T * TryAt(size_t index, const rex::kernel::MemoryView &view) const
Definition memory.h:239
const T & operator[](size_t index) const
Definition memory.h:225
be_ptr< T > first
Definition memory.h:176
const T * TryAt(size_t index) const
Definition memory.h:279
u32 GetAddress(size_t index) const
Definition memory.h:228
be_ptr< T > last
Definition memory.h:177
be_ptr< T > limit
Definition memory.h:178
const T * end(const rex::kernel::MemoryView &view) const
Definition memory.h:218
const T * end() const
Definition memory.h:203
const T * begin(const rex::kernel::MemoryView &view) const
Definition memory.h:210
std::optional< T > TryGet(size_t index, const rex::kernel::MemoryView &view) const
Definition memory.h:261
Definition memory.h:75
T * TryGetHost() const
Definition memory.h:108
T * GetHost() const
Definition memory.h:92
u32 GetAddress() const
Definition memory.h:83
T * TryGetHost(const rex::kernel::MemoryView &view) const
Definition memory.h:132
T * GetHost(const rex::kernel::MemoryView &view) const
Definition memory.h:121
Integer types, byte order wrappers and size literals.