-
Notifications
You must be signed in to change notification settings - Fork 129
Memory
The memory subsystem provides a 4 GB guest virtual address space mapped into host memory, with heap management matching Xbox 360 memory semantics. See Runtime Architecture Overview for where Memory fits in the subsystem initialization sequence.
The entire 4 GB guest address space is backed by a memory-mapped file placed at a stable fixed address in the host address space (typically 0x100000000). This avoids TLB emulation and enables direct pointer arithmetic for guest-to-host translation.
| Start | End | Size | Page Size | Heap | Purpose |
|---|---|---|---|---|---|
0x00000000 |
0x3FFFFFFF |
1024 MB | 4 KB | v00000000 |
Virtual 4K pages (includes GPU-visible physical mapping) |
0x40000000 |
0x7FFFFFFF |
1024 MB | 64 KB | v40000000 |
Virtual 64K pages |
0x80000000 |
0x8BFFFFFF |
192 MB | 64 KB | v80000000 |
XEX image (code + data sections) |
0x8C000000 |
0x8FFFFFFF |
64 MB | 64 KB | v80000000 |
XEX encrypted region |
0x90000000 |
0x9FFFFFFF |
256 MB | 4 KB | v90000000 |
XEX 4K pages |
0xA0000000 |
0xBFFFFFFF |
512 MB | 64 KB | PhysicalHeap |
Physical 64K pages |
0xC0000000 |
0xDFFFFFFF |
512 MB | 16 MB | PhysicalHeap |
Physical 16M pages |
0xE0000000 |
0xFFFFFFFF |
512 MB | 4 KB | PhysicalHeap |
Physical 4K pages |
Physical memory (512 MB) is stored at host offset 0x200000000 and is shared with the GPU subsystem. The three physical heap ranges (0xA0000000, 0xC0000000, 0xE0000000) are different views of the same physical backing with different page granularities.
Page-based allocation for guest virtual address ranges. Each VirtualHeap manages a contiguous region of the address space with its own page table.
Key operations:
| Method | Description |
|---|---|
Alloc(size, alignment, type, protect, top_down) |
Allocate contiguous pages |
AllocFixed(base, size, alignment, type, protect) |
Allocate at a specific address |
AllocRange(low, high, size, ...) |
Allocate within an address range |
Decommit(address, size) |
Release backing memory, keep reservation |
Release(address) |
Decommit and unreserve pages |
Protect(address, size, protect) |
Change page protection flags |
QueryRegionInfo(address, info) |
Query allocation state of a region |
Protection flags: kMemoryProtectRead, kMemoryProtectWrite, kMemoryProtectNoCache, kMemoryProtectWriteCombine.
Maps physical pages, backed by a parent VirtualHeap in the guest virtual address space. Used for GPU-visible and audio-accessible memory. PhysicalHeap supports invalidation callbacks for cache coherency: when guest code writes to a watched physical page, registered callbacks are triggered so subsystems (e.g., GPU texture cache) can invalidate stale data.
Allocated from the top of virtual heaps via Memory::SystemHeapAlloc(size, alignment, flags). Keeps kernel structures (object table entries, process blocks, TLS data) separate from game-visible memory while remaining accessible through normal guest virtual addresses.
SystemHeapFree(address) releases system heap memory.
// Virtual address translation
template <typename T>
T Memory::TranslateVirtual(uint32_t guest_address) const {
uint8_t* host = virtual_membase_ + guest_address;
auto heap = LookupHeap(guest_address);
if (heap) host += heap->host_address_offset();
return reinterpret_cast<T>(host);
}
// Physical address translation
template <typename T>
T Memory::TranslatePhysical(uint32_t guest_address) const {
return reinterpret_cast<T>(physical_membase_ + (guest_address & 0x1FFFFFFF));
}The host_address_offset() on each heap accounts for the gap between the logical guest address and the actual host mapping position. For most virtual heaps this is zero; for physical heaps it maps the 0xA0000000+ guest range onto the 0x200000000 host physical backing.
HostToGuestVirtual(host_ptr) performs the reverse translation.
All data at translated addresses is big-endian, matching the Xbox 360's PowerPC byte order. Use rex::be<T> wrappers for typed access.
Windows enforces a 64 KB allocation granularity for memory-mapped file views (MapViewOfFile), while Linux allows 4 KB alignment. When the SDK maps the guest address space as file-backed views, each view's file offset is rounded down to the nearest 64 KB boundary on Windows. This is transparent for most heaps because their file offsets are already 64 KB-aligned.
The exception is the 0xE0000000 physical heap. Its backing data starts at file offset 0x100001000 (the physical memory region at 0x100000000 plus a 4 KB page offset). On Windows, the 64 KB granularity mask rounds this down to 0x100000000, losing the 0x1000 offset. The heap compensates by setting a host_address_offset of 0x1000:
// PhysicalHeap::Initialize
if (heap_base >= 0xE0000000 && allocation_granularity() > 0x1000) {
host_address_offset = 0x1000; // compensate for granularity masking
}This offset is applied in two places:
-
TranslateVirtual: addsheap->host_address_offset()to the computed host pointer (shown above). -
Generated code: the
PPC_PHYS_HOST_OFFSET(addr)macro returns0x1000when the address falls in the0xE0000000range on Windows, and0on Linux or for other ranges. AllPPC_LOAD_*/PPC_STORE_*macros in the physical 4K region incorporate this offset.
HostToGuestVirtual performs the reverse: if the host address falls within the 0xE0000000 range, it subtracts the offset before computing the guest address.
| Heap | File Offset | Granularity Issue | host_address_offset |
|---|---|---|---|
v00000000 |
0x000000000 |
None (aligned) | 0 |
v40000000 |
0x040000000 |
None (aligned) | 0 |
v80000000 |
0x080000000 |
None (aligned) | 0 |
v90000000 |
0x080000000 |
None (aligned) | 0 |
PhysicalHeap 64K |
0x100000000 |
None (aligned) | 0 |
PhysicalHeap 16M |
0x100000000 |
None (aligned) | 0 |
PhysicalHeap 4K |
0x100001000 |
Masked to 0x100000000 on Windows |
0x1000 |
Note
On Linux, allocation granularity is 4 KB, so the 0x1000 file offset maps correctly and no compensation is needed. The host_address_offset remains 0 for all heaps.
The recompiled function dispatch table is stored in guest memory immediately after the XEX image. This is the table that FunctionDispatcher and thread dispatch use to resolve guest addresses to native C++ functions.
-
Location:
IMAGE_BASE + IMAGE_SIZE -
Index formula:
(guest_addr - CODE_BASE) * 2. Each 4-byte-aligned guest address maps to an 8-byte host function pointer slot.
// Register a recompiled function
memory->SetFunction(guest_addr, host_func_ptr);
// Look up at runtime (used by PPC_LOOKUP_FUNC / PPC_CALL_INDIRECT_FUNC)
PPCFunc* func = memory->GetFunction(guest_addr);The table is populated during Runtime::Setup() from the PPCFuncMappings[] array in Generated Code Structure.
Thunk allocation (FunctionDispatcher::AllocateThunk) provides slots for dynamically resolved functions (e.g., addresses returned by XexGetProcedureAddress that need host-callable wrappers).
For games that use standard CRT heap functions (malloc/free/realloc via RtlAllocateHeap/RtlFreeHeap), the SDK provides a replacement allocator that operates directly in guest memory. Configure CRT function mappings in the [rexcrt] section of the rexglue CLI Configuration File.
Design:
- Based on o1heap: O(1) worst-case allocation and deallocation.
- Multi-segment: if the initial segment runs out of space, additional segments are allocated from the guest virtual heap on demand, avoiding hard OOM on large allocations.
- Thread-safe via
std::mutex.
Configuration:
-
rexcrt_heap_size_mbCVar controls the initial segment size (default varies by project). -
rexcrt_heap_enableCVar can disable the heap entirely. - Initialization happens in ReXApp::OnInitialize() after
LoadXexImage, so the heap region does not conflict with the XEX image mapping.
API (rex::kernel::crt::ReXHeap):
| Method | Description |
|---|---|
Alloc(size, zero) |
Allocate guest memory, optionally zeroed |
Free(guest_addr) |
Free a previous allocation |
Realloc(guest_addr, new_size, zero_new) |
Resize allocation |
Size(guest_addr) |
Query allocation size |
InHeap(guest_addr) |
Check if address belongs to the rexcrt heap |
GetDiagnostics() |
Capacity, allocated, peak, OOM count |
The heap is activated by codegen when the [rexcrt] section in the rexglue CLI Configuration File maps CRT functions. Original heap implementations in the game binary are replaced with calls to this allocator.
ReXGlue SDK
CLI Reference
Recompilation Pipeline
Runtime Architecture
Technical Reference