mirror of
https://github.com/RPCS3/rpcs3.git
synced 2026-05-12 16:19:44 -06:00
Emu: enable JIT write mode in SPRX Loader on Apple Silicon
The SPRX Loader thread spawned in Emulator::Load() invokes
ppu_initialize() and ppu_precompile(), both of which write into the
PPU JIT code cache. On AArch64 Apple Silicon, MAP_JIT pages default
to execute mode for newly created threads, so any write into the
cache from this thread segfaults before the game can boot.
Reproducible on a clean RPCS3 0.0.40-19340 boot of Red Dead
Redemption (BLUS30418) on macOS arm64: the emulator crashes ~12s
into boot with "Segfault writing location 0x300010000" originating
from the {SPRX Loader} thread, never reaching the title screen.
Mirror the W^X handling already used by the PPU thread's
ppu_cmd::initialize handler in PPUThread.cpp: enable write mode at
thread entry and pair it with an RAII guard so execute mode is
restored on every exit path (normal return, early-exit on
Emu.IsStopped(), exception). No effect on x86_64 or non-Apple
ARM64 builds (entire block is inside #ifdef __APPLE__).
This commit is contained in:
parent
4312221498
commit
a0b2485c07
@ -1835,6 +1835,17 @@ game_boot_result Emulator::Load(const std::string& title_id, bool is_disc_patch,
|
||||
|
||||
g_fxo->init<named_thread>("SPRX Loader"sv, [this, dir_queue, is_fast = m_precompilation_option.is_fast]() mutable
|
||||
{
|
||||
#ifdef __APPLE__
|
||||
// Apple Silicon W^X: SPRX Loader writes JIT code via ppu_initialize().
|
||||
// Without entering write mode, writes to MAP_JIT pages segfault.
|
||||
pthread_jit_write_protect_np(false);
|
||||
|
||||
// RAII guard so execute mode is restored on every exit path
|
||||
// (return, exception, etc.).
|
||||
struct jit_write_guard {
|
||||
~jit_write_guard() { pthread_jit_write_protect_np(true); }
|
||||
} _jit_guard;
|
||||
#endif
|
||||
std::vector<ppu_module<lv2_obj>*> mod_list;
|
||||
|
||||
if (auto& _main = *ensure(g_fxo->try_get<main_ppu_module<lv2_obj>>()); !_main.path.empty())
|
||||
|
||||
Loading…
Reference in New Issue
Block a user