[PR #852] [MERGED] cpu_patches: Patch just-in-time using signal handlers. #1806

Closed
opened 2026-02-27 21:14:01 +03:00 by kerem · 0 comments
Owner

📋 Pull Request Information

Original PR: https://github.com/shadps4-emu/shadPS4/pull/852
Author: @squidbus
Created: 9/9/2024
Status: Merged
Merged: 9/15/2024
Merged by: @raphaelthegreat

Base: mainHead: patch-sigill


📝 Commits (3)

  • 69b7088 cpu_patches: Patch just-in-time using illegal instruction handler.
  • cc8e746 core: Add common signal dispatch system and use for on-demand TCB patches.
  • 559d3fd page_manager: Re-add userfaultfd implementation.

📊 Changes

7 files changed (+404 additions, -143 deletions)

View changed files

📝 CMakeLists.txt (+2 -0)
📝 src/core/cpu_patches.cpp (+138 -42)
📝 src/core/cpu_patches.h (+6 -6)
📝 src/core/module.cpp (+4 -3)
src/core/signals.cpp (+168 -0)
src/core/signals.h (+56 -0)
📝 src/video_core/page_manager.cpp (+30 -92)

📄 Description

Reworks the patching system to patch on demand using a signal handler, instead of completely ahead of time.

The current system works on the assumption that just scanning down segments will generally work out without becoming misaligned by data or patching data as if it were code. In practice this generally works, but there are some games where it does not and code that needs patching will be missed.

Instead, we can discover instructions that need patching by actually running the code and trapping signals on bad instructions. I've introduced a platform-common way of registering multiple handlers for a signal, captured using either vectored exception handlers on Windows or signal handlers on POSIX systems, and wired up both this and the existing page manager to it.

One caveat is that when running under Rosetta 2 on macOS, for whatever reason patching an instruction at the beginning of a page does not work. It just acts like the instruction was not patched and raises SIGILL again. I've tried a few things to get around this but couldn't figure it out, so I left a workaround to patch instructions at the beginning of each code page ahead of time on macOS.

Tested this by running through a few games on macOS that need these patches. Needs testing on other OSes since this impacts TCB access patches and GPU page invalidation.

One game fixed by this is CUSA02799, which currently crashes on launch on ARM64 macOS due to a missed BMI1 instruction patch.


🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.

## 📋 Pull Request Information **Original PR:** https://github.com/shadps4-emu/shadPS4/pull/852 **Author:** [@squidbus](https://github.com/squidbus) **Created:** 9/9/2024 **Status:** ✅ Merged **Merged:** 9/15/2024 **Merged by:** [@raphaelthegreat](https://github.com/raphaelthegreat) **Base:** `main` ← **Head:** `patch-sigill` --- ### 📝 Commits (3) - [`69b7088`](https://github.com/shadps4-emu/shadPS4/commit/69b7088120587e3fd6f8bd53767940f0d705beed) cpu_patches: Patch just-in-time using illegal instruction handler. - [`cc8e746`](https://github.com/shadps4-emu/shadPS4/commit/cc8e7468081019e343411a747cfc273d24d00908) core: Add common signal dispatch system and use for on-demand TCB patches. - [`559d3fd`](https://github.com/shadps4-emu/shadPS4/commit/559d3fdb9df9aa6c7011a6e0f24c9e1de9bec6f6) page_manager: Re-add userfaultfd implementation. ### 📊 Changes **7 files changed** (+404 additions, -143 deletions) <details> <summary>View changed files</summary> 📝 `CMakeLists.txt` (+2 -0) 📝 `src/core/cpu_patches.cpp` (+138 -42) 📝 `src/core/cpu_patches.h` (+6 -6) 📝 `src/core/module.cpp` (+4 -3) ➕ `src/core/signals.cpp` (+168 -0) ➕ `src/core/signals.h` (+56 -0) 📝 `src/video_core/page_manager.cpp` (+30 -92) </details> ### 📄 Description Reworks the patching system to patch on demand using a signal handler, instead of completely ahead of time. The current system works on the assumption that just scanning down segments will generally work out without becoming misaligned by data or patching data as if it were code. In practice this generally works, but there are some games where it does not and code that needs patching will be missed. Instead, we can discover instructions that need patching by actually running the code and trapping signals on bad instructions. I've introduced a platform-common way of registering multiple handlers for a signal, captured using either vectored exception handlers on Windows or signal handlers on POSIX systems, and wired up both this and the existing page manager to it. One caveat is that when running under Rosetta 2 on macOS, for whatever reason patching an instruction at the beginning of a page does not work. It just acts like the instruction was not patched and raises SIGILL again. I've tried a few things to get around this but couldn't figure it out, so I left a workaround to patch instructions at the beginning of each code page ahead of time on macOS. Tested this by running through a few games on macOS that need these patches. Needs testing on other OSes since this impacts TCB access patches and GPU page invalidation. One game fixed by this is CUSA02799, which currently crashes on launch on ARM64 macOS due to a missed BMI1 instruction patch. --- <sub>🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.</sub>
kerem 2026-02-27 21:14:01 +03:00
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
starred/shadPS4#1806
No description provided.