Repository navigation
SPU Analyzer: Giga Block Crash Fix for Skylanders Giants - #18935
Conversation
|
maybe the test file needs to be added also in rpcs3_test.vcxproj |
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>
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>
10d8141 to
4e73b55
Compare
|
So I had originally kept the fix very narrow since based on how the other guards worked I didn't think pruning was right. This set of commits fixes that. I also had Claude scan across the SPUCommonRecompiler.cpp for any other range violations and it also found a typo. I've had it implement tests for all the changes and picked up @digant73's note about the CMake vs Visual Studio project miss (I don't have a Windows box handy so I'm hoping CI catches any errors on that edit).
Tests: the original stop-trap regression plus three more. The exported-map test is discriminating (fails without the prune); the loop-body-walk and re-decode tests are positive coverage (the /41 effect is internal-only, so it can't be pinned through analyse()'s public output). All four pass locally via rpcs3_test; every SPU word is made-up data. |
When running Skylanders Giants with SPU LLVM, the game crashes. I used Claude to isolate down to a minimal fix and test case. Post fix the title launches correctly.
In giga block mode, a brsl whose return address holds a stop (0x0) word gets a return-point block during discovery that the cleanup pass then deletes (its result.data word is 0) without dropping the m_targets edge pointing at it. The reg-state walk follows that dangling edge into initiate_patterns, where ::at32(m_bbs, bpc) range-check-fails and freezes the SPU thread (reproduced on Skylanders Giants, giga + SPU LLVM).
Guard the lookup the same way get_block_targets/get_block_preds already do.
Add tests/test_spu_analyser.cpp: a claude-written SPU program that reproduces the crash on the unpatched analyser.