Commit Graph
65 Commits
Author SHA1 Message Date
MarcZX10 d824ec2264 test(libSceLibcInternal): let the spawn test's child die from SIGBUS in an ASan build 2026-10-25 22:19:02 +00:00
fogydes 19a3d60aed fix(libSceLibcInternal): declare _NSGetExecutablePath on Apple hosts 2026-10-25 13:57:18 +01:00
fogydes 723d932f73 feat(libSceLibcInternal): implement posix_spawn process creation and reaping 2026-10-25 13:57:17 +01:00
boykopovar fdf9ca7574 fix(sdk): reconcile public headers after rebase 2026-10-24 23:17:47 +03:00
boykopovar f38d29fd08 refactor(sdk): add canonical headers for remaining libraries 2026-10-24 23:17:42 +03:00
Adrià a0aaf24b68 Merge pull request #8996 from hypermoist/feat/libc-init-once-clr
feat(libSceLibcInternal): add the __std_init_once _clr calls
2026-10-24 18:14:49 +02:00
Adrià 5d251e6b0e Merge pull request #8994 from hypermoist/feat/libc-filesystem-primitives
feat(libSceLibcInternal): add the std::filesystem file and directory primitives
2026-10-24 14:39:57 +02:00
orezraeyandClaude Opus 5.5 3717573887 fix(libkernel): answer sceKernelGetModuleInfoFromAddr's flags and failures as measured on a PS5
Flags 1 finds any module and flags 2 only non-system ones; other flags return EINVAL instead of throwing, every failure clears the 0x1A8 bytes, and st_size is left 0.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-23 11:49:24 -03:00
Dean 4997726a5f Merge pull request #8703 from nikowolf123/feat/libcinternal-double-underscore-inet
feat(libSceLibcInternal): export __inet_ntoa_r
2026-10-24 03:29:12 +13:00
Dean efc6cd8f1b Merge pull request #8702 from nikowolf123/feat/libcinternal-underscore-err-warn-progname
feat(libSceLibcInternal): export _err, _warn and _getprogname
2026-10-24 03:25:55 +13:00
Kang, Harry Zixuan 726edc503b feat(windows): support MSYS2 GCC runtime builds 2026-10-21 20:29:55 -07:00
NikoandClaude Opus 5.5 c8ad92f878 feat(libSceLibcInternal): export _err, _warn and _getprogname
The PS5 3.20 export inventory lists _err, _warn and _getprogname in
libSceLibcInternal next to err, warn and getprogname, with the NIDs
UhKI6z9WWuo, XQFE8Y58WZM and iI6kGxgXzcU. In FreeBSD 11.4 libc the
underscore names are the definitions and the public names are weak
references to them (lib/libc/gen/err.c, lib/libc/gen/getprogname.c),
and libthr interposes none of them, so each pair is one function.

_err and _warn now hand their arguments to verr and vwarn, which use
errno at the call as err and warn do; _getprogname returns
getprogname(). The debt file records that the console's module was not
read.

guest_err checks the _warn and _err text for errno 13 with a formatted
message, that _err passes its status to the err_set_exit hook, and that
_warn without a format returns without calling the hook.
guest_program_name checks that _getprogname returns the current
__progname pointer.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-21 17:02:54 +02:00
NikoandClaude Opus 5.5 3e1b0f5aa4 feat(libSceLibcInternal): export __inet_ntoa_r
The PS5 3.20 export inventory of libSceLibcInternal lists
__inet_ntoa_r next to inet_ntoa_r, and no AnyPS5 library exported it,
so a title importing it could not resolve it. It now runs inet_ntoa_r:
FreeBSD 11.4's arpa/inet.h names the function __inet_ntoa_r, and
inet_ntoa.c makes inet_ntoa_r a weak alias of it.

__inet_addr, __inet_aton and __inet_ntoa are in the same inventory,
but libc already exports them and the relinker also looks up
libSceLibcInternal imports in libc, so they are not added here.

