The "Fill more block info" re-decode indexed result.data[(ia - lsa) / 41] instead of / 4 (its companion decode uses / 4), so it read the wrong word and corrupted the per-block reg_const / reg_val32 constant propagation.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Giga cleanup clears m_block_info for removed blocks but left their in-range edges in m_targets, so the register-state walk dereferenced a stale target and aborted ("Range check failed") - e.g. a brsl whose return is a stop-trap, hit in Skylanders Giants. Prune those edges at the m_targets cleanup; export out_target_list after the prune so callers see the cleaned map; keep the initiate_patterns and cond_next-walk guards as defense in depth.
Adds made-up-data regression tests (the exported-map test fails without the prune) and the rpcs3_test.vcxproj entry.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- Some SPU programs inexplicably fail to compile when TBL2/TBX2 are used.
- As an insane workaround, first try to compile with TBL2/TBX2, if LLVM crashes while compiling, try to compile the same program without TBL2/TBX2.
Address review feedback on #18701 (cc @elad335): combine the SPU
worker fix from #18701, the SPRX Loader fix from #18703, and three
additional similar W^X leaks discovered while auditing the codebase
for the same pattern. Use Allman-style braces to match RPCS3 coding
style.
Background:
On AArch64 Apple Silicon, MAP_JIT pages enforce W^X per-thread.
pthread_jit_write_protect_np(false) enables write mode and
pthread_jit_write_protect_np(true) restores execute mode. When code
takes an early return or throws between these calls, the thread is
left in write mode, which can cause segfaults on subsequent code
fetches or inconsistent state at thread teardown.
Fixes applied (all gated on __APPLE__):
1. Emu/Cell/SPUCommonRecompiler.cpp - SPU cache worker thread
Add RAII guard so execute mode is restored on worker exit.
2. Emu/System.cpp - SPRX Loader thread
Enter write mode (was missing entirely) so ppu_initialize() and
ppu_precompile() can write to MAP_JIT pages, and pair with an
RAII guard. Reproducer: Red Dead Redemption (BLUS30418) crashes
~12s into boot at 0x300010000 without this fix.
3. Emu/Cell/SPULLVMRecompiler.cpp - SPU LLVM compile path
The compile function enters write mode, then has an early
"return nullptr" path on rebuild_ubertrampoline failure that
skipped the explicit restore. Add RAII guard so execute mode
is restored on every exit path. The existing explicit restore
before the cache-flush asm directives is preserved.
4. Emu/Cell/PPUThread.cpp - PPU LLVM worker thread (operator())
Worker entered write mode but never restored it on operator()
return. Add RAII guard.
5. Emu/Cell/PPUThread.cpp - ppu_initialize() main path
This scope alternates write/execute mode and contains an early
"return compiled_new" at the empty-jits check plus a final
return that both leak write mode. Add RAII guard so execute
mode is always restored on exit. Intermediate explicit
transitions for the symbol-resolver invocation are preserved.
No behavioral change on x86_64 or non-Apple ARM64 (all changes are
inside #ifdef __APPLE__ / #if defined(__APPLE__)).
Supersedes #18703.
Build RPCS3 / RPCS3 Mac ${{ matrix.name }} (8e21bdbc40711a3fccd18fbf17b742348b0f4281, rpcs3/rpcs3-binaries-mac-arm64, .ci/build-mac-arm64.sh, Apple Silicon) (push) Waiting to run
Build RPCS3 / RPCS3 Mac ${{ matrix.name }} (8e21bdbc40711a3fccd18fbf17b742348b0f4281, rpcs3/rpcs3-binaries-mac-arm64, .ci/build-mac-arm64.sh, Apple Silicon) (push) Waiting to run
Build RPCS3 / RPCS3 Mac ${{ matrix.name }} (8e21bdbc40711a3fccd18fbf17b742348b0f4281, rpcs3/rpcs3-binaries-mac-arm64, .ci/build-mac-arm64.sh, Apple Silicon) (push) Waiting to run
Build RPCS3 / RPCS3 Mac ${{ matrix.name }} (8e21bdbc40711a3fccd18fbf17b742348b0f4281, rpcs3/rpcs3-binaries-mac-arm64, .ci/build-mac-arm64.sh, Apple Silicon) (push) Waiting to run
Build RPCS3 / RPCS3 Mac ${{ matrix.name }} (8e21bdbc40711a3fccd18fbf17b742348b0f4281, rpcs3/rpcs3-binaries-mac-arm64, .ci/build-mac-arm64.sh, Apple Silicon) (push) Has been cancelled