mirror of
https://github.com/boykopovar/AnyPS5.git
synced 2026-10-23 09:03:22 -05:00
macOS has no counterpart to userfaultfd write-protect or MEM_WRITE_WATCH, so GuestWriteWatch had no backend there and the driver re-read every guest buffer on each use. The macOS backend write-protects watched pages. The first write to a page faults, the SIGBUS/SIGSEGV handler records the page and restores its protection, and Collect reports the recorded pages and protects them again. A page is protected before its record is cleared, under the lock the handler takes, so a write that lands in between is recorded. The lock hands out turns in order: an unfair one starved writers under Rosetta. The protection is real, which adds three entry points: - GuestWriteWatchBeginHostWrite/EndHostWrite lift it around a system call that writes guest memory, which would otherwise fail with EFAULT. GuestArena::HostWrite calls them, as it calls the Windows equivalent. - GuestWriteWatchProtectionChanged tells the watch the protection given to watched pages by mprotect or a new mapping. - GuestWriteWatchProtection reports that protection, since a watched page is read-only between a collection and the next write. Register keeps the recorded protection of a page it already watches: read from the kernel it would be the watch's own read-only protection, and the page would never be watched again. The tests build without the prx libraries and run natively and through Rosetta. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>