Repository navigation
feat(libSceContentExport): check the session in the remaining export calls - #7
Closed
KernelPanicNT wants to merge 137 commits into
Closed
KernelPanicNT wants to merge 137 commits into
KernelPanicNT wants to merge 137 commits into
Conversation
send, sendto, sendmsg, recv, recvfrom and recvmsg failed with EOPNOTSUPP
for MSG_DONTWAIT (0x80), so code that polls a blocking socket with it
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 as 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;
On Linux and macOS the flag now maps to the host's MSG_DONTWAIT, next to
MSG_PEEK on a receive and MSG_NOSIGNAL on a send. 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 <noreply@anthropic.com>
…ters progress_history passed filter="data" to TarFile.extractall, which only exists from Python 3.12 and the 3.11.4/3.10.12 security releases. On Python 3.10.11 every measured commit raised TypeError, so progress_history failed. Pass the filter when tarfile has data_filter and extract without it otherwise; the archive is git archive output of the repository's own commits.
…2PortGetState sceAudioOut2PortGetState returned the two channels of the host output for every port. It now reports the channel count of the port's data format and clears the rest of the state, so the reserved fields no longer keep the caller's stack contents. The speaker info and system state calls are unchanged; a new test covers all three, since none had one. The channel count follows SharpEmu, another emulator; no console measurement exists, recorded in TechnicalDebt.md. ASTRO BOT and ASTRO's PLAYROOM reportedly stop on an assertion that depends on the reported state (boykopovar#4317); which field matters is not isolated. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Four catalog titles (ProsperoTV PPSA99003, ProsperoRadio PPSA99001,
ProsperoLight PPSA99002, ProsperoLichess PPSA99009) locate their own
directory with stat("/app0/eboot.bin"), which always exists on the
console, and fall back to /data/homebrew/<title id> without it; that
directory is empty here, so they fail to load their fonts and die with
"renderer init failed". Staging the original eboot.bin next to the app
resources makes all four load their fonts; ProsperoLichess then renders
(1267 frames in 60 s on Windows).
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…put groups The test recompiled and rebuilt the same program for every group of 32 input pairs. Only the input buffer changes between groups, so compile once per compare, EXEC/VCC capture and float mode (96 programs instead of 768) and dispatch it for each group. On lavapipe the test drops from about 11.5 s to 1.3 s; it is the slowest test of the Linux CI run (14.5 s). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
sceNetCtlGetState reports IPOBTAINED from the host's addresses, but sceNetCtlGetInfo returned NOT_CONNECTED for every code. It now answers from the host interface that holds an IPv4 address, preferring the one with the default route: its address, netmask, gateway, MTU and DNS servers. The link is presented as wired, connected, configured by DHCP and without a proxy, with the Ethernet address sceNetGetMacAddress reports. A null info returns INVALID_ADDR and a code outside 1..21 INVALID_CODE; the Wi-Fi, DHCP host name, PPPoE and proxy server codes throw. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
The JpegDec structures were libScePngDec's under new names. OpenOrbis jpeg.h and SharpProspero JpegDec.cs agree on a 12-byte create param, a 0x30-byte decode param with a coefficient buffer, decode mode and down scale, and a 0x24-byte image info that reports the coefficient memory size, the suitable CSC attribute and the output size. Accept the CSC attributes 1 and 2 that SharpProspero passes, fill the output size, component count, coefficient memory size and suitable attribute, apply the requested alpha, and throw for decode modes other than 0 and down scales other than 1. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
GCN and RDNA code reads a compute wave's index in its workgroup from TG_SIZE[11:6] (ACO: s_bfe_u32 tg_size, 6 | 6 << 16). The prologue wrote it only at bit 20, so every wave read 0 there and cross-wave reductions such as RADV's radix sort lost the carries of all but wave 0. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Aps5FiberMain kept the fiber's entry address in rbp when it called the entry, so the guest entry saved that code address as the caller's frame. A guest walking frame pointers from inside a fiber read machine code as a frame record and faulted. libSceFiber is now built with frame pointers: Aps5FiberMain sets up a frame whose saved rbp is the zero of the initial fiber frame, and the chain ends there.
…location A storage image whose surface runs past the end of its registered allocation had every write-back dropped as "memory no longer registered". Titles can size a single-level surface's allocation as pitch x height. A tiled mip's 64 KiB blocks are stored row-major, so that size ends inside the last block row, and the bytes after it are the tail of that row: they hold texels with y < height, which the GPU's own store writes into the next allocation. When the allocation ends inside the last block row and registered readable memory continues to the surface's end, the write-back now stores the whole surface, as the GPU does. Padding slots keep their bytes, since the store writes only bytes that changed. Epic Mickey: Rebrushed streams its lightmaps into an 8160x8160 BC3 pool (SW_64KB_S, 2048 block rows) through a 2040x2040 RGBA32UI alias written by compute. The game allocates 2040 rows, so all its write-backs were dropped and the walls sampled leftover memory as speckled noise. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A relink killed between writing <output>.tmp and renaming it left that file behind, and every later relink of the output then fell back to the in-place write, bringing back the failure on a running build. The temporary file is now created under a new name beside the output with O_CREAT | O_EXCL and the previous permission bits, and written through that descriptor, so a file left by an earlier run never blocks a replacement and is never touched. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… locks sceAgcCreateInterpolantMapping resolved the pixel shader's ABI, which takes the process-wide shader preparation lock until the scope ends, and then waited under that lock for the vertex shader's background registration preparation. sceAgcCreatePrimState and sceAgcLinkShaders could wait the same way. Every other shader registration and ABI resolution queued behind that one compile: on PPSA07411 the lock was held 8 to 10 s of every 10 s, almost all of it waiting for registration preparations, while its loader threads waited 13 to 45 s per 10 s to take it. A preparation scope now names the shaders it resolves and waits for their registration preparations before it can take the lock. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…e library Every library under core/libs/prx links the libc and libkernel import libraries, and every NID patch step depended on the unpatched libc.prx. GNU ld 2.46 rewrites the import library on every link with new archive timestamps (the member headers and the symbol map header), so the restat on the link edge never pruned anything: one libc or libkernel .cpp edit relinked all 124 libraries and re-patched all of them. On MinGW the shared library link now writes the import library to <implib>.new with SOURCE_DATE_EPOCH=0 (ld then writes zero member timestamps), makes the symbol map deterministic with ranlib -D and copies the result over the import library only when its bytes differ (cmake -E copy_if_different). The link edge keeps restat, so a link that keeps the exports leaves the import library untouched and prunes every dependent link. The SOURCE_DATE_EPOCH also zeroes the export directory TimeDateStamp of the DLL; the COFF header TimeDateStamp that the unwinder keys on is unchanged. The NID patch steps only use the names libc exports. nid_patcher --write-export-list writes those names, normalized and sorted, to libc.exports and leaves the file untouched when they did not change; the patch steps read it with --preserve-export-list and depend on it instead of libc.prx, on every platform. A patched library is byte-identical to one patched against libc.prx. Measured on Windows (GCC 15.2, -j 4, loaded machine) after touching libc/src/Strings.cpp: with CMAKE_LINK_DEPENDS_NO_SHARED off, 124 links and 124 patches in 74.9 s before, 1 compile, 1 link, the export list and the libc patch in 4.3 s after; with it on, 124 patches in 7.8 s before and the same four steps in 5.3 s after. Touching libkernel/Time/Time.cpp runs 123 links and 123 patches (89.1 s) before and one compile, link and patch (3.4 s) after. Removing a libc export still relinks and re-patches all 124 libraries. nid_patcher_macho covers --write-export-list (sorted normalized names, no rewrite when unchanged, rewrite when changed) and --preserve-export-list (the same exports kept as with --preserve-exports; malformed lists and two references refused). It fails on main, where the option is unknown. Sources: SOURCE_DATE_EPOCH, https://reproducible-builds.org/specs/source-date-epoch/; ranlib -D and ld --out-implib, GNU binutils documentation; ninja restat, https://ninja-build.org/manual.html#ref_rule. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…locks On a host-imported surface a storage write-back keeps the 64 KiB blocks the CPU wrote since their tracked layer's generation, stores the rest and stamps the stored ranges with MarkWritten. Settling advanced the stored layers' generations past those stamps only when no layer kept a block (or when an adjacent pending surface needed the collect). When one tracked layer kept a block, every other stored layer kept its old generation, so the write-back's own stamps read as CPU writes: the next write-back kept those layers as well and did not store the GPU's newer results over them. A tracked layer is one 64 KiB unit when the surface has block units: tiled (not linear), 64 KiB-aligned base, not thick, with layer and block tracking on. Otherwise it is an array layer (64 KiB-aligned layer slices, layer tracking on) or the whole surface. Settling now collects and advances each stored layer that kept no block; a layer that kept a block keeps its old generation and re-uploads at its next use, as before. When no stored layer advances (nothing stored, or every selected layer kept a block, such as a single tracked layer that kept one), no adjacent pending surface needs the collect and no unit was retiled into the unit shadow, settling still skips the collect, as main did. Units retiled into the unit shadow are now marked at the settle collect's generation also when a block was kept; main marked them at TrackerGeneration() there without collecting. The two differ only for a CPU write to a stored unit made after the keep decision: main left it to a later walk, which made the retiled unit stale so the CPU's bytes won; now the walk stamps it at the marked generation and the stored results win, as they already did when no block was kept. agc_storage_kept_unit_settle uses a 1024x512 RGBA8 surface in 64 KiB tiling (32 block units): it writes one byte of unit 0 from the CPU, stores a red clear, stores a blue clear, and requires units 1-31 to hold blue and unit 0 to keep the CPU's byte after both stores. On main the GPU-mapped direct memory case fails with unit 1 still red. The watched-memory case (host imports off: the write-back that stores through the CPU) passes on main; it guards the kept layer's old generation and fails when settling also advances a layer that kept a block. The test returns 77, naming the reason, when the direct-memory case cannot run: no write watching, no host imports, direct memory not write-watched, or its host import refused. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ompared agc_storage_kept_unit_settle checked that the GPU-mapped direct memory was write-watched before it made the host import. On Linux, when host imports resolve write protection and dma-buf imports keep it, the host-pointer import is tried first in a window that does not stay watched, and dma-buf only when it fails (importAllocation in GuestBufferMemory.cpp). Where the host-pointer import of shared memory succeeds, as on Intel's ANV, the import takes the direct memory out of the write watch, so the case ran on the compared path: the upload saves the guest bytes, the first write-back keeps unit 0 by comparison and drops the saved bytes of every unit it selected, and the second write-back has nothing to compare. Before e544993 it stored every unit whole, over the CPU's byte in unit 0, which is the failure reported on Linux; on main it throws (technical debt: results over memory outside the write watch without saved bytes). Neither depends on the settle change. On Windows, importing watched private memory (compared there) reproduces both: on 7e181fc, with or without this branch's Texture.cpp change, the second check fails with that message; on main the second write-back throws. The case now checks the write watch again after the import and returns 77, naming the reason, when the import took the memory out of it. Where the import keeps the memory watched (the Windows alias import, a Linux dma-buf import) it runs as before. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Pointer-shaped NID kW3GLb7QfPg calls from public homebrew succeed on console; returning an error left those titles failing init after boykopovar#4835.
…p-wait fix(agc): settle registration preparations before a preparation scope locks
…k-overhang fix(agc): store a storage image whose last block row runs past its allocation
docs(build): link the supported WinLibs release
docs(user): stage the original eboot.bin in app0
A sampled depth texture whose layers are all backed by host depth surfaces is gathered host-to-host, plane by plane. The gather located the surface for layer n at base.address + n * DepthSliceBytes(extent), the host depth slice stride, and required the guest descriptor's sliceLinearBytes to equal that stride. Bendy and the Ink Machine (PPSA27616) samples a 64x64 F32 cube over six D32 depth surfaces. The descriptor's per-layer footprint is the tiled depth slice, but its linear footprint is smaller, so the check refused a valid resource and the game aborted as soon as it sampled the cube. Locate each layer at base.address + geometry.GuestLayerOffset(layer) instead. That is the address the descriptor itself uses, and the one the guest-memory fallback already used, so both ways of finding a layer agree by construction. Keep the geometry check for the mixed case, where a layer has no host surface and is filled from guest memory, because that path lays its layers out at sliceLinearBytes. The storage-image path still refuses a layer pitch that is not the depth slice size; that is unchanged and out of scope.
…nternal-helper-nids fix(videoout): keep mouse helpers out of NID exports
…rivatives-linear-groups fix(shader): group compute derivatives by four consecutive lanes
…ess-lock-1488 fix(libkernel): defer raises while a thread holds the address-wait lock on Windows
…lice-htile fix(agc): give each slice of a depth array its own HTILE
…ack-any-storage fix(agc): store a written storage image over a depth plane into the surface
…compile test(agc): compile each v_cmp denormals program once for its eight input groups
…out2-advance-grains fix(audio): preserve completed AudioOut2 grains across threads
…ve-id fix(shader): put the compute wave index in TG_SIZE[11:6]
…-walk perf(libc): remember clean pages once per run in Windows write collects
…mpress-msaa fix(agc): handle FMASK decompress on MSAA targets
…ration-preparation-at-submit fix(agc): wait for queued registration preparations before accepting a submission
…be-gather fix(agc): gather a sampled depth cube at the descriptor's layer offsets
…info fix(libSceNetCtl): answer sceNetCtlGetInfo from the host IPv4 interface
…erence-abi fix(libSceJpegDec): use the JpegDec parameter and image info layouts
…service-lifetime fix(memory): preserve process-owned services during exit
…k-out-of-range fix(agc): return 0 for out-of-range sceAgcInit without table lookup
…e-capture-status refactor(libSceShare.native): drop duplicated exports
…undancy perf(shader): avoid redundancy traversal map copies
…host-streams fix(libkernel): keep host standard streams open on guest close
…tat-symbolic-links feat(libkernel): report relative symbolic links in lstat on Windows
…calls sceContentExportFromData, sceContentExportFromFile and sceContentExportFromFileWithThumbnail take their Orbital signatures and check the session as sceContentExportFromDataWithThumbnail does: not initialized and unknown sessions throw as before. The host has no media library to export into, so a live session throws before a data callback is called or a source file is read, and the output path is never written. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
KernelPanicNT
force-pushed
the
feat/libscecontentexport-remaining-exports
branch
from
October 14, 2026 18:47
b65ea96 to
9679ea5
Compare
Owner
Author
|
Superseded: published upstream; closing the CI draft. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Gives
sceContentExportFromData,sceContentExportFromFileandsceContentExportFromFileWithThumbnailtheir signatures and the session check thatsceContentExportFromDataWithThumbnailalready has. No export ever succeeds: once the session is valid, each call throws because the host has no media library to export into.Source of the behaviour. No console measurement is involved.
Signatures: Orbital's IDA type database, db_types.json L547-L550, the commit the library's debt entry already cites:
int32_t sceContentExportFromData(int32_t expId, const struct* param, size_t cotentlength, sceContentExportDataProvideFunction func, void* userdata, char* path, size_t pathbuflen)int32_t sceContentExportFromFile(int32_t expId, const struct* param, const char* srcpathname, char* path, size_t pathbuflen)int32_t sceContentExportFromFileWithThumbnail(int32_t expId, const struct* param, const char* srcpathname, const char* thumbnailpath, char* path, size_t pathbuflen)paramis the existingContentExportParam; the data-provide function is passed asvoid*, since it is never called.Session model: the one merged in feat(libSceContentExport): implement export sessions boykopovar/AnyPS5#3721 for
sceContentExportFromDataWithThumbnail, through the sameRequireSession: beforesceContentExportInit2the call throwsstd::logic_error, for a session id thatsceContentExportStartdid not hand out orsceContentExportFinishalready closed it throwsstd::invalid_argument.Changes:
core/libs/prx/libSceContentExport/Export.cpp: the three(void)throwing stubs take the signatures above, check the session under the session mutex, and throwstd::runtime_error("the host has no media library to export into") for a live session. They do not call the data-provide function, read the source or thumbnail file, or write the output path.core/libs/tests/GuestContentExport.cpp:guest_content_exportcalls each of the three before init, on a live session and aftersceContentExportFinish, and checks the exception type in each state, that the output path stays empty and that the data-provide callback is never called.docs/dev/debt/libSceContentExport.md: the existing session entry names the three calls next tosceContentExportFromDataWithThumbnail.What stays throwing, and why: every call on a live session. The PS5 writes the exported content into its media library and reports the resulting path; the host has no such library, and the console's result for an export that cannot be stored is unknown. The error precedence between an invalid session and invalid arguments is unverified, as for the rest of the library; arguments are not checked.
Progress: libSceContentExport 7/10 → 10/10; system libraries 3249/3678 (88.34%) → 3252/3678 (88.42%) by
tools/progress.pyon the branch basecaee23f.Tested
Head
3d10f3b94744a8d0db0aee5d4d36750c475116d4, base84b01f9cd042e1d2e9e112f8783aa5a9d26399ee.BUILD_TESTING=ON, tests run under QEMU 8.2 user mode with-cpu EPYC-Romebecause the build host lacks AVX2):guest_content_export_tests5/5 passes.core/libs/prx/libSceContentExport/Export.cppwith the base version:guest_content_export_testsfails withsceContentExportFromData not implemented. Restoring the PR source and rebuilding passesguest_content_export_tests5/5.git diff --checkpass. The Linux job of the Build workflow now targets the project's self-hosted runner, so it was not run on the fork; no title was run.Duplicate and overlap check
Checked the files of all 443 open PRs on 2026-10-14 and searched open, merged and closed PRs for the three names and the NID
AOWqIYsgVHs. No open PR toucheslibSceContentExport/Export.cpp,GuestContentExport.cppordocs/dev/debt/libSceContentExport.md, and none names these functions.Earlier PRs on the same exports, all closed: boykopovar#1537 copied exported files to a host directory; boykopovar#4332 and boykopovar#4568 turned the three stubs into silent
return 0; boykopovar#4313 only asserted that the stubs throw, which already passes onmain. Here the stubs keep throwing on a live session, and the new session-state assertions (std::invalid_argumentaftersceContentExportFinish) fail onmain, where the stubs throw thenot implementedstd::runtime_errorin every state. boykopovar#3721 established the model forsceContentExportFromDataWithThumbnail; boykopovar#714 named theAOWqIYsgVHsstub.The branch is one commit on
caee23f; none of the newer commits onmain(84b01f9) touch these files, and it merges without conflicts.Checklist
main; no other open PR implements the same functionsNotImplemented_nid_no_patch); silent stubs are listed under Silent stubs in their library's technical debt file.mdfiles or images added to the repository (attach them to this PR)