Skip to content

fix(relinker): resolve kernel variant imports via canonical kernel - #8867

Merged
adriadam10 merged 4 commits into
boykopovar:mainfrom
MarcZX10:codex/kernel-variant-host-fallback
Oct 21, 2026
Merged

adriadam10 merged 4 commits into
boykopovar:mainfrom
MarcZX10:codex/kernel-variant-host-fallback

Conversation

@MarcZX10

Copy link
Copy Markdown
Contributor

What

The Windows relinker already adds canonical libkernel.prx when libkernel_web.prx is a dependency, but not for libkernel_sys.prx. Also, a scoped host import from either variant searched only that variant (and the existing libc fallback), even if canonical libkernel was loaded. This made a synthetic getpagesize import fail when scoped to libkernel_sys.prx or libkernel_web.prx despite canonical libkernel exporting it.

Load canonical libkernel for either variant and search a scoped variant import in this order: the requested variant, canonical libkernel, then the existing libc fallback. This keeps requested-provider precedence and does not search guest modules as aliases. Regression coverage checks the generated search order and both variant dependency lists. The overlap report found shared source/test files with #3965, #7594 and #7532; manual diff review shows their startup-stack/MXCSR changes are separate from this provider-resolution behavior. This PR does not depend on them.

Tested

Linux x86-64, GCC 12.2, relinker-only Ninja build:

  • cmake -S . -B build -G Ninja -DANYPS5_RELINKER_ONLY=ON -DBUILD_TESTING=ON -DANYPS5_RELINKER_CLI=ON
  • cmake --build build --target entry_stub_tests -j4
  • ctest --test-dir build -R '^entry_stub$' --output-on-failure: passed.
  • python3 tools/check_conventions.py --base upstream/main: passed.
  • python3 tools/pr_overlap.py --branch codex/kernel-variant-host-fallback: no duplicate behavior found; reported shared files were manually reviewed as described above.

Not run: Windows execution of the synthetic startup-import reproducer or a retail title.

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 under Silent stubs in their library's technical debt file
  • 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: none
  • Fixes: Windows: scoped kernel variant imports miss canonical libkernel providers #8853
  • Unblocks: none
  • GPUs tested: n/a (Windows relinker import resolution)
  • AI-assisted: yes

@github-actions

github-actions Bot commented Oct 21, 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 8880 core/relinker/elfpatcher/tests/EntryStubTests.cpp L3, L118, L128

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 3965 core/relinker/elfpatcher/src/windows/WindowsEntryStubBuilder.cpp

@MarcZX10

Copy link
Copy Markdown
Contributor Author

Manual overlap review for the bot warning: #3965 changes WindowsEntryStubBuilder.cpp in the startup-stack setup and unwind-table emission sections; this PR changes only import provider ordering around the earlier hostModule branch. #7532 changes the generic Linux entry-stub builder and adds a test at the start of EntryStubTests.cpp; this PR adds Windows-specific cases later in that same test file. The touched hunks are separate and should compose, though #3965’s new unwind entries warrant rerunning the Windows entry-stub tests after integration.

@ycbuzi

ycbuzi commented Oct 21, 2026

Copy link
Copy Markdown
Contributor

Windows run of fef2755, the part the description lists as not run: the synthetic startup-import reproducer from #8853, executed.

Windows 11 Home 10.0.26200, MinGW-w64 GCC 15.2.0 (ucrt-posix-seh r7), Release, BUILD_TESTING=ON, RTX 4070 not involved. The reproducer is #8853's generator as posted there (a PE from WindowsImportBuilder, WindowsEntryStubBuilder and WindowsPeWriter with one strong import of getpagesize, k+AXqu2-eBc, an eight-byte GOT and a guest entry of xor eax,eax; ret), built twice against relinker_core: once from main 7ab4b2e and once from this head, and run beside the patched libkernel_sys.prx, libkernel_web.prx, libkernel.prx and libc.prx of a full build of current main.

qualified to main this PR
libkernel_sys.prx exit 0xc0000139, FAIL: unresolved ELF import k+AXqu2-eBc from libkernel_sys.prx exit 0, control reaches the guest entry
libkernel_web.prx exit 0xc0000139, same exit 0
libkernel.prx (control) exit 0 exit 0

On this head ctest -R "^(entry_stub|windows_dependency_diagnostics)$": 2 of 2 pass. Not run: a retail title.

@MarcZX10

Copy link
Copy Markdown
Contributor Author

Thanks for running the synthetic reproducer on Windows. That fills the platform gap I called out: both scoped kernel variants now resolve on the PR head, the canonical libkernel control remains green, and the two focused relinker tests pass. The retail-title limitation is clearly stated.