guest_inet_address formats an address through __inet_ntoa_r into a
buffer of exactly the text's size, and checks that a buffer one byte
short is returned unchanged with ENOSPC and that inet_ntoa's buffer is
left alone.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-21 16:25:51 +02:00
hypermistandClaude Opus 5.5 b3b6e83aca feat(libSceLibcInternal): add the __std_init_once _clr calls
__std_init_once_begin_initialize_clr, __std_init_once_complete_clr and
__std_init_once_link_alternate_names_and_abort were not exported. As in
the PS5 12.00 module, begin moves an idle once object to running and
reports pending, reports done without pending, and waits on the object
while another caller runs; complete marks it done, or idle again for
flag 4, wakes every waiter and returns 1; the third aborts.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01RbLgECLQ2bpDM7oe2urGZK
2026-10-21 22:02:40 +13:00
hypermistandClaude Opus 5.5 e66eae3c5a feat(libSceLibcInternal): add the std::filesystem file and directory primitives
The Dinkumware std::filesystem in titles calls twelve low-level helpers
that libSceLibcInternal exports and this project did not: _Stat, _Lstat,
_File_size, _Last_write_time, _Make_dir, _Remove_dir, _Unlink, _Chmod,
_Current_get, _Open_dir, _Read_dir and _Close_dir. They now follow the
PS5 12.00 module on top of the guest stat, mkdir, rmdir, unlink, chmod,
getcwd and directory calls, with its results: file_type codes from the
mode, not_found for ENOENT, ENOTDIR, EINVAL and ENAMETOOLONG, mkdir's
1/0/-errno, -1 for a failed size, and directory reads that skip the dot
entries and report the type as unknown. As on the console, _Lstat
follows links like _Stat.

The two _Xfilesystem_error overloads are exported and still throw, as
the guest filesystem_error type is not provided yet.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01RbLgECLQ2bpDM7oe2urGZK
2026-10-21 21:58:09 +13:00
Dean ecd45318d9 Merge pull request #8208 from al3w0f205/fix/statvfs-null-output-order
fix(libSceLibcInternal): check null output before path in statvfs
2026-10-20 18:31:31 +13:00
al3w0f205 a8c5a3afc8 fix(libSceLibcInternal): check null output before path in statvfs 2026-10-19 22:14:06 -05:00
xXPBSXxandClaude Sonnet 5.5 7535eb45fc fix(libSceLibcInternal): start fdopendir at the descriptor position and set FD_CLOEXEC
fdopendir listed the directory from its first entry whatever position the
descriptor had, and left FD_CLOEXEC unchanged. FreeBSD 11.4 fdopendir sets
FD_CLOEXEC on the descriptor and preserves the initial seek position (lib/libc/gen/opendir.c).
The Windows directory handle now skips the entries the descriptor already
consumed, the Linux handle duplicates the descriptor, and the test requires both.

Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
2026-10-20 03:11:14 +02:00
Adrià 3fdd1f52e9 Merge pull request #6668 from DavidSamir/fix/libc-statvfs-path-macos
fix(libSceLibcInternal): read statvfs by path on macOS
2026-10-19 10:19:46 +02:00
Adrià 9cc0f16f6e Merge pull request #6533 from ArjenS-LA/feat/guest-getopt-long-only
feat(libc): implement getopt_long_only
2026-10-19 06:04:23 +02:00
Adrià 6e27fc8f07 Merge pull request #6233 from milescoviello/fix/spawn-missing-program
fix(libSceLibcInternal): fail posix_spawn with ENOENT when the program is not there
2026-10-18 22:37:14 +02:00
Dean cb1d6e5bd6 Merge pull request #7123 from thuanquang/fix/guest-frame-chain-zero-record
fix(libkernel): end guest thread, fiber and context frame chains at a zero record
2026-10-18 22:04:31 +13:00
T3cm0andClaude Opus 5.5 53a1fe47d6 feat(libSceLibcInternal): implement err, warn, psignal and sys_signame
Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-18 03:02:13 -05:00
Dean 1d8524be7c Merge pull request #7352 from T3cm0/bionic/inet-aton-ntoa
feat(libSceLibcInternal): implement inet_aton, inet_addr and inet_ntoa
2026-10-18 15:52:20 +13:00
T3cm0andClaude Opus 5.5 300b7ff34c feat(libSceLibcInternal): implement inet_aton, inet_addr and inet_ntoa
Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-17 20:42:20 -05:00
T3cm0andClaude Opus 5.5 f9b7b230fc feat(libSceLibcInternal): implement the remaining posix_spawnattr accessors
Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-17 20:41:26 -05:00
milescovielloandClaude Opus 5.5 a7c68a3919 fix(libSceLibcInternal): fail posix_spawn with ENOENT when the program is not there
Dusklight (PPSA99305) aborts on main as soon as its Select disc image
item is chosen: SDL's file dialog probes "zenity --version" through
posix_spawnp, and posix_spawnp throws "process creation not implemented".

