Commit Graph

6138 Commits

Author SHA1 Message Date
DariusHQ bad19037a6 feat(libkernel): implement sendfile
PS5MC (PPSA99420) stops at start-up on sendfile. It follows FreeBSD 11:
headers, the file range and trailers go to a connected stream socket, the
file offset does not move, a non-blocking socket fails with EAGAIN after
a partial send, and *sbytes reports what was sent. The checks and the
point where *sbytes is written follow kern_sendfile.c.
2026-10-11 16:19:13 +03:00
DariusHQ b9fc448343 fix(libc): format positional arguments on Windows
The guest formatter threw on %n$ and *m$, which FreeBSD's vfprintf and
glibc accept. It now reads the arguments a numbered format names into a
table first, with the types their conversions give them, and follows
FreeBSD's rules for unnumbered conversions and unnamed arguments.
2026-10-11 16:19:13 +03:00
DariusHQ d9fe7ee614 fix(libc): accept the ' flag in Windows formatting
FreeBSD's vfprintf takes ' as the thousands-grouping flag. The Windows
formatter threw on it as an unsupported conversion. The guest's setlocale
only accepts the C locale, which has no thousands separator, so the flag
changes nothing: it is dropped before the host's printf sees it, and the
host's locale cannot add separators.
2026-10-11 16:19:12 +03:00
DariusHQ b1fe54e331 fix(libc): print 0 for %#.0o of zero on Windows
C and FreeBSD's vfprintf print a single 0 when # meets octal zero with a
precision of 0. The Windows formatter passed the conversion to the host's
printf, which printed nothing; it now asks for one digit instead.
2026-10-11 16:19:12 +03:00
David 88cd5bbde5 fix(libSceAgc): accept a hand-built GE_USER_VGPR register offset in sceAgcCreatePrimState
EVO Player (PPSA99039), Jelly5 (PPSA99505), Emby5 (PPSA99515) and
Nuvio PS5 (PPSA99997) stop on main 0f863c10 with

  what():  sceAgcCreatePrimState: invalid user configuration register offsets

All four build their shader headers by hand (EVO-PLAYER-PS5
evo_agc_shader_header.c, ported from ps5-xash3d-halflife) and store the
ge_user_vgpr_en special at 0x25c (GE_USER_VGPR1, value 0) instead of
0x262 (GE_USER_VGPR_EN), as analysed in #3457. They run on the console.

OpenAGC's reconstruction of the FW 5.50 sceAgcCreatePrimState
(src/game_compat.c at 3c7e8072) copies the four special register pairs
verbatim without checking their offsets; KytyPS5's offset checks
(src/libs/agc.cpp at 16a7fe68) are EXIT_NOT_IMPLEMENTED guards. The
special is now copied at the offset the header stores, not moved to
0x262; the driver reads neither register. GE_CNTL, VGT_SHADER_STAGES_EN
and a used VGT_GS_OUT_PRIM_TYPE are still required at their own
offsets because the driver reads them there, and the error now names
the special and the offset found.

With the change all four titles get past sceAgcCreatePrimState and stop
in the shader recompiler (GetImageResource dword 3 is not a valid
runtime value), as #3457 reported for EVO Player.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
(cherry picked from commit aeaa5080d9595305aa73e74d966f989c88b79839)
2026-10-11 13:19:03 +00:00
David 6db0a4df7c fix(libkernel): sync read-only and directory descriptors on Windows
FreeBSD's fsync and fdatasync succeed on a descriptor opened read-only and on a directory. _commit needs write access, so both returned EBADF there. A read-only descriptor is now flushed through a write handle from ReOpenFile and a directory through a handle opened for it, as sceKernelSync already does.
2026-10-11 15:15:00 +02:00
Mouad-Scriptz-0 b63996f1ff fix(agc): read a merged program's vertex tables past its hidden user words
A merged (NGG geometry path) program's user data starts with eight
hidden words, so the vertex buffer and attribute table offsets of its
AGC header, which count from the first user SGPR, were read eight words
too early and found zeros. Killzone: Liberation (PPSA11142) stopped on
`AGC graphics: null vertex buffer table address` at the first frame of
its PSP game. The decoder now adds the hidden word count to the table
reads; the registers reported to the recompiler are unchanged, as it
already maps them from the first user SGPR. `agc_driver_graphics` gains
a merged and a plain layout case.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-10-11 13:13:01 +00:00
David 9c7aa0d61a feat(libc): implement ftrylockfile
Porpoise PPSA99764 stops after pthread_attr_* (#3494) with the
predicted `FAIL: unresolved ELF import h05OHOMZNMw from
libSceLibcInternal.prx` (idx 311, call site 0x8EC37); RetroArch
PPSA99169 imports it at idx 448 (call site 0xA4A27). h05OHOMZNMw is
ftrylockfile by tools/nid_names.py and aerolib.csv (zecoxao/sce_symbols
2883963a); ps5-payload-dev/sdk f5d40f02 declares
`int ftrylockfile(FILE *)` in include/freebsd/stdio.h.

ftrylockfile tries the same host CRT stream lock that flockfile,
funlockfile and every locking host stdio call on the stream take, so
no second lock exists beside the one stdio uses. It returns 0 when the
lock is acquired or already owned by the caller (recursive, released by
as many funlockfile calls) and -1 when another thread holds it, as
FreeBSD 8c639945 lib/libc/stdio/_flock_stub.c:89-104 does. Linux calls
glibc ftrylockfile. UCRT has no try variant of _lock_file, so Windows
calls TryEnterCriticalSection on the CRITICAL_SECTION that _lock_file
enters (__crt_stdio_stream_data::_lock, ucrt/inc/corecrt_internal_stdio.h,
same layout in Windows SDK 10.0.19041, 10.0.22621 and 10.0.26100). A
null or closed stream throws. The UCRT layout dependency is recorded in
TechnicalDebt.

guest_standard_streams covers trylock on an unlocked stream, re-entry
by the owner, failure from another thread while held (also after one of
two unlocks and while another thread holds flockfile), stdio calls
from another thread blocking on the trylock-held lock, release order,
and null and closed streams.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-10-11 18:42:23 +05:30
Superhe11 83c9eb7af1 fix(agc): keep uncached storage images out of the resource cache 2026-10-11 16:12:02 +03:00
EdouardSence 295e48f059 feat(libSceNgs2): export sceNgs2ReportRegisterHandler and sceNgs2ReportUnregisterHandler
PPSA04540 (Rise of the Ronin) imports both and now loads past them;
calling either throws until NGS2 produces reports.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-11 15:11:24 +02:00
EdouardSence 9f3cc31f77 feat(libSceRazorCpu): add sceRazorCpuPushMarker
PPSA04540 (Rise of the Ronin) imports it. Like sceRazorCpuPushMarkerStatic
it does nothing without a capture and returns 0.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-11 15:09:35 +02:00
MarcZX100 a0e3d2098d fix(shader): omit sRGB variants for comparisons 2026-10-11 13:09:21 +00:00
thibaut db1f3c38ef fix(shader): drop masked selects proven unobserved through whole quad mode
A lane set contained in X is contained in WQM(X). Containment is proven
through BitwiseAnd and through ballots evaluated in the uniform entry
blocks, where every invocation is active. Under a whole quad mode mask the
masked lanes form whole quads, so implicit-LOD pixel samples, which only
read their own quad, do not observe them.

This removes the selects that kept the packed pixel ancillary input alive
after its fields were extracted in GTA V (PPSA04264) pixel shaders.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01V1W4jdNSKTV7xwuS6xQPJV
2026-10-11 15:05:49 +02:00
Scramblrrrr 3943287d63 refactor(shader): drop the overlapping global loop join fallback 2026-10-11 10:00:07 -03:00
Scramblrrrr 3a80442635 fix(shader): validate conditional exits before accepting every fallback 2026-10-11 10:00:07 -03:00
Scramblrrrr b23b54a6d7 perf(shader): avoid rerouting synthetic loop-exit forwarders 2026-10-11 10:00:07 -03:00
Scramblrrrr 5781203184 test(shader): expect main to merge the shared exit tail without routing 2026-10-11 10:00:07 -03:00
Scramblrrrr 901c627862 fix(recompiler): preserve the guarded loop exit fallback before shared routing
Keep the AlxcBTW #24 fallback as a separate guarded attempt before enabling shared-exit and nested-continuation repairs. Add the reduced padded shader reported by orishamir on #2523 as an end-to-end regression; the abstract graph does not reproduce the same failure.
2026-10-11 10:00:07 -03:00
Scramblrrrr b0c86ec07f fix(recompiler): privatize shared continuations before loop gateways 2026-10-11 10:00:07 -03:00
Scramblrrrr e6c8e1e9c7 fix(recompiler): route shared loop exit selections in the guarded fallback 2026-10-11 10:00:07 -03:00
AlxcBTW 4df387d0c1 fix(recompiler): reject a loop-exit pass result that is not structured
The third structurize pass, which routes loop exits that leave the loop
before they meet, runs only when the plain and the privatized pass
throw, and its result was used without a check. Merged with #2471, it
turns some of those budget failures into graphs that spirv-val
rejects. In this one, selection 12 of the result lies in the selection
at 7 and branches to 7's merge block 13:

  {{1}, {2, 3}, {4}, {5}, {6, 7}, {}, {8, 9}, {10, 11}, {1}, {12, 4},
   {5}, {13}, {8, 14}, {15, 16}, {7}, {13}, {4}}

  block 12 exits the selection headed by block 12, but not via a
  structured exit

hasStructuredConstructs checks the third pass's result against the
structured control-flow rules of the SPIR-V specification (2.11), with
dominance and post-dominance taken over branch, merge and continue
edges. Back edges come only from a loop's continue block. A conditional
without a merge breaks or continues its innermost loop. A header
strictly dominates its merge, and a loop header its continue block. A
construct contains the merge of every header inside it and is entered
only through its header. It is left only to its own merge or to the
innermost loop's merge or continue block, and a continue construct only
to its loop's header or merge. When the result fails, the second pass's
error is reported, as when the third pass throws. The first two passes
are unchanged.

Differential fuzz with the structured-program generator and random
reducible graphs. Oracle: exact post-dominators,
requireStructuredBranches, merges dominated by their headers, the
original's executions, and spirv-val (SPIRV-Tools v2026.4).
- Against 9fa7d06a: the same outcome and output on every graph. That
  covers 100,000 random graphs at 0 words and with one block at 1000,
  and 30,000 programs at 16 and at 1000 words per block, each also with
  one block at 1000.
- Merged with #2471, the same 30,000 programs: the third pass had made
  41, 42 and 45 of them invalid (16 words, 16 with one block at 1000,
  1000 words). These end in #2471's own error again, and nothing else
  changes. The 1, 1 and 18 graphs that d59a9167 merged with #2471
  already structures invalidly come from the first two passes and stay
  as they are.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-11 10:00:06 -03:00
AlxcBTW 6500daa012 fix(recompiler): route loop exits that leave the loop before they meet
A loop whose exit paths leave the loop construct before they meet got
the nearest common post-dominator of its exits as merge, and
splitSharedMergeBlocks never separated it. An exit continues the
enclosing loop, so its path to that merge runs through the outer
header again, or an exit enters a block that a branch before the loop
also reaches. splitOneLoopMerge gave the loop a forwarding merge block
each round, the other path still bypassed it, and the post-dominator
stayed the same block until "CFG shared merge splitting exceeded
budget". These shapes from #2642 fail that way on main, on d59a9167,
with #2471 and with both:

  {{1}, {2}, {3, 4}, {2, 5}, {}, {1}}
  {{1}, {2, 3}, {4, 5}, {}, {3, 6}, {1}, {2}}
  {{1, 3}, {2, 4}, {3, 1}, {4}, {}}
  {{1, 2}, {3, 2}, {4}, {4, 1}, {}}
  {{1, 2}, {4}, {3, 1}, {4, 2}, {}}

When the plain and the privatized pass both fail, Structurize now runs
a third pass. It routes such a loop's exits through one junction with
routeLoopExits, as loops whose exits have no common post-dominator are
routed already, and gives an outer loop whose only latch lies in an
inner loop its own continue block. In that pass a loop exit conditional
that is neither a direct break or continue nor has an exit tail of its
own is structured as a selection, and an exit tail that the other arm
reaches is not used as one. Without that, graphs the routing unblocks
keep a conditional without merge (the rule from #2762) or a selection
entered past its header. Graphs that the first two passes structure
are unchanged, and when the third pass fails too, the second pass's
error is reported.

Differential fuzz against main, reducible graphs with 5 to 9 blocks,
each with 0 estimated words per block and again with one block at 1000
words (the privatizeSharedReturns path). Oracle: exact post-dominators,
requireStructuredBranches, merges dominated by their headers, the same
executions as the original graph, and spirv-val (SPIRV-Tools v2026.4,
Vulkan 1.3) on a module emitted from the structured graph.

- 200,000 random graphs. main structures 178,743 (0 words) and 178,750
  (1000 words); the output is identical on all of them. Of main's
  14,256 and 14,311 budget failures 13,527 and 13,596 now structure,
  and 2,576 and 2,565 of its refusals. No new output is invalid. The
  invalid outputs are main's 530, plus at 1000 words one graph that
  d59a9167 already turns from a budget failure into a back edge to a
  block that is not a loop header.
- 24,000 structured programs from orishamir/anyps5-cfgfuzz's
  generator (if/else, loops, break, continue, return). main structures
  21,093 and 21,022; the output is identical. 619 of 2,448 and 634 of
  2,429 budget failures now structure. No new output is invalid; the
  invalid outputs are main's 92.

agc_structurizer has the five shapes; requireOriginalBranches now
follows route variables. agc_shader_control_flow has two RDNA programs
of the first two shapes. The non-GPU tests and the 253 agc_driver GPU
tests pass on Windows (RTX 5070 Laptop).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-11 10:00:06 -03:00
AlxcBTW 5182c031a7 fix(recompiler): merge a loop selection where its arms meet in the iteration
A selection in a loop whose arms both reach their nearest common
post-dominator within the iteration got that post-dominator as its
merge. When an arm can also continue the loop, the post-dominator
follows the back edge: the continuing path re-enters the loop header
and reaches the outer selection's merge without passing the block where
the arms meet. In the loop {1}, {2, 4}, {3, 4}, {4, 5}, {1, 6}, {1}, {}
from #2642 (latches 4 and 5) the selections at 1 and 2 both merged at 4.
splitSharedMergeBlocks gave 2 a forwarding merge block, recomputed 4 for
it because 3 continues through 5, and repeated until "CFG shared merge
splitting exceeded budget: originalBlocks=9 currentBlocks=45
splitBudget=36".

When that post-dominator is inside the loop construct, findSelectionMerge
now takes the arms' nearest common post-dominator over the paths of the
iteration that reach it, so paths that leave through the continue block
or the loop's merge no longer move the merge past the arms' join. When
no arm leaves early the result is the same block as before. The loop
structures with two forwarding blocks and no clones or route variables;
so do three latches, the selections on the false side, and an if-else
whose one arm continues.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-11 10:00:06 -03:00
LeandroLP23 ce0239c940 fix(libkernel): return lseek errors for directory descriptors instead of throwing
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-11 14:59:57 +02:00
Hussein Kadhim 6db8c81aae docs(technical-debt): describe the Windows directory snapshot lifetime exactly 2026-10-11 14:59:57 +02:00
Hussein Kadhim cb6dcbf844 fix(libkernel): keep directory lseek off the shared lock and report offset overflow
lseek on a non-directory descriptor no longer takes the directory table lock when no directory is open, and a listing is read under the descriptor's own lock. SEEK_CUR with offset 0 only reports the position, and an overflowing SEEK_CUR offset reports EOVERFLOW.
2026-10-11 14:59:57 +02:00
Hussein Kadhim 7a68e11ab4 fix(libkernel): rewind Windows directory descriptors on lseek
lseek on a directory descriptor returned 0 without moving the listing, so getdents after lseek(fd, 0, SEEK_SET) reported nothing.
2026-10-11 14:59:57 +02:00
LeandroLP23 23dad48559 docs(debt): record the RDNA2 sweep for every f16 rounding mode of v_fma_mixlo/mixhi_f16
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-11 14:59:56 +02:00
AlxcBTW bc517d6058 fix(shader): give an exact zero mix f16 sum -0 when rounding toward -infinity
With f16 rounding toward -infinity, v_fma_mixlo_f16 and v_fma_mixhi_f16
gave +0 for an exact cancellation such as 1.0 * 1.0 + -1.0, because the
f64 sum is computed to nearest. RDNA2 gives -0 there, as IEEE 754 does
for an exact zero sum rounded toward -infinity, measured on gfx1036 in
#2631. An exact zero sum now gives -0 in that mode unless both the
product and the addend are +0. A nonzero result that rounds to zero
keeps its sign, so a tiny positive sum still gives +0.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-11 14:59:56 +02:00
AlxcBTW f22b9fa02a fix(shader): round v_fma_mixlo_f16 and v_fma_mixhi_f16 in every f16 rounding mode
The f16 forms of v_fma_mix threw for any FLOAT_MODE with an f16 rounding
other than to nearest even. ps5-opengl's shaders run with FLOAT_MODE
0xcc, f16 rounding toward zero with f16 denormals kept, so PPSA99005
stopped at its first draw (#2631).

The exact product-sum, already computed in f64 with round to odd, is now
rounded once in the mode's direction: scaled by the f16 step at its
exponent, truncated, floored or ceiled, and scaled back. A result beyond
65504 becomes infinity or 65504 as IEEE 754 gives for the direction. On
RDNA2 (gfx1036) -1.5 * 2^-24 + 2^-126 gives 0x8002 with round toward
-infinity, and this gives the same. Flushed f16 denormals still throw.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-11 14:59:55 +02:00
ducloc080202 e9736282f7 fix(libc): name the throw site in unhandled exception reports 2026-10-11 19:59:31 +07:00
XairRrR 79c8d36901 fix(agc): reject constant color factors and memory-writing stages in split SWAP_ALT blends
Review follow-up to the 8_8 SWAP_ALT blending. The second channel of
such a target holds the guest's alpha. Vulkan applies the green blend
constant to it for CONSTANT_COLOR and ONE_MINUS_CONSTANT_COLOR, where the
guest's alpha equation uses the alpha constant. Decoding now throws for
these factors on a SWAP_ALT 8_8 target, unless the equation is MIN or
MAX, which ignore factors.

The second pass of a split draw runs every stage again, not only the
pixel shader, so a vertex or geometry stage that writes memory would
write twice. The memory-write check (now ShadersWriteMemory) covers all
the draw's stages.
2026-10-11 14:58:57 +02:00
jweidenh 82c04e4027 fix(shader): keep sRGB comparisons in the emulated runtime mode
(cherry picked from commit 5377951c552f2313c8f7a52b57bd7a54c5f7fb7f)
2026-10-11 12:54:54 +00:00
XairRrR 94cffec3a7 perf(agc-driver): prepare shader ABI variants before taking the preparation lock
A shader preparation transaction took the global writers lock when it
was constructed and kept it to its end. ResolveShaderAbi, reached from
sceAgcCreateInterpolantMapping and sceAgcLinkShaders, compiled its
variants inside such a transaction, so every game thread creating or
linking shaders waited behind one compile: Uncharted's stalled frames
spent about half a second each in shader registration.

The root transaction now takes the lock on its first Read, Edit or
Hold. ResolveShaderAbi prepares the variants before reading the
prepared state when its ABI was not committed yet. Registry
publication holds the lock as before: PublishRegisteredShader holds
it, and RegisterShader holds it before the driver mutex, so the lock
order is unchanged. Commit takes no lock: a transaction with changes
already holds it.
2026-10-11 14:54:48 +02:00
lorkydey cb9932007a fix(relinker): ignore no-op executable relocations 2026-10-11 14:53:59 +02:00
Hannah Lyons bf4cb4974d feat(libScePosixForWebKit): implement fnmatch 2026-10-11 08:52:48 -04:00
hugodearaujo bdf67fcc49 feat(libs): declare the PS VR2 exports PPSA15878 imports
Propagation: Paradise Hotel (PPSA15878) does not load on main: its
executable imports 15 PS VR2 functions that no library exports, the
first reported being sceVrTracker2GetPlayAreaOrientedBoundingBox
(snYs7Nf-RKk). Declare the nine libSceHmd2 reprojection and gaze
exports, three libSceVrTracker2 exports and three scePadVrController
trigger effect exports, without parameters, as throwing stubs. Names
come from the aerolib NID list.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-11 09:51:00 -03:00
hugodearaujo a61e2d35dd fix(libSceSysmodule): return INVALID_VALUE for module id 0
Measured on a PS5 (firmware 13.60): sceSysmoduleIsLoaded,
sceSysmoduleLoadModule and sceSysmoduleUnloadModule with id 0, and the
Internal and InternalWithArg calls with id 0 or 0x80000000, return
0x805A1000 and leave the WithArg result untouched. They threw.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-11 09:51:00 -03:00
Hannah Lyons 0e9a8dd949 feat(libkernel): export execv 2026-10-11 08:50:20 -04:00
Adrià Franch b33d2e3736 docs(debt): record the disabled user VGPR enable alias in sceAgcCreatePrimState
Co-Authored-By: Claude <noreply@anthropic.com>
2026-10-11 12:49:38 +00:00
MarcZX100 a9575dc70b fix(agc): normalize disabled user VGPR special offset 2026-10-11 12:49:38 +00:00
Abdulrahman Elkordy 8b0b78f529 test(libkernel): don't require restoring the directory time on Windows
The empty-path utimes check restores the working directory's write time
afterwards and requires the restore to succeed. With MinGW,
std::filesystem::last_write_time fails with EACCES when setting a
directory's time (a file's works), so guest_filesystem aborts there on
Windows. The restore stays, only its result is no longer checked.

Claude-Session: https://claude.ai/code/session_012SLQbhAiexxW6TtjYToW8a
2026-10-11 15:49:25 +03:00
MarcZX100 9e8b5a21bc fix(shader): allow constant-zero sRGB comparisons 2026-10-11 12:49:23 +00:00
ArjenS-LA 859736aa0e fix(net): preserve truncated UDP receives on Windows 2026-10-11 09:48:50 -03:00
MarcZX100 b316c9885d fix(libc): resume host foreign exceptions with host unwinder 2026-10-11 12:48:47 +00:00
MarcZX100 5550ca63dd fix(agc): wait for shutdown at shader ABI entrypoints 2026-10-11 12:48:40 +00:00
Hussein Kadhim d4301cf9b3 fix(libkernel): parse and print inet text addresses by the guest rules
inet_pton and inet_ntop no longer call the host resolver library, whose
accepted forms and output differ from the guest's (leading zeros,
zone ids, IPv4-embedded printing).

(cherry picked from commit 058d808ae7c43042d0ffd5fad76062a2df16b871)
2026-10-11 12:46:21 +00:00
pushkarreddyy 06f84010bb feat(libc): implement reallocf
Two catalog titles stop on the absent libSceLibcInternal export reallocf
(YMZO9ChZb0E) on main 0f863c10:

- PPSA97510 PSXS5 2.2.0
- PPSA98510 SwanStationPS5 1.1.3

    FAIL: unresolved ELF import YMZO9ChZb0E from libSceLibcInternal.prx

reallocf follows FreeBSD 11 lib/libc/stdlib/reallocf.c (freebsd-src
stable/11 5ed7eb0d97ba4436218e810f61bd059acba984c2) on top of the guest
realloc: it reallocates through the application heap, and when realloc
fails (the application allocator returns null or the default heap
rejects the size) it frees the block through the same allocator, sets
ENOMEM and returns null. Size 0 frees and returns null as realloc does
here, so the block is not freed twice. Other heap failures throw, as
for realloc. The NID matches tools/nid_names.py and aerolib.

The application heap tests cover grow, shrink, a null pointer, size 0
and failure with both the replacement and the default allocator.

Co-Authored-By: screamm <noreply@github.com>
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-10-11 18:16:07 +05:30
Mouad a553e22638 feat(agc): write memory for WRITE_DATA with DST_SEL 3
Killzone: Liberation (PPSA11142) writes its frame fence with
`sceAgcDcbWriteData(dst 6, cache policy 3, write confirm)`, which the
SPRX-confirmed encoding turns into WRITE_DATA with DST_SEL 3 and a label
address in the title's memory that RELEASE_MEM and WAIT_REG_MEM then
use. The validator rejected DST_SEL 3 as the GDS; it now writes guest
memory like DST_SEL 5, resolves as a label, and the title runs past its
first frame. TechnicalDebt records where the semantics come from.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
(cherry picked from commit 9c53b7f6e8ce2ca81d8f0fa551d12632acfeb60d)
2026-10-11 12:45:26 +00:00
Adrià a11c8f7f70
Merge pull request #3511 from krishalivaibhav/codex/fix-imgui-submodule-config
build: remove accidental imgui gitlink
2026-10-11 14:42:34 +02:00