Repository navigation
feat(libkernel): implement sceKernelGetModuleList and sceKernelGetModuleInfo - #2028
adriadam10 merged 2 commits into
Conversation
|
The overlap with #2001 is substantive, not just shared context: its current diff deletes ModuleInfo.cpp and GuestModuleInfo.cpp and removes their CMake test registration, while this PR adds the export and regression in those files. If #2001 merges first, this implementation will need to be reapplied; if this PR merges first, #2001 deletes it. Please coordinate with the #2001 author/maintainer on intended scope and merge order before approval. I have not approved while this conflict is unresolved. |
|
Thanks for flagging it. I looked at #2001 before deciding how to handle it: it's a 967-file change (+11,386/−57,803) that, by its own description, deletes ModuleInfo.cpp along with many implemented handlers, the libjpeg-turbo integration, and several CI and conventions gates. Any open PR that touches libkernel, libc, or AGC conflicts with it, so the overlap doesn't come from anything specific to this PR's scope. I'd rather not make #2028 depend on it. If #2001 is accepted in its current form, I'll reapply the export and the regression onto whatever replaces ModuleInfo.cpp. Until then, #2028 stays scoped to the single export, with the Ruffle PPSA68091 stop line as evidence. @Praetorian0420, if you intend to keep the module-info code, let me know and I'll rebase onto your layout. |
|
Thanks for flagging it. I looked at #2001 before deciding how to handle it: it's a 967-file change (+11,386/−57,803) that, by its own description, deletes ModuleInfo.cpp along with many implemented handlers, the libjpeg-turbo integration, and several CI and conventions gates. Any open PR that touches libkernel, libc, or AGC conflicts with it, so the overlap doesn't come from anything specific to this PR's scope. I'd rather not make #2028 depend on it. If #2001 is accepted in its current form, I'll reapply the export and the regression onto whatever replaces ModuleInfo.cpp. Until then, #2028 stays scoped to the single export, with the Ruffle PPSA68091 stop line as evidence. @Praetorian0420, if you intend to keep the module-info code, let me know and I'll rebase onto your layout. |
|
Native Windows run, since no Windows results were posted. Setup: Windows 10 (19045), MinGW-w64 GCC 15.2.0 (WinLibs r7), Release. Head
No title was run. 🤖 Addressed by Claude Code |
adriadam10
left a comment
There was a problem hiding this comment.
Thanks for the PR. It now conflicts with main, and it isn't a mechanical conflict:
core/libs/prx/libkernel/Module/src/ModuleInfo.cpp:mainrestructured the file (sharedEhFrame.hpp,ToU32/SetNamemoved out of the#ifndef _WIN32block, and a WindowsFillforsceKernelGetModuleInfoFromAddr).FillNameAndSegments,ImageSearch<TInfo>andFindImage<TInfo>need to be rebuilt on that layout. Please decide whethersceKernelGetModuleInfocan reuse the new WindowsFillinstead of callingNotImplemented_nid_no_patch, or keep it Linux-only and say so in TechnicalDebt.docs/dev/TechnicalDebt.md: conflict in "Unknown function info" next to thesceKernelGetModuleInfoFromAddrline, which changed onmain. Update your lines if the Windows behaviour changes, and keep them away from the end of the section.
The overlap with #2001 that was raised earlier is gone, since it was closed.
After rebasing, please rerun guest_module_info and confirm the sceKernelGetModuleInfoFromAddr checks still pass.
Fill takes either info struct, so sceKernelGetModuleInfo reports the name and segments sceKernelGetModuleInfoFromAddr reports for the same image, on Linux and Windows.
ce9018d to
8a41d28
Compare
|
Rebased onto
Tested:
AI-assisted: yes |
adriadam10
left a comment
There was a problem hiding this comment.
Checked on Linux (merged onto current main): build and guest_module_info pass, and the test no longer builds without the change. sceKernelGetModuleList / sceKernelGetModuleInfo signatures and errors (EFAULT, ENOMEM without writing actual, EINVAL on st_size, ESRCH) match the cited shadPS4 code; the TechnicalDebt lines record the deviations (ids, prot bits, zero fingerprint). #2001 is closed, so the overlap is gone. Windows is code review only (compiles, per the thread). Merging.
…rnel-get-module-list feat(libkernel): implement sceKernelGetModuleList and sceKernelGetModuleInfo
What
sceKernelGetModuleList(IuxnUuXk6Bg, libkernel) is missing onmain. Ruffle Flash (PPSA68091) stops at it once itslstatstop (#1624) is fixed.It now returns the handles of the loaded guest modules: the main program and every loaded
.prximage, in load order. Host runtime libraries are left out. Each handle is the idsceKernelGetModuleInfoFromAddralready reports for that image, so the two agree, and it is thesceKernelLoadStartModulehandle when the image was opened through the loader. On Linux the images come fromdl_iterate_phdr, on Windows fromEnumProcessModules.The
(int32_t* handles, size_t count, size_t* actual)signature and the errors follow shadPS4 (process.cpp):handlesoractualreturnsEFAULT;count, the firstcounthandles are written and it returnsENOMEMwithout writingactual.The ENOMEM case, the filtering, and handles that are AnyPS5 ids rather than the console's are listed in TechnicalDebt.
Log
@babyhuey's runs of the homebrew catalog release with #1624 merged (thanks):
maind64134f + feat(libkernel): implement lstat #1624 (comment): onmainit stops atapp.elf: symbol lookup error: app.elf: undefined symbol: DRGXpDDh8Ng(lstat), and with feat(libkernel): implement lstat #1624 the next stop isIuxnUuXk6Bg.mainf145139 + feat(libkernel): implement lstat #1624 (comment):Both of those builds also had babyhuey's other open PRs merged. Only #1624 exports
lstat.The call site is in Ruffle's own
eboot.bin(release 1.2.0,PPSA68091.zipsha256b34b40b69da30dafce4ea67ee312a55b6bd9b07b59849741253b2c46147076be). I unwrapped the SELF and disassembled it:sceKernelGetModuleList(handles, 0x200, &count)with a 4-byte handle array.Ruffle PS5: module list -> %#x, and the title then loads/system/common/lib/%s.sprxitself.sceKernelGetModuleInfoon each handle. It triesst_size0x160, 0x1a8, 0x1b0, 0x158 and 0x200, and matches names withstrstr.sceKernelGetModuleInfois also absent onmain. A rig run has since shown it is the next stop, and the second commit adds it (see below).Tested
aarch64 Debian 13 host. The full project can't be built here because it needs x86-64.
core/libs/tests/GuestModuleInfo.cpp(guest_module_info, Linux):libkernel.prxexactly once, leaves out the dlopened non-.prxfixture, and has no duplicate ids;ENOMEM, fills the slots it has and leavesactualalone;EFAULT.ModuleInfo.cppandDynamicLoader.cppbuilt as a sharedlibkernel.prx, with Zig 0.17 clang, also under UBSan, and it passes. Two mutants each fail at the expected check: one without the.prxfilter, and one that writesactualonENOMEM. In that harness the existinginvalid_argumentchecks needcatch (...), because libc++ is linked statically into both binaries. That applies tomain's test as well.ModuleInfo.cppand the test compile for x86_64-linux-gnu and x86_64-windows-gnu with-Wall -Wextra(Zig 0.17 clang). The only warning is the existing-Wreturn-type-c-linkagefromGeneral.hpp. On Windows,ModuleInfo.cppalso links into a DLL and the test into an executable against it, but neither was run here.guest_module_infois registered on Windows onmain, so the Windows CI job runs it.python3 tools/check_conventions.py --base origin/mainpasses.Follow-up:
sceKernelGetModuleInfoOn my x86-64 Linux box (Ubuntu 24.04, lavapipe),
mainf145139 with #1624 and this PR merged (ref d973cd6f), Ruffle Flash PPSA68091 1.2.0 gets pastlstatandsceKernelGetModuleListand stops at:That NID is
sceKernelGetModuleInfo; the second commit adds it. With both commits it moves on tosigemptyset(claimed by #1641), and theguest_module_infotest passes on x86-64 (ctest, 1/1):The call site is the loop from the description, in Ruffle's unwrapped
eboot.bin(capstone):name, at offset 8. Nothing reads the segments, the count or the fingerprint.size0x160 is tried first. A nonzero return is not fatal: the title tries the next size, then the next handle. When no name matches, it logsRuffle PS5: %s not in %zu modules (%d named, info rc %#x): %sand loads/system/common/lib/%s.sprxitself.Init/Open/Readfunctions are null (0x0a1a). The import is what stops the load. The loop itself is a fallback path.sceKernelGetModuleInfo(int32_t handle, ModuleInfo* info)fills the 0x160-byteSceKernelModuleInfo:st_size(u64) at 0,name[256]at 8, four{u64 address, u32 size, s32 prot}segments at 0x108,segment_countat 0x148 andfingerprint[20]at 0x14c. The layout is the same in fpPS4 (packed record,size:QWORD…fingerprint:array[0..19] of Byte) and shadPS4 (OrbisKernelModuleInfo). The OpenOrbis docs give the same layout. prosper (643ad45e) does not implement this export.static_asserts inSceTypes.hpppin the offsets.The handle has to be one that
sceKernelGetModuleListreturns, so the two agree. Name and segments come from the same codesceKernelGetModuleInfoFromAddruses. On both Linux and Windows,Fillis a template over the info struct; theModuleInfoEx-only fields are behindif constexpr. The Windows path reuses the PEFillfrommain, so a relinked image reports its.elfsections and any other image its sections with memory access.The errors follow shadPS4 and the other functions in this file:
inforeturnsEFAULT;st_sizeother than 0x160 returnsEINVALand leaves the buffer alone;ESRCH, assceKernelDlsymdoes here.fpPS4 also returns
EFAULTandESRCHbut does not check the size.The fingerprint is left zero. Segment
protuses the 1/2/4 bits thatsceKernelGetModuleInfoFromAddralready reports, while fpPS4 and shadPS4 copy the ELFp_flags. All of this is listed in TechnicalDebt.Tested (aarch64 Debian 13, Zig 0.17 clang), extending
GuestModuleInfo.cpp:libkernel.prx's info matchessceKernelGetModuleInfoFromAddr(name, segments) and has a zero fingerprint.EINVALand leave the buffer alone.EFAULT. The dlopened non-.prxfixture's handle and -1 returnESRCH.ModuleInfo, andEINVALfor null.ModuleInfo.cpp,Module.cppand the test compile for x86_64-linux-gnu and x86_64-windows-gnu with-Wall -Wextra. The only warning is the existing one fromGeneral.hpp.mainc9d4261 the same test, includingmain'ssceKernelGetModuleInfoFromAddrchecks, passes natively (3 runs, also with UBSan and ASan).main's unchanged test passes against the rebased library too. ThesceKernelGetModuleInfochecks are the same on Windows; they were not run there.check_conventions.pypasses.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)