FreeBSD 11.4's posix_spawn returns the error of the child's exec, and
an exec of a program that is in no directory of PATH (_PATH_DEFPATH
when PATH is unset) fails with ENOENT. Both calls now return ENOENT
without writing the process ID when the program is not in the guest
file system, and keep throwing when it is. SDL then reports the file
dialog as unsupported and the title stays on its menu.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-17 18:31:37 +00:00
thuanquangandClaude Opus 5.5 ff9bf22281 fix(libkernel): end guest thread, fiber and context frame chains at a zero record
Unreal Engine walks the frame-pointer chain until it reads a return
address of 0 and never checks the frame pointer itself. Guest threads
started with whatever rbp the host code held, so the walk ran into host
start-up frames (glibc's saved rbp 0x21 in a LEGO Batman core dump,
address 8 in Returnal on Windows) and faulted. Fibers ended their chain
with a null frame, and makecontext started its function with rbp 0, so
the same walker read address 8 there too.

Guest threads now start through a thunk that points rbp at a
{saved rbp 0, return address 0} record, as the relinker's entry stub
does for the main thread; the fiber trampolines push the same record,
and the makecontext start function is built with frame pointers so its
frame, over the zero return address makecontext stores, ends the chain.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-17 19:27:53 +07:00
David 09e2c0e9cf fix(libSceLibcInternal): read statvfs by path on macOS
statvfs opened the path with O_PATH, which macOS does not have, so
libSceLibcInternal did not build there. No open mode stands in for it:
on macOS O_RDONLY and O_EVTONLY fail with EACCES on a file or directory
without read permission, and O_SEARCH on such a directory, where
FreeBSD's statvfs only needs search permission on the path.

On macOS statvfs now asks the host statvfs by path, which needs exactly
that, fills the kernel statfs the way _fstatfs fills it from the host
fstatvfs, and converts it with the code fstatvfs uses. A path that must
name a directory and does not fails with ENOTDIR, as the O_DIRECTORY open
does elsewhere. Other hosts are unchanged.
2026-10-16 07:25:54 +04:00
David ea7ea289d2 refactor(libSceLibcInternal): share the statvfs layout and its conversion
fstatvfs kept the guest struct statvfs and the sfs2svfs conversion from
the kernel's statfs to itself. Both move to include/Statvfs.hpp so that
statvfs can convert a volume the same way without opening the path.
Nothing changes for fstatvfs.
2026-10-16 07:24:08 +04:00
ArjenS-LA 725ad5649c feat(libc): implement getopt_long_only 2026-10-15 11:27:50 -07:00
akkadbakkad89 bf4945eabd feat(libc): export the fmin and fmax family
Adds fmin, fminf, fminl, fmax, fmaxf and fmaxl, the remaining
missing members of the C99 minimum/maximum family, with the NaN
propagation and signed-zero handling guest_fminf pins down (host
std::fmin does not guarantee the sign of a zero result). The
previous libSceLibcInternal copy of fminf is removed so the export
stays single-owner. PPSA28319 imports fmaxf from libc.prx; the
other five names were exported by nothing.
2026-10-14 19:25:39 +00:00
screammandClaude Fable 5.1 9849a1db64 feat(libSceLibcInternal): export sys_siglist and sys_nsig
PS5CEMU-HAR (PPSA99360, ps5-payload-dev build, relinks with
--trap-sdk-syscall-stubs) imports the data objects sys_siglist
(yCdGspbNHZ8) and sys_nsig (ZD+Dp+-LsGg) from libSceLibcInternal.prx;
the import audit lists both as absent (registry entries 364 and 378,
after pthread_setaffinity_np at 276). No run has reached them yet; the
predicted stop line is

  FAIL: unresolved ELF import ZD+Dp+-LsGg (sys_nsig) from libSceLibcInternal.prx

or yCdGspbNHZ8 (sys_siglist), whichever the loader resolves first.

The table and count are FreeBSD 11.4 lib/libc/gen/siglist.c (8c639945):
32 descriptions, signal 0 to SIGUSR2 (NSIG 32), and sys_nsig is their
number, 32. ps5-payload-dev declares both as objects exported by
libSceLibcInternal and its strsignal reads them.