@MarcZX10

MarcZX10 commented Oct 21, 2026 •

Copy link
Copy Markdown
Contributor Author

Thanks for running the Windows reproducer. This closes the host coverage gap I had called out: both kernel variants now reach the guest entry, while the libkernel control still passes on main. I will keep the console and title limitation clear.

@MarcZX10

Copy link
Copy Markdown
Contributor Author

Follow-up for the variant-only __error cases reported on #8853: ReadLibraries appended canonical libkernel.prx after it had already decided whether to append the shared libc.prx, so variant-only loads omitted libc from the Windows startup symbol table. I added dependency-list regressions for both kernel variants, then made the inferred list include canonical kernel followed by libc (without duplicating explicitly requested providers).

Validation on the updated PR head: the new entry_stub regression failed before the source fix with libkernel_sys.prx: canonical kernel fallback and its libc provider are not loaded, and passes after it. python3 tools/check_conventions.py --base upstream/main --head HEAD and git diff --check pass. This is Linux relinker-only validation; I did not run the Windows-only dependency-diagnostics executable or a retail title.

@ycbuzi

ycbuzi commented Oct 21, 2026

Copy link
Copy Markdown
Contributor

Windows run of 7fdad07, the part the follow-up lists as not run: the variant-only dependency closure UnhealthyKraken reported on #8853, executed, plus the Windows-only dependency-diagnostics test.

Same host and toolchain as my run above (Windows 11 Home 10.0.26200, MinGW-w64 GCC 15.2.0 ucrt-posix-seh r7, Release, BUILD_TESTING=ON). Each probe takes its library list from WindowsImportBuilder::ReadLibraries over a dynamic section with a single DT_NEEDED entry, imports one NID qualified to that module (eight-byte GOT, guest entry xor eax,eax; ret), and runs beside the patched libc.prx, libkernel.prx, libkernel_sys.prx and libkernel_web.prx of a full build of main 7ce3b1d. The generator is built twice against relinker_core: from main 7ce3b1d and from this head merged onto it (7e589461f5, clean).

DT_NEEDED, scoped import main: inferred list, result this PR: inferred list, result
libkernel_sys.prx, __error (9BcDykPmo1I) [libkernel_sys], exit 0xc0000139, unresolved ELF import 9BcDykPmo1I from libkernel_sys.prx [libkernel_sys, libkernel, libc], exit 0
libkernel_web.prx, __error [libkernel_web, libkernel], exit 0xc0000139, same [libkernel_web, libkernel, libc], exit 0
libkernel_sys.prx, getpagesize (k+AXqu2-eBc) [libkernel_sys], exit 0xc0000139 [libkernel_sys, libkernel, libc], exit 0
libkernel_web.prx, getpagesize [libkernel_web, libkernel], exit 0xc0000139 [libkernel_web, libkernel, libc], exit 0
libkernel.prx, __error (control) [libkernel, libc], exit 0 [libkernel, libc], exit 0

On this head ctest -R "^(entry_stub|windows_dependency_diagnostics)$" --repeat until-fail:3: both pass every repeat. Not run: a retail title.

@MarcZX10

Copy link
Copy Markdown
Contributor Author

Thanks for running the updated head against the variant-only __error and getpagesize cases. The results distinguish the fix from the base on both libkernel_sys.prx and libkernel_web.prx, while the canonical libkernel.prx control stays green. The repeated Windows diagnostics test adds useful coverage too; the limitation to synthetic imports rather than a retail title is clear.

@adriadam10 adriadam10 self-assigned this Oct 21, 2026
@adriadam10
adriadam10 merged commit 765d3d1 into boykopovar:main Oct 21, 2026
12 checks passed
@adriadam10

Copy link
Copy Markdown
Collaborator

Checked the provider order (requested variant, canonical libkernel, libc) in WindowsEntryStubBuilder and the inferred dependency list in ReadLibraries for both kernel variants without duplicates; both new tests fail on main. The Windows runs by @ycbuzi and @UnhealthyKraken confirm the base failing and the head resolving; merged.

@mpratsaki mpratsaki mentioned this pull request Oct 21, 2026
12 tasks done
ycbuzi added a commit to ycbuzi/AnyPS5 that referenced this pull request Oct 21, 2026
Resolves the conflict with boykopovar#8867 in EntryStubTests.cpp: keep its two
kernel-variant tests and the BufferUtils include, and this branch's
libSceAmpr-to-libc fallback test, with all three called from main.

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

Labels

fix error Closes an issue (Fixes #N) relinker

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Windows: scoped kernel variant imports miss canonical libkernel providers

3 participants