Files
AnyPS5/docs/dev/debt/libSceLibcInternal.md
T

8.6 KiB

libSceLibcInternal technical debt

Unknown function info

  • _sceLibcInternalThreadAtexit, _sceLibcInternalThreadDtors (libSceLibcInternal) - FreeBSD __cxa_thread_atexit semantics assumed; a null or non-image destructor and an allocation failure throw
  • _sceLibcInternalForceTlsDestructor (libSceLibcInternal) - behaviour follows sceLibcForceTlsDestructor(int) in a title's libc.prx (disassembly): the calling thread's destructors whose dso belongs to the module run newest first, only if the dso's module is loaded and the dso points to itself, in up to 4 passes. The return type is unknown (that function returns nothing), 0 is returned. The module of each dso is looked up when the destructors are forced, not when they are registered as libc.prx does

Functional

  • std::filesystem::_Xfilesystem_error (libSceLibcInternal, NIDs B0CeIhQty7Y and C6-7Mo5WbwU) - both overloads still throw NotImplemented: on the console they throw std::filesystem::filesystem_error, whose guest type information and layout this library does not provide yet. The filesystem primitives beside them follow the PS5 13.60 module
  • makecontext (libSceLibcInternal) follows FreeBSD 11's lib/libc/amd64/gen/makecontext.c: at most six arguments, a stack of at least MINSIGSTKSZ (2048) bytes, and exit(0) when the function returns with no uc_link. The console's version is not verified
  • makecontext (libSceLibcInternal) on Windows pins its stack writable until a later makecontext stack overlaps it, since nothing tells the library when the guest frees the stack
  • Thread exit destructors (libSceLibcInternal) run when a libkernel thread finishes; on the main or a host thread only _sceLibcInternalThreadDtors runs them, as exit does, else they are dropped
  • fdopendir (libSceLibcInternal) follows FreeBSD 11's fdopendir: it sets FD_CLOEXEC on the descriptor first, and the stream starts at the descriptor's current position instead of the first entry. On Windows the stream skips the entries the descriptor's cursor (lseek or getdirentries) has passed, which assumes that the descriptor and the stream list a directory in the same host order; on Linux the stream is opened on a duplicate of the descriptor, which shares its position. The Linux path is not run by the tests here. As in FreeBSD, a descriptor that is not open fails with EBADF, one that is not a directory with ENOTDIR (both leave it open, and FD_CLOEXEC stays set on the latter), and closedir closes it
  • fstatvfs (libSceLibcInternal) converts _fstatfs to the 88-byte struct statvfs as FreeBSD 9.2's sfs2svfs does (f_bsize from the transfer size, f_frsize from the block size, f_favail equal to f_ffree, f_fsid 0, ST_RDONLY and ST_NOSUID only). Differences: f_namemax is the statfs value, not fpathconf(_PC_NAME_MAX); negative f_bavail and f_ffree wrap to unsigned without EOVERFLOW, as the same-width copy in FreeBSD does; inode counts are 0 on Windows, inherited from _fstatfs; a null output returns EFAULT after the descriptor is validated, where FreeBSD would fault. Layout and conversion are unverified against the PS5 library (PS5MC imports fstatvfs but was not run)
  • posix_spawn and posix_spawnp (libSceLibcInternal) create a native child running the requested program's converted image, which must be under /app0/ (/app0/eboot.bin maps to the running image); posix_spawnp searches PATH as FreeBSD 11's _execvpe, and the FreeBSD 11.4 file actions and attributes are applied to the child. A null argv returns EFAULT; a null envp inherits the parent environment; guest process IDs are the host's. Limits: the child executes the conversion made at relink time; Windows redirects only descriptors 0 to 2 and starts the child on the parent's std handles; Linux applies only POSIX_SPAWN_RESETIDS and POSIX_SPAWN_SETPGROUP, other flags or a nonzero set on Windows throw. The console sandbox's effect on child creation is unverified, and null or uninitialized objects, which FreeBSD dereferences, throw. PPSA99305 (Dusklight) reaches this when SDL looks for zenity
  • getopt, getopt_long (libSceLibcInternal) follow FreeBSD 11 getopt.c and getopt_long.c with GNU_COMPATIBLE: getopt does not permute, getopt_long permutes unless POSIXLY_CORRECT is set in the guest environment or the option string starts with +, and the exported opterr, optind, optopt, optreset and optarg start at 1, 1, 0, 0 and null. Warnings go to the guest's current stderr prefixed with __progname, where FreeBSD's warnx keeps the stderr of its first call. 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. That the console's libSceLibcInternal uses this FreeBSD code is unverified
  • posix_spawnattr_getflags, getpgroup, getschedparam, getschedpolicy, getsigdefault, getsigmask, setpgroup, setschedparam, setschedpolicy and setsigmask (libSceLibcInternal) read and write the 0x30-byte attribute object at the offsets of the console's libSceLibcInternal.sprx (SDK 4.5x build of J03950001, 0x8D860 to 0x8D910: flags at 0, process group at 4, scheduling parameter at 8, policy at 0xC, default and masked signal sets at 0x10 and 0x20), which never fail there and return 0; the layout matched on a PS5 (firmware 13.60). Uninitialized attributes and null pointers, which the console dereferences, throw as the existing setters do
  • sys_siglist and sys_nsig (libSceLibcInternal) hold the 32 descriptions and the count of FreeBSD 11.4 siglist.c (NSIG 32, signal 0 to SIGUSR2); the console's table was not read
  • _err, _warn and _getprogname (libSceLibcInternal) are assumed to be the same functions as err, warn and getprogname and run their code; the console's module was not read. FreeBSD 11.4 defines the underscore names and makes the public names weak references to them (_err, _warn, _getprogname)
  • inet_aton, inet_addr, inet_ntoa and inet_ntoa_r (libSceLibcInternal) follow the FreeBSD code in the console's libSceLibcInternal.sprx (SDK 4.5x build of J03950001, 0x8ADE0 to 0x8B3D0) and matched it on a PS5 (firmware 13.60) for 20 inet_aton inputs; a null text, which the console dereferences, throws. inet_ntoa_r formats through libkernel's __inet_ntop, so a null buffer with room for the text throws and a null buffer that is too small sets ENOSPC, as __inet_ntop does for a null destination; the console's inet_ntoa_r was not measured with a null buffer
  • __inet_ntoa_r (libSceLibcInternal) was not measured on the console: it runs inet_ntoa_r, as FreeBSD 11.4 names the function __inet_ntoa_r (arpa/inet.h) and makes inet_ntoa_r a weak alias of it (inet_ntoa.c)