Repository navigation
fix(libs): give each .native wrapper a dependency edge to its plain twin - #1009
Dextroid17 wants to merge 1 commit into
Conversation
A guest module's DT_NEEDED names the .native wrapper, but symbols that only the plain twin exports were unreachable: the wrapper had no DT_NEEDED edge to the twin, so the defining object never entered the new module's lookup scope and RTLD_NOW binding failed with "undefined symbol" (boykopovar#906). Link each .native library against its plain twin on ELF targets, where lookup is scope-based. Windows is unaffected: PE resolution binds against every module already loaded and the relinker points guest imports at the implementing library, so the edge is not added there. Verified by dlopen: before the change, loading libSceMsgDialog.native.prx left libSceMsgDialog.prx unmapped; after, it is mapped. The same holds for all nine wrappers, and the full suite (369 tests) passes.
|
Closing this: @jeffrey12cali measured on PPSA28997 that this exact approach regresses the title (see #906). Pulling the plain twin in through a The twin has to stay out of the global scope. I will pick this up again on that basis — most likely the relinker emitting the implementing library in the converted guest module's Branch |
What
Gives each
.nativewrapper aDT_NEEDEDedge to its plain twin (the first option in #906). Closes #906.A guest module's
DT_NEEDEDnames the.nativewrapper, but symbols that only the plain twin exports were unreachable — the wrapper had no edge to the twin, so the defining object never entered the new module's lookup scope andRTLD_NOWbinding failed:All nine wrappers lacked the edge (
libSceAjm.native,libSceAudiodec.native,libSceAvPlayer.native,libSceFont.native,libSceMsgDialog.native,libSceNgs2.native,libSceSaveDataDialog.native,libSceSaveData.native,libSceShare.native), and all nine plain twins exist.The change links each
.nativelibrary against its plain twin on ELF targets. Windows is left alone: PE resolution binds against every module already loaded and the relinker points guest imports at the implementing library, so the edge is not needed there.This is option 1 of the three listed in the issue; option 2 (the relinker emits the implementing library in the converted guest module's
DT_NEEDED) would also work and touches the relinker instead of the library graph. Happy to switch if you prefer that direction.Tested
readelf -don all nine wrappers: noNEEDED libSceX.prxbefore the change, present after.dlopenprobe withRTLD_LOCAL(the way a guest module binds), checking/proc/self/maps:dlopen(libSceMsgDialog.native.prx)leaveslibSceMsgDialog.prxunmappedlibSceAudiodec.nativeandlibSceAjm.native)cmake --build build --target libs→ 106.prxbuilt.ctest --test-dir build -j 8 --timeout 120→ 369/369 pass.Checklist
main; no other open PR implements the same functionsNotImplemented_nid_no_patch); silent stubs are listed in TechnicalDebt.mdfiles or images added to the repository (attach them to this PR)