scePthreadCondInit, and pthread_cond_init through it, threw when attr
pointed to a null attribute: a zeroed one that was never initialized or
one that scePthreadCondattrDestroy has set to null. FreeBSD 11.4 libthr
(thr_cond.c, cond_init) takes a null attribute as the default one and
creates a CLOCK_REALTIME condition variable. A PS5 (firmware 13.60)
takes a zeroed attribute as the default one in scePthreadMutexInit
(#4158). Take it as the default here too, as scePthreadMutexInit and
scePthreadCreate already do.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Prospero Themes (PPSA90210) imports nmount (3YnXspQNyw8) from libkernel
and fails to load without it:
"./app.elf: symbol lookup error: ./app.elf: undefined symbol: 3YnXspQNyw8".
Mounting file systems is not supported, so it throws if called, like
execvp does for executable replacement. The title opens its theme
library without calling it.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01Sovthwyu4H63RMbRVha2Sy
PSFlyCast (PPSA99247) imports pthread_condattr_setpshared (3BpP850hBT4)
from libkernel and fails to load without it:
"./app.elf: symbol lookup error: ./app.elf: undefined symbol: 3BpP850hBT4".
The attribute stores PTHREAD_PROCESS_PRIVATE (0) or
PTHREAD_PROCESS_SHARED (1); a null or uninitialized attribute and any
other value return EINVAL without changing it, following FreeBSD 11
libthr thr_condattr.c and pthread_mutexattr_setpshared here. Sharing
across processes is not modeled, as for mutexes.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01Sovthwyu4H63RMbRVha2Sy
socket() returned EPROTONOSUPPORT for every socket type it does not create.
FreeBSD 11.4's socreate returns EPROTOTYPE when no protocol is found, the
protocol is 0 and the type is not 0, and EPROTONOSUPPORT when a protocol was
given. Its inet domain (in_proto.c) has SOCK_RAW entries in every kernel and
a SOCK_SEQPACKET entry only with SCTP, and no SOCK_RDM or other type.
Return EPROTOTYPE for a type the inet domain never has, such as SOCK_RDM,
with protocol 0. SOCK_RAW and SOCK_SEQPACKET keep EPROTONOSUPPORT, since
whether the console creates them is not known. Test the unknown types and
mismatched protocols for AF_INET and AF_INET6, and list the socket types and
families that are not created in the library's technical debt file.
Written with AI assistance (Claude).
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Under -DANYPS5_ENABLE_ASAN=ON with ASAN_OPTIONS=detect_leaks=0, 14 of
the 849 tests outside the AGC driver, shader and VideoOut suites failed
on main for reasons that come from the ASan build itself, not from the
code they test:
- libc copies the main executable's file-backed writable pages before
remapping them anonymously. In an instrumented test executable those
pages hold ASan's redzones around globals, so the memcpy reported a
global-buffer-overflow at load (patched_libraries,
guest_memory_lifetime). The ASan build copies the pages word by word
without instrumentation.
- Five tests check that a local variable is on the thread's stack.
With detect_stack_use_after_return, which is on by default on Linux,
instrumented locals live on ASan's fake stack. These tests now run
with it off. guest_kernel_is_stack also bounded the worker stack by
the application area without the ASan build's arena offset.
- The relinker module tests and loadexec_arguments load instrumented
libraries into a Python process or a relinked guest, so the ASan
runtime is not first in the initial library list. They now run with
verify_asan_link_order=0. Preloading libasan instead put its
__cxa_throw interceptor ahead of libc.prx's and broke the unwind of
an exception that LoadExec throws and catches.
- guest_allocator_failures limits RLIMIT_DATA to 128 MiB and then
commits 300 GiB. ASan maps 37.5 GiB of shadow for that commit, which
the limit refuses, and aborts. The ASan build skips that section.
- fiber checks the address of a local against the fiber's context too,
so it runs without fake stacks as well. Its CheckActiveContext then
reads the fiber stack word by word above that local, through the
redzones of the frames on that stack, and is no longer instrumented.
- agc_multisample_guest_access passed aligned_alloc a size that is not
a multiple of the alignment, which C11 does not allow and ASan
rejects. It now rounds the size up.
add_asan_test_options appends to ASAN_OPTIONS for one test in an ASan
build and does nothing otherwise.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
clock_gettime threw invalid_argument when the result pointer was null,
before looking at the clock id. FreeBSD 11.4's sys_clock_gettime reads the
clock through kern_clock_gettime, which fails with EINVAL for an unknown
clock, and only then copies the result out, so a null pointer fails with
EFAULT.
Read the clock into a local value first, then fail with -1 and EFAULT when
the pointer is null. A clock that is not supported still throws before the
pointer is looked at. Test the null pointer for the supported clocks.
Written with AI assistance (Claude).
Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
MeasureStackReserve took the distance from the stack top to a local
variable. In an ANYPS5_ENABLE_ASAN build that local lives on
AddressSanitizer's fake stack (detect_stack_use_after_return is on by
default on Linux), away from the thread's stack, so the reserve could
come out negative. scePthreadCreate then asked the guest arena for a
stack of nearly 2^64 bytes and threw 'guest address space arena
exhausted'. The frame address is on the real stack in every build.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
On Linux, FIONREAD on a datagram socket reports the next datagram only,
where FreeBSD's sbavail counts every queued byte, so a read mark above 1
there could never fire. kevent now throws for it as before; stream
sockets and marks of 1 are unchanged.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
kevent threw for NOTE_LOWAT. On a socket's EVFILT_READ it now sets the
low-water mark as FreeBSD 11's filt_soread does: the event fires once the
buffered bytes reach it, or at end of file or on a listening socket, and
a later change of the knote replaces it. EVFILT_WRITE takes a mark of 1,
where the host's writability stands in for a free byte; other write marks
and marks below 1 still throw. A pipe ignores the mark, as filt_piperead
does.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
A socket's EVFILT_WRITE and sceKernelAddWriteEvent reported the whole SO_SNDBUF in data, however much was already queued. FreeBSD 11.4's filt_sowrite reports sbspace, the space still free. On Linux the queued bytes from SIOCOUTQ are now taken off SO_SNDBUF. Windows has no query for the queued bytes and macOS is not wired up, so both keep reporting SO_SNDBUF; the debt entry says so.
The fcntl tests only ever held locks in the guest's own process, where FreeBSD's lf_blocks never reports a conflict, so the host lock path that answers F_GETLK was not exercised. A forked process now holds a read lock, a write lock and a write lock to the end of the file through the host. F_GETLK with F_UNLCK reports only the write locks, F_RDLCK the same and F_WRLCK the read lock, each with the owner's pid and SEEK_SET; F_SETLK over the read lock fails with EAGAIN, and nothing is reported once the owner exits.
fcntl threw for F_GETLK with an F_UNLCK request on the hosts that use POSIX locks, as Linux's F_GETLK rejects that type. FreeBSD 11.4's kern_fcntl accepts it and lf_getlock reports the first overlapping lock that lf_blocks lets conflict: another owner's lock, one of the two being a write lock. For an F_UNLCK request that is exactly another owner's write lock, the same set an F_RDLCK request finds, so the host is asked with F_RDLCK and the reply is written back as for the other types.
pthread_rwlock_timedrdlock, pthread_rwlock_timedwrlock and
pthread_mutex_timedlock threw for a null abstime. FreeBSD's libthr
passes a null abstime on to the untimed kernel lock, so these calls
then wait like pthread_rwlock_rdlock, pthread_rwlock_wrlock and
pthread_mutex_lock.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Both threw std::invalid_argument for a null or uninitialized attribute.
FreeBSD's libthr returns EINVAL for one, as the other scePthread
attribute calls here already do. The clock id is still stored as
given.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
mprotect already returns 0 for a zero length. The sceKernel entry
points passed it to DoMprotect, which throws for an empty range.
Co-Authored-By: Claude Opus 5.5 <[email protected]>