Skip to content

feat(libkernel): sceKernelGetModuleInfoFromAddr on macOS hosts, without reading st_size - #8

Merged
mugurc merged 1 commit into
mugurc:macos-portfrom
vladbondarenko97:feat/libkernel-module-info-macos
Oct 11, 2026
Merged

mugurc merged 1 commit into
mugurc:macos-portfrom
vladbondarenko97:feat/libkernel-module-info-macos

Conversation

@vladbondarenko97

@vladbondarenko97 vladbondarenko97 commented Oct 10, 2026 •

Copy link
Copy Markdown

What

sceKernelGetModuleInfoFromAddr works on macOS hosts, and no longer reads the caller's st_size on any host. sceKernelGetModuleList and sceKernelGetModuleInfo are untouched and still throw as not implemented on macOS.

Why

The unwinder in a title's own libc.prx asks this function for the eh_frame of the frame it is in. On macos-port the call was not implemented, and it threw before that when st_size was not the full size. Cloudberry Kingdom (PPSA23827) passes a stale st_size (8 on one run, a pointer on another), so its first C++ throw, a minute or two in, ended the process:

libc++abi: terminating due to uncaught exception of type std::invalid_argument: sceKernelGetModuleInfoFromAddr: unsupported st_size 8

Implementation

  • st_size is not read. shadPS4's process.cpp fills the structure whatever the caller left there; the result still carries the full size.
  • On macOS the image is found with dl_iterate_phdr over the program headers a converted image keeps, through the Fill and FindImage templates the Linux branch already has for the name, the load segments, the TLS image and the eh_frame (now read with EhFrame::ReadTables). The id comes from the image's Mach-O header.
  • Limits, recorded in TechnicalDebt.md: tls_index, init_proc_addr and fini_proc_addr stay 0 on macOS, and an image opened through the loader gets a stable id of its own instead of its sceKernelLoadStartModule handle.

Tested

All on an M4 Pro, macOS 26.5.1, under Rosetta, on this branch rebased onto macos-port at 21930ce:

  • module-info fixture (new, in run_macos_fixtures.py): the unwind-info fixture with this import, flags 2 and st_size 8; it exits with eh_frame_size, 20 with the terminator. The byte-built fixtures all pass: argv, import, tls, mprotect-slide, mprotect-pages, unwind-info, module-info. The compiled fixtures were skipped (no LLVM toolchain here).
  • Full ctest: 712 tests. Two runs passed everything and one had a single failure, guest_socket_read_write, which aborts intermittently on its own here (check failed at line 101, errno 54, about 1 run in 20) and does not touch this code. 264 tests report skipped, nearly all for want of libvulkan.1.dylib on the test path.
  • Not run: guest_module_info, whose expectation for a short st_size I changed; it is not built on macOS, so the Linux and Windows result of that change is unverified by me.
  • Before the rebase, PPSA23827 with fix(relinker): keep Linux imports declared from host modules off guest exports boykopovar/AnyPS5#1529, fix(agc): typed image heaps on devices without nullDescriptor boykopovar/AnyPS5#2015 and four MoltenVK fixes from my fork applied ran past its first throw (230 s without a stop, where it died after one to two minutes). Not repeated after the rebase.

Checklist

  • Based on current main (through macos-port at 21930ce); 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: none
  • AI-assisted: yes

🤖 Generated with Claude Code

@mugurc

mugurc commented Oct 11, 2026

Copy link
Copy Markdown
Owner

Thank you, this is exactly what the port needs. macos-port was merged with main at 21930ce (it was 1242 commits behind), so this branch now conflicts in core/libs/prx/libkernel/Module/src/ModuleInfo.cpp: main added sceKernelGetModuleList and sceKernelGetModuleInfo there, and the merge made all three throw as not implemented on macOS. Yours should replace the sceKernelGetModuleInfoFromAddr stub only. Could you rebase on the current macos-port? I will merge it once ctest passes on my machine.

…ut reading st_size

The unwinder in a title's own libc.prx asks sceKernelGetModuleInfoFromAddr
for the eh_frame of the frame it is in. On macOS the call was not
implemented, and on every host it threw when the caller's st_size was
not the full size. Cloudberry Kingdom (PPSA23827) passes a stale st_size
(8, or a pointer), so its first C++ throw, a minute or two in, ended the
process with `unsupported st_size`.

