Skip to content

fix(relinker): accept matching defined relative symbols - #6357

Merged
adriadam10 merged 1 commit into
boykopovar:mainfrom
MarcZX10:codex/relinker-relative-defined-symbol-3093
Oct 19, 2026
Merged

adriadam10 merged 1 commit into
boykopovar:mainfrom
MarcZX10:codex/relinker-relative-defined-symbol-3093

Conversation

@MarcZX10

Copy link
Copy Markdown
Contributor

What

Some PS4 libc.prx files use R_X86_64_RELATIVE relocations with a nonzero symbol index. The six reported entries reference defined function or object symbols whose st_value equals the nonnegative relocation addend. The relocation still resolves to the module base plus that addend, so the guest reader can canonicalize this exact form to a symbol-zero RELATIVE entry, and code analysis can follow the same target.

The reader rejects undefined symbols and defined symbols whose value differs from the addend. The change is related to #3093. It does not claim the remaining PS4 relinker work in that issue is complete.

Tested

Linux x86-64, GCC 12.2.0, Release, relinker-only build:

  • Built the relinker target.
  • ctest --test-dir /tmp/AnyPS5-3093-build --output-on-failure -R '^(guest_none_relocations|none_relocations)$' — 2/2 passed.
  • guest_none_relocations covers SysV and SCE dynamic tables, function and object symbols, and generated ELF, PE and Mach-O outputs. Native execution was tested on Linux only.
  • python3 tools/check_conventions.py --base upstream/main --head HEAD and git diff --check upstream/main...HEAD passed.

Checklist

@MarcZX10

Copy link
Copy Markdown
Contributor Author

I manually checked the shared GuestImageReader.cpp change against #6112. #6112 adds readLifecycleArray(32, 33, image.PreInitArray) in the lifecycle-array parsing block. This PR only changes the R_X86_64_RELATIVE relocation validation/normalization block earlier in the function. The diff hunks do not overlap and I found no behavioral interaction between preinit-array parsing and relative-symbol relocation handling.

@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.

Ran this on macOS, including executing the Mach-O output under Rosetta 2, since the PR's native load check only runs on Linux.

Setup: Apple M2 Max, macOS 27.2, head 32fe3aa8b merged without a commit onto main b7cedd900 (clean). Relinker-only Release builds for arm64 and for x86_64 under Rosetta (/usr/bin/python3 3.9.6).

  • Full relinker-only suite: arm64 173/173. x86_64 170/173; the 3 failures (pr_overlap_tools, release_package, linux_fixed_base) fail the same way on main (Python 3.9 issues unrelated to this PR).
  • guest_none_relocations with only the test change applied to main fails on both arches with RELATIVE relocation has a symbol for relative-defined-symbol; with the fix it passes.

Execution of the macOS output: for baseline, relative-defined-symbol, relative-defined-object and mixed, each with SysV and SCE dynamic tables (8 cases), I converted the test's module with --macos, put an empty x86_64 libkernel.prx dylib in libs/ to satisfy the @rpath/libkernel.prx load command, and dlopened module.prx.guest.prx from an x86_64 Python under Rosetta. In all 8 cases dyld rebased the image to a slid address, shared#guest returned 42, the slot at TARGET held the slid function address, and calling through that pointer returned 42. Same result with the arm64-built and the x86_64-built relinker.

So the canonicalized symbol-index RELATIVE entry is rebased correctly by dyld on macOS, not only by the Linux loader.

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

@MarcZX10

Copy link
Copy Markdown
Contributor Author

Thanks for checking the generated Mach-O on Apple silicon and under Rosetta 2. That adds useful execution coverage beyond the Linux load test.

@github-actions

github-actions Bot commented Oct 16, 2026 •

Copy link
Copy Markdown

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 6974 core/relinker/relinker/src/analysis/CodeInstructionCollector.cpp
PR 6977 core/relinker/relinker/src/analysis/CodeInstructionCollector.cpp
core/relinker/relinker/src/guest/GuestImageReader.cpp
core/relinker/relinker/tests/test_guest_none_relocations.py
PR 7450 core/relinker/relinker/src/analysis/CodeInstructionCollector.cpp
core/relinker/relinker/src/guest/GuestImageReader.cpp

@MarcZX10

Copy link
Copy Markdown
Contributor Author

I checked the overlap notice against both heads. #6977 independently contains the same matching-defined-symbol R_X86_64_RELATIVE acceptance in GuestImageReader.cpp and CodeInstructionCollector.cpp as this PR; its larger PS4 integration therefore overlaps this PR’s production behavior. #6977 does not appear to carry this PR’s focused guest_none_relocations regression fixture. The #6447 hunk is separate: it adds overflow checking for header.Offset + relative. I’ll leave both PRs open per the standing instruction; please preserve the focused regression coverage or coordinate the merge order if #6977 lands first.

@DProkos

DProkos commented Oct 18, 2026

Copy link
Copy Markdown

Windows check of 32fe3aa merged onto current main (48d61f53b, clean merge).

Windows 11 Pro 26200, WinLibs GCC 15.2.0 r7 UCRT, Ninja, Release, ANYPS5_RELINKER_ONLY=ON, BUILD_TESTING=ON, Python 3.11.0.

  • guest_none_relocations: passed.
  • Full relinker suite: 196/196 passed.

Negative control: with CodeInstructionCollector.cpp and GuestImageReader.cpp restored to main and the updated test kept, guest_none_relocations fails on the relative-defined-symbol case (non-SCE, Linux output): FAIL: ...\sce_module\module.prx: RELATIVE relocation has a symbol.

Not run: titles or homebrew.

AI-assisted: yes

@savvaniss

Copy link
Copy Markdown
Contributor

Second-title data point: Hasbro Family Fun Pack (CUSA03312, my own dump) needs this PR, on Linux and Windows.

Relinker-only Release build, Windows 11 Pro 26300, WinLibs GCC 15.2.0 r7. Starting from main f3059421f, I merged, in this order: #7660, #6619 (a9fa0e8b0), #5138 (5f5641732), #6381 (6f8d9a09d), 3b158c1 from #6977, #6354 (81561867f), #6357 (32fe3aa8b), #6684 (ab9d21afc) and #6618 (bf06a8e5c). With that stack, the Linux and --windows conversions of the eboot and its 9 bundled modules complete. I then rebuilt the relinker once per member with only that member left out. Without this PR, both targets stop in libc.prx:

FAIL: ...\sce_module\libc.prx: RELATIVE relocation has a symbol

With #5138 also in the stack, the two conflict in GuestImageReader.cpp. I resolved it by accepting either form: a zero-value section symbol (#5138) or a defined symbol whose value equals the addend (this PR).

The other members each stop at their own step, so every one of them is needed for this title; the whole table is on #6977.

AI-assisted: yes (Claude Code)

@MarcZX10

Copy link
Copy Markdown
Contributor Author

Thanks for the second-title report. The leave-one-out conversions show Hasbro Family Fun Pack needs this relative-defined-symbol handling on both Linux and Windows within the composed dependency stack, and the omission control stops at the reported relocation in libc.prx. This adds title-level evidence alongside the existing relinker tests; I’ve recorded it.

@adriadam10 adriadam10 self-assigned this Oct 18, 2026
@adriadam10
adriadam10 merged commit 7b12450 into boykopovar:main Oct 19, 2026
10 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants