collate<char>::do_transform gave the result std::string a capacity of exactly its length and threw for results of 4095 characters or more. The console's libc.prx grows the string from its inline capacity of 15 to length | 15, so a 26-character result has capacity 31 and a 32-byte allocation. Once capacity + 1 reaches 0x1000 bytes it takes the over-aligned large allocation that the guest's inlined deallocation expects: operator new(bytes + 0x27), the data aligned to 32 bytes and the raw pointer stored just before it. This is the scheme of Dinkumware's basic_string (_Newsize | _ALLOC_MASK) and of its _Allocate in <xmemory0> (_BIG_ALLOCATION_THRESHOLD 4096, _BIG_ALLOCATION_ALIGNMENT 32, _NON_USER_SIZE sizeof(void*) + 31), including its bad_alloc when bytes + 0x27 would wrap. do_transform now uses that capacity and allocation; the throw for long results is gone. The debt entry in docs/dev/debt/libc.md now records the capacity and large storage as unverified on hardware. guest_collate checks the capacity and allocation size of a 26-character result, the last small result (4079 characters, a 4080-byte block) and the first large one (4080 characters, capacity 4095, a 4096 + 0x27-byte block with the data aligned to 32 and the raw pointer before it). With main's LocaleSupport.cpp it aborts at the allocation-size check of the 26-character result (lastSize 27 instead of 32). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> |
||
|---|---|---|
| .. | ||
| nid | ||
| prx | ||
| tests | ||
| CMakeLists.txt | ||
| HitLog.hpp | ||
| SceShaders.hpp | ||
| SceTypes.hpp | ||