- The caller's st_size is no longer read: shadPS4's process.cpp fills
  the structure whatever it holds. The result still carries the full
  size.
- On macOS the image is found through dl_iterate_phdr over the program
  headers a converted image keeps, with the code the Linux branch uses
  for the name, the load segments, the TLS image and the eh_frame. The
  id comes from the image's Mach-O header. tls_index, init_proc_addr
  and fini_proc_addr stay 0, and an image opened through the loader gets
  a stable id of its own; TechnicalDebt.md records both.

The module-info fixture asks for its own information with flags 2 and
st_size 8 and exits with eh_frame_size, 20 with the terminator; it is
the unwind-info fixture with another import. guest_module_info expects
a short st_size to succeed; it is not built on macOS and was not run.
The title now runs past its first throw (230 s without a stop).

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@vladbondarenko97
vladbondarenko97 force-pushed the feat/libkernel-module-info-macos branch from 51711d7 to 1f02b19 Compare October 11, 2026 12:33
@vladbondarenko97

Copy link
Copy Markdown
Author

Rebased onto macos-port at 21930ce (head is now 1f02b19, still one commit).

  • Conflict in ModuleInfo.cpp: I took main's file as it is and put the macOS path back on top of it, so this was a re-port, not a mechanical merge. As you asked, only the sceKernelGetModuleInfoFromAddr stub is replaced; sceKernelGetModuleList and sceKernelGetModuleInfo still throw as not implemented on macOS. macOS now goes through main's Fill and FindImage templates and EhFrame::ReadTables. CollectGuestImage and GuestImages stay Linux-only, since they need dladdr1 and link_map.
  • st_size: the check is removed for every host, which now includes the Windows path main added. guest_module_info expects a short st_size to succeed; that test is not built on macOS, so I could not run it. That is the one part worth a look on Linux or Windows.
  • TechnicalDebt.md: kept main's entries, with the macOS and st_size wording merged into the sceKernelGetModuleInfoFromAddr one.
  • Tested here (M4 Pro, macOS 26.5.1, Rosetta): the seven byte-built fixtures pass, including the new module-info. Full ctest is 712 tests; two runs passed everything and one had a single failure, guest_socket_read_write. That test aborts on its own about 1 run in 20 here (check failed at line 101, errno 54) and does not touch this code. 264 tests report skipped, nearly all for want of libvulkan.1.dylib on the test path.
  • Conventions: passes now; the description is on the template.
  • Possible overlap: perf(libkernel): read a loaded image's unwind tables once in sceKernelGetModuleInfoFromAddr boykopovar/AnyPS5#3514 is open against the same function (it caches the unwind tables). If it lands in main first, this will need another small rebase.

AI-assisted: yes

@mugurc
mugurc merged commit d838d7d into mugurc:macos-port Oct 11, 2026
1 of 2 checks passed
@mugurc

mugurc commented Oct 11, 2026

Copy link
Copy Markdown
Owner

Merged #7 and #8 into macos-port, and merged current main on top (874 commits, 11 conflicts). Your sceKernelGetModuleInfoFromAddr change lines up with main's own st_size change, so I kept main's test and wording and your macOS notes. macos-port is now at b5b1215; please branch from it for anything new. Thanks for the quick rebases.

@mugurc

mugurc commented Oct 12, 2026

Copy link
Copy Markdown
Owner

@vladbondarenko97 Thank you again for this one. I am sending the macOS port to boykopovar/AnyPS5 as single-topic pull requests (series announced on boykopovar#1: boykopovar#1 (comment)). This change is one of them: I will open it upstream as it is, with your commit and authorship kept, and mention you in the description. If you would rather open it yourself, tell me and I leave it out.

@vladbondarenko97

Copy link
Copy Markdown
Author

I checked #8 against current upstream main and it looks like it still depends on some of the macOS groundwork you’re already upstreaming, so I’m not gonna try to force a standalone PR. Feel free to handle it whenever it fits your series. I’d just appreciate keeping my commit/authorship attached where it still applies. Thanks again for carrying this stuff upstream bro.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants