MoH Vanguard (SLUS-21597) bring-up: 18.9k functions recompiled with 0 undecoded instructions — generated code builds, links and boots to guest execution (+ toolchain findings)
Maintainers usually reply within 5 days
Nobody has claimed this yet.
Assessment
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Newbie friendliness
- 35/100
Research direction
Start by reading the four toolchain findings and their cited locations: ps2_recompiler.cpp, code_generator_tests.cpp, ps2xRuntime/src/runner/register_functions.cpp, and the dump workflow. The report proposes separate fixes, each with a suggested test where applicable; choose one finding and confirm its scope with the maintainers before changing code. Done means a focused fix and the corresponding test or workflow check demonstrates the reported problem is addressed.
Written by the indexing model from the issue text.
Description
We brought Medal of Honor: Vanguard through the full M1 pipeline: ISO → ELF extraction → ps2_analyzer → ps2_recomp → generated code compiled and linked against ps2xRuntime. This is a report of how the toolkit handled a multi-MB retail EA title end to end, plus a few toolchain findings. The full measured report can be pasted in this issue on request.
Environment: toolkit at eb8688b, MSVC Release, Windows 11.
Disc facts: BOOT2 = cdrom0:\SLUS_215.97;1 (NTSC) — the boot ELF is only a 124 KB loader; the real game is MOH5RDVD.ELF, 4.89 MB ELF32 MIPS. IOP modules on disc: PADMAN, LIBSD, SNDDRV, SIO2MAN, MCMAN, MCSERV, MTAPMAN + IOPRP280.IMG.
Results:
| Vanguard | |
|---|---|
| Functions discovered | 18.876 (485 via SCE symbol DB, 0 ELF symbols — retail stripped) |
| Configured → applied stubs | 134 → 133 (see finding 1) |
| Undecoded instructions | 0 (Unhandled instructions: 0, decode failures: 0) |
| Generated code | 18.878 .cpp + 2 headers, 7.31 M lines, ~51 s generation |
| Build (MSVC, unity) | 0 errors in generated code, 28.6 min |
| Link + boot | ps2EntryRunner loads the ELF (Entry point: 0x10a008), enters run(); call/return-balanced trace proves recompiled game code executes (7.120 enters = 7.120 exits over 54 functions) |
For a 4.89 MB retail ELF, low_memory_mode = true + multi-file output worked well; note that low_memory_mode forces a single output worker (ps2_recompiler.cpp:1325), so output_worker_threads is inert in that mode — worth a README mention.
Findings while doing this (happy to file/PR separately):
- Configured stubs at non-function-boundary addresses are silently dropped. Vanguard: 134 stubs configured, 133 applied —
sceGsSetDefLoadImage@0x00471F80produced no warning. The apply loop only iterates discovered functions (ps2_recompiler.cpp:1091) and the existing warning (:1106-1109) only fires for a matched function, so there is no inverse check "every configured stub matched something". By contrast, non-boundaryentry_pointsentries do get a synthesized entry (e.g.SetT2@0x004A0558) — asymmetric handling of the same condition. ps2_recompexits 0 even when a recompile reports decode errors (observed while validating the recompiler against an additional retail ELF; the Vanguard recompile itself was clean). A CI/probe calling the tool silently passes on partial decodes. Same run also emitted byte-identical duplicate lines in the unhandled-instruction output, which inflates counts.ps2x_testsVU0 macro mappings cover all S1/S2 enums(code_generator_tests.cpp:1277) resolvesinstructions.hvia repo-relative paths and fails when the suite runs from outside the repo root.ps2xRuntime/src/runner/register_functions.cppis tracked upstream but is overwritten by the gen dump workflow (the rest ofsrc/runner/and theps2_recompiled_*.hheaders are already gitignored). After installing 18.878 generated files, the clone holds ~517k lines of game-derived code in a tracked file — one routinegit add -uwhile preparing a fork/PR would publish it. Making it untracked would make the documented dump workflow safe.
Proposed PRs (after your feedback):
| # | Topic | Content | Test |
|---|---|---|---|
| 1 | recomp: warn on configured stubs that match no discovered function |
Inverse check after the apply loop: configured stub with no match → warning (and/or error behind a flag) | new ps2xTest case with a non-boundary stub in config |
| 2 | recomp: non-zero exit code when decode errors remain |
Exit ≠ 0 when errors > 0 (or opt-in --strict-exit); dedupe identical unhandled lines (count + first address) |
integration test with an ELF containing an unsupported instruction |
| 3 | test: make VU0 enum coverage test independent of CWD |
Resolve instructions.h from the source file's path |
fix to the test itself |
| 4 | runtime: stop tracking ps2xRuntime/src/runner/register_functions.cpp |
.gitignore change so the documented dump workflow can't leak game-derived code |
n/a (.gitignore change) |
- 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
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from ran-j/PS2Recomp
-
Difficulty 2/5 1-3 hours Newbie friendliness 88/100
ran-j/PS2Recomp#393 · 1 comment ·
Maintainers usually reply within 5 days
-
EE sceCdStatus stub always reports READ (6), hanging games that wait for PAUSEPossibly taken @ahmedgamalalzatary claimed this 12 days ago. Open
Difficulty 1/5 Under an hour Newbie friendliness 95/100
Maintainers usually reply within 5 days
-
VU0 macro VSQI / VSQD: address and source registers swapped in generated codePossibly taken @yanm1103 claimed this 20 days ago. Open
Difficulty 2/5 1-3 hours Newbie friendliness 72/100
Maintainers usually reply within 5 days
-
Runtime: SampleTexture casts unbounded or NaN texture coordinates to int, which is undefined behaviourMay be free again A pull request for this issue was closed without being merged. Open
Difficulty 2/5 1-3 hours Newbie friendliness 68/100
ran-j/PS2Recomp#273 · 2 comments ·
Maintainers usually reply within 5 days
-
Build: /Qspectre- is MSVC-only and breaks every Release target under clang-clPossibly taken @ahmedgamalalzatary claimed this 12 days ago. Open
Difficulty 2/5 1-3 hours Newbie friendliness 88/100
Maintainers usually reply within 5 days
Similar issues
-
bug libcudf
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
Maintainers usually reply within 2 days
-
level/task module/cloud monitoring type/maintenance
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
Maintainers usually reply within 1 day
-
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
LadybirdBrowser/ladybird#13809 ·
Maintainers usually reply within 1 day
-
bug module:nodes tests
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
rocketride-org/rocketride-server#3020 ·
Maintainers usually reply within 2 days
-
Difficulty 2/5 1-3 hours Newbie friendliness 72/100
Maintainers usually reply within 9 days