sceUserServiceGetKeyboardType now returns the keyboard type of the configured
system language from the repository owner's table (languages 0 to 29), with 20
(US English) for a language outside it. The input variants stay 0, the only
value the table gives for Japanese and Traditional Chinese.
sceConvertKeycodeGetImeKeyboardType takes the PS4 client rule from the title ID
prefix (CUSA is PS4); a missing or custom ID is treated as PS5. Tests walk the
owner's table through both calls and the title ID cases; both debt entries
updated.
The DES test catches std::invalid_argument thrown through the library's
sysv_abi frames; like the digest test, it now links libc and calls
configure_windows_unwind.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01FzhWRMauD3ouc8kSxT2NnT
0c6765e6a6 stopped bounds-checking the SCE comment and library version
segments, which decrypted modules list past the end of the file. Some
decrypted modules also end with an unmapped PT_NOTE (address 0, memory
size 0) right after those two: Hollow Knight: Silksong's
Media/Modules/Il2cppUserAssemblies.prx (PPSA12544) lists one at offset
0x54ad408 in a file of 0x54ad407 bytes, so converting the title failed
with "ELF range exceeds file". The guest writer already drops unmapped
notes (SegmentFilter), and nothing reads their bytes.
Skip the bounds check for a note with address 0 and memory size 0. A
mapped note outside the file still fails. test_guest_trailing_note
covers both, with an unmapped note inside the file as well.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
A headless device presents a DCC display buffer while a recorded kernel
that copies over its keys is still pending, holding the GPU mutex once as
Driver::Present does. The present must release the mutex for that wait
(the hold serial advances), read the keys the kernel stored and reach the
swapchain; with nothing pending it must keep the mutex. It stops at the
missing swapchain, after the key check.
Return SCE_SHARE_PLAY_ERROR_INVALID_ARGS (0x810E0001) instead of throwing APS5_INVALID_ARG_EX when an invalid prohibition value is passed to sceSharePlayProhibitController. Update regression test assertions in GuestSharePlay to verify the error code and record technical debt.
The draw was split into draw and finishDraw, so the skip flag and the per-program
classification cache declared in draw were out of scope where finishDraw records
the classification. Indirect draws never hand off to the finisher, so both
functions run on the same thread; make the cache and the switch file-scope
accessors that both use.
With APS5_PROFILE_DRAW set, the [present] line now counts the presents
whose sync through the display buffer's DCC keys waited for the GPU
before the key check, outside the GPU mutex, and the milliseconds they
waited: the waits the presenter took under the mutex before.
The presenter checks a display buffer's DCC keys under the device lock.
When the batch of the kernel that writes those keys had not finished,
the check waited for the GPU while holding the lock, and the queue
worker recording the next frame waited behind the presenter.
PresentDisplayBuffer now first syncs through the key range with the
unlocked wait the flush hook uses: the presenter's acquisition is the
outermost on its thread and nothing has been decided yet, so the lock
is released for the GPU wait and retaken for the completions. The key
check that follows finds the batch finished.
Tested on Windows in a title's menu: the presenter's GPU waits under
the lock went from 721 (1.38 s) to 1 (0 ms) per 10 s, and the queue
worker's waits for the lock from 1.47 s to 0.18 s per 10 s.
RaiseOn suspends the target, reads its context and, while it is in host
code, resumes it and samples again after SwitchToThread. On a 16-core
Ryzen 9 5950X (Windows 11 22H2) that resampled the writer of
guest_raise_in_host_code about every 10 us before it could run: in the
raise that hung, 4,989 samples over 50 ms all found it in ucrtbase, so
the 50 ms host-code limit ran out and the handler was redirected into
fwrite, where it deadlocked on the stream lock (the test timed out at
30 s on every run). In a passing raise the samples sat at one RIP for
14,695 of 14,703 samples and the raise took 145 ms.
Spin for 20 us before each new host-code sample, so the target gets to
leave host code. With that, guest_raise_in_host_code passes 5 of 5 runs,
no raise is redirected in host code, and the longest raise is 0.46 to
0.53 ms. Other samples keep SwitchToThread.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
The debt entry says the rule follows a static reading of the console's
wcsncat_s in libc.prx, that wcscat_s inherits it unread, and that the
narrow strncat_s keeps a wider rule, as asked in review.
Co-Authored-By: Claude <[email protected]>
link took the source's std::filesystem::status first, and MinGW-w64's
libstdc++ reports a Windows symbolic link loop as not found (ENOENT), so
it returned ENOENT before FollowLinkPath, which maps the loop's
ERROR_CANT_RESOLVE_FILENAME to ELOOP, was reached. guest_kernel_sys's
loop case failed at that check wherever symbolic links can be created
(Windows 11 22H2: "check failed at line 835 (guest errno 2)").
When the status reports the source missing, ask FollowLinkPath first:
a loop now returns ELOOP and a dangling link still ENOENT; a missing
path is unchanged.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Initialize, Terminate, UpdateStatus, GetStatus, Open, OpenA, Close and
GetResult run the common-dialog state machine. There is no PSN profile
UI, so Open and OpenA finish at once and GetResult reports result 0,
userAction USER_CANCELED and the caller's userData, as shadPS4 does when
its window is dismissed.
Paths where shadPS4 and the other common dialogs here return different
errors throw, and so does a param whose size or mode does not match the
shadPS4 layout. The common-dialog codes the library uses are added to
libSceCommonDialog/CommonDialog.hpp.