Repository navigation
feat(libc): export the std::__sce_v2 locale::global, empty, classic and _Locinfo category calls - #16113
Merged
oneandonlydean merged 1 commit intoNov 5, 2026
Conversation
…nd _Locinfo category calls Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Progress report (dd6efc7 → d18e1c7)📈 System libraries: 26.91% (+0.02%, +8 implemented functions) ✅ 8 implemented
Changed libraries (implemented exports)
|
Contributor
|
Windows check of head Setup: Windows 11 Enterprise 22621, WinLibs GCC 15.2 UCRT, Release. The hosted Windows check does not run these tests on pull requests.
AI-assisted: yes. |
This was referenced Nov 5, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Export the versioned
std::__sce_v2locale::classic,locale::empty,locale::global,locale::_Setgloballocale,_Locimp::_New_Locimp(bool),_Locimp::_Clocptr,_sceLibcLocinfo, and the_Locinfoconstructor and_Addcatsthat take a category, from libc._ZNSt8__sce_v26locale16_SetgloballocaleEPvkyDNldAZhv40xCFD50_ZNSt8__sce_v26locale7classicEvf0KW1y+Ea0Q0xCFE30_ZNSt8__sce_v26locale5emptyEvKA0vt-WXdqQ0xD0D90_ZNSt8__sce_v26locale7_Locimp11_New_LocimpEbVUJZ+pCrRn40xD0DF0_ZNSt8__sce_v26locale6globalERKS0_v+WMV7IIp7w0xF18A0_ZNSt8__sce_v28_Locinfo13_Locinfo_ctorEPS0_iPKc6cl-GjyMBbU0xF27F0_ZNSt8__sce_v28_Locinfo16_Locinfo_AddcatsEPS0_iPKcTM74yWf91xI0xF2860_ZNSt8__sce_v215_sceLibcLocinfoEPKcdJM+bL2BU9E0xF28B0_ZNSt8__sce_v26locale7_Locimp8_ClocptrEHWch8-MtqmQ0x197900The behavior comes from the
libc.prxbundled with PPSA03671 v01.001.005 (J03848509, SHA-256483961e086b8a1fffa8138b3c0badf798987fb5f35ec908d828946408be2d8a6).They build on main's versioned locale, which shares the unversioned
0x30-byte_Locimpand has the classic locale ready from the start. As in the module:classic()returns a staticlocalethat holds the classic_Locimp, and_Clocptrpoints at that_Locimp;empty()and_New_Locimp(bool)build a_Locimpwith one reference, no facets, category 0 and the name*;empty()makes it transparent and_New_Locimptakes the flag;_Setgloballocalestores the global_Locimp, and_Getgloballocaleand_Init(bool)now return that global instead of the classic one, so they follow it once it changes;_Initstill takes a reference when its flag is set;global()returns the previous global through_Init(true). When the new locale differs, it releases the old global's reference, installs and retains the new one, and callssetlocalewith its name for each category in its mask, or once for all six;_sceLibcLocinfothrowsruntime_error("bad locale name")unless the name is""or"C". The two_Locinfocalls ignore the category, check the name the same way, and storesetlocale(LC_ALL, nullptr); the constructor first stores the current name, and both store the classic name only after the check._Locimp_ctorand_Locimp_dtorare left for a follow-up, since they need reference counting in_Locimp_Addfacand_New_Locimp(const _Locimp&), which main does not do yet. A new debt entry records what differs here. The existing versioned locale entry now says_Initand_Getgloballocalereturn the global locale.Tested
Windows x86-64, WinLibs GCC 15.2.0, Release,
BUILD_TESTING=ON, maind893997f1a6. Exact tested commit:d18e1c71325.Built libc, libkernel, their NID-patched production libraries and the related tests. The new
guest_sce_v2_locale_basicspasses, along withguest_sce_v2_locale,guest_localeandguest_sce_v2_exceptions.The NID-patched libc exports all 9 NIDs above.
The new test checks:
classic(),_Clocptr,_Getgloballocaleand_Initagree on the classic_Locimp;_Locimpthatempty()and both_New_Locimp(bool)build;global()takes and releases when it installs a locale, keeps the same one and restores the classic one;_Setgloballocaletakes no reference, and that a null locale throws and keeps the global;_Locinfocalls write, for accepted names and four categories, and thebad locale nameexception and the fields left for six rejected names.The original functions were loaded from the bundled module with their relocations applied. Their imports were bound by NID to this branch's libc and libkernel. The module's heap is not set up outside a console process, so its allocation calls were redirected to the host's. Its
_Xruntime_errorand this branch's were both redirected to one recorder, so each side's rejections were compared by message.Side by side with the patched production library, over two seeds with 20,000 trials each:
_Locimpthatempty()and_New_Locimpbuild, compared field by field;classic(),_Clocptr,_Getgloballocaleand_Initagree after the module's_Initbuilt its classic locale;global,_Setgloballocale,_Initand_Getgloballocalecalls over the classic locale and six other_Locimps, with about 8,000 switches, of which about 3,300global()calls changed the global. Each step compared the returned locale, the global and every reference count except the classic one's, which differs by design.No comparison differed.
Negative control: five lines were altered one at a time:
global()kept the old global's reference;empty()built an opaque_Locimp;_Init(true)took no reference;_Locinfoconstructor stored the classic name before checking the name.The new CTest failed on each, and the side-by-side run reported differences each time. The source was then restored byte for byte (SHA-256 checked) and rebuilt, and the test and side-by-side run passed again.
Code conventions and
git diff --checkpass.tools/pr_overlap.pyread 1,863 open PRs at the tested commit and reports no overlap. It keeps exit 2 for 38 branches that already conflict with main. Merging each of the 38 with this branch and with main usinggit merge-treegives the same conflict blocks, except indocs/dev/debt/libc.mdfor feat(aot): consolidate native ARM64 compiler, runtime and consumers #5021, fix(libc): follow a Windows symbolic link before .. in a guest path #9371, feat(libc): add the std::__sce_v2 thread start, timed wait, clock and processor count calls #9447 and feat(libc): add std::__sce_v2::_Random_device, _Fiopen and setw #9526: their conflict block there already spans the end of the functional section, which holds the versioned locale entry this PR corrects, so the corrected line and the new entry next to it land inside it. The new entry adds no conflict with any of the 141 open PRs that touch that file. fix(relinker): match AppContent utility import to provider #13486 names the unversionedstd::locale::_SetgloballocaleinlibSceLibcInternal, not these exports. No open PR adds these names or NIDs. The branch also merges cleanly with fix(libc): preserve Dinkumware zero signs when no conversion occurs #14595, feat(libc): export the std::__sce_v2 extended-precision helpers #15336, feat(libc): export the std::__sce_v2 multiprecision helpers #15471, feat(libc): export the std::__sce_v2 _Poly and _XLgamma helpers #15484, feat(libc): export the std::__sce_v2 _Xtime_diff_to_millis2 helper #15490, feat(libc): export the std::__sce_v2 _Exp and _FExp helpers #15501, feat(libc): export the std::__sce_v2 _Pmsw, _FPmsw and _LPmsw helpers #15519, feat(libc): throw std::bad_cast and the std::__sce_v2 bad_any_cast, format_error and future_error #15552, feat(libc): forward the std::atomic wait and notify helpers to libkernel #15561, feat(libc): count the std::__sce_v2 _Winit and ios_base::Init initializations #15602, feat(libc): export the std::__sce_v2 floating-point constants #15614, fix(libc): store the std::__sce_v2 _Throw_Cpp_error value in the first code word #15667, feat(libc): export the std::__sce_v2 _Stollx, _Stoullx, _Stolx and _Stoulx parsers #15683, feat(libc): export std::_Throw_bad_any_cast and std::_Throw_bad_node_access #15791, feat(libc): export the std::error_category complete and deleting destructors #15796, feat(libc): export the std::__sce_v2 resetiosflags, setiosflags, setbase and setprecision manipulators #15809, feat(libc): export the std::__sce_v2 _Timespec64_get_sys and _Timespec64_diff_to_ts clock helpers #15834, feat(libc): export the std::__sce_v2 at-thread-exit registry calls #15879, feat(libc): export the remaining std::__sce_v2 facet ids and ios_base _Sync and _Index #15923 and feat(libc): export the std::__sce_v2 clog, wclog and standard stream pointers #16083.Not tested: Linux, macOS, another SDK, a game, GPU or console. No game compatibility claim. No original module, extracted bytes, harness or log is committed or uploaded.
Checklist
main; no other open PR implements the same functionsNotImplemented_nid_no_patch); silent stubs are listed under Silent stubs in their library's technical debt file.mdfiles or images added to the repository (attach them to this PR)🤖 Generated with Claude Code