Commit Graph

196 Commits

Author SHA1 Message Date
Adrià fc1f063f51
Merge pull request #4622 from jagrat04/feat/libkernel-lutimes
feat(libkernel): implement lutimes
2026-10-13 09:48:07 +02:00
Dean c2565f0149
Merge pull request #4391 from MarcZX100/codex/socket-descriptors-4366
fix(libkernel): give guest sockets ordinary descriptor numbers below FD_SETSIZE
2026-10-13 19:52:08 +13:00
Dean 4fe3123627
Merge pull request #4640 from MarcZX100/codex/win-host-standard-handles-4631
fix(libc): preserve host standard handles on Windows redirects
2026-10-13 17:49:02 +13:00
Dean 88f48fddef
Merge pull request #4688 from eliyarson/fix/kernel-stat-relinked-prx
fix(libkernel): resolve original .prx names to relinked .guest.prx in stat, open and reachability
2026-10-13 17:48:42 +13:00
MarcZX100 eb2b360f0b fix(libkernel): route updated socket descriptors by table 2026-10-13 03:22:38 +00:00
MarcZX100 c33036eefe fix(libkernel): return bad descriptor from fstat 2026-10-13 03:22:38 +00:00
screamm e99816e8f3 fix(libkernel): give guest sockets ordinary descriptor numbers below FD_SETSIZE
libkernel numbered guest sockets from GuestSockets::FirstDescriptor
(0x10000000), so a title that puts a socket in a 1024-bit fd_set writes
fd / 8 bytes past it. The Epic Online Services SDK does this on its
RtcNetworkThread and three titles stop there (#1794):

Palworld PPSA23126 (queeeef, main a11c8f7f7):
  FATAL: unhandled exception 0xc0000005 on thread 37164 'RtcNetworkThread'
    rip 0x00007ffcdb1ea2be eossdk-ps5-shipping.prx.guest.prx+0xdea2be
    rcx 0000000010000005 rsi 0000000000400000 r12 0000000010000005
The Mound PPSA26223 (xXPBSXx, main 0a8b1d32b):
  FATAL: unhandled exception 0xc0000005 on thread 'RtcNetworkThread',
  rip eossdk-ps5-shipping.prx.guest.prx+0xefc6f4, rcx = 0x10000005,
  rsi = 0x400000
Dying Light 2 PPSA02262 (tv7):
  FATAL: unhandled exception 0xc0000005 on thread 'RtcNetworkThread'
    rcx 0000000010000005 ... rsi 0000000000400000 ... r12 0000000010000005

On FreeBSD 11.4 (8c639945) FD_SETSIZE is 1024 (sys/sys/select.h:58-59)
and sockets take the lowest free entry of the one process descriptor
table that files use (kern_descrip.c:1643-1660 fdalloc,
uipc_syscalls.c kern_socket through falloc).

Every socket number is now a real host descriptor: a zero-access NUL
handle registered with _open_osfhandle on Windows (as directory
descriptors already are) and an F_DUPFD_CLOEXEC duplicate of the host
socket on Linux. The socket table maps that number to the socket, so
"is this a socket" is a table lookup instead of a range check at the 31
former FirstDescriptor comparisons. close releases both the socket entry
and the number, dup and dup2 duplicate the number through the host table
and keep the socket shared, dup2 of a file onto a socket number drops the
socket entry, and sceKernelClose now closes sockets too. sceNetSocket and
sceNetAccept take their ids from the same table instead of a counter from
32, so libkernel and libSceNet numbers never collide.

select polls guest sockets alongside libSceNet sockets, the random device,
stdio and (on Linux) host descriptors; poll throws only for an open
descriptor that is not a guest socket and reports POLLNVAL otherwise.
File calls that used to fail with EBADF on the socket range return
FreeBSD's answer for a socket: lseek ESPIPE (kern_lseek), ftruncate and
getdirentries EINVAL (invfo_truncate, getvnode), flock EOPNOTSUPP;
fstat on a socket throws. pread on a closed descriptor returns EBADF.

title failing on host descriptor numbers; these three titles are that
case, and this change keeps host numbering for files and only moves
sockets into it.

Tests: guest_socket_descriptors (new: socket below 1024, select on a
socket and a file together, close frees the number for a file, dup of a
socket, sceKernelClose), guest_select (socket and pipe together, Linux),
guest_poll, guest_dup, guest_socket_pair, guest_fstatfs,
guest_posix_filesystem and guest_sce_net updated.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
(cherry picked from commit 20378375b31eb5db922db6e55f45e44a4dae6445)
2026-10-13 03:22:36 +00:00
Dean b17fb4a4a7
Merge pull request #4792 from marshmll/fix/linux-host-stderr-redirect
fix(libc): keep host diagnostics on stderr when a guest redirects it on Linux
2026-10-13 15:36:51 +13:00
Dean 37a0a3608c
Merge pull request #4480 from milescoviello/carry/fcntl-record-locks-windows-4479
feat(libkernel): implement fcntl record locks on Windows
2026-10-13 15:36:03 +13:00
jagrat Singh 8d08caa529 feat(libkernel): implement lutimes 2026-10-13 06:29:45 +05:30
marshmll 438d410824 fix(libc): keep host diagnostics on stderr when a guest redirects it on Linux
On Linux a guest stderr redirect also moves the host's: guest
descriptors are host descriptors, and the guest stderr stream wraps the
host stderr FILE. After dup2(fd, 2), or freopen(path, mode, stderr) with
full buffering, the libc terminate report, the host fprintf(stderr)
diagnostics and libstdc++'s terminate message go into the title's pipe
or file, and abort() discards what is still buffered. RetroArch
(PPSA99169) reopens stderr onto app0/trace.txt with full buffering, so
its stop on main left no message anywhere.

Before the first guest redirect of descriptor 2 (libkernel dup2, libc
freopen of a stream on descriptor 2), keep a close-on-exec duplicate of
the host descriptor 2 and point the host stderr at an unbuffered stream
on it. The guest stream keeps its own FILE and follows the redirect.
The libc terminate report writes to the kept descriptor with write()
instead of the stderr stream, and libkernel's sceKernelDebugOutText uses
the same kept descriptor.
2026-10-12 19:00:08 -03:00
David c22654102b fix(libc): keep the host standard handles when a guest replaces descriptor 0, 1 or 2 on Windows 2026-10-12 21:23:00 +00:00
Adrià 5efd09afc4
Merge pull request #4653 from Lorkydey/feat/libc-statvfs
feat(libc): query filesystem statistics by guest path
2026-10-12 23:08:17 +02:00
David 9ef4aa2c40 feat(libkernel): implement kqueue and kevent over the event queue
Cloudberry Kingdom (PPSA23827, #3177) calls kqueue right after start-up
and stopped on the throwing declarations merged with #3337; Palworld's
Discord module (PPSA23126, #2648) imports kevent.

kqueue reserves a host null-device descriptor in the file descriptor
space and registers it as an event queue that reports each ready event
once per call and moves level-triggered ones behind the others, as
kqueue_scan does. close and sceKernelClose close the queue and drop the
descriptor's events from every queue, dup2 drops them for the target,
and dup/dup2 of a kqueue throw, so a reused descriptor number is never
read as a stale kqueue.

kevent follows FreeBSD 11 kern_event.c (release/11.0.1 34bd3475):
kqueue_kevent for the changelist (filter 0 skipped, EV_SYSFLAGS
cleared, EV_ERROR receipts with the errno in data, EV_RECEIPT, the
early return when nevents is exhausted), kqueue_register for EV_ADD,
EV_DELETE, EV_ENABLE, EBADF, ENOENT and EINVAL, kqueue_scan for the
timeout (EINVAL for a bad timespec, zero polls, above INT32_MAX waits
forever) and filt_timerattach, filt_usertouch for the timer and user
filters. Read and write events reuse the guest socket poll of
sceKernelAddReadEvent/WriteEvent.

Throws: other filters, EV_DISABLE, EV_DISPATCH, EV_FORCEONESHOT,
NOTE_LOWAT, EV_CLEAR on a socket, read/write events on non-socket
descriptors or another kqueue, changes to an existing timer (11.0 and
11.4 differ), a NOTE_NSECONDS fraction above one second and a negative
nevents. Recorded in TechnicalDebt.

Test guest_kqueue covers creation and close, timers, a user event
triggered from another thread, read and write events on a socket pair,
EV_ERROR receipts, the timeout and the error cases.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-10-12 22:36:59 +02:00
Adrià 9ea71307a9
Merge pull request #3872 from LeandroLP23/fix/kernel-windows-directory-dup
fix(libkernel): share the directory state between duplicated descriptors on Windows
2026-10-12 22:18:02 +02:00
Adrià 16f993a534
Merge pull request #3787 from YossiYad/carry/libkernel-jit-shared-memory
feat(libkernel): implement the JIT shared memory calls
2026-10-12 22:17:55 +02:00
screamm 7d3dd554da feat(libkernel): implement the JIT shared memory calls
The three JIT shared memory exports (avvJ3J0H0EY, MR221Mwo0Pc,
YKT49TOLQWs) are absent imports of three homebrew titles that cannot
finish loading without them. Predicted next stops (registry order):

- VLC PPSA85300 after getdtablesize (idx 354):
  "FAIL: unresolved ELF import YKT49TOLQWs from libkernel.prx"
  (Map idx 452, Create idx 462)
- XPSemu PPSA97358 after tcsendbreak (idx 214):
  "FAIL: unresolved ELF import avvJ3J0H0EY from libkernel.prx"
  (Create idx 398, Map idx 399)
- RetroArch PPSA99169:
  "FAIL: unresolved ELF import avvJ3J0H0EY from libkernel.prx"
  (Create 476, Alias 477, Map 478)

XPSemu and VLC (ps5/compat/mmap.c, __wrap_mmap) create an object for
every anonymous PROT_EXEC mapping (QEMU's TCG buffer) and map it with
the same protection, falling back to flexible memory on any non-zero
return. RetroArch's eboot runs a probe: Create("ps5-platform-probe",
0x10000, 7, &fd), Alias(fd, 3, &alias), Map(fd, 5, &address), then logs
"jit create=0x%08x alias=0x%08x map=0x%08x".

Signatures from Orbital cc408367 tools/ida/db_types.json (name, len,
maxProt, fdOut; fd, maxProt, fdOut; fd, prot, startOut), matching
ps4sdk 4df9d001 include/sce/kernel.h, ps5-jar-loader 8034177e
LibKernel.java and the three titles' call sites. SharpProspero 5dfdb4b0
declares the alias as returning the descriptor; the RetroArch call site
passes an out pointer.

The object is a host anonymous file (memfd on Linux, a delete-on-close
temporary file mapped as a PAGE_EXECUTE_READWRITE section on Windows),
the alias a duplicate descriptor, and each map maps the whole object
through the direct memory placement path, so a write through one view
is visible through the others. Bad lengths and protection bits are
EINVAL, protection past the descriptor's maximum is EACCES (FreeBSD 11
vm_map_protect), unknown descriptors are EBADF; close, dup and dup2
keep the descriptor table in step. Unverified details are recorded in
TechnicalDebt.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-10-12 21:59:19 +02:00
screamm 51b3e3ef38 feat(libkernel): implement the remaining termios calls
Adds tcsendbreak (vXE-dIUIZlE), tcdrain (brGGJWsZauw), tcflush
(FxHW5NuEXsY), tcflow (OG8xRaGIpqk), tcgetpgrp (5OEl1mRhUm0) and
tcsetpgrp (YMuesZTyTl4) next to tcgetattr and tcsetattr in
File/src/Terminal.cpp. The NIDs come from tools/nid_names.py and match
aerolib.csv (zecoxao/sce_symbols 2883963a).

They follow FreeBSD 11.4 lib/libc/gen/termios.c (8c639945), which
implements each one over a terminal ioctl: tcflush returns EINVAL for a
queue other than TCIFLUSH, TCOFLUSH or TCIOFLUSH and tcflow for an
action outside TCOOFF..TCION before the descriptor is used; every other
call fails with the error the merged tcgetattr gives (EBADF for a closed
descriptor, ENOTTY for a file or pipe, EADDRNOTAVAIL or EOPNOTSUPP for a
socket, per soo_ioctl and in_control/in6_control). tcsendbreak fails on
TIOCSBRK before its 0.4 s pause, and tcflow's TCIOFF/TCION fail in
tcgetattr. FreeBSD's pipe_ioctl answers TIOCGPGRP/TIOCSPGRP on a pipe or
FIFO with the SIGIO owner, which is not modelled, so tcgetpgrp and
tcsetpgrp throw on a host pipe above descriptor 2.

Titles (homebrew catalog #1578), predicted stops from registry order:
- PS5MC PPSA99420 imports tcsendbreak (442), tcdrain (443), tcflush
  (444), tcflow (445), tcgetpgrp (462) and tcsetpgrp (463); once pause
  and setrlimit are in, it stops at
  "FAIL: unresolved ELF import vXE-dIUIZlE from libkernel.prx".
- XPSemu PPSA97358 imports tcsendbreak (214), its first uncovered import
  after execv, sigwait, setrlimit, mlockall, setuid and getopt:
  "FAIL: unresolved ELF import vXE-dIUIZlE from libkernel.prx".

guest_terminal covers each call over stdin, stdout, stderr, a file, both
pipe ends and an AF_INET socket, the EINVAL cases (also on -1), and
EBADF for -1, a closed socket, a closed pipe and a closed file.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-10-12 21:48:20 +02:00
Eli Yarson f80a2f5535 fix(libkernel): resolve original .prx names to relinked .guest.prx in stat, open and reachability
Titles check for a plugin with sceKernelStat before loading it through the engine path. The relinker emits only X.prx.guest.prx, so the check failed and PSNCore started with the raw (0, NULL) arguments. Share the dlopen mapping with sceKernelStat, read-only sceKernelOpen and sceKernelCheckReachability when the original name is absent.
2026-10-12 16:02:14 -03:00
LeandroLP23 d3011ae113 fix(libkernel): share the directory state between duplicated descriptors on Windows
dup and dup2 of a Windows directory descriptor threw. FreeBSD's
kern_dup makes both descriptors refer to one open file, so they share
the read position; the duplicate now points at the same DirectoryState,
which getdents and lseek go through, and keeps it after the original
is closed.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-12 21:01:33 +02:00
screamm 43ffba87e4 feat(libkernel): implement fcntl record locks on Windows
ProsperoRadio (PPSA99001) stops at 33.7 s on Windows, with #3649
applied so that it gets past poll, on the throw from #3840:

    what():  fcntl: record locks are not implemented on Windows, command=12, fd=3

F_GETLK, F_SETLK, F_SETLKW and the F_OGETLK, F_OSETLK and F_OSETLKW
forms now follow FreeBSD 11.4's kern_fcntl and lf_advlockasync
(8c639945): an SEEK_CUR start is resolved against the descriptor offset
(EOVERFLOW past OFF_MAX), F_RDLCK needs read access and F_WRLCK write
access (EBADF), another type is EINVAL, and the range is checked against
the file size for SEEK_END (EINVAL for a negative start or an unknown
whence, EOVERFLOW past OFF_MAX). The guest is one process, and
lf_blocks never lets locks of one owner conflict, so whichever
descriptor or thread asks, F_SETLK and F_SETLKW succeed without waiting
and F_GETLK reports F_UNLCK, as on the console. Nothing is held on the
host: Windows byte-range locks are mandatory and would fail the guest's
own reads and writes through other descriptors. A lock from the end of
a directory throws.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-10-12 18:42:53 +00:00
Dean 21c27e60a4
Merge pull request #4536 from orishamir/fix/debugout-host-stderr
fix(libkernel): keep sceKernelDebugOutText off a redirected guest stderr
2026-10-13 07:31:53 +13:00
Dean 3b5c96377d
Merge pull request #4516 from Ondra97/codex/file-lock-lifetime
fix(libs): share Windows flock state between duplicated descriptors
2026-10-13 07:30:48 +13:00
Dean f7b238e43b
Merge pull request #4513 from winstrex/fix/libkernel-open-directory-trailing-separator
fix(libkernel): open directories whose host path ends in a separator on Windows
2026-10-13 07:30:26 +13:00
lorkydey c052b7c720 feat(libc): query filesystem statistics by guest path 2026-10-12 19:42:52 +02:00
Dean a7614930a4
Merge pull request #4349 from milescoviello/fix/open-nofollow
fix(libkernel): fail open with O_NOFOLLOW on a symbolic link
2026-10-13 04:53:25 +13:00
Dean 3881117feb
Merge pull request #4348 from milescoviello/fix/rmdir-symlink
fix(libkernel): fail rmdir on a symbolic link instead of removing it
2026-10-13 04:53:02 +13:00
Ori Shamir fc0d46ba00 fix(libkernel): throw instead of aborting when there is no host standard error to keep
A Windows GUI build started without standard handles has no descriptor 2.
_dup(2) then reached the invalid-parameter handler, which aborts, before the
"cannot keep the host standard error" error could be thrown. It now goes
through WithoutParameterHandler like the other descriptor calls in this file.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-12 17:53:41 +03:00
Scott Schuster 2585eeb7ee fix(libkernel): keep sceKernelDebugOutText off a redirected guest stderr
Guest descriptors are host descriptors, so a guest that moves standard
error with dup2 also moves the stream sceKernelDebugOutText writes to. A
title that forwards its standard error to the kernel log through a pipe
then reads its own debug output back and logs it again without end. Before
the guest's first dup2 onto descriptor 2, the host's standard error is kept,
and sceKernelDebugOutText writes there.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-12 17:53:41 +03:00
Dean fe66af13ef
Merge pull request #4038 from santhoshkumar-dev/fix/libkernel-symlink-file-size
fix(libkernel): report the target size of symbolic links on Windows
2026-10-13 03:08:09 +13:00
Ondra97 bd842bc7d2 fix(libs): share Windows flock state between duplicated descriptors 2026-10-12 16:03:47 +02:00
winstrex a47178b86f fix(libkernel): open directories whose host path ends in a separator on Windows
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-12 10:06:44 -03:00
Dean ed14cb4e0a
Merge pull request #4053 from nikowolf123/fix/libkernel-close-guest-sockets
fix(libkernel): close guest sockets in sceKernelClose
2026-10-13 01:20:47 +13:00
Dean 5f3b94cb19
Merge pull request #3840 from ahir061/feat/libkernel-fcntl-files
feat(libkernel): support fcntl and ioctl on non-socket descriptors
2026-10-12 23:53:24 +13:00
Dean c3204078e4
Merge pull request #4270 from ErenYeager1836/fix/shm-unlink-windows-return
fix(libkernel): return after NotImplemented in Windows shm_unlink
2026-10-12 23:46:32 +13:00
Dean 9b152c43d0
Merge pull request #4090 from yunusshaikh7/fix/libc-fopen-delete-sharing-windows
fix(libc): open fopen streams with delete sharing on Windows
2026-10-12 21:39:18 +13:00
Dean 7b03a42185
Merge pull request #3659 from MarcZX100/carry/win-getdents-name-limit-3327
fix(libkernel): reject oversized Windows directory entry names
2026-10-12 21:35:24 +13:00
Santhosh Kumar 6b38cdda8c fix(libkernel): report the target size of symbolic links on Windows
_wstat64, the FindFirstFileExW listing and std::filesystem::file_size
report the size of a file symbolic link itself (0). stat therefore gave
0 for linked files, and APR resolved them as empty, so Unity treated a
linked globalgamemanagers as empty and never read it.

stat takes the size from the handle it already opens, which follows the
link. The APR listing skips reparse points, and names missing from it
are sized through stat.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-12 13:48:56 +05:30
Dean 98c07d8e77
Merge pull request #4111 from jdmagic/fix/kernel-close-net-sockets
fix(libkernel): close() and setsockopt() reach libSceNet sockets
2026-10-12 20:28:00 +13:00
Dean fedcb3c813
Merge pull request #4117 from PrintOrb/fix/windows-positioned-invalid-descriptors
fix(libkernel): return positioned descriptor errors without CRT reports
2026-10-12 20:25:44 +13:00
Ahir 99b1b32f31 fix(libkernel): read the fcntl argument by command
fcntl and sceKernelFcntl read a third argument as a 64-bit integer for
every command on a non-socket descriptor. F_GETFD and F_GETFL pass no
third argument, and the commands that take one pass an int or a pointer.
They now read nothing, an int or a pointer, by command. An int read as
a 64-bit value kept whatever the caller left in the upper half of the
register, so F_READAHEAD -1 enabled read-ahead instead of disabling it.
2026-10-12 12:17:26 +05:30
screamm 01b7bb3e2f feat(libkernel): support ioctl on non-socket descriptors
ioctl and _ioctl answered EBADF for every descriptor outside the
libSceNet socket table. Decoded call sites: PS5MC (PPSA99420, FIONBIO x3,
FIONREAD x2, TIOCGWINSZ x3), ProsperoTV (PPSA99003, FIONBIO on a pipe
once poll on pipes is in), XPSemu (PPSA97358, 21 sites).

Following FreeBSD 11.4 kern_ioctl (sys/kern/sys_generic.c:758),
vn_ioctl (sys/kern/vfs_vnops.c:1488), pipe_ioctl (sys/kern/sys_pipe.c:1346)
and randomdev_ioctl (sys/dev/random/randomdev.c:301), release/11.4.0
8c639945: FIONBIO sets or clears O_NONBLOCK through the same status
flags as fcntl F_SETFL (EFAULT for a null argument before EBADF);
FIONREAD reports the size past the offset of a file, the queued bytes of
a pipe's read end, 0 on its write end, ENOTTY on the random device, and
throws on a directory or another character device; termios requests
(group 't', TIOCGWINSZ included) fail with ENOTTY, as tcgetattr already
takes these descriptors as not a terminal; any other request throws
naming the request and descriptor kind. Sockets keep their path
unchanged.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-10-12 12:17:26 +05:30
screamm 591e8ddadc feat(libkernel): support fcntl on non-socket descriptors
fcntl and sceKernelFcntl answered EBADF (sceKernelFcntl threw) for
every descriptor outside the libSceNet socket table, so files, pipes,
directories and descriptors 0 to 2 could not be queried or changed.

Observed: Yamagi Quake II (PPSA99007) stops with
"Sys_Error: change stdin to blocking Bad file descriptor", from
fcntl(fileno(stdin), F_SETFL, fcntl(0, F_GETFL, 0) & ~FNDELAY)
(yquake2 src/backends/unix/system.c:81-86).

Predicted from the titles' sources and decoded call sites: XPSemu
(PPSA97358, 97 fcntl sites: F_GETFD 12, F_SETFD 20, F_GETFL 8,
F_SETFL 9, F_DUPFD 1, F_DUPFD_CLOEXEC 7, F_GETLK 9) fails in
qemu_init_main_loop, where its pipe2 (pipe plus F_SETFD FD_CLOEXEC) and
glib's g_unix_set_fd_nonblocking (F_GETFL, F_SETFL) build the event
notifier (util/event_notifier-posix.c:44-67); VLC (PPSA85300, 43 sites,
F_RDAHEAD on every file it opens), RetroArch (PPSA99169, 17),
Porpoise (PPSA99764, 13) and Ruffle (9) call it on files and pipes.

The commands follow FreeBSD 11.4 kern_fcntl and kern_dup
(sys/kern/kern_descrip.c:479-799, 812, release/11.4.0 8c639945):
F_GETFD/F_SETFD keep the close-on-exec flag per descriptor, F_GETFL
reports the host access mode with the status flags, F_SETFL changes
only O_NONBLOCK, O_APPEND, O_ASYNC, O_FSYNC, O_DIRECT and FRDAHEAD,
F_DUPFD/F_DUPFD_CLOEXEC give the lowest free descriptor at or above the
start through dup (EINVAL for a negative start), F_DUP2FD goes through
dup2, F_RDAHEAD/F_READAHEAD set FRDAHEAD on files (EBADF on pipes,
ENOTTY elsewhere), and unknown commands fail with EINVAL. Status flags
live in a guest table shared by dup, dup2 and F_DUPFD like an open file
description. O_NONBLOCK switches a pipe (PIPE_NOWAIT on Windows, where an
empty read and a full write now report EAGAIN; the host flag on Linux).
Record locks use the host POSIX locks on Linux and throw on Windows.
Changes the host cannot model throw naming the flag and descriptor kind.
Sockets keep their path unchanged.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-10-12 12:17:25 +05:30
AlxcBTW b42ef24e07
fix(libs): keep thread_local objects with destructors out of module teardown on Windows (#4029)
* fix(agc): keep the driver's per-thread scratch out of thread_local teardown

With MinGW's emulated TLS, a thread_local with a destructor in a DLL is
destroyed after its storage is gone: when a std::thread ends, winpthread
runs libgcc's emutls key destructor, which frees the thread's thread_local
storage, and only then does the loader's DLL_THREAD_DETACH run the DLL's
tls_atexit list, so the destructors run on freed memory. The queue worker
touches four of them in libSceAgcDriver (the dispatch-ahead map, the
pending waits, the draw-snapshot compare vectors and the image decode
memo), and Driver::stop's join of the worker then corrupts the heap.
Under cdb's checking heap agc_driver_draw_cache_reuse stopped at the
worker's exit with heap corruption in all 127 runs, with graphics
pipeline libraries, with APS5_NO_PIPELINE_LTO=1 and with APS5_NO_GPL=1.
Without it the damage shows intermittently, as exit 0xc0000374 (2 of 143
runs with a cold NVIDIA shader cache) or as a fault in whatever allocates
next, such as NVIDIA's compiler on the optimized-link thread (#2980).

These objects now live in HostThreadLocal, fiber-local storage that owns
them, as the recorder's buffers do since e424b6b7b.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(libs): keep thread_local objects with destructors out of module teardown

The teardown order behind the driver's heap corruption holds in every
module: with MinGW's emulated TLS a thread's thread_local storage is freed
before the module's DLL_THREAD_DETACH runs its thread_local destructors,
so they run on freed objects. PreciseSleepUs's timer (used, among others,
by the video-out vblank thread) then closes a stale handle; libkernel's
directory path, socket waker and UUID random device, libSceRandom's random
device and libScePosixForWebKit's random device and host lookup free or
close stale objects. They move to HostThreadLocal. The other thread_locals
in the modules are trivially destructible or only built for Linux.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* test(libs): fail when a module registers a thread_local destructor

prx_thread_local_destructors lists the symbols of every built module and,
where MinGW's thread_local destructor support is linked in, disassembles
the module for calls to __cxa_thread_atexit outside libc's registration of
guest destructors. A module that keeps a thread_local with a destructor
fails it with the function that registers one: with main's libSceRandom
it reports sceRandomGetRandomNumber, and with this branch all 122 modules
pass, libc being the only one that links the support.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(agc): keep the image memo behind its pointer

The image decode memo went into HostThreadLocal as the whole array. On
Linux, where HostThreadLocal is a plain thread_local, that put 1024 memo
entries into every thread's TLS block instead of one pointer. It keeps
its unique_ptr as before, now owned by HostThreadLocal, so Linux builds
the same thread_local as main.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: Dean Galvin <dean.galvin@live.com>
2026-10-12 18:25:29 +13:00
Nithishvelan M bc71f97667 fix(libkernel): return after NotImplemented in Windows shm_unlink 2026-10-12 09:03:06 +05:30
Dean 5fe4bebec6
Merge pull request #3923 from AchrafReyani/fix/libkernel-close-ebadf
fix(libkernel): close an unopened descriptor on Windows without the invalid-parameter report
2026-10-12 16:10:27 +13:00
Dean f0674d3c08
Merge pull request #3968 from babyhuey/feat/libkernel_sys-openat
feat(libkernel_sys): implement openat
2026-10-12 16:08:11 +13:00
ArjenS-LA b41c0b3da9 fix(libkernel): reject oversized Windows directory entry names
(cherry picked from commit b0e0c1c4bfd1487047873663115a94a46987b831)
2026-10-12 01:51:01 +00:00
winstrex 8f9efc25f2 fix(libs): take guest entropy from the host OS instead of std::random_device
std::random_device in libstdc++ reads RDSEED on x86 Linux. On an AMD
EPYC 9V45 (Zen 5) CI runner its 32-bit results repeat about 130 times
in 65536 draws, so guest_posix_random fails. libc now exports
HostEntropy_nid_no_patch, which uses getentropy (rand_s on Windows) and
throws when the OS cannot provide entropy. arc4random, arc4random_buf,
sceRandomGetRandomNumber, /dev/random and /dev/urandom reads,
std::_Random_device and sceKernelUuidCreate use it, and the arc4random
and random device TechnicalDebt entries say so.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-11 22:07:49 -03:00
PrintOrb 4680a52c1e fix(libkernel): return positioned descriptor errors without CRT reports 2026-10-11 18:35:17 -05:00