Conflicts with main's newer libc changes resolved without changing either
side: the debt list keeps each side's entry changes (per entry, deletions
included), GuestMath.cpp keeps both sides' test functions and calls, and
Math.cpp differs from main by exactly this branch's own changes.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
- mlock on macOS skipped every page the locked ranges recorded, but a
mapping that replaces a locked range in place leaves the record behind
without wires, so a later mlock returned 0 and wired nothing. Within a
recorded range it now wires again the host regions whose wire count is
0. The mlock test locks, remaps the range fixed and locks again.
- munlock and munlockall on macOS hold the locked-range lock across the
host unwire and the record update, so a concurrent mlock cannot see a
range as wired while it is being unwired.
- sceKernelVirtualQuery limits the host region it reports to the write
watch run that holds the address, so the permissions it reports hold
for the whole extent.
- The libc debt entry says what the mapping paths do: they register the
range again, and GuestWriteWatchProtectionChanged has no caller yet.
- mlock on macOS wires only the pages libkernel has not wired yet. XNU
counts each wire of a page, and the locked ranges merge overlapping
locks, so a page locked twice stayed wired after munlock and
munlockall. The mlock test checks the wire count on macOS.
- mprotect changes a watched page through GuestWriteWatchProtect, which
applies the host protection and records it under the write watch's
lock, so a collection on another thread cannot run between the two.
The write watch test covers it.
- sceKernelVirtualQuery takes a watched page's write permission from the
write watch for memory outside the guest allocation registry.
- GuestAllocationsGuestPages counts an image segment up to the end of
its last host page, as the image page collection does.
- The macOS includes stay in main's include block, so the host code
other pull requests add there still sees them; the unused Mach-O
headers and the end trim, which never changed the protected spans,
are gone, and the guest page size is passed in.
- The libc and libkernel debt entries describe what is wired now.
The host sinh set errno to ERANGE on overflow and sinhf does, but the msun port
returned the overflowed value with errno untouched. The overflow path of
sinh_nid_postfix sets ERANGE again; msun itself sets no errno.
Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
rand and rand_r both used FreeBSD's do_rand (Park and Miller on
state % 0x7ffffffe + 1, minus one), so rand returned values up to
0x7ffffffd and rand(), rand_r() and every seeded sequence differed
from the console. The libc.prx that titles ship (the same code in the
copies of PPSA13934, PPSA07923 and PPSA05916, read from disassembly)
uses two different generators:
- rand steps a 64-bit state, initially 1, as
state * 0x5851F42D4C957F2D + 1 and returns (state >> 32) & 0x3FFFFFFF,
so its results stay at or below 0x3FFFFFFF. srand stores the seed
zero-extended as that state.
- rand_r is the minimal standard generator, state * 16807 modulo
2^31 - 1 on the signed 32-bit state (1 gives 16807, 282475249,
1622650073), and a zero state becomes 0x2AE1B767.
guest_math now expects those results: the rand_r chain from 1, the
zero and 0x7FFFFFFF states, rand after srand(1), srand(0) and
srand(0xFFFFFFFF), and rand's range over 1000 calls. Its previous
checks expected FreeBSD's values and rand matching rand_r.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Add the BSD "quad" `strtoq` export for the libc PRX as a thin wrapper
around `strtoll`, as FreeBSD 11.4 lib/libc/stdlib/strtoq.c does. The
unsigned sibling `strtouq` is already here as the same alias of
`strtoull`. Extend the guest wide strings test to probe the signed
path on an under/overflow run and a short positive run with a trailing
non-digit. Document the export in docs/dev/debt/libc.md with the
registry NID `yUUOxgk8Dmc`; console behavior is unverified beyond the
existing `strtoll` contract.
Co-Authored-By: Claude Opus 4.7 <[email protected]>
Two host differences failed all 19 feupdateenv tests on macOS:
- Apple's libc++ looks up /usr/lib/libstdc++.6.dylib with a no-load
dlopen the first time a process builds a std::logic_error, and that
failed lookup leaves errno at ENOENT. The null check builds the first
one, so it saw errno change although feupdateenv never touched it. The
test now builds one std::invalid_argument on macOS before the checks.
- Rosetta 2 keeps the six MXCSR exception masks set and raises no
floating-point trap, x87 included. The mask check now expects the SSE
masks the host keeps, and the pending-trap tests are skipped (exit 77)
on a host that does not keep an unmasked MXCSR exception. A libc debt
entry for feupdateenv records it.