Repository navigation
feat(libkernel): map app0.zar archive-backed files - #11625
Felipebmaitan wants to merge 11 commits into
Conversation
MarcZX10
left a comment
There was a problem hiding this comment.
Reviewed exact head e97bbf045122e4326b0f5332a9844df37bd1d5dc. Archive mappings materialize a request-local read-only backing object, preserve loose-file precedence and descriptor cursor/lifetime semantics, and retain the regular-file mapping path for validation, protections and unmaps. The archive read changes scatter through checked guest writes and translate EFAULT at the public wrappers. The tests cover offset/alignment/EOF behavior, private/shared protections, descriptor replacement/close, partial unmaps, damage and backing failures. Hosted conventions, eligibility, intake, labels, report, register-context, relinker, ASan and write-watch checks pass; product build jobs are skipped by path policy. The author reports Windows and WSL full builds and focused tests, with the DrvFS-only inotify failure explicitly excluded; I did not independently rerun the local suite. I found no blocking issue.
|
Other open pull requests touch the same code. Merging one will break the other, or both implement the same thing. If this one builds on them, list them in Depends on.
Some comparisons could not be completed because a pull request conflicts with the base branch. Review these shared files manually before concluding that there is no overlap.
|
jotitadev
left a comment
There was a problem hiding this comment.
First bare-metal Linux run, since the Linux results in the PR are from WSL2 and the memfd + /proc/self/fd backing is Linux-only.
Exact head e97bbf045122e4326b0f5332a9844df37bd1d5dc, merged on main cb45ae2dd. Linux x86_64 (bare metal, ext4), i7-8700, Ubuntu 26.04, kernel 7.0, GCC 15.2, glibc 2.43, CMake 4.2.3, Ninja, Release, BUILD_TESTING=ON, full build.
- The 5
guest_kernel_app_archive_*tests (archive,plain,mmap,mmap-failure,mmap-damaged) pass, 3 of 3 runs. guest_filesystempasses here, so the inotify assertion that failed on DrvFS is fine on a native filesystem.- A wider subset of 76 file, stdio, mmap and app-archive tests (
guest_kernel*,guest_stdio*,guest_file*,guest_mmap*,guest_app*, ...) passes. Full non-GPU suite on the samemainwithout the PR: 1361/1361. - With the implementation reverted to
main(AppArchive*, the libcCMakeLists.txt,PosixMemory.cpp,ArchivedFile.cpp,Open.cpp,Stdio.cpp; new tests and their CMake modes kept),mmap,mmap-failureandmmap-damagedabort withmmap on a file read from app0.zar, fd=7 not implemented;archiveandplainstill pass.
Written with AI assistance (Claude Code). I ran the builds and tests above on my machine.
|
@Felipebmaitan my docs-only #11732 appends to the AI-assisted: yes (Claude Code) |
|
For coordination with #11872, I am selecting #11872 first, then #11625 for these two PRs under my account. The later archive-mapping rebase must retain the POSIX Io/descriptor admission and HostWrite scopes while applying this PR's archive result-to-POSIX/SCE error mapping, keeping the two return conventions separate. Archive mmap work remains in this PR. Combined checks should retain archive read/positioned/vector/mapping and descriptor close/reuse cases. This records the merge-order decision; I have updated only this PR's Depends on line to #11872 for merge ordering. Its branch head and source files are unchanged; no combined runtime test is claimed. AI-assisted coordination. |
|
@Felipebmaitan the mapping side reads right to us: the sealed memfd reopened read-only on Linux, the helper descriptor closed before
|
|
@Felipebmaitan a merge-order question from #12296 (Windows: map shared-memory descriptors with the regular-file checks). The repository's overlap check pairs the two PRs on CONTRIBUTING asks overlapping authors to agree on an order and record it under Depends on. #12296 is small and its reviewer otherwise found no defect, so I'd propose #12296 lands first and the rebase here is the small textual merge described above. If you'd rather this PR go first, say so and I'll set Depends on: #11625 on #12296 and do the rebase myself after yours lands. Either works for me. AI-assisted: yes (Claude Code). |
e97bbf0 to
ebf93ca
Compare
|
@oneandonlydean addressed both questions at published head
The requested same-machine cost measurements are retained in the PR body, with reproducible benchmark source/hashes: Windows 11 / Ryzen 7 9800X3D / WinLibs GCC 15.2, baseline main Fresh exact-head validation: Ubuntu 24.04.5/GCC 13.3 Release in a linux/amd64 container on Apple silicon. Rebuilt focused executables and their production library dependencies: 21/22 selected tests passed, including all five guest_kernel_app_archive modes, four guest_app_archive modes, read/vector/positioned/AIO/dup cases. The broader guest_memory test fails at GuestMemory.cpp:4084 (zero-length mincore errno at the user-address boundary); rebuilding upstream main @MarcZX10 @jotitadev thank you for the earlier reviews and bare-metal run. Those remain evidence for |
|
@milescoviello replying explicitly to your #11732 ordering request: the live state has overtaken the proposed #11625-first order. #11732 merged on October 28, so the actual order is #11732 first, then #11625. Published head |
|
@JJenkx agreed to #12296 first, then #11625, and live state now satisfies that order: #12296 merged on October 30. Published archive head |
|
@Felipebmaitan thanks, agreed. #11732 landed first on October 28, so my ordering request is satisfied and nothing is left for me on this PR. AI-assisted: yes (Claude Code) |
|
A macOS runtime run of head
AI-assisted: yes |
# Conflicts: # docs/dev/debt/libc.md
|
@imellag reproduced and fixed in published head On macOS 27.0.1 / Apple M5 Pro / Apple clang 21 / x86-64 Release under Rosetta, I used your exact support branch pin The catch selects EIO and writes it correctly; exception cleanup then changes the shared host/guest errno slot back to ENOENT before mmap returns. The fix keeps the selected error in a local result while the mapping helper finishes its catches and resource destruction, then publishes errno in the public wrapper. TemporaryBacking still reports its native temp_directory_path/mkstemp errors internally. The abstraction stays general: a missing host backing directory is an I/O failure mapping an already-open guest file; access and supported resource errors keep their existing classifications, and damaged data remains EIO. Added regression checks require sceKernelMmap to return the matching SCE code and leave its output pointer untouched, alongside the existing POSIX/cursor/cleanup assertions. After removing instrumentation, the matched support composition passes 15/15 native cases (all nine archive cases, file-vector and file-vector-memory, dup, positioned race, memory and AIO). A focused public-API driver against NID-patched/ad-hoc-signed libc/libkernel/libSceLibcInternal passes normal, missing-temp and damaged modes; it checks both POSIX and SCE errors repeatedly, nonzero offset contents, positioned/vector reads and mapping lifetime after close. Patched coverage uses that narrow driver; the complete archive executable above uses unpatched libraries. This validates the fix on the pinned support composition, not standalone main or the entire published tree on macOS. The refreshed production source also builds in Linux Ubuntu 24.04.5/GCC 13.3 Release (linux/amd64 container on Apple silicon): 21/22 selected cases pass, including every archive/read/vector/positioned/AIO/dup case. The remaining guest_memory zero-length mincore errno assertion at line 4225 also fails on a freshly rebuilt main Remote maintainer history is preserved, bounded window backing and checked reads remain, and no cancellation-stack branch was changed. #12682 stays the open predecessor. Prior read-cost evidence remains supplied and awaits acceptance; no new speed claim, fresh Windows/title/console or combined unmerged-stack validation is made. The PR body pins the support composition, patch hashes and platform limits. AI-assisted: yes. |
|
@Felipebmaitan confirmed on macOS at Same setup and method as my earlier run: Apple M4 Pro, macOS 27.2, Apple clang 21.0.0, x86-64 Release under Rosetta 2, support branch
I didn't rerun the title-level or Windows parts; this covers the macOS path only. AI-assisted: yes |
# Conflicts: # core/libs/prx/libkernel/File/src/Stdio.cpp
✅ AMD GPU test: passedPR head
Unstable on main (1, these also failed in recent main runs on this machine; not counted against this PR)Failing on main too (13, not counted against this PR)Passed on retry (1, failed in the parallel run, passed when re-run with a 360 s timeout; not counted against this PR)Validation IDs already present on main (4 IDs in 753 tests)Skipped (59)ReproduceAutomated build and test on a contributor's AMD machine; it does not replace upstream CI. A new comment is posted for each new push. Full logs. |
XairRrR
left a comment
There was a problem hiding this comment.
Reviewed — approved
mmap on app0.zar files now goes through the regular-file mapping path, backed by a separate read-only copy of the requested window for each mapping. The change builds, the focused tests pass on Linux, and both negative controls fail as expected. I found nothing blocking. There are three non-blocking notes; the main one is the cost of the read path.
What I ran
Head 783098aabe1d930b25a10c85280ed02a4c219f1f, main 086c0686c8adff3ee648fdbe34e0b0b647e1d511, merged with --no-ff in a clean worktree (merged tree e34c6e0da86340e7048a4bdd82ea4c60d3f5f5d1). Debian 13 VM, 2× Xeon Gold 6136, GCC 14.2.0, Release, Ninja, BUILD_TESTING=ON.
git diff --check 086c0686c8adff3ee648fdbe34e0b0b647e1d511...783098aabe1d930b25a10c85280ed02a4c219f1f
python3 tools/check_conventions.py --base 086c0686c8adff3ee648fdbe34e0b0b647e1d511
ctest --test-dir build -j8 --test-load 32 --output-on-failure -R "^(guest_kernel_app_archive_.*|guest_app_archive_.*|guest_memory|guest_dup|guest_file_vector.*|guest_positioned_race|guest_aio.*|guest_kernel_sys_aio)$"
ctest --test-dir build -V -R "^guest_kernel_app_archive_mmap"
# negative control A: PosixMemory.cpp from main
git show 086c0686c8adff3ee648fdbe34e0b0b647e1d511:core/libs/prx/libkernel/DirectMemory/PosixMemory.cpp > core/libs/prx/libkernel/DirectMemory/PosixMemory.cpp
ninja -C build -j32 -l32 guest_kernel_app_archive_tests
ctest --test-dir build -R "^guest_kernel_app_archive_" --output-on-failure
# negative control B: merged tree, but AppArchiveDescriptorRead_nid_no_patch body replaced by main's direct read
ninja -C build -j32 -l32 guest_kernel_app_archive_tests
ctest --test-dir build -R "^guest_kernel_app_archive_" --output-on-failure
# restore merged files, rebuild, rerun
git show e34c6e0da86340e7048a4bdd82ea4c60d3f5f5d1:<path> > <path>
ninja -C build -j32 -l32 guest_kernel_app_archive_tests
ctest --test-dir build -R "^guest_kernel_app_archive_"
git status --porcelain
Results
| Check | Result |
|---|---|
Merge into main |
clean |
git diff --check |
clean |
check_conventions.py |
All conventions checks passed |
Configure / build / libs (script) |
ok |
| Script test run (3759 tests selected) | 0 new failures, 0 timeouts; 9 known failures that also fail on main; guest_net_ctl skip also happens on main |
| Focused selection (22 tests) | 22/22 passed, total 1.82 s |
guest_kernel_app_archive_mmap, -mmap-failure, -mmap-damaged |
passed, 0.01–0.03 s each |
| Vulkan validation | not applicable (no AGC, shader or VideoOut files changed) |
Notes from the verbose mmap run
3486: no writable noexec temporary filesystem available; missing-directory backing independence passed
1/3 Test #3486: guest_kernel_app_archive_mmap ........... Passed 0.03 sec
2/3 Test #3487: guest_kernel_app_archive_mmap-failure ... Passed 0.02 sec
3/3 Test #3488: guest_kernel_app_archive_mmap-damaged ... Passed 0.02 sec
On this machine the noexec-storage branch of MappingStorageIndependence was skipped. Only the missing-directory variant ran.
guest_memory passed here. The author's container run failed it on the zero-length mincore assertion, which they also reproduced on main. That failure does not happen on this machine.
Negative control
- A: mapping path reverted (
PosixMemory.cppfrommain, everything else merged). All three mmap modes fail, andarchiveandplainstill pass:3/5 Test #3486: guest_kernel_app_archive_mmap ...........Subprocess aborted***Exception what(): mmap on a file read from app0.zar, fd=7 not implemented 4/5 Test #3487: guest_kernel_app_archive_mmap-failure ...Subprocess aborted***Exception 5/5 Test #3488: guest_kernel_app_archive_mmap-damaged ...Subprocess aborted***Exception - B: checked read reverted. Merged tree, but
AppArchiveDescriptorRead_nid_no_patchusesmain's directAppArchiveReadinto the destination.guest_kernel_app_archive_mmapthen crashes the host process (***Exception: SegFault), and the other four modes pass. So the bounce-buffer copy is what keeps the new invalid-destination cases (MappingReadDestinations) from crashing. This adds evidence to the second question in oneandonlydean's comment: the outerHostWriteguard alone does not prevent the crash. - After restoring the merged files and rebuilding, all 5 archive tests pass again, and
git status --porcelainis empty.
Findings
Blocking
None.
Non-blocking
- Every
app0.zarread now pays the per-page checked copy (core/libs/prx/libc/src/AppArchive.cpp:258and:277). This affects all archive reads, not only mappings. Each 4 KiB chunk costs oneAppArchiveReadplus oneGuestCopyOut. The author's own figures show about 4× slower large reads and about 7× slower small reads. Control B confirms the check is needed for safety. However, partial progress only has to be page-exact when a copy fails.- Suggested fix: copy through a larger buffer (for example 64 KiB, the size
AppArchiveMaterialize_nid_no_patchalready uses), and fall back to page-by-page copying only when a chunk'sGuestCopyOutfails. That keeps the EFAULT-before-progress and partial-count behaviour and should recover most of the cost on valid destinations. - Scope: this read-path hardening is also a separate topic from mapping. The maintainer's acceptance of the cost is still open in the thread.
- Suggested fix: copy through a larger buffer (for example 64 KiB, the size
- Window materialization holds the descriptor mutex (
core/libs/prx/libc/src/AppArchive.cpp:244-246).AppArchiveMaterialize_nid_no_patchdecompresses and writes the whole requested window while holdingfile->mutex. Reads, seeks and other mappings on the same descriptor, and on its duplicates, which share the attachment, block for the whole copy. That can be a long wait for a large window. It is correct, but the file node could be copied under the lock and the materialization run after releasing it. - The libc debt entry is narrower than the code (
docs/dev/debt/libc.md:273in the merged tree). The rewritten entry lists onlyfopen,access,lstatandfdopenas unsupported. However,ResolvePath_nid_no_patchandResolvePathOrRelinkedModule_nid_no_patch(core/libs/prx/libc/src/General.cpp:862-872) still throw for any archive-only path, and so does thechdirpath (General.cpp:920). The previous wording ("any call other than the archive-aware libkernel ones throws") was the accurate gap statement. Consider keeping that general sentence instead of the short list.
Not verified
- Windows (
CreateFileW/ReOpenFiledelete-on-close backing, private snapshot path) and macOS (mkstemp+ unlink backing, the errno-publication fix inf5d5756c79). This machine is Linux only. The macOS fix is covered by imellag's confirmation on the support branch, not by me. - The noexec temporary-storage branch of
MappingStorageIndependence: no writable noexec filesystem was available here. - The author's read benchmark figures. I did not rerun them.
- Combined behaviour with the declared predecessor #12682 (still open). This PR builds and passes on
mainwithout it, so the dependency looks like merge ordering only. - Title or console behaviour.
✅ AMD GPU test: passedPR head
Unstable on main (6, these also failed in recent main runs on this machine; not counted against this PR)Failing on main too (12, not counted against this PR)Validated but not compared (64, not in the main baseline's validation pass)Validation IDs already present on main (8 IDs in 797 tests)Skipped (62)ReproduceAutomated build and test on a contributor's AMD machine; it does not replace upstream CI. A new comment is posted for each new push. Full logs. |
What
November 1 fix at
f5d5756c799d2257de279a0963d93068e9f43fff, published in current head91f8d4b237b99a1d996824de43090f452dbce40e: publish the selected mmap errno after exception/resource cleanup. The macOS report is reproduced; the catch selected EIO (5), then exception cleanup changed the host/guest errno slot to ENOENT (2) before return. Mapping now computes its result/error internally and the public wrapper publishes the error after that work has ended. The error classification stays intact: host backing-directory failures and damaged archive data produce EIO, while supported access/resource failures retain their own codes. A missing host temporary path does not mean the already-open guest archive file is missing. Added SCE wrapper checks require the same error and an untouched output pointer on failure.Bounded requested-window storage, permission/EOF/lifetime semantics and checked reads are retained. The supplied read-cost explanation/benchmark awaits acceptance; this update makes no speed claim. #11732/#12296 ordering is satisfied by their merges; #12682 remains open and is the declared predecessor. Its inspected current head is
0e88eeebc91c233aaba95c056c970a1d8b273b36. No I/O cancellation-stack branch (#12682/#12688/#12700/#12965) was changed.Implement archive-backed file mappings through the regular-file mapping paths. Loose app0 entries still override app0.zar. This is AnyPS5 host ZArchive packaging, not console PFS.
The backing now contains only the requested guest-page-rounded window, clipped at EOF, stored at native offset zero. Linux uses a sealed memfd reopened read-only; Windows/macOS use read-only temporary disk backing. Each live mapping owns independent native storage. No hidden descriptor remains after mmap returns, preserving close/reuse and dup2 behavior. Failed backing writes retain resource errors and clean up without installing a mapping.
Private writable copies, shared read-only permissions, protections, partial unmaps, offsets and EOF retain the established native mapping contract. Linux requires memfd_create and /proc/self/fd. Windows retains regular-file private snapshots and whole-page EOF rejection; macOS execution evidence uses the separately pinned support composition above.
Read copies remain deliberately checked. I audited all actual ReadArchivedFile/ReadArchivedIovecs callers: sceKernelRead, POSIX pread, both host implementations of sceKernelPread, Windows TransferIovecs, POSIX sceKernelReadv/Preadv, and AIO NativePread. Each holds HostWrite/OpenIovecs over its destination. Those guards open watched pages; they do not validate arbitrary pointers. On Linux GuestArenaBeginHostWrite returns true and the write-watch hook is a no-op; on Windows BeginHostWrite checks tracked views, not all arbitrary private/foreign memory. ZArchive copies with CPU stores, so restoring direct destination reads would reintroduce host faults for protected/unmapped pointers. Page-bounded GuestCopyOut preserves EFAULT-before-progress and partial count/cursor semantics. The nested guards also cover direct internal-helper callers. New scalar/positioned/vector/AIO regressions exercise invalid pointers, partial vectors and watched destinations. The measured cost is recorded below, without a title speed claim.
Ordering: #12682 first (replacement for #11872), then this PR, as previously declared. Its current published head is
55161f97476a8bd413c279829cabb6390307e4d5; no candidate is consumed here, and its branches remain untouched. #12296 merged during validation; its Windows shared-memory checks are retained in this rebase, alongside the archive source descriptor and native window offset. #11732 is also merged; its newer VirtualQuery debt text is preserved. Both older order requests are therefore already resolved by main, and neither is an open prerequisite. Direct replies to the outstanding review and ordering comments are recorded in the conversation below.Tested
November 1 exact published head:
91f8d4b237b99a1d996824de43090f452dbce40e. Preserves the remote maintainer merge4cb2bc9b2cceab3ef2ff7b8d736f7e04bc89ab9e; integrates upstream main66e1f7f993c9c1339c2de11264b76bab03218cd2without rewriting history. Runtime validation built source at fix commitf5d5756c799d2257de279a0963d93068e9f43fff; the final main merge changes none of libc/libkernel/libSceLibcInternal, their test sources or SceTypes.hpp, confirmed by tree comparison.66e1f7f993c9c1339c2de11264b76bab03218cd2reproduces the identical assertion. userfaultfd returns EPERM here, so actual Linux write-watch collection is unavailable.05bd71a66bed21dea323da545849781b883fe7f0+ this PR's original a294df9 own diff against de824c2 + the two-file f5d5756 fix. Both reported modes fail before the fix at the original line 924; ordinary mappings pass. After the fix, 15/15 native tests pass: all guest_app_archive and guest_kernel_app_archive modes, guest_file_vector/guest_file_vector_memory, guest_dup, guest_positioned_race, guest_memory and guest_aio. Both fix(libkernel): build the file, module and rtld calls on macOS hosts #10552 Apple empty-iovec blocks are preserved after archive read error conversion in this support composition. This is support-branch composition evidence, not an assertion that standalone main or the full published tree builds/runs on macOS.--exec --only-sce). All three modes passed: normal mapping (nonzero offset contents, scalar/vector positioned reads, lifetime after descriptor close), missing temporary directory, and damaged archive. Each failure mode repeats both POSIX and SCE boundary checks eight times, checking EIO and unchanged SCE output/cursor. Fixture compression is linked into the driver so its native codec symbols stay local. The complete host-linked regression executable has native helper/weak-import resolution requirements; patched coverage is this focused driver, while the complete archive suite above runs unpatched.python3 tools/check_conventions.py --base origin/main), whitespace and public-header audit pass (399 libraries / 26,750 exports). Overlap scan of f5d5756 against main 66e1f7f completed across 1,848 open PRs, with confirmed adjacency at fix(libkernel): build the file, module and rtld calls on macOS hosts #10552 (Stdio) and fix(libc): sort with FreeBSD 11.4's merge.c in mergesort #12271 (debt text). Other conflicting-main comparisons, including feat(libkernel): support deferred cancellation in POSIX accept #12965, remain inconclusive and the scanner exits nonzero; no clean-overlap claim or new author agreement is made. fix(libkernel): build the file, module and rtld calls on macOS hosts #10552 composition was inspected and tested as above. Other threads' branches remain untouched.The macOS support composition is reproducible from patch hashes: original PR diff SHA256
83a1be116e75086554aaaadfe53494e2374d5b29b60eeabcc10dfcc1f00a87ba; two-file fix diff SHA256677d4d05aed6d41fcb18d79ebab60a0981ec3e1f1b7ea7fc94ed68172d3bdf4e. Temporary instrumentation, driver and logs are outside the repository. No fresh Windows, complete full-suite, GPU, title/console, performance or combined cancellation-stack run is claimed. Earlier evidence below remains pinned to its original heads.October 31 refresh: exact head
a294df92fa9d61d291251a114691a1e689f4d6b0, preserving published headebf93ca4f62a55df2ef1001b811d1a013a8ef495and merging upstream mainde824c2919ca65086c6324a1e0388866a7327eea. The bounded backing fix was already published in1440791c77a7e1bbee1684f0726a903ed999dd94; this refresh retains it, the checked reads, and maintainer changes. No history was rewritten and no other I/O head was pushed.Fresh validation: Ubuntu 24.04.5 / GCC 13.3 / Release / LinuxKit 7.0.12, linux/amd64 container on Apple silicon. Built the selected test targets and their production libc, libSceLibcInternal, libkernel and libkernel_sys dependencies. Focused CTest selection below: 21/22 passed. Every archive, scalar/vector/positioned-read, AIO and descriptor test passed.
guest_memoryaborted at GuestMemory.cpp:4084 (mincore(0x800000000000, 0, nullptr)errno expectation); after overlaying upstream main and explicitly rebuilding its changed production sources, the identical assertion failed on main too. This is a reproduced baseline/container limitation, not a passing memory suite. userfaultfd returned EPERM, so write-watch collection was unavailable; no actual Linux write-watch coverage is claimed. The archive mmap test also passed a verbose run, including executable mappings with noexec temporary storage.Conventions (
--base origin/main), whitespace and public-header audit passed (393 libraries / 24,536 exports). Fresh overlap scan ran in an isolated clone at this exact head against 1,558 open PRs: confirmed adjacency with #12271 and #12597 (debt text) and #12868 (Stdio readv/preadv return lines). Manually inspected #12868 at619546539e534ea4c05e66460f4b79b30d92895a: retain its private-descriptor admission while keeping this PR's archive result-to-SCE conversion. These are integration seams, not duplicate implementations. No new author agreement is claimed; conflicting-main comparisons remain inconclusive and the scan exits nonzero, as designed. The earlier #11732/#12296 order requests are resolved by their merges; #12682 remains the declared predecessor.Native macOS configuration was attempted but stopped on pre-existing empty LibAtrac9 checkout contents; the original dirty submodules were preserved. No fresh Windows, macOS runtime, full-suite, GPU, title/console, performance, or combined unmerged-stack execution is claimed. The Windows/WSL runs and synthetic benchmark below are historical, pinned to their stated heads; the archive read/backing sources and archive regression file are unchanged between ebf93ca and this refresh.
Historical evidence follows.
Maintenance source head:
ebf93ca4f62a55df2ef1001b811d1a013a8ef495, rebased on fetched main08a10d225306ad102b57408e2ef7566bcfb829b2. The bounded-window implementation is commit1440791c77a(before the latest main refresh:9c840020b8e3b0252cf18c9206f39ee6a42cc37c). Earlier approvals and external bare-metal results at e97bbf0 are historical, not validation of this head.On that exact integrated head:
libsandrelinker) plus focused test executables passed. CTest selection: 24/24 passed, zero skips, longest 2.50 s.libsandrelinker) plus focused test executables passed. Same applicable selection: 22/22 passed, zero skips, longest 0.94 s. The two Windows-only cases are excluded.guest_kernel_app_archive_*(archive/plain/mmap/mmap-failure/mmap-damaged),guest_app_archive_*,guest_memory,guest_dup,guest_file_vector*,guest_positioned_race,guest_aio*,guest_kernel_sys_aio, and Windowswindows_write_watch. This covers requested-window backing size/content, offset rebasing, COW/shared permissions, protections, partial unmaps, concurrent maps, descriptor duplication/close/reuse, native-handle cleanup, bad pointers and partial vector progress, HostWrite and AIO destinations. Linux additionally constrains RLIMIT_FSIZE: a one-page window of a larger entry succeeds; a two-page request fails with EFBIG, without leaks/cursor changes, and retries after restoring the limit.tools/check_conventions.py --base origin/main,git diff --check, and public-header audit passed (373 libraries, 14,243 exports). Required overlap scan completed. The complete GPU/non-GPU CTest suite was not run; unrelated test executables are not part of the full production build command.Same-machine synthetic archive read measurements, Windows 11, Ryzen 7 9800X3D, WinLibs GCC 15.2, Release. Benchmark source pins: main
1189ec3003672bb364dd9f3119ead7b3976e3c83versus final integrated implementationebf93ca4f62a55df2ef1001b811d1a013a8ef495. Main is the baseline fetched at the start of this maintenance pass; it is not relabeled as the later main revision. identical benchmark executable, archive and APIs (sceKernelOpen/Read/Lseek/Close). Three alternating main/change runs, one warm-up per workload per process, seven recorded samples each (21 samples per cell). Large workload: 256 MiB in 256 reads of 1 MiB. Small workload: 65,536 sequential reads of 64 bytes (4 MiB). First/last bytes and checksums are verified per call; archive creation is outside timing. Host compiler jobs were active, so ranges include contention and these are synthetic cost measurements, not controlled game/scene performance evidence. No trace_digest/game speed claim is made.The checked copy has a substantial measured cost. It is retained to preserve the fault/partial-progress contract; HostWrite alone is insufficient. The implementation bounds mapping storage independently of this read-path tradeoff.
No macOS runtime, PS5/console, title, GPU or combined unmerged-dependency runtime result is claimed unless separately pinned below.
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)Reproducible synthetic read benchmark
Historical overlap scan on ebf93ca (isolated scan clone, branch alias
archive-maint-review, same exact SHA): completed against 1,453 open PRs on main08a10d225306. Confirmed overlaps are this PR itself (same new file), #12682 (Stdio.cpp, declared predecessor), and docs adjacency with #8965 and #12271. The doc-adjacency order is not agreed; no agreement is invented and no contributor message was sent. Other shared-file comparisons that conflict with main remain inconclusive. The earlier #12296 and #11732 requests are already resolved by their merges.For the later #12682 integration, retain its POSIX Io, descriptor-admission and HostWrite/OpenIovecs scopes, applying the archive native-error conversion separately at the POSIX and SCE return boundaries. The published predecessor head inspected on October 31 is
55161f97476a8bd413c279829cabb6390307e4d5. #12688 transport and #12700 writes remain open downstream of it; they are not additional direct prerequisites of this archive PR. No combined execution with an unpublished refresh is claimed.