Frame-pointer leaf functions address red-zone locals through RBP below
RSP (e.g. [rbp-0x108] with rsp = rbp-0xc8). The patcher only modeled
RSP-relative operands, so such functions were left unprotected and a
handled access fault overwrote their locals (PPSA10595 crash in a
decompressor on Background Worker #2).
Track RBP - RSP through the CFG, translate frame-relative operands into
the red-zone model, resolve mov rsp,rbp / lea rsp,[rbp+k] / leave deltas,
and fall back to conservative protection when the offset is unknown.
Also follow resolved jump-table successors in the liveness pass.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
* fix: keep hint-less guest mappings at the canonical PS5 base
FindGuestFreeRange searched the low system-managed range first for
mappings with no address hint, so the first hint-less direct-memory map
could land as low as 0x200000. The PS5 kernel never places hint-less
user mappings below 0x200000000 and guest code relies on that: Sony's
libc maps 4 MiB of direct memory for its internal heap, fails its
mspace setup when the returned address is that low, and the first
malloc then dereferences a null mspace (a read at 0x38, the mspace
magic check). On macOS this made Raiden III crash on the main guest
thread a couple of seconds after boot, 100 percent reproducible with
--printf-direction Silent.
Search from the canonical base first, fall back to the user range, and
keep the low system-managed range only as a last resort. The mmap path
already anchored hint-less searches at 0x200000000; this aligns the
shared search helper with it.
Adds two regression tests: the libc-shaped allocation must come back at
or above the canonical base and hold writes, and direct-memory content
must survive an unmap and remap of the same physical range.
* macos: make the fatal-report memory dumps fault-safe
IsReadableRange returned true for any nonzero address on macOS, so the
fatal report's guest memory dumps dereferenced whatever the crashed
thread had in its registers. A fault inside the reporter re-enters the
signal handler and wedges the reporting thread, which hid real guest
crashes whenever logging was enabled: the game kept running with a dead
thread and the report was never completed.
Walk the Mach regions covering the range and require read permission
before dumping, the same contract the Linux implementation provides.
* do not fallthrough HOST_SYSTEM_MANAGED_MIN
---------
Co-authored-by: nmzik <Nmzik@mail.ru>