[GH-ISSUE #4138] PS1 (PS-X EXE, MIPS I + GTE) analysis: tested add-on and findings for #1948 #1630

Open
opened 2026-10-16 21:08:12 +00:00 by bsakaguchi · 0 comments
Owner

Originally created by @majbal87 on GitHub (Oct 15, 2026).
Original GitHub issue: https://github.com/morluto/rea/issues/4138

Before submitting

  • I searched open and closed issues and PRs (related: #1948, #2734).
  • I understand the contribution scope must be reviewed before integration.
  • No credentials, private samples or sensitive target data included.

Area

Native analysis or decompilation

Current limitation

On main, a PS-X EXE is rejected (unsupported binary format), raw-binary mode has no MIPS, and an honest MIPS-I ELF header is refused (#2734). Under the generic MIPS language, GTE (COP2) ops decode as opaque copFunction(2, …) calls and lwc2/swc2 are misdecoded, which corrupts dataflow.

Use cases

Studying and preserving PlayStation 1 games whose source is lost, and supporting community byte-matching decomps (splat, m2c, objdiff), where REA's xrefs, call graphs and named library calls help.

What works today (outside REA)

Add-on: https://github.com/majbal87/rea-addons

  • Wrap the PS-X EXE or a raw overlay in an ELF32 header that the elf32-exec-arch32-legacy-pinned-v1 lane admits.
  • Run REA on a Ghidra 12.1.4 copy with ghidra_psx_ldr and REA_GHIDRA_LANGUAGE_ID=PSX:LE:32:default.

Tested on a retail US title against a community byte-matching decomp:

  • 6 matched functions decompiled with the same logic, including GTE-heavy and PsyQ-library ones.
  • gte_* ops and many PsyQ names were recovered.
  • 11 of 12 native tool families worked.

Findings for #1948

  1. A header gp0 of 0 is applied as a real gp (ReaGhidraPreparePsx.java:57), so gp-relative globals show as uRam000000d4 instead of DAT_8002xxxx. Suggest treating 0 as unknown, as sp0 = 0 already is.
  2. The PSX language override is refused for psx-exe targets. With ghidra_psx_ldr, it is what makes GTE code readable.

Other gaps hit

  • gp can't be supplied: .reginfo / PT_MIPS_REGINFO isn't applied under the PSX language.
  • The CLI's --snapshot doesn't keep the Ghidra database. Each call re-analyses: about 40 s for a main executable, about 3 min for a large overlay.
  • analyze_function returns 100–900 KB; a summary or paging mode would help.
  • No set_comment for the Ghidra provider.
  • No way to create a function at an address: non-entry addresses are reported as unmapped file offsets.

Desired outcome and success criteria

A first-party PS1 profile, like the PSP/Allegrex lane (#1330):

  • PS-X EXE and overlay admission with load address and gp;
  • MIPS I with GTE through a fingerprinted ghidra_psx_ldr (PSX:LE:32:default);
  • verified with a fixture that contains no game data.

Happy to test candidates.

Expected interaction with targets

Read existing files or captured data

Originally created by @majbal87 on GitHub (Oct 15, 2026). Original GitHub issue: https://github.com/morluto/rea/issues/4138 ### Before submitting - [x] I searched open and closed issues and PRs (related: #1948, #2734). - [x] I understand the contribution scope must be reviewed before integration. - [x] No credentials, private samples or sensitive target data included. ### Area Native analysis or decompilation ### Current limitation On main, a PS-X EXE is rejected (`unsupported binary format`), raw-binary mode has no MIPS, and an honest MIPS-I ELF header is refused (#2734). Under the generic MIPS language, GTE (COP2) ops decode as opaque `copFunction(2, …)` calls and `lwc2`/`swc2` are misdecoded, which corrupts dataflow. ### Use cases Studying and preserving PlayStation 1 games whose source is lost, and supporting community byte-matching decomps (splat, m2c, objdiff), where REA's xrefs, call graphs and named library calls help. ### What works today (outside REA) Add-on: https://github.com/majbal87/rea-addons - Wrap the PS-X EXE or a raw overlay in an ELF32 header that the `elf32-exec-arch32-legacy-pinned-v1` lane admits. - Run REA on a Ghidra 12.1.4 copy with ghidra_psx_ldr and `REA_GHIDRA_LANGUAGE_ID=PSX:LE:32:default`. Tested on a retail US title against a community byte-matching decomp: - 6 matched functions decompiled with the same logic, including GTE-heavy and PsyQ-library ones. - `gte_*` ops and many PsyQ names were recovered. - 11 of 12 native tool families worked. ### Findings for #1948 1. A header gp0 of 0 is applied as a real gp (`ReaGhidraPreparePsx.java:57`), so gp-relative globals show as `uRam000000d4` instead of `DAT_8002xxxx`. Suggest treating 0 as unknown, as sp0 = 0 already is. 2. The PSX language override is refused for psx-exe targets. With ghidra_psx_ldr, it is what makes GTE code readable. ### Other gaps hit - gp can't be supplied: `.reginfo` / `PT_MIPS_REGINFO` isn't applied under the PSX language. - The CLI's `--snapshot` doesn't keep the Ghidra database. Each call re-analyses: about 40 s for a main executable, about 3 min for a large overlay. - `analyze_function` returns 100–900 KB; a summary or paging mode would help. - No `set_comment` for the Ghidra provider. - No way to create a function at an address: non-entry addresses are reported as unmapped file offsets. ### Desired outcome and success criteria A first-party PS1 profile, like the PSP/Allegrex lane (#1330): - PS-X EXE and overlay admission with load address and gp; - MIPS I with GTE through a fingerprinted ghidra_psx_ldr (`PSX:LE:32:default`); - verified with a fixture that contains no game data. Happy to test candidates. ### Expected interaction with targets Read existing files or captured data
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
morluto/rea#1630
No description provided.