On Linux these four exports took the guest's registers as named parameters
and rebuilt a va_list from them. The register save area held only the
argument registers after the fixed ones, followed by zeros, with gp_offset 0,
so va_arg read the zeros for the remaining integer slots before moving to the
overflow area. overflow_arg_area was the seventh integer parameter, which is
the value of the first stack argument, not its address.
snprintf(buffer, size, "%d %d %d %d", 1, 2, 3, 4) produced "1 2 3 0",
"%s/%s/%s/%s" with four strings produced "a/b/c/(null)", and eight integers
dereferenced the value 4 and crashed. sprintf and sscanf lost their fifth
and sixth arguments, libc_printf its sixth.
They are now variadic functions that use va_start, like printf, sprintf_s,
snprintf_s and printf_s on Linux already do.
Recognize the exact typed pattern-fill kernel and route aligned, nonaliased uniform ranges through existing fill/coherence handling. Preserve control and descriptor bounds, partial dispatch counts, queued labels, and shader fallback for other cases.
Semantics checked on Radeon RX 6600: native RDNA wave32/wave64 typed R32_UINT loads/stores, execution masks, and descriptor bounds (16 cases). Real PM4 tests cover HLE and shader paths, imports and copies, indirect/partial dispatch and GPU-to-label ordering under Vulkan validation. Graphics and PM4 tests pass; Skyrim Helgen save visually checked. 64 MiB copied-buffer fill median reduced from 67.5 ms to 3.8 ms.
Written with AI assistance.
A color target with both DCC and CB_COLOR_INFO.FAST_CLEAR keeps its fast
clear in the DCC keys and fills its CMASK with 0xF (expanded), as radv
does (radv_get_cmask_fast_clear_value) and as PPSA21567 does
(CB_COLOR_INFO 0x10042730, reported on #419). Such targets now decode;
their clear is materialized by the existing DCC path. A DCC target's
CMASK that is not all expanded throws.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Draws into a color target with CB_COLOR_INFO FAST_CLEAR (bit 13) were
rejected. The CMASK keeps one nibble per 8x8 tile: 0 means the tile is
fast-cleared and reads as CB_COLOR_CLEAR_WORD, 0xF means expanded (the
texels hold the color). The texture units and display scanout do not read
it, so a title runs a fast-clear eliminate pass before sampling or
flipping such a target.
DecodeColorBuffer now takes the CMASK address (CB_COLOR0_CMASK and
CB_COLOR0_CMASK_BASE_EXT) and the bytes one nibble per 8x8 tile spans.
Before a draw renders into the target, and in a fast-clear eliminate
pass, a CMASK whose nibbles are all 0 is materialized: the target is
filled with the clear texel (FillClear on its resident image, else
guest memory on the CPU) and the CMASK bytes are stored as expanded,
through the same GPU-ordered store as the DCC "uncompressed" keys
(0xFF either way). The result equals the draw followed by the eliminate
pass. An all-expanded CMASK changes nothing; a mixed one throws, as do
fast clears of DCC, mipmapped, 3D and array targets.
PPSA14632 (LEGO Horizon Adventures) fast-clears its two 3840x2160
display buffers through CMASK, so its final composite draw was dropped
on every frame and only black was presented.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
sceAppContentAppParamGetInt numbers the SKU flag 0 and
USER_DEFINED_PARAM_1..4 as 1..4 (fpPS4 ps4_libsceappcontent). Id 1
returned the SKU flag and 2..5 returned zero. UFC 6 (PPSA23566) checks
that param 1 is its title number, userDefinedParam1 in param.json, and
crashes otherwise. Absent params read as zero.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Read the module layout from the PE image that holds the address. A
relinked image reports its .elf sections as segments and the
eh_frame_hdr recorded in .ehmeta; any other image reports its sections
with memory access and its .ehfram section. The eh_frame_hdr and
eh_frame helpers are shared with the Linux path, and the guest module
info test now also runs on Windows.
Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
A 16-bit PCM block whose num_samples exceed its data starts a stream, and waveform blocks with flag 0x2 append more data to it. The voice outputs silence while it has played all appended data and CONTINUE is set, and ends at num_samples or when CONTINUE is cleared.
Accept COMP_SWAP STD_REV and ALT_REV on 16_16_16_16 color targets and
map them onto RGBA16 with the same export component mappings used for
8_8_8_8. ALT on 16_16_16_16 is still refused.
SuspendThread returns before the thread has stopped, and GetThreadContext waits until it has. waitCount was read right after SuspendThread, so a thread that was leaving its wait could still decrement it and drain its APCs with NtTestAlert before QueueUserAPC queued the delivery, which then waited for an alertable wait that never came. The context is now read first, so waitCount is read from a stopped thread.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
The new phase's vectored handler continues every exception the thread raises, so the thread spends much of its time in NtContinue, where a redirect is lost unless the raise retries. Without the retry the phase hangs in every run; with it the test passes.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
The Linux guest module writer emitted DT_HASH with a single bucket, so
every symbol lookup that reached a guest module walked its whole symbol
table. Guest modules come first in the global scope, so each host prx
lookup paid that walk at load and on every lazy PLT call. Build the
standard SysV table from the final symbol names with one bucket per
symbol, as the console's modules ship it.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
waitMemory's timeout report keeps a function-local static std::set of the
addresses already reported and a static counter. Two queue workers whose
waits time out at the same time insert into the set concurrently, which
is a data race on a std::set and can corrupt the tree. The set and the
counter are now updated under a mutex.