Skip to content

fix(relinker): stop module syscall scans at the PLT and skip the PS4 loader path - #5994

Merged
adriadam10 merged 2 commits into
boykopovar:mainfrom
Get-fix:ps4/sce-module-code-extent
Oct 18, 2026
Merged

adriadam10 merged 2 commits into
boykopovar:mainfrom
Get-fix:ps4/sce-module-code-extent

Conversation

@Get-fix

@Get-fix Get-fix commented Oct 14, 2026

Copy link
Copy Markdown
Contributor

What

OpenOrbis modules (sce_module/*.prx) stop in the relinker at two places after #5138, which makes their section-symbol relocations convertible. Both are about where a module's code is, so they are one change.

  • Syscall scan: OpenOrbis modules keep read-only data after their code, as executables do. The syscall scan of sce_module modules decoded that data, and the library sample's libExample.prx failed with FAIL: Forbidden syscall instruction at code offset 0xd016e. For modules with a PT_SCE_DYNLIBDATA segment, the scan now stops at the end of the PLT after the last unwind function, found by FindSceCodeEnd as for executables (fix(relinker): keep code analysis inside the code extent of PS4 executables #5195).
  • Loader path: the same modules begin their executable segment with the /libexec/ld-elf.so.1 string but have no PT_INTERP header, so code analysis decoded the string and failed with FAIL: Unsupported Windows guest TLS instruction (bytes: 64 2d 65 6c 66 2e) (offset 0x400a), which is the text d-elf.. When no PT_INTERP covers the start of a PS4 code segment and the segment begins with exactly that string, code analysis starts after it.

The relinker debt file records that code after the PLT is not scanned. Part of the PS4 homebrew work tracked in #3093.

Tested

Windows 11 Pro 26200, WinLibs GCC 15.2.0 r7, Release, on main e442f4c2e:

Not tested on Linux or macOS.

Checklist

🤖 Generated with Claude Code

…loader path

OpenOrbis modules keep read-only data after their code, as executables
do. The syscall scan of sce_module modules decoded it, and the module of
the OpenOrbis library sample (libExample.prx) failed with "Forbidden
syscall instruction". For modules with a PT_SCE_DYNLIBDATA segment, the
scan now stops at the end of the PLT after the last unwind function,
found by FindSceCodeEnd as for executables.

The same modules begin their executable segment with the
/libexec/ld-elf.so.1 string but have no PT_INTERP header, so code
analysis decoded the string and failed with "Unsupported Windows guest
TLS instruction (bytes: 64 2d 65 6c 66 2e)", which is the text "d-elf.".
When no PT_INTERP header covers the start of a PS4 code segment, code
analysis now starts after that exact string.

@jotitadev jotitadev left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

macOS data point: the --macos target hits the same loader-path failure, and this PR fixes it there too.

Apple M2 Max, macOS 27.2 (26B5091g), AppleClang, Ninja Release, relinker-only. Head 8997cac1b merged without conflicts into main c26982f63.

  • arm64: ctest 164/164.
  • x86_64 under Rosetta 2 (-DCMAKE_OSX_ARCHITECTURES=x86_64, Python 3.9.6): 160/164; the 4 failures (pr_overlap_encoding, stubgen_stdout_newlines, release_package, linux_fixed_base) fail the same way on unmodified main here.
  • sce_module_code_extent with only the test applied on main fails on both builds with Unsupported Windows guest TLS instruction (bytes: 64 2d 65 6c 66 2e) (offset 0x100a); with the PR it passes.

The test converts both fixtures with --windows only. I ran the same two fixtures (fixture(rodata_address=False, interp_header=False) and sce_module() from the test) through every target, same results on the arm64 and x86_64 binaries:

Target Fixture main This PR
Linux (default) loader path, no PT_INTERP converts converts
Linux (default) module with data after code Forbidden syscall instruction at code offset 0x1020 converts
--macos loader path, no PT_INTERP Unsupported macOS guest TLS instruction (bytes: 64 2d 65 6c 66 2e) (offset 0x100a) converts
--macos module with data after code Forbidden syscall instruction at code offset 0x1020 converts
--windows loader path, no PT_INTERP Unsupported Windows guest TLS instruction ... converts
--windows module with data after code Forbidden syscall instruction at code offset 0x1020 converts

So the syscall-scan part matters on all three targets and the loader-path part on macOS and Windows; this covers conversion on the Linux and macOS hosts the description lists as untested. Running the fixtures with --macos as well would keep the macOS TLS path under test.

Written with AI assistance (Claude Code). I ran the builds and tests above on my machine.

@github-actions

github-actions Bot commented Oct 15, 2026 •

Copy link
Copy Markdown

Other open pull requests touch the same code. Merging one will break the other, or both implement the same thing. If this one builds on them, list them in Depends on.

Pull request Conflicting files (lines on main) Same exports Same new files
PR 6314 core/relinker/relinker/src/guest/GuestModuleBuilder.cpp L330-331
PR 6354 docs/dev/debt/relinker.md L17
PR 6977 core/relinker/relinker/tests/test_sce_module_code_extent.py

Some comparisons could not be completed because a pull request conflicts with the base branch. Review these shared files manually before concluding that there is no overlap.

Pull request Shared files not compared
PR 2780 core/relinker/CMakeLists.txt
core/relinker/relinker/src/guest/GuestModuleBuilder.cpp
PR 5021 core/relinker/CMakeLists.txt
docs/dev/debt/relinker.md
PR 6044 core/relinker/CMakeLists.txt
PR 6111 docs/dev/debt/relinker.md
PR 6879 core/relinker/CMakeLists.txt

The two fixtures were converted for Windows only. They now run for
Linux, Windows and macOS. The syscall scan of a module with data after
its code fails on all three without the fix, and the loader path
without PT_INTERP fails on Windows and macOS, so the macOS code
analysis stays under test.
@Get-fix

Get-fix commented Oct 15, 2026

Copy link
Copy Markdown
Contributor Author

@jotitadev Thanks for running it on macOS. I followed your suggestion: Get-fix/AnyPS5@f7ec358ec converts both fixtures for Linux, Windows and macOS.

I checked each target without each part of the fix, using --macos conversions run on Windows. The results match your table:

  • Loader-path rule removed: Windows and macOS stop at Unsupported … guest TLS instruction (bytes: 64 2d 65 6c 66 2e) (offset 0x100a), and Linux converts.
  • Scan limit removed: all three stop at the module's syscall scan.

The relinker-only ctest passes (165/165).

I checked the overlap the bot lists. I fetched each listed pull request and, for every file it shares with this one, merged its change with git merge-file into current main (a5e2a80c6) and into main with this pull request merged. A conflict that appears only in the second case is one this pull request adds.

The bot lists 24 pull requests, with 45 shared files between them. This pull request adds a conflict in three:

Combined build: I built main with this pull request, #6354, #6314 and #5138 merged.

AI-assisted: yes (Claude Code). I ran these checks myself on Windows 11.

🤖 Generated with Claude Code

@adriadam10

Copy link
Copy Markdown
Collaborator

Checked on the head merged onto current main: relinker-scope build and ctest (137 tests) pass, and sce_module_code_extent fails when the two code changes are reverted. Relinker CI jobs are green on Linux, Windows and macOS, and @jotitadev's macOS run agrees. Merging once the full Build is green.

@adriadam10
adriadam10 merged commit e00260b into boykopovar:main Oct 18, 2026
9 checks passed
SandstromPL added a commit to SandstromPL/AnyPS5 that referenced this pull request Oct 18, 2026
Resolve the docs/dev/debt/relinker.md conflict with boykopovar#5994: keep its
sce_module syscall-scan entry, which now also stops at the end of the
last unwind function when the PLT comes before the code (it calls the
same FindSceCodeEnd), and its /libexec/ld-elf.so.1 start in the code
analysis entry, with this PR's end for a PLT before the code.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants