Skip to content

feat(relinker): write a registry for each converted bundled module - #1462

Merged
adriadam10 merged 1 commit into
boykopovar:mainfrom
abderahmane-ai:feat/module-registry
Oct 9, 2026
Merged

adriadam10 merged 1 commit into
boykopovar:mainfrom
abderahmane-ai:feat/module-registry

Conversation

@abderahmane-ai

Copy link
Copy Markdown
Contributor

What

relinker --registry only described the imports of the executable, so a title whose own modules import system functions (PSN.prx, libc.prx and others) could not be audited completely. With --registry the relinker now also writes <output-stem>.<module>.registry.json for every converted bundled module.

An entry is written for each relocation, in DT_RELA and DT_JMPREL, against an undefined symbol that no other bundled module exports. That is the test GuestModuleBuilder already uses to decide that a dependency is satisfied by a sibling. Entries carry nid, library and targetOffset; the symbol has lost its # suffix by the time the module is read, so the NID is the bare 11 characters. The executable's registry is unchanged. The import audit from #1461 accepts these files as they are, and its docs are updated for them.

The first commit of this branch is #1461; the second is this change.

Tested

  • core/relinker/relinker/tests/test_guest_registry.py (registered in CTest as guest_registry), for Linux and Windows output: two modules where one is provided by its sibling, both relocation tables, the same module importing the sibling's function once the sibling is removed, and no registry file without --registry.
  • Broke the change three ways in throwaway copies (sibling exclusion removed, DT_JMPREL ignored, wrong target offset); the test caught all three.
  • All 25 relinker Python tests pass with a relinker built from this branch on macOS 26.5 arm64, and the audit over the executable and module registries gave the expected counts.
  • python3 tools/check_conventions.py --base origin/main passes. A trial merge with fix(relinker): resolve internal libc imports from guest libc #1454, the other open relinker PR, is clean.
  • Not tested: GCC or MinGW builds (built with clang here), and a real title.

The code, tests and docs were written with AI assistance. I read every line and ran the checks above.

Checklist

  • Based on current main; no other open PR implements the same functions
  • One topic per PR; follow-ups go in a new PR
  • No comments in code except technical debt
  • Unimplemented paths throw (NotImplemented_nid_no_patch); silent stubs are listed in TechnicalDebt
  • No notes, investigation .md files or images added to the repository (attach them to this PR)
  • New third-party code is a submodule built from source
  • Generic behaviour, not specific to one title
  • Depends on: feat(tools): add an import audit for converted games #1461
  • AI-assisted: yes

@adriadam10

Copy link
Copy Markdown
Collaborator

Rebased onto current main: #1461 landed, so its commit dropped out and one commit remains. Checked on Linux: build + full ctest green (464/464); guest_registry fails with the non-test changes reverted; the diff matches the description (relocations in DT_RELA and DT_JMPREL against symbols no other bundled module exports; executable registry unchanged); module registries are accepted by tools/import_audit.py as is. Merging once CI is green on the rebased head.

@github-actions github-actions Bot removed the needs rebase Conflicts with main, rebase needed label Oct 8, 2026
@github-actions

github-actions Bot commented Oct 8, 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
#1529 core/relinker/relinker/src/guest/GuestModuleBuilder.cpp L184-185
#1597 core/relinker/CMakeLists.txt L230

--registry only described the imports of the executable, so a title whose
own modules import system functions (PSN.prx, libc.prx and others) could
not be audited completely. With --registry the relinker now also writes
<output-stem>.<module>.registry.json for every converted guest module.

An entry is written for each relocation against an undefined symbol that
no other bundled module exports, the same test the module builder uses to
decide that a dependency is satisfied by a sibling. Entries carry nid,
library and targetOffset; the symbol name no longer has the # suffix by the
time the module is read, so the NID is the bare 11 characters. The
executable's registry is unchanged.

The test converts two modules where one is provided by its sibling, for
Linux and Windows output, covers the DT_RELA and DT_JMPREL tables, checks
that the same module imports the sibling's function once the sibling is
absent, and that nothing is written without --registry. Registered in
CTest as guest_registry.
@adriadam10
adriadam10 force-pushed the feat/module-registry branch from 20e15db to bd750b5 Compare October 9, 2026 20:44
@adriadam10
adriadam10 merged commit c30b87a into boykopovar:main Oct 9, 2026
7 checks passed
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.

2 participants