From 79fcbf226c6a26a3cb3c4c770b9e7cfe1d19f4de Mon Sep 17 00:00:00 2001 From: David Date: Tue, 13 Oct 2026 15:58:05 +0530 Subject: [PATCH] feat(libkernel): add getdtablesize getdtablesize (sZuwaDPATKs, aerolib) is a throwing export. FreeBSD 11.4 makes it system call 89, sys_getdtablesize (sys/kern/kern_descrip.c:338-355, freebsd-src 8c639945a44588f6cfdddfb057bb5aad88735da0): min(lim_cur(RLIMIT_NOFILE), maxfilesperproc); FreeBSD 11.4 has no lib/libc/gen/getdtablesize.c. Neither the console's RLIMIT_NOFILE soft limit nor kern.maxfilesperproc is published: shadPS4 443f0224 has no getdtablesize or RLIMIT_NOFILE (its posix_sysconf table answers _SC_OPEN_MAX with -1, without a stated source), KytyPS5 4733b7e and OpenOrbis 0a1aaf9d have neither, fpPS4 04cefd43 returns High(Integer) as a placeholder, SharpProspero 5dfdb4b0 only binds it. getrlimit keeps throwing for RLIMIT_NOFILE for the same reason. Recorded in technical debt. VLC (PPSA85300) and XPSemu (PPSA97358) import it and call it only from their own closefrom (ZiZc3/VLC f3253020 and ZiZc3/XPSemu 8eec07b4, ps5/compat/libc_stubs.c:67-73). --- core/libs/prx/libkernel/System/src/Process.cpp | 4 ++++ core/libs/tests/GuestGetrlimit.cpp | 12 ++++++++++++ docs/dev/debt/libkernel.md | 1 + 3 files changed, 17 insertions(+) diff --git a/core/libs/prx/libkernel/System/src/Process.cpp b/core/libs/prx/libkernel/System/src/Process.cpp index 0d7b1a5bff4f..566b1ae606dc 100644 --- a/core/libs/prx/libkernel/System/src/Process.cpp +++ b/core/libs/prx/libkernel/System/src/Process.cpp @@ -539,6 +539,10 @@ int APS5_VABI getrlimit_nid_postfix(int resource, GuestResourceLimit* limit) { } } +int APS5_VABI getdtablesize_nid_postfix(void) { + throw std::runtime_error("getdtablesize: the console's RLIMIT_NOFILE soft limit and kern.maxfilesperproc are not known"); +} + int APS5_VABI sceKernelIsTrinityMode(void) { return 0; } diff --git a/core/libs/tests/GuestGetrlimit.cpp b/core/libs/tests/GuestGetrlimit.cpp index 73b23df87b6e..8849806d3d30 100644 --- a/core/libs/tests/GuestGetrlimit.cpp +++ b/core/libs/tests/GuestGetrlimit.cpp @@ -14,6 +14,7 @@ struct ResourceLimit { extern "C" int APS5_VABI getrlimit_nid_postfix(int resource, ResourceLimit* limit); extern "C" int* APS5_VABI __error_nid_postfix(); +extern "C" int APS5_VABI getdtablesize_nid_postfix(void); static constexpr int GUEST_EFAULT = 14; static constexpr int GUEST_EINVAL = 22; @@ -74,6 +75,16 @@ static void LoweredHostLimitIsReported() { } #endif +static void RequireTableSizeUnsupported() { + bool rejected = false; + try { + getdtablesize_nid_postfix(); + } catch (const std::runtime_error&) { + rejected = true; + } + Require(rejected); +} + static void RequireUnsupported(int resource) { ResourceLimit limit{}; bool rejected = false; @@ -123,4 +134,5 @@ int main() { }) { RequireUnsupported(resource); } + RequireTableSizeUnsupported(); } diff --git a/docs/dev/debt/libkernel.md b/docs/dev/debt/libkernel.md index 6e33ad17fc56..7fbc6990a083 100644 --- a/docs/dev/debt/libkernel.md +++ b/docs/dev/debt/libkernel.md @@ -163,3 +163,4 @@ - [pthread_cond_reltimedwait_np](../../../core/libs/prx/libkernel/Pthread/Posix/Cond.cpp) (libkernel) takes `(cond, mutex, usec)`, a relative timeout in microseconds, and is `scePthreadCondTimedwait` with POSIX error numbers. FreeBSD 11.4 has no such function; the signature comes only from shadPS4, which registers one function for this NID and for `scePthreadCondTimedwait` ([`condvar.cpp`](https://github.com/shadps4-emu/shadPS4/blob/3a9f57265d28975658f1ca941daa5c879c7a74bd/src/core/libraries/kernel/threads/condvar.cpp#L229-L234)). shadPS4 reads a 64-bit count; here it is the 32-bit `SceKernelUseconds` of the SCE twin, as for `sem_reltimedwait_np`. Unverified on the console - [sysctl kern.arandom](../../../core/libs/prx/libkernel/System/src/SystemConfiguration.cpp) (libkernel) serves FreeBSD 11's MIB {1, 37} (CTL_KERN, KERN_ARANDOM) and the "kern.arandom" sysctlbyname lookup through std::random_device, returning min(*oldLength, 256) random bytes. Following FreeBSD's sysctl_kern_arnd, a null buffer reports min(*oldLength, 256) without writing, a null length returns 0 without writing, and requests with a new value return EPERM (1) as the node is read-only. Cryptographic quality depends on the host's random device implementation. - [sceKernelGetPageTableStats](../../../core/libs/prx/libkernel/DirectMemory/Export.cpp) (libkernel) - reports 2048 page-table entries on each side (a 4 GiB pool of 2 MiB entries, the constants of [KytyPS5](https://github.com/KytyPS5/KytyPS5/blob/main/src/kernel/memory.cpp)) and all of them available: no entries are counted as used, so a title never sees page-table pressure. KytyPS5 counts the 2 MiB entries of the committed CPU- or GPU-accessible ranges as used, which this port does not do. The four `int*` arguments follow OpenOrbis' `libkernel.h`, the Orbital type database and SharpProspero; a null pointer returns `SCE_KERNEL_ERROR_EFAULT` as in KytyPS5. None of the values is measured on a console. PPSA30601 (Resonance) calls it during start-up +- [getdtablesize](../../../core/libs/prx/libkernel/System/src/Process.cpp) (libkernel) throws: FreeBSD 11.4's [`sys_getdtablesize`](https://github.com/freebsd/freebsd-src/blob/8c639945a44588f6cfdddfb057bb5aad88735da0/sys/kern/kern_descrip.c#L338-L355) returns the smaller of the `RLIMIT_NOFILE` soft limit and `kern.maxfilesperproc`, and neither value is published for the console (`getrlimit` throws for `RLIMIT_NOFILE` for the same reason); fpPS4 returns `High(Integer)` as a placeholder. PPSA85300 and PPSA97358 import it and fail to load without it. Both call it only from their own `closefrom` ([VLC libc_stubs.c](https://github.com/ZiZc3/VLC/blob/f3253020a64368153233ede29183014c0b6c8979/ps5/compat/libc_stubs.c#L67-L73), [XPSemu libc_stubs.c](https://github.com/ZiZc3/XPSemu/blob/8eec07b4e31f66dce8e0b05c1ca1281af303e933/ps5/compat/libc_stubs.c#L67-L73)), which closes every descriptor below the value, so the value decides how many `close` calls run, including over the libSceNet descriptor range