Co-Authored-By: Claude Fable 5.1 <[email protected]>
2026-10-14 14:15:55 +13:00
Dean e09ee165d5 Merge pull request #3651 from MarcZX100/codex/libc-posix-spawn-3624
feat(libSceLibcInternal): implement posix_spawn actions
2026-10-14 00:37:44 +13:00
Dean Galvin cd9573b41c fix(libSceLibcInternal): return the negative zero from fminf for zeros of different sign 2026-10-13 21:12:48 +13:00
DavidandClaude Fable 5.1 2fe382c658 feat(libSceLibcInternal): implement the posix_spawn attribute and file action calls
XPSemu (PPSA97358) imports eleven posix_spawn calls from
libSceLibcInternal.prx, one reference each, and no call site is known.
Predicted stop (import order, not measured), behind isnanf (idx 296):
`FAIL: unresolved ELF import 44hlATrd47U from libSceLibcInternal.prx`
(posix_spawnattr_init, idx 347), followed by p--TkNVsXjA, LG6O0oW9bQU,
Sj7y+JO5PcM, Ud8CbISKRGM, Hq9-2AMG+ks, IUfBO5UIZNc, Heh4KJwyoX8 (348-355),
UV4m0bznVtU, Ani6e+T-y6Q and 3Nr9caNHhyg (379-381).

The nine object calls follow FreeBSD release/11.4.0 (8c639945a445)
lib/libc/gen/posix_spawn.c: posix_spawnattr_init allocates a zeroed
attribute object (ENOMEM on failure), _destroy frees it, _setflags and
_setsigdefault store the value; posix_spawn_file_actions_init allocates an
empty list (-1 on failure, as in 11.4), _destroy frees it with its
entries, and _addopen (path copied), _adddup2 and _addclose append in
order after returning EBADF for a negative descriptor. Null or
uninitialized objects, which FreeBSD dereferences, throw.

posix_spawn and posix_spawnp throw "process creation not implemented",
as execvp does: FreeBSD validates no argument before rfork/vfork, and no
child process can be created here. TechnicalDebt records them.
guest_posix_spawn covers the attribute round trips, the recorded action
sequence, the EBADF cases and the throws. NIDs computed with
tools/nid_names.py and present in aerolib.

Co-Authored-By: Claude Fable 5.1 <[email protected]>
2026-10-13 07:56:19 +00:00
Leonardo 02d1dbb9f3 feat(libSceLibcInternal): implement fminf required for PPSA99902 startup 2026-10-12 23:27:13 +02: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
Adrià 28c9dae73d Merge pull request #4569 from pipe1os/feat/libkernel-fdopendir
feat(libSceLibcInternal): implement fdopendir
2026-10-12 23:00:17 +02:00
Felipe Arce f3b8ef7abf feat(libSceLibcInternal): implement fdopendir 2026-10-12 16:23:42 -03:00
David 1d67426ede feat(libSceLibcInternal): implement getopt and getopt_long
Export getopt (VUtibKJCt1o) and getopt_long (8VVXJxB5nlk) from
libSceLibcInternal together with the guest variables optind
(zCnSJWp-Qj8), optarg (zG0BNJOZdm4), opterr (yaFXXViLWPw), optopt
(FwzVaZ8Vnus) and optreset (CZNm+oNmB-I). The NIDs were computed with
tools/nid_names.py and all seven are in aerolib; the PS5 payload SDK
f5d40f02 lists the functions and the five objects in
sce_stubs/libSceLibcInternal.c.

Titles (predicted stops from registry order, not observed runs):
- XPSemu PPSA97358, after execv/execve, the signal waits, the
  credential setters, mlockall and tcsendbreak:
  "FAIL: unresolved ELF import VUtibKJCt1o from libSceLibcInternal.prx"
  (getopt idx 204, 10 call sites from 0xF6C23D), then optind (207),
  optreset (208), optarg (209).
- RetroArch PPSA99169: getopt_long (idx 554, call sites 0xD2FC0C,
  0xD3002A), optind (553), optarg (555).

Behaviour follows FreeBSD release/11.4.0 8c639945: getopt is
lib/libc/stdlib/getopt.c (no permutation, GNU "::" optional argument,
lone "-" as an option when listed), getopt_long is getopt_internal
from lib/libc/stdlib/getopt_long.c with GNU_COMPATIBLE (permutation,
POSIXLY_CORRECT read through the guest getenv on the first call and on
optreset, "+" and "-" prefixes, "W;", optind 0 as a reset, abbreviation
and ambiguity rules and the GNU warning texts). Warnings are written to
the guest stderr stream as "<__progname>: <message>", as warnx does.
The struct option layout and argument kinds are include/getopt.h.
The code lives in libSceLibcInternal because __progname is a libkernel
export that libc cannot link.

A null getopt option string, a null argument vector or argument, a
negative optind and an optind moved inside a pending permutation throw
where FreeBSD faults. getopt_long_only is not exported.

guest_getopt runs the FreeBSD getopt_test cases (contrib/netbsd-tests
t_getopt.sh with the h_getopt and h_getopt_long result format) plus
grouped and optional arguments, "--", permutation order, "+" and "-"
prefixes, optreset and optind 0 restarts, POSIXLY_CORRECT, all three
long argument kinds, abbreviations, ambiguity, flag pointers, "W;",
optopt with opterr 0 and the exact stderr text.

Co-Authored-By: Claude Fable 5.1 <[email protected]>
(cherry picked from commit a2740166d93920c301e1add23ceea762b4acad27)
2026-10-12 18:46:43 +00:00
lorkydey c052b7c720 feat(libc): query filesystem statistics by guest path 2026-10-12 19:42:52 +02:00
Adrià 59584d58b1 Merge pull request #3858 from LeandroLP23/fix/libc-internal-force-tls-destructor-windows-test
test(libSceLibcInternal): run guest_force_tls_destructor on Windows
2026-10-12 00:10:39 +02:00
LeandroLP23andClaude Opus 5.5 c27e67ceb5 test(libSceLibcInternal): run guest_force_tls_destructor on Windows
sceKernelGetModuleInfoFromAddr has a Windows path since 77ef75c1d, so
_sceLibcInternalForceTlsDestructor finds each dso's module there too.
The test takes the other module's address with GetProcAddress where
Linux uses dlsym(RTLD_NEXT), and the TechnicalDebt entry no longer says
the call throws on Windows.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-11 19:31:41 +02:00
lorkydey 5bd43e3e8e build(libc): register filesystem statistics source separately 2026-10-11 16:55:03 +02:00
lorkydey 1ead4a120c feat(libc): implement guest fstatvfs volume statistics 2026-10-11 15:57:20 +02:00
DariusHQ cf1545d751 feat(libkernel): implement getcontext, setcontext and makecontext
PSXS5, SwanStationPS5 and Nuvio stop at start-up on setcontext on main,
and EVO Player and ProsperoStore do on Windows. The three are imported
by the statically linked OpenSSL's ASYNC code.

The three use FreeBSD 11's amd64 ucontext_t (mcontext at 0x10, mc_len
800, uc_link at 0x330, 0x370 bytes), which the titles are built
against: EVO Player's ASYNC_is_capable captures into a 0x370-byte stack
buffer, and async_fibre_makecontext sets uc_link at 0x330 and uc_stack
at 0x338. getcontext saves every register at its call in assembly and
stores the context as FreeBSD's sys_getcontext does: rax and rdx as 0,
the carry flag clear, the FXSAVE image and the signal mask, and nothing
from uc_link on. setcontext checks mc_len and mc_flags as set_mcontext
does, installs the signal mask, masks MXCSR with the host's MXCSR_MASK
and returns through iretq, so every general register and the flags are
restored and nothing is written below the target stack pointer.
makecontext follows FreeBSD 11's amd64 libc.

Windows checks guard-page growth and exception unwinding against the
stack bounds in the TEB. setcontext and longjmp now set them to the
stack they switch to, which makecontext registers and pins writable as
libSceFiber does for fiber stacks. OpenSSL enters a context with
setcontext and then switches with _setjmp and _longjmp.
2026-10-11 13:00:38 +03:00
overlordxrz-source 2806eb57a2 feat(libSceLibcInternal): implement getprogname 2026-10-11 04:22:28 -04:00
Scott SchusterandClaude Opus 5.5 383bffd8c7 feat(libc): implement alarm
RetroArch (PPSA99169) stops at alarm on main: `FAIL: unresolved ELF import DQXJraCc1rA from libSceLibcInternal.prx`.

alarm(seconds) arms one process-wide real-time alarm and returns the seconds left on the previous one, rounded up like FreeBSD's alarm.c (any partial second counts); alarm(0) cancels it. When it expires, SIGALRM's disposition as recorded by sigaction or signal applies: ignored, nothing happens; default, the process terminates as on FreeBSD (exit status 128 + 14); a guest handler throws, because asynchronous delivery to a guest handler is not implemented.

The timer lives in libkernel next to the signal dispositions (GuestAlarm_nid_no_patch); libSceLibcInternal, which the titles import alarm from, forwards to it.

AI-assisted (Claude Code).

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-10 17:59:58 -05:00
QRMOE da26c7e86e fix(libSceLibcInternal): preserve errno after successful utime
AI-assisted: yes. Restore guest errno only on successful utimes forwarding and retain delegated failure errors. Register the controlled-backend regression test. Windows library build and focused tests pass; Linux rerun pending.
2026-10-10 14:42:35 -04:00