Repository navigation
fix(libc): find a relinked module by stem when the exact name misses - #6226
lendinglibrary wants to merge 1 commit into
Conversation
jotitadev
left a comment
There was a problem hiding this comment.
Static check on macOS (Apple M2 Max, macOS 27.2, APFS, Apple clang 21 / libc++), head 7b2385aa0. Not built: main does not link on macOS yet. I compiled RelinkedSiblingByStem verbatim from the PR in a small driver.
With libc++, the shortest-name-first rule does not hold when two or more siblings match the stem. The loop shares one std::error_code between directory_iterator, is_regular_file and equivalent. libc++ implements LWG 2937, so equivalent(existing, missing, ec) sets ec to ENOTSUP when the requested path does not exist, which is always the case on this fallback path. On the next iteration, if (error || ...) continue; sees that stale value and skips every remaining entry, so the first stem match in directory order wins.
Directory with Il2CppUserAssemblies.{elf,prx.elf,sprx.elf}.guest.prx, request Il2CppUserAssemblies.prx. arm64 and x86_64 under Rosetta give the same result:
visit Il2CppUserAssemblies.sprx.elf.guest.prx (error=0)
visit Il2CppUserAssemblies.prx.elf.guest.prx (error=45)
visit Il2CppUserAssemblies.elf.guest.prx (error=45)
picked: Il2CppUserAssemblies.sprx.elf.guest.prx
equivalent(<existing file>, <missing file>, ec) alone gives eq=0 err=45 Operation not supported.
I did not check libstdc++. With a single candidate the result is right, so the new test would not catch this. A local std::error_code for the equivalent call, or clearing error at the top of each iteration, keeps the shortest-name rule that docs/dev/debt/libc.md describes.
Written with AI assistance (Claude Code). I ran the snippets above on my machine.
|
The same shared-error issue is present on Linux/libstdc++, not only libc++. Checked exact head For Here The review's clear-at-the-top option also covers another per-entry error:
The remaining failure in the middle row comes from Tested minimal change: for (const auto& sibling : std::filesystem::directory_iterator(parent, error)) {
+ error.clear();
if (error || !sibling.is_regular_file(error)) continue;The 30-run cases are five processes for each of six directories populated in different creation orders. This filesystem enumerated the same longest-first order in all six; these are not six different observed enumeration orders. An empty-directory control returns no candidate with the patch. Scope: standalone execution of the actual helper bodies with ordinary test files and a real dangling symlink. No full runtime/library build, module loading or title result is claimed. No repository source was changed. |
|
Fixed in the amended commit: the shared error code is cleared at the top of each iteration, so a stale result from |
7b2385a to
431218a
Compare
A title asks for a module by its console name and the relinker names the converted module after the ELF it was built from: Unity IL2CPP titles load Media/Modules/<name>.prx and Media/Plugins/<name>.prx while the dump holds <name>.elf.guest.prx, so sceKernelLoadStartModule failed with 0x80020002 and the title stopped 3 s after start. After the exact and the case-insensitive <name>.guest.prx lookups miss, take the sibling whose stem matches the request and ends with .guest.prx, shortest name first.
|
Rebased on current main after eac8bfc. The stem rule is now a second |
431218a to
138a74c
Compare
|
Retested the rewritten Linux — Ubuntu 24.04, GCC 13.3. Compiled the complete unchanged production
Matched original-head control: rebuilding only macOS 27.2 arm64 / Apple clang 21 / libc++ — the complete translation unit still fails on unrelated No repository source changed. This verifies filesystem selection and native loading of a synthetic library, not guest |
|
Thanks. One fix is needed before merge, and the branch needs a rebase: The stem is cut at the first dot, not the last. For a request like Also, #6544 changes the same function ( The branch is about 600 commits behind main, so please rebase onto current main before we run CI. |
|
Windows runtime check. Windows 11 Pro 10.0.26200, Ryzen 7 7800X3D, WinLibs GCC 15.2.0 r7 (UCRT), Release. This PR's head
AI-assisted: yes (Claude Code). |
|
I carried this onto current AI-assisted (Claude Code). |
fix(libc): find a relinked module by stem when the exact name misses (carries #6226)
|
@lendinglibrary thanks for this. Your stem fallback has landed on |
What
A title asks for a module by its console name, and the relinker names the converted module after the ELF it was built from. Unity titles load
Media/Modules/<name>.prxandMedia/Plugins/<name>.prxwhile the dump holds<name>.elf.guest.prx, soRelinkedModulePathmisses andsceKernelLoadStartModulefails with 0x80020002. A Unity IL2CPP title stopped 3 s after start withunable to load /app0/Media/Modules/Il2CppUserAssemblies.prx, error:0x80020002.After the exact
<name>.guest.prxand the case-insensitive lookup (#5892's predecessor f0c3a5c) both miss, the lookup now takes the sibling whose stem (name up to the first dot, ASCII case ignored) equals the requested stem and that ends with.guest.prx, shortest name first. The test loadsguest_module_fixture.prxfrom a directory holding onlyguest_module_fixture.elf.GUEST.PRX. The assumption about the console's module namespace is recorded indocs/dev/debt/libc.md.Tested
Linux (Ubuntu, i5-12400, RTX 5070 Ti).
guest_dynamic_loader_variant_namesand the loader tests pass. A Unity IL2CPP title whose dump holds only<name>.elf.guest.prx: loadsIl2CppUserAssemblies.prxandPS5Util.prx, plays its intro videos, reaches the main menu and starts a game. A title whose dump already has<name>.prx.guest.prxcopies: unchanged. Windows: not tested.Checklist
main; no other open PR implements the same functions.mdfiles or images added to the repository