Porpoise 2.7 (PPSA99764) stops at load on main 0f863c10:
FAIL: unresolved ELF import oc98+zOImus from libkernel_sys.prx
oc98+zOImus is pathconf (tools/nid_names.py, aerolib.csv at
zecoxao/sce_symbols 2883963a). It is exported from libkernel_sys next to
link and readlink.
The lookup follows FreeBSD 11's kern_pathconf and namei (release/11.0.0,
671fb7df): links are followed, a path of 1024 bytes or more or a
component over 255 fails with ENAMETOOLONG, a missing path with ENOENT.
The values are the constants of FreeBSD 11's UFS ufs_pathconf, which
vop_stdpathconf shares where both answer. Names whose UFS value depends
on the mount, the kernel options or the page size, or on which UFS and
vop_stdpathconf disagree, throw; other names fail with EINVAL. The
console's filesystem values are unverified and recorded in
TechnicalDebt.
Co-Authored-By: Claude Fable 5.1 <[email protected]>
PPSA30601 (Resonance) stops at the throwing stub. The four int* arguments follow
OpenOrbis' libkernel.h, the Orbital type database and SharpProspero; the values
follow KytyPS5 (2048 entries of 2 MiB per side) without its accounting of used
entries, listed in TechnicalDebt.md. A null pointer returns EFAULT.
Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
There is no PSN sign-in, so the code getter answers SCE_NP_ERROR_SIGNED_OUT
instead of throwing; its parameters are unknown and not read. Minecraft
(PPSA17221) calls it after its sign-in dialog and treats the result as
offline play. The request, token and wait calls are left to #3604.
Co-Authored-By: Claude Fable 5.1 <[email protected]>
ProsperoTV (PPSA99003) stops after its menu opens because poll threw for
the read end of a pipe it polls next to its sockets. poll now reports pipe
readiness as FreeBSD's pipe_poll does: readable when data is buffered,
POLLHUP once the other end is closed, writable when PIPE_BUF bytes are
free. On Windows the pipe is checked with NtQueryInformationFile while the
sockets are waited on in 1 ms slices; on Linux the host poll waits on both.
A closed descriptor below the socket range reports POLLNVAL.
Before: raise, kill and pthread_kill delivered a signal at once or failed
with EINVAL, nothing stayed pending, and pause, sigwait, sigwaitinfo and
sigtimedwait called NotImplemented_nid_no_patch.
Now: a process-wide pending set holds signals 1 to 128. A signal raised
while it is blocked stays pending and is delivered when _sigprocmask
unblocks it, taken by sigwait, sigwaitinfo or sigtimedwait, or delivered by
pause, which runs its handler on the calling thread and returns -1 with
EINTR. pthread_kill to another thread leaves the signal pending for
whichever thread waits for it and answers ESRCH for a handle that is not a
live guest thread. sigtimedwait follows FreeBSD's sigtimedwait(2): EAGAIN
on timeout, EINVAL for a tv_nsec outside 0 to 1000000000 while nothing is
pending, and an indefinite wait with a null timeout.
On an RTX 3060 (Windows, driver 591.86) a dispatch never finishes when
the lanes of read_bda_span split between its in-place dword loads and
its per-dword byte fallback, which calls read_bda_dword_bytes: Windows
resets the GPU and the device is lost. The two were the arms of one
selection in the DontInline function. They are now two selections, the
loads under the span's condition and the fallback under its negation,
joined after both. Loads, lookups, faults and stops are unchanged for
every lane; only the SPIR-V control-flow shape changes (SPIR-V
specification 2.11, structured control flow). Every stage except mesh
shaders is emitted as SPIR-V 1.3, and OpSelect chooses between
composites with a scalar condition only from 1.4 on, so the join stays
a selection.
The same hang and fix were reported in #3291 on an RTX 4060 Laptop GPU
(Windows, driver 591.86) and an RTX 5060 (Linux, driver 590.48.01). An
RTX 4070 Laptop GPU on driver 616.92 does not hang with either shape.
The driver-side cause is unknown, so the shape is recorded in
docs/dev/debt/shader.md.
On main the hang fails nine tests on the RTX 3060, in two ways.
agc_driver_{flat,global}_loads{,_x2_x3,_x4} and
agc_driver_flat_apertures_{2,5} abort after 64 to 71 s: the lost batch
keeps its lease, so teardown waits 60 s for the pinned guest allocation.
agc_driver_pixel_interlock fails after about 4 to 7 s with
vkDeviceWaitIdle returning VK_ERROR_DEVICE_LOST (-4) and never reaches
the pin wait. All nine pass with the change.
Fixes#3291
Co-Authored-By: Claude Opus 5.5 <[email protected]>
FreeBSD's vfs_kqfilter checks neither the vnode type nor fflags, so the
registration is valid; it is only delivered for a move between directories,
which the Windows directory handle cannot tell from a removal plus an addition.
Also moves the TechnicalDebt entries to docs/dev/debt after main split the file.
Co-Authored-By: Claude <[email protected]>
sceNetSend, sceNetSendto, sceNetRecv, sceNetRecvfrom, sceNetRecvmsg and
sceNetSendmsg failed with EOPNOTSUPP for any flag other than MSG_PEEK on
a receive, so a game polling a socket with MSG_DONTWAIT got an error on
every call instead of its data or EWOULDBLOCK.
FreeBSD 11.4 defines the flag in sys/sys/socket.h:
#define MSG_DONTWAIT 0x80 /* this message should be nonblocking */
and soreceive_generic() (sys/kern/uipc_socket.c) treats it like a
non-blocking socket for that one call:
if ((so->so_state & SS_NBIO) ||
(flags & (MSG_DONTWAIT|MSG_NBIO))) {
SOCKBUF_UNLOCK(&so->so_rcv);
error = EWOULDBLOCK;
goto release;
shadPS4's sceNet uses the same value (ORBIS_NET_MSG_DONTWAIT 0x80).
On Linux and macOS the flag now maps to the host's MSG_DONTWAIT, alone
or with MSG_PEEK on a receive. Winsock has no per-call non-blocking
flag, so Windows keeps failing with EOPNOTSUPP for it; TechnicalDebt
records that. Other flags still fail with EOPNOTSUPP.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
The trace gets a gpu track: one slice per recorder batch from its timestamp
pair, and with APS5_PROFILE_GPU=1 one per command class range under the
[gputime] class names. The GPU clock is mapped onto the CPU clock from
calibrated timestamps (VK_KHR_calibrated_timestamps or the EXT version,
enabled only when a trace switch is set) taken when the window opens and
when it closes. A traced thread's wait for the GPU mutex becomes a
GpuMutex.wait.<site> slice, and the shader preparation threads are traced
with smaller buffers.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
PS5MC (PPSA99420) imports setitimer (hPWDGx8ioXQ, aerolib) at registry
index 472, after tcsetpgrp and before getitimer. Predicted stop:
"FAIL: unresolved ELF import hPWDGx8ioXQ from libkernel.prx".
setitimer follows FreeBSD 11.4 kern_time.c (8c639945) sys_setitimer and
kern_setitimer: EINVAL for an unknown timer and for an itimerfix failure
or more than INT32_MAX / 2 seconds; a zero value clears the interval and
disarms; a null value reads the timer, EFAULT when the output is null too.
ITIMER_REAL shares the alarm state, now with an interval that re-arms it
as realitexpire does; alarm clears it, as FreeBSD's alarm.c does.
Guest SIGALRM handlers are not run, so an expiry with a handler, or with
SIGALRM blocked (signals are never left pending), throws naming the
interval; SIG_IGN drops it and the default disposition exits with 142,
as alarm already did. Intervals below 1 ms throw (itimerfix rounds them
to tick / 16 and the console's hz is unknown). ITIMER_VIRTUAL and
ITIMER_PROF throw when armed and read and disarm as zero.
Co-Authored-By: Claude Fable 5.1 <[email protected]>
UFC 6 (PPSA23566) imports sceNetResolverAbort (#992, #1502); Palworld
(PPSA23126) and LEGO Horizon Adventures (PPSA14632) import
sceNetResolverStartNtoaMultipleRecords.
Signatures and behaviour follow shadPS4 811bfcd7d17e
(src/core/libraries/net/net.cpp, net_resolver.cpp); the abort signature
also matches SharpProspero Interop/Net/Socket.cs.
sceNetResolverStartNtoaMultipleRecords shares the lookup of the Ex form
and, like it, throws for any flag. sceNetResolverAbort returns EBADF for
an unknown resolver and throws for flag bits other than NTOA (1) and
ATON (2) preservation. Host lookups cannot be interrupted, so an abort
during a running lookup makes it fail with EINTR when the host call
returns, without writing its output; with nothing running, the
preservation flags make the next lookup of that kind fail with EINTR.
Co-Authored-By: Claude Fable 5.1 <[email protected]>
(cherry picked from commit bcc8be8a58aa6a9e6b7c288d8a90af6ed63837aa)
Review of #3787 asked for no retries after an error in Jit.cpp.
Linux: memfd_create is called once with MFD_CLOEXEC. MFD_EXEC was
tried first and dropped on EINVAL; the flag only sets the file's execute
permission bits (Linux 6.3 and later), not whether the object maps
PROT_EXEC, which is decided by the mapping protection, as for the direct
memory memfd in DirectMemory.cpp. A one-shot choice from the headers
would fail on older kernels, so the flag is dropped; TechnicalDebt
records it.
Windows: the delete-on-close backing file is named from the process id,
a process-wide atomic counter and the performance counter, so CREATE_NEW
cannot meet an existing name, and any CreateFileW failure throws with
the Win32 error instead of looping up to 64 times on ERROR_FILE_EXISTS.
The descriptor stays a CRT descriptor on the file, so close, dup and
dup2 keep working as before.
Co-Authored-By: Claude Fable 5.1 <[email protected]>
The three JIT shared memory exports (avvJ3J0H0EY, MR221Mwo0Pc,
YKT49TOLQWs) are absent imports of three homebrew titles that cannot
finish loading without them. Predicted next stops (registry order):
- VLC PPSA85300 after getdtablesize (idx 354):
"FAIL: unresolved ELF import YKT49TOLQWs from libkernel.prx"
(Map idx 452, Create idx 462)
- XPSemu PPSA97358 after tcsendbreak (idx 214):
"FAIL: unresolved ELF import avvJ3J0H0EY from libkernel.prx"
(Create idx 398, Map idx 399)
- RetroArch PPSA99169:
"FAIL: unresolved ELF import avvJ3J0H0EY from libkernel.prx"
(Create 476, Alias 477, Map 478)
XPSemu and VLC (ps5/compat/mmap.c, __wrap_mmap) create an object for
every anonymous PROT_EXEC mapping (QEMU's TCG buffer) and map it with
the same protection, falling back to flexible memory on any non-zero
return. RetroArch's eboot runs a probe: Create("ps5-platform-probe",
0x10000, 7, &fd), Alias(fd, 3, &alias), Map(fd, 5, &address), then logs
"jit create=0x%08x alias=0x%08x map=0x%08x".
Signatures from Orbital cc408367 tools/ida/db_types.json (name, len,
maxProt, fdOut; fd, maxProt, fdOut; fd, prot, startOut), matching
ps4sdk 4df9d001 include/sce/kernel.h, ps5-jar-loader 8034177e
LibKernel.java and the three titles' call sites. SharpProspero 5dfdb4b0
declares the alias as returning the descriptor; the RetroArch call site
passes an out pointer.
The object is a host anonymous file (memfd on Linux, a delete-on-close
temporary file mapped as a PAGE_EXECUTE_READWRITE section on Windows),
the alias a duplicate descriptor, and each map maps the whole object
through the direct memory placement path, so a write through one view
is visible through the others. Bad lengths and protection bits are
EINVAL, protection past the descriptor's maximum is EACCES (FreeBSD 11
vm_map_protect), unknown descriptors are EBADF; close, dup and dup2
keep the descriptor table in step. Unverified details are recorded in
TechnicalDebt.
Co-Authored-By: Claude Fable 5.1 <[email protected]>
PRAGMATA (PPSA02530) imports sceSharePlayProhibitController (NID
FzQS6DREDfk), which no library exports on main, so the load fails on the
unresolved import. It is one of the "six declared-only imports" of
xXPBSXx's branch in #3043 (comment 6107100345): "These only stop the
load failure; as described above, the title calls some of them later and
needs their real behavior."
sharpemu src/SharpEmu.Libs/Share/SharePlayExports.cs:9-31
(a2983692930564815a77f81e74c151268f5b935f, used as a source of facts)
takes one value, accepts 0 and 1 and returns 0. Nothing here would read
the setting, as no Share Play session or visitor controller exists, so
it is not stored. sharpemu rejects other values with its synthetic
0x80020003, not a Share Play code, so they throw, as
sceSharePlayInitialize does for its unknown error. Like the other exports
of the library it does not check initialization. The NID hashes from the
name and is in aerolib. Unverified points are in TechnicalDebt.
Co-Authored-By: Claude Fable 5.1 <[email protected]>
PRAGMATA (PPSA02530) imports sceRazorCpuSync (NID Ax7NjOzctIM), which no
library exports on main, so the load fails on the unresolved import. The
title calls it after sceConvertKeycodeGetCharacter. From #3043 (comment
6106731532): "`sceRazorCpuSync`: answering 0 and doing nothing was
enough to carry on (the other `sceRazorCpu*` calls in `main` are no-ops
without a capture)."
SharpProspero src/SharpProspero/Interop/Debug/RazorCpu.cs:119-122
(5dfdb4b0b166e83dc9ae275001afb695f12c7174, GPL-3.0, used as a source of
facts) gives int sceRazorCpuSync(void), an unnamed frame-boundary event.
Without a capture there is no event to record, so it returns 0 and does
nothing, like the other sceRazorCpu markers here and the shadPS4 stub
(razor_cpu.cpp:143, 3a9f57265d28975658f1ca941daa5c879c7a74bd). The NID
hashes from the name and is in aerolib. Unverified points are in
TechnicalDebt.
Co-Authored-By: Claude Fable 5.1 <[email protected]>