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
This commit is contained in:
Mihawk committed 2026-10-04 23:17:30 -04:00
1 parent 5ee2d48455
commit bf939c43c8
5 files changed
+39 -24

No files matched your search

+22
View File
@@ -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"
]
}
+11
View File
@@ -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": ""
}
-18
View File
@@ -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<wchar_t>::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 <string.h>
#include <sys/stat.h>
#include <unistd.h>
#include <wctype.h>
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;
+5 -5
View File
@@ -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 \
+1 -1
View File
@@ -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