qsort was a heapsort. It sorted correctly, but elements that compare
equal ended in a different order from FreeBSD's Bentley-McIlroy qsort,
in 18947 of 20000 random arrays with repeated keys, and below 7
elements, where FreeBSD's insertion sort keeps equal elements in
place, a heapsort does not. qsort now follows FreeBSD 11 qsort.c,
including its comparator call sequence.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VZWLdTjf1S57iLgn2rcaFb
pr_overlap only skipped a pair when one pull request named the other
directly. In a stack where #3 depends on #2 and #2 on #1, #1 and #3 were
reported as overlapping, and two pull requests built on the same #1 were
reported for the files and exports both inherit from it. Dependencies are
now followed through open pull requests, and what a shared dependency adds
is left out of the same-file and same-export columns.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0189deyapHNNqKQJboZBJQei
DecodeInstruction did not treat 0F 0F as having a ModRM byte, so a
RIP-relative 3DNow! operand was not reported to the analyses and the
--to-intel stub relocation that read HasRipRelativeDisp.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VZWLdTjf1S57iLgn2rcaFb
0F 0F was decoded as a two-byte instruction. 3DNow! instructions are
0F 0F ModRM [SIB] [displacement] imm8, the trailing byte selecting the
operation (AMD64 Architecture Programmer's Manual Volume 3, Appendix A,
3DNow! opcodes).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VZWLdTjf1S57iLgn2rcaFb
sceKernelFsync returned the host fsync or _commit result, so a failure
returned -1 instead of an SCE error code, and a guest socket descriptor
reached the host call. fsync then set the guest errno from the host
errno rather than from that result.
Handle sockets and return SCE error codes as sceKernelFdatasync does
(EINVAL for an open socket, EBADF for a closed one or an unknown
descriptor), and have fsync take the errno from sceKernelFsync's result
like the other POSIX wrappers.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Ha6Tsy62AFUyp9a5Mf7vjA
GuestError passed host error values up to 34 through and reported every
other value as EIO, so readlink failed with EIO for a name that is too
long or a symbolic link loop, and a host EAGAIN would have been reported
as the guest's EDEADLK. The values whose numbering differs are now
mapped to FreeBSD's.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Ha6Tsy62AFUyp9a5Mf7vjA
Root ignores the file mode, so truncating a file with only the owner
read bit succeeds and guest_truncate aborted when the suite ran as root,
as it does in containers. The read-only cases now run only for other
users and the test says on stderr when it skips them.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Ha6Tsy62AFUyp9a5Mf7vjA
Ubuntu's GCC links with --as-needed, so a test that calls nothing in
libc.prx directly dropped it from DT_NEEDED and satisfied the prx
libraries' __cxa_* and __gxx_personality_v0 references from the static
libstdc++ instead. Those copies interpose libc.prx's, so exceptions
thrown inside the prx libraries were searched by libgcc and resumed by
the guest unwinder, which aborted guest_kernel_stack_protect. libc now
propagates to every consumer of a prx with --no-as-needed on Linux.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Ha6Tsy62AFUyp9a5Mf7vjA
SceErrorFromErrno in the libkernel file functions passed host errno
values 1-34 through and turned every other value into EIO. Linux numbers
EAGAIN 11, which is FreeBSD's EDEADLK, so a read from an empty
non-blocking pipe returned SCE_KERNEL_ERROR_EDEADLK, and ENAMETOOLONG,
ELOOP, ENOTEMPTY, EDQUOT and EOVERFLOW, whose host values differ from
FreeBSD's, all became EIO.
Map those host values to the guest's FreeBSD numbers, as
SceIoErrorFromErrno in Open.cpp already does for EAGAIN, EDEADLK,
EDQUOT and EOVERFLOW. The guest constants the callers pass are all at
most 34 and never 11, or GUEST_ENOTEMPTY, so they are unchanged.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Ha6Tsy62AFUyp9a5Mf7vjA
Two defects found in review of the Linux delivery:
A raise right after scePthreadCreate reached the new thread before
RunThread set currentThread, so scePthreadSelf() in the handler adopted
a second handle, and could deadlock on glibc's thread lock when the
signal interrupted pthread_getattr_np. The creator now blocks all
signals around the std::thread construction, so the child starts with
them blocked, and RunThread restores the creator's mask once the thread
is registered, as libthr does. A raise in that window stays pending and
is delivered just before the entry runs.
A handler that set reserved MXCSR bits made rt_sigreturn fail with
SIGSEGV. The MXCSR the handler leaves is now masked with the frame's
MXCSR_MASK (0xffbf when it reads 0), as FreeBSD's fpusetregs does, on
both platforms; Windows also keeps CONTEXT.MxCsr equal to
FltSave.MxCsr.
guest_raise_exception raises right after each of 50 thread creations and
checks scePthreadSelf() in the handler, and its context round trip sets
a reserved MXCSR bit and FZ and checks that only FZ is kept.
AI-assisted: yes
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LwJx7AHrSUaMGSpEGhL1Kb
sceKernelRaiseException threw on Linux, so a title whose garbage
collector stops threads with it (Unity's PS5Util raises SIGUSR1 on each
thread and reads mc_rsp from the handler's context) could not run there.
The raise now sends the host SIGUSR1 to the target thread with
pthread_kill. The host handler, installed on first use with SA_SIGINFO
and SA_RESTART, builds the FreeBSD-layout ucontext from the interrupted
registers and the FXSAVE area, calls the guest handler on the target's
own stack and writes the registers back, so the handler's changes reach
the interrupted code, as they do on Windows. errno is left as the
handler leaves it, as libthr does.
A raise on another thread takes the target's join lock with the host
signal blocked and returns ESRCH once the thread has finished, so a
detached thread's pthread_t is never signalled after it exits. The
pthread_t is recorded when the thread is created or adopted. Handlers
are now lock-free atomics, as the host handler reads them.
guest_raise_exception now runs on every platform. It also checks that
r13 and xmm8 reach the handler and that r12 and xmm8 written by the
handler reach the interrupted code.
AI-assisted: yes
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LwJx7AHrSUaMGSpEGhL1Kb
Link libc, configure Windows unwinding for the test so its runtime_error
checks are caught, and run it from libSceFiber's output directory so
openHostModule finds the unpatched libSceFiber.prx next to the modules the
test already loads.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01K9MzdVqDf6wHUKzNymQSze
The guest's unsigned long is 64 bits. _Stoul was declared with the
host's unsigned long and returned std::strtoul, which are 32 bits on
Windows (LLP64): "4294967296" clamped to 4294967295 with ERANGE and
"-1" gave 0xffffffff, so a guest std::stoul threw out_of_range on values
the console accepts. It now returns std::uint64_t from std::strtoull,
as strtoul_nid_postfix and _Stoull already do; on Linux nothing changes.
The binary-prefix check stays in front of the host call.
Reported in #2424 by AchrafReyani; the same change was proposed in #2442
by SurajKhanna, whose two guest_math cases are taken here. Folded in at
MarcZX100's suggestion on #1459.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
wcstol, wcstoll, wcstoul and wcstoull parse the ASCII prefix of the
guest's UTF-16 text with std::strtoll and std::strtoull, which glibc 2.38
and later bind to the C23 __isoc23_* functions: wcstol(u"0b101", &end, 0)
returned 5 with the end pointer after the whole string. They now check
StopAtBinaryPrefix_nid_no_patch first, like the narrow functions, and the
end pointer maps back through ParseAsciiPrefix as before.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
C17 has no binary prefix: with base 0 or 2, strtol("0b101", &end, base)
reads the subject "0", returns 0 and leaves end at the 'b'. With glibc
2.38 or later, g++ (which defines _GNU_SOURCE) binds std::strtoll,
strtoull, strtoul, strtoimax and strtoumax to the C23 __isoc23_*
functions, which accept 0b/0B: the Linux exports returned 5 and
consumed the whole string. The Windows UCRT already follows C17, so the
same guest call gave different results on the two hosts.
strtol, strtoul, strtoll, strtoull, _Stoull, strtoimax, strtoumax and
_Stoul now return 0 with the end pointer after the '0' when, after
white space and an optional sign, the text starts with 0b or 0B and a
binary digit, in base 0 or 2. Everything else still goes to the host
function. The scanf family's %i has the same glibc behaviour; it is
recorded in TechnicalDebt.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
On a host without IPv6, socket(AF_INET6) fails with EAFNOSUPPORT, so
guest_sce_net aborted at its first IPv6 socket and never ran the TCP,
UDP, epoll, sendmsg/recvmsg, resolver and NetCtl checks after it.
When sceNetSocket reports guest EAFNOSUPPORT (47) for the IPv6 socket,
skip those socket checks, run the rest of the test, and exit with 77,
which ctest reports as skipped. Hosts with IPv6 run every check.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Ha6Tsy62AFUyp9a5Mf7vjA
llvmpipe builds the high dword of the shader clock with a left shift by
32 (emit_clock in Mesa's lp_bld_nir_soa.c), so it is always 0 and
s_memtime and s_memrealtime wrap every 2^32 ns. A pass of
agc_driver_shader_clock whose two reads straddle a wrap failed with
"memtime: lane N went back from 4294921902 to 3823"; dispatching right
before the boundary fails every lane of that pass.
On llvmpipe compare the low dwords modulo 2^32, which stays correct if
Mesa fixes the shift. Other devices keep the 64-bit comparison.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Ha6Tsy62AFUyp9a5Mf7vjA
When a queue worker failed, it published the failure and woke the idle
waiters before failing the flips of the submission it was executing.
A thread returning from AgcDriverWaitIdle with that failure could still
see one of those flips neither completed nor failed, which made
agc_driver_flip fail with "failed flip was completed successfully" in
2 of 240 runs under four-way parallel load on lavapipe.
Fail the executing submission's flips first, as ReportFailure already
does for the pending submissions it drops before it notifies.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Ha6Tsy62AFUyp9a5Mf7vjA
The decoder threw on the GFX10.1 DS src2 opcodes 0x80-0x8b, 0x8d,
0x92, 0x93 and 0x95. Each reads DS[B], where B is the address plus
four times the 15-bit signed offset in offset1[6:0]:offset0, and
applies the matching operation to DS[A]: add, sub, rsub, inc, dec,
signed and unsigned min and max, and, or, xor, f32 min, max and add
through the 32-bit LDS atomics, and a plain write for
ds_write_src2_b32. The form that takes the offset from the address
bits (offset1[7]), the 64-bit forms and GDS still throw.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
No request reaches the network, so sceHttpsSetSslVersion has no TLS
connection to configure, sceHttpSetRedirectCallback and
sceHttpSetCookieRecvCallback register callbacks that are never called,
and sceHttpsGetSslError reports error 0 with detail 0. A null errNum or
detail returns SCE_HTTP_ERROR_INVALID_VALUE like sceHttpGetLastErrno.
Signatures follow shadPS4.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
sceKernelGetModuleInfoForUnwind and sceKernelGetModuleInfoFromAddr each
parsed .ehmeta and the eh_frame_hdr it names. Both now read them through
Module/EhFrame.hpp, so a bad table fails the same way in both: an
eh_frame_hdr version other than 1, an indirect or non-absptr/pcrel
encoding, a 64-bit record length or anything outside the image throws.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JkiyF6p7oDAaTtVe8ci5zP
hypotf now widens both arguments to double and calls the double hypot.
The float-to-double conversion raises FE_INVALID for a signaling NaN and
quiets it, so hypotf(sNaN, inf) returns +inf with the invalid flag set in
either argument order, matching the PS5 libc routine. Before, MinGW UCRT's
hypotf returned +inf without the flag and glibc's returned NaN.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Scr6DkuJDqiUcJHr9mJv6T
Textures in SW_256B_D, SW_4KB_D, SW_64KB_D, SW_64KB_S_T, SW_64KB_D_T,
SW_4KB_S_X and SW_4KB_D_X (tile modes 2, 6, 10, 17, 18, 21 and 22)
threw while their T# was decoded. They are detiled with address
equations generated from AMD addrlib's GFX10 swizzle patterns for the
same 16-pipe non-RB+ configuration as the 64 KiB XOR table, and share
the block shape and mip tail placement of the standard mode of their
block size. The pipe/bank XOR base check of the XOR and T modes now
uses the block size.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
image_gather4_lz(_o) on a 1D array view threw. The 1D gather emulation
now takes the width from the array view's size, keeps the layer
coordinate and samples both texel centres of that layer, so 1D array
gathers return the same footprint as 1D ones.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Every library CMakeLists.txt ended with the same block removing -static,
-static-libgcc and -static-libstdc++ from CMAKE_EXE_LINKER_FLAGS on MinGW,
because core/libs/CMakeLists.txt only removed them after adding the library
directories. Remove them before the libc and library directories are added
so each directory inherits the stripped flags, and drop the 52 copies.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017pTZqAyVSZy2FZmaqakPHZ
Comparison sampling of a color texture threw on the _o, _b and _cl
forms and on a sampler LOD bias. The emulation fetches the texels
itself, so the 6-bit offsets of the address are added to the point or
bilinear texel indices, as on the hardware and in Vulkan. The emulation
runs only at level zero or on a single-level view, where an LOD bias or
clamp cannot select another level, so they are accepted with no effect.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
EmitImage listed all 27 image atomic opcodes by hand to reach
EmitAtomicOp, although it already looks up ImageOpcodeInfoOf for the
instruction. Route every opcode whose access is ImageAccess::Atomic to
EmitAtomicOp before the switch; the set of opcodes is unchanged.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017pTZqAyVSZy2FZmaqakPHZ
libSceAvPlayer.native/Export.cpp was a byte-identical copy of
libSceAvPlayer/Export.cpp. Point add_sce_avplayer_library at the guest
directory's Export.cpp, as the Audiodec and Font library functions do, and
remove the copy.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017pTZqAyVSZy2FZmaqakPHZ
Nine SPIR-V backend sources each defined an identical FailEmit in an
anonymous namespace. Declare it once in SpirvEmitterHelpers.hpp and
define it in SpirvEmitterHelpers.cpp; the message is unchanged.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MBXJqzgohLeVAeHsn4Jpm7
Mount, unmount, param, icon and mount-info calls read and wrote the
global mount slot table without a lock, so two threads mounting at
once could take the same slot and one would later fail to unmount its
own mount point. Guard the table with a mutex and make the initialization
count atomic.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MBXJqzgohLeVAeHsn4Jpm7
3D textures in the 64 KiB Z and S XOR swizzles threw. As in AMD
addrlib's GFX10 rules, a Z_X volume is thin: each depth slice is laid
out like an array slice with the 2D Z_X equation, as the R_X and D_X
volumes already were. An S_X volume is thick: it takes the standard
64 KiB thick block and mip tail with its own S3 XOR equation, generated
from addrlib for the same configuration as the other equations.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A T# of type 12 (1D array) threw while decoding. It now decodes to a
1D array dimension, checked like a 2D array with a height of one, and
holds depth + 1 layers laid out as a 2D array's. Its Vulkan image is
1D with that many layers, viewed as VK_IMAGE_VIEW_TYPE_1D_ARRAY for
sampling and storage, and the recompiler declares a 1D array shape for
arrayed 1D image resources instead of failing.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
image_gather4_lz_o on a 1D view threw. The 1D gather emulation picks
the two texels around the coordinate itself, so the 6-bit x offset of
the address is added to the left texel index before both texel
centres are sampled, as the hardware offsets the footprint.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
sceAgcWriteDataPatchSetDst, sceAgcWriteDataPatchSetCachePolicy, their
Async forms and sceAgcAsyncWriteDataPatchSetAddressOrOffset threw. They
now rewrite a WRITE_DATA packet in place: the destination in the
graphics (sceAgcDcbWriteData) or compute (sceAgcAcbWriteData) encoding,
the cache policy in bits 25-26 and the address in dwords 2-3, so the
patched packet equals the one written with those values. A register
destination is rejected when the packet requests write confirmation,
as when the packet is written.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The 106-key (Japanese) arrangement threw. Its alphanumeric layer now
follows the JIS layout of the HID usages: the symbol keys right of the
digits and letters, the Ro key (0x87) and the Yen key (0x89). With the
Kana LED set it still throws, as the kana the console returns are
unknown.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The relinker redefined 61 ELF constants 93 times across seven files,
38 of them already in elfpatcher's ElfConstants.hpp. Add the missing
dynamic tags, relocation types and symbol constants to that header and
remove the local copies; every value is unchanged. strict_nid_filter_tests
compiles these sources and now gets the elfpatcher include directory.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MBXJqzgohLeVAeHsn4Jpm7
On Linux scePthreadExit called pthread_exit, whose forced unwind runs
the personality routine of every guest frame. Those resolve to
libc.prx's __gxx_personality_v0, which cannot read libgcc's unwind
context and aborts, so guest_thread_self crashed on Linux.
Record a jump target in the thread start routine and longjmp back to it
from scePthreadExit instead. Like _endthreadex on Windows, this skips
the guest frames without unwinding them; the start routine still
releases the thread normally. Threads not created by scePthreadCreate
keep the pthread_exit fallback.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018emyZ4Rk8yoSJvxTFBe4DL
Bring in the resolved#25 branch, which already carries upstream main
including boykopovar/AnyPS5#10, and re-apply the KernelErrors.hpp
refactor onto the rewritten files:
- Equeue: drop the local EQUEUE_ERROR_* constants and use the shared
SCE_KERNEL_ERROR_* names.
- Pthread Attr/Thread: drop local error constants and include
KernelErrors.hpp.
- Pthread Cond/Mutex: take upstream; they no longer define local
SCE_KERNEL_ERROR_* constants.
- Semaphore: drop KERNEL_SEMA_ERROR_* in favour of KernelErrors.hpp.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018emyZ4Rk8yoSJvxTFBe4DL
Resolve conflicts with boykopovar/AnyPS5#10 (sce module loading) and
later upstream changes.
- Pthread Cond/Mutex: take upstream. It already releases mutex
ownership across condition waits, returns ETIMEDOUT 0x8002003C, and
rejects unlocks from non-owners for every mutex type.
- Pthread Thread: keep upstream's lifecycle, Windows adoption and job
affinity; re-apply the POSIX fixes on top: reference-counted
release on join/detach/exit, self-join rejection on both platforms,
and scePthreadSelf adoption for threads not created by
scePthreadCreate.
- Semaphore: keep upstream's TimedWait::Condition and wait tracing;
re-apply sceKernelDeleteSema waking waiters with EACCES.
- Relinker: keep --windows-gui alongside upstream's --skip-sce-module,
trampoline-aware Patch signature and new Python tests.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018emyZ4Rk8yoSJvxTFBe4DL