Skip to content

fix(libc): build the host-facing libc code on macOS - #4627

Merged
oneandonlydean merged 1 commit into
boykopovar:mainfrom
mugurc:fix/libc-macos-host
Oct 23, 2026
Merged

oneandonlydean merged 1 commit into
boykopovar:mainfrom
mugurc:fix/libc-macos-host

Conversation

@mugurc

@mugurc mugurc commented Oct 12, 2026 •

Copy link
Copy Markdown
Contributor

What

The parts of libc that talk to the host and do not build with Darwin's headers and libSystem. Part of the macOS series announced on #1 (#1 (comment)).

  • feof_unlocked, ferror_unlocked, getc_unlocked and putc_unlocked are macros on macOS, so they are called without the :: qualifier.
  • CLOCK_REALTIME_COARSE and st_mtim do not exist on macOS: the write mark of General.cpp uses CLOCK_REALTIME and st_mtimespec.
  • tm_zone is a char*, not a const char*.
  • libSystem's __cxa_thread_atexit returns void; the wrapper returns 0.
  • Darwin's stack protector reads __stack_chk_guard from libSystem, and the library's own definition under that name would be bound by every other library's host code. On macOS the guard has the name __stack_chk_guard_nid_postfix, which the NID patcher gives the NID of the original.
  • APS5_EXPORT spells its symbols with the leading underscore of Mach-O.
  • The fclose failure check of GuestFiopen fills /dev/full, which exists on Linux only.
  • exception_runtime is registered everywhere but macOS (the follow-up I promised on feat(libc): exception runtime on macOS hosts #927). It expects a host throw to go through libc's exception runtime, which libc takes over on Linux by exporting the host runtime names; on macOS it does not export them, and the system libc++abi handles the throw.
  • The formatting test names GCC's __builtin_sysv_va_list, which clang does not have; for clang it is va_list, the System V one on the hosts where it is used.

Tested

  • macOS 26.5.1, Apple M5 Max, Apple clang 21, x86-64 build under Rosetta 2. main 7e2ba73 with the rest of the macOS series (ci/macos-series-2 on my fork, which now includes feat(libkernel): JIT shared memory on macOS hosts #7937) and the libSceSsl change of feat: macOS on Apple Silicon host support (Rosetta 2 and MoltenVK) #7332. The libraries do not link on macOS without the series. ninja, ninja libs and ctest -j4: 1798 tests, 1123 passed, 25 failed, the rest skipped (no Vulkan loader in the environment); guest_formatting, guest_fiopen and guest_fopen_errors pass.
  • Rebased on main 7e2ba73. The conflict was getc_unlocked_nid_postfix, which fix(libc): switch update streams to reading as FreeBSD does #8226 now reads through a local native; the call stays unqualified. The GuestArena.cpp change is gone from this pull request, because feat(libc): reserve the guest arena on macOS #6124 builds the same code on macOS.
  • Earlier, with this pull request alone on main: the changed libc sources and the formatting and file stream tests compiled on macOS, and they did not compile without it.
  • Linux and Windows: not run for this version. The only edits outside __APPLE__ are the four unqualified calls (the functions are declared in the global namespace by glibc), the moved test registration (the test is still registered on Linux), the va_list mapping in the test for clang, and #ifdef __linux__ in place of #ifndef _WIN32 around the /dev/full check (Windows skipped it already). An earlier version ran on my fork's CI with the rest of the series: 960 tests on Linux and 966 on Windows pass (https://github.com/mugurc/AnyPS5/actions/runs/38256280627).

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 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 (none added)
  • Generic behaviour, not specific to one title
  • Depends on: none
  • Unblocks: none
  • AI-assisted: yes

@mugurc mugurc mentioned this pull request Oct 12, 2026
This was referenced Oct 12, 2026
@MarcZX10

Copy link
Copy Markdown
Contributor

I opened #5394 to carry the Windows line-buffering fix from #5391. It touches putc_unlocked_nid_postfix for newline flushing; I listed #4627 as a dependency so the macOS portability change can land first, then I can rebase and resolve the shared lines. If you prefer a different merge order, please say so.

feof_unlocked, ferror_unlocked, getc_unlocked and putc_unlocked are macros
on macOS, so they are called without the global scope qualifier. The
remaining differences are the ones Darwin's headers and libSystem have:

- CLOCK_REALTIME_COARSE and st_mtim do not exist; the write mark uses
  CLOCK_REALTIME and st_mtimespec.
- tm_zone is a non-const char*.
- __cxa_thread_atexit returns void, so the wrapper reports success.
- Darwin's stack protector reads __stack_chk_guard from libSystem; the
  guard of the guest libc has the postfixed name, which receives the NID
  of the original.
- APS5_EXPORT spells the symbols with the leading underscore of Mach-O.
- GuestArenaSetProtection and PosixProtection are built on macOS as on Linux.
- The fclose failure test fills /dev/full, which exists on Linux only.

exception_runtime relies on the Itanium unwinder of libc, which is not
registered on macOS (the host libc++abi is used), so its test is only
registered elsewhere.
@krishalivaibhav

Copy link
Copy Markdown
Contributor

Code review: the portability changes read correctly. The macros behind getc_unlocked/feof_unlocked explain the dropped ::. tm_zone needs the const_cast on Apple. __cxa_thread_atexit returns void there, so the unconditional return 0 is right. The APS5_EXPORT underscore prefix matches Mach-O symbol naming. Could you add the macOS build output and the libc ctest results to the description? MarcZX10's #5394 lists this PR as a dependency, so a review from a maintainer would unblock both. (Diff review only.)

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants