From bf939c43c82d33cd0978f98202683d5a8a7995ef Mon Sep 17 00:00:00 2001 From: Mihawk <163614687+mihawk-99@users.noreply.github.com> Date: Sun, 4 Oct 2026 23:17:30 -0400 Subject: [PATCH] Pin the payload SDK whose iswctype_l answers FreeBSD's masks PS5_PayloadSDK f05c5de fixes ps5_iswctype_l at its source. It used to hand libc++'s FreeBSD class mask to the console's Dinkumware iswctype, which reads it as a table index; that faulted EmulationStation in std::locale("C"). It now answers from the rune type, as FreeBSD's does. This project pins it (tools/setup-native-dependencies.sh). The pin also brings the SDK's two opt-in modules since f674976, fdv and elevation, which this title does not call. frontends/common/frontend_shims.c loses its own iswctype_l, and tools/build-frontend.sh binds the name to the platform's like the other locale variants. It is on the hand list, because libc++'s wide ctype names it and no stub defines it. Evidence: evidence/sdk-iswctype/ (capture.json, expectation.json). Base PS5 13.40, build 716a3c05: ES-DE started on the platform's iswctype_l: "Audio driver: ps5", pictures PASS, GL error 0 game mode on the new pin: Snes9x ran, RetroArch quit (status 0), back to ES-DE, no fatal line PS5_PayloadSDK: make test PASS. Command: bash tools/setup-native-dependencies.sh PS5_FRONTENDS='es-de picker' tools/build-title.sh tools/run-title.sh --no-build --relaunch-test=1 --relaunch-image=es-de/es-de.bin \ --frontend-capture=4,12 --frontend-scroll --watch 35 --- evidence/sdk-iswctype/capture.json | 22 ++++++++++++++++++++++ evidence/sdk-iswctype/expectation.json | 11 +++++++++++ frontends/common/frontend_shims.c | 18 ------------------ tools/build-frontend.sh | 10 +++++----- tools/setup-native-dependencies.sh | 2 +- 5 files changed, 39 insertions(+), 24 deletions(-) create mode 100644 evidence/sdk-iswctype/capture.json create mode 100644 evidence/sdk-iswctype/expectation.json diff --git a/evidence/sdk-iswctype/capture.json b/evidence/sdk-iswctype/capture.json new file mode 100644 index 0000000..da06917 --- /dev/null +++ b/evidence/sdk-iswctype/capture.json @@ -0,0 +1,22 @@ +{ + "step": "sdk-iswctype", + "recorded": "2026-10-05T03:17:30Z", + "console_run": "base PS5 13.40, runs 231157 and 231524", + "revision": "3f40d2d + payload SDK f05c5de", + "command": "tools/run-title.sh --no-build --relaunch-test=1 --relaunch-image=es-de/es-de.bin --frontend-capture=4,12 --frontend-scroll --watch 35", + "raw_capture": "klog/sdk-iswctype/summary.txt", + "raw_lines": 10, + "raw_bytes": 857, + "lines": [ + "==> base PS5 13.40, build 716a3c05 (PS5_FRONTENDS='es-de picker'), payload SDK f05c5dea (ps5_iswctype_l from the rune type)", + "frontends/common/frontend_shims.c: no iswctype_l of its own; tools/build-frontend.sh binds iswctype_l=ps5_iswctype_l", + "ES-DE start (--relaunch-test=1 --relaunch-image=es-de/es-de.bin --frontend-capture=4,12 --frontend-scroll --watch 35, run 231157):", + " es_log: Setting up AudioManager... Audio driver: ps5 (ES-DE ran past std::locale, where the console's iswctype faulted)", + " frontend capture PASS: 2 pictures from 1 process(es), GL error 0", + "game mode on the new SDK (--frontend-launch --retroarch-frames=600 --watch 80, run 231524):", + " game mode: RetroArch quit (status 0) after 11 s; back to the frontend", + " frontend capture PASS: 3 pictures from 2 process(es)", + " fatal lines in the run's kernel log: 0", + "host: PS5_PayloadSDK make test PASS" + ] +} diff --git a/evidence/sdk-iswctype/expectation.json b/evidence/sdk-iswctype/expectation.json new file mode 100644 index 0000000..34a5343 --- /dev/null +++ b/evidence/sdk-iswctype/expectation.json @@ -0,0 +1,11 @@ +{ + "step": "sdk-iswctype", + "note": "The payload SDK's iswctype_l answers FreeBSD's masks from the rune type (PS5_PayloadSDK f05c5de, now this project's pin); EmulationStation uses it in place of its own shim and still starts, and RetroArch with a core runs on the new pin.", + "must_contain": [ + "Audio driver: ps5 (ES-DE ran past std::locale", + "game mode: RetroArch quit (status 0) after 11 s; back to the frontend", + "fatal lines in the run's kernel log: 0" + ], + "must_not_contain": [], + "human_check": "" +} diff --git a/frontends/common/frontend_shims.c b/frontends/common/frontend_shims.c index 0323c8d..a65845d 100644 --- a/frontends/common/frontend_shims.c +++ b/frontends/common/frontend_shims.c @@ -12,15 +12,6 @@ * the console's libc has none. access() itself is the platform's here (bound by * tools/build-frontend.sh), the console's refusing every path a title asks about. * - * iswctype_l: libc++ classifies wide characters through it with FreeBSD's ctype - * masks (_CTYPE_S for a space; ctype_byname::do_is, which a named - * std::locale reaches while it builds its time facets). The platform's - * ps5_iswctype_l hands the mask to the console's iswctype, which is Dinkumware's - * (it exports _Iswctype and _Getpwctytab) and reads its argument as an index into - * its class table: ES-DE's std::locale("C") faulted there on its first line - * (klog/run-PPSA99169-154622.log: SIGSEGV in libSceLibcInternal, c 0x20, mask - * 0x4000). This answers from the platform's FreeBSD rune type, as FreeBSD does. - * * pathconf: libc++'s std::filesystem::current_path sizes its buffer with it, and * only libkernel_sys exports it, which a title does not load: the import would be * null. The limits are the console's FreeBSD ones, for a path that exists. @@ -48,8 +39,6 @@ #include #include #include -#include - void *__memset_chk(void *destination, int value, size_t length, size_t destination_length) { @@ -69,13 +58,6 @@ int faccessat(int directory, const char *path, int mode, int flags) return access(path, mode); } -unsigned long ps5____runetype_l(int c, void *locale); - -int iswctype_l(wint_t c, wctype_t class_mask, locale_t locale) -{ - return (ps5____runetype_l((int)c, (void *)locale) & class_mask) != 0; -} - long pathconf(const char *path, int name) { struct stat status; diff --git a/tools/build-frontend.sh b/tools/build-frontend.sh index cf60919..0b6d403 100755 --- a/tools/build-frontend.sh +++ b/tools/build-frontend.sh @@ -91,9 +91,9 @@ cp "$opengl/native-app/ps5-pie.ld" "$opengl/native-app/app-symbols.map" "$work/t # locale variants libc++ calls, bound by name as ../PS5_Vulkan's tools/radv-link.sh # binds them for eboot.bin, so a frontend sees the files RetroArch sees. Only names # the platform defines are bound, and not the ones ../PS5_OpenGL's shims define -# (mkstemps, openlog, popen, pclose) or frontends/common does (iswctype_l, whose -# platform version gives FreeBSD's masks to the console's Dinkumware iswctype); -# the version script keeps every one local. +# (mkstemps, openlog, popen, pclose); the version script keeps every one local. +# (iswctype_l was frontends/common's until the platform answered FreeBSD's masks +# itself: PS5_PayloadSDK f05c5de.) # # That list is eboot.bin's. A frontend imports more of the functions the platform # replaces (ES-DE's first start called readlink, which no module exports to a title, @@ -109,12 +109,12 @@ mapfile -t replaced < <("$sdk/bin/llvm-nm" --defined-only "$platform" 2>/dev/nul awk '$2 ~ /^[TDR]$/ && $3 ~ /^ps5_/ { print substr($3, 5) }' | sort -u) declare -A is_replaced=() for name in "${replaced[@]}"; do is_replaced[$name]=1; done -own=" mkstemps openlog popen pclose iswctype_l " +own=" mkstemps openlog popen pclose " bindings=() bind() { [[ $own == *" $1 "* ]] || bindings+=("--defsym=$1=ps5_$1"); } for name in qsort_r __xuname __assert regcomp regexec regfree regerror localtime_r newlocale freelocale \ strtod_l strtof_l dladdr utimensat localeconv_l strtoll_l strtoull_l strtold_l snprintf_l sscanf_l \ - asprintf_l strcoll_l strxfrm_l strftime_l wcscoll_l wcsxfrm_l btowc_l wctob_l mbrlen_l \ + asprintf_l strcoll_l strxfrm_l strftime_l wcscoll_l wcsxfrm_l btowc_l wctob_l iswctype_l mbrlen_l \ mbrtowc_l mbsrtowcs_l mbsnrtowcs_l wcrtomb_l wcsnrtombs_l mbtowc_l ___mb_cur_max_l ___runetype_l \ ___tolower_l ___toupper_l __runes_for_locale catopen catgets catclose __cxa_thread_atexit_impl \ localeconv arc4random arc4random_buf arc4random_uniform gmtime_r statvfs fstatvfs futimens \ diff --git a/tools/setup-native-dependencies.sh b/tools/setup-native-dependencies.sh index f129ddd..5bea999 100644 --- a/tools/setup-native-dependencies.sh +++ b/tools/setup-native-dependencies.sh @@ -23,7 +23,7 @@ zlib_stamp="$zlib_root/.source-version" # there). The pinned revision is exported with git archive, so a build never # depends on the fork's working tree, and the SDK directory records it. sdk_fork="${PS5_PAYLOAD_SDK_FORK:-$root/../PS5_PayloadSDK}" -sdk_revision=f674976f48a8c319abd5646079eca284fde790fd +sdk_revision=f05c5dea5110cbcac6ba4e8f090d8e400311770e zlib_url="https://zlib.net/fossils/zlib-$zlib_version.tar.gz" zlib_hash="bb329a0a2cd0274d05519d61c667c062e06990d72e125ee2dfa8de64f0119d16" skip_sdk=false