Recompiler: a delay slot past the function end is replaced by a NOP

Open
#370 0 comments 0 reactions 0 assignees View on GitHub

Maintainers usually reply within 5 days

Nobody has claimed this yet.

Assessment

Difficulty
4/5
Estimated time
3-5 days
Newbie friendliness
45/100
Issue type
Bug
Clarity
Mostly clear
Activity status
Active
Tech stack
cpp
Domain
compilers

Research direction

Start with function_emitter.cpp:143-147 and trace how delay slots are decoded when a branch or jump ends a function range. Check how the ELF section provides the word at inst.address + 4, and compare that behavior with makeSyntheticDelaySlot. Done means the real delay instruction is preserved, or a warning identifies when a non-NOP word would be replaced.

Written by the indexing model from the issue text.

Description

When a branch or jump is the last instruction of a function's range, function_emitter.cpp:143-147 emits a synthetic NOP for its delay slot (makeSyntheticDelaySlot) instead of decoding the real word at inst.address + 4 from the ELF. Nothing is logged.

So any function start that lands on a delay slot silently drops that delay instruction from the owner. The fallback heuristics are fixed in the linked PR, but the same thing can still happen with starts from JAL targets, the entry point, symbols, DWARF or Ghidra maps.

Seen in FIFA Street 2 (SLUS-21369): a heuristic start at 0x202020 cut sub_00201FD8 right after jal 0x431c88. The delay-slot lw $a0, 0($v0) that loads the call argument was replaced by the NOP, the lookup returned null, and the main thread died on a virtual call at 0x202048.

Suggested fix: decode the real word from the section when the delay slot sits outside the range, or at least warn when that word is not a NOP.

Related PR: fix/delay-slot-function-starts

Dominant language
C++
Stars
3.3k
Forks
149
Avg merge
8h 46m
Merged PRs (30d)
1

Getting set up

This project ships no dev container, Dockerfile or contributing guide, so setting up is up to you: start from its README, and see our first-contribution guide for the general steps.

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from ran-j/PS2Recomp

All issues in ran-j/PS2Recomp

Similar issues

More C++ issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.