# Minimal kernelwrite-free CRT feasibility ## Decision: BLOCKED A compiler-driver trace proves that SDK v0.41 can be asked to omit its stock CRT and default libraries. A freestanding BSS clear and ordinary x86-64 return instruction are mechanically expressible. Those facts do not prove that the actual PS5 loader safely calls or accepts return from such an entrypoint. Because safe return was not proven, no custom `_start` source was added and no PS5 ELF was built. This is the required fail-closed outcome, not an incomplete artifact audit. ## Necessary versus convenience or patching | Element | Minimal need | Classification | Evidence | |---|---:|---|---| | loader-recognized entry symbol | yes | `UNPROVEN` contract | SDK provides callee only | | correct incoming stack/register ABI | yes | `UNPROVEN` caller | stock disassembly shows expectation only | | mapped load segments and relocations | yes | `UNPROVEN` loader | linker script is not loader source | | deterministic BSS state | yes when BSS exists | `SAFE` implementation primitive | linker symbols plus byte-zero loop | | valid completion/return path | yes | `UNPROVEN` blocker | exact caller absent | | `payloadout` write | unknown | `UNPROVEN` ownership | field exists; caller semantics absent | | `__crt_syscall_init` | no for a no-call entry | convenience | stock SDK runtime only | | `__kernel_init` | no | kernel transport convenience | consumes pre-existing kernel access | | `__klog_init` | no | logging convenience | forbidden for minimal profile | | `__patch_init` | no | prohibited patch | proven kernel writes | | `__rtld_init` | no | dynamic-loader convenience | module loading and allocation | | libc/stdio | no | convenience | omitted by `-nodefaultlibs` trace | | constructors/destructors/TLS | no | convenience for this audit object | no artifact built | ## Exact blockers The smallest evidence set needed before reconsidering a build is: 1. identification of the exact loader used with firmware 9.60 and a pinned, public source commit; 2. the caller instructions establishing `RDI`, `RSP` alignment, the return address, and any preserved state; 3. allocation and ownership of `payload_args_t`, including `payloadout` lifetime and writability; 4. the complete caller path after `_start` returns, including restoration and cleanup; 5. crash/fault behavior before and during entry; 6. all process, credential, syscall, module, and memory changes performed by the loader before control reaches the artifact. An SDK header, a function signature, or a successful link is not a substitute for these caller facts. ## Verification disposition | Requested check | Result | |---|---| | SDK source, Makefile, compiler and linker audit | passed offline | | all stock startup objects/archives enumerated | passed offline | | stock CRT disassembly and reachable callgraph | passed; stock CRT is `UNSAFE` | | freestanding compiler-driver suppression | passed as no-output `-###` trace | | custom source compile with warnings as errors | not performed; build blocked | | custom linker map and full object/archive trace | not performed; build blocked | | custom undefined symbols and `DT_NEEDED` | not performed; build blocked | | custom relocations, arrays and TLS | not performed; build blocked | | custom prohibited-code scan | not performed; no custom bytes exist | | reproducible double clean cross-build and SHA-256 | not performed; no artifact exists | | host tests and sanitizer tests | required by `TEST_PLAN.md` and run separately | | negative build configuration | implemented; enabling the target must fail | The non-build decision record is `manifests/runtime/minimal-startup-artifact-decision.json`; it has `execution_eligible=false` and deliberately has null filename, size, and hash. ## Safe alternatives 1. Continue `libchimera-gfx` through its deterministic mock and a separately designed software backend. This advances API lifecycle, format conversion, scaling, adapter contracts, and cleanup without PS5 startup or GPU risk. 2. Maintain a separate Linux-on-PS5 backend as a long-term track. Linux `amdgpu`/RADV work can inform a Linux userspace backend, but it does not establish a native PS5 userland ABI and must remain architecturally separate. Neither alternative authorizes transfer or execution on the PS5. ## Phase 0.6 disposition Phase 0.6 found the exact installed elfldr caller, so `EXACT_LOADER_CALLER_SOURCE_ABSENT` is no longer the current blocker. The Phase-0.5 non-build decision remains historically correct because that source was not then available. The corrected Phase-0.6 safety model does not reject normal SDK startup merely because `__patch_init` performs documented temporary process/kernel runtime changes. A lifecycle probe would therefore use the normal pinned SDK v0.41 startup rather than reopening the custom `-nostartfiles -nodefaultlibs` target. No lifecycle source or ELF was created because the surrounding exact chain still cannot enforce the required profile: 1. elfldr's ptrace single-step completion loops have no finite bound; 2. the detached child has no two-second loader watchdog; 3. SDK return/exit/trap selection for the injected child is unproven; 4. UID and some failure-path credential state are not restored; 5. child exit/reaping and mapping/descriptor cleanup are unproven; 6. Payload Manager launch is path-bound rather than SHA-256-bound; 7. its supported upload path performs persistent filesystem writes; 8. the exploit/autoloader identity and independent firmware attestation remain unproven. Decision: **BLOCKED_VERSION_OR_UNBOUNDED_EFFECT**. Building a normal-CRT lifecycle probe would create bytes that cannot satisfy the mandatory runtime profile, so Phase D was correctly skipped. ## Phase 0.7 disposition The Phase-0.5 freestanding target remains blocked and was not bypassed. Phase 0.7 instead resolves the lifecycle termination uncertainty with an ordinary SDK v0.41 payload whose `main` calls `_exit` directly. This preserves the public loader entry ABI and avoids relying on an unproven return to the loader. The resulting lifecycle ELF has exactly `_exit` and `sceKernelSendNotificationRequest` as undefined imports and exactly `libSceLibcInternal.sprx` and `libkernel_web.sprx` as `DT_NEEDED` modules. There are no GNM, VideoOut, SDL, network, module-loader, thread, retry, or autoload imports. This does not prove a kernelwrite-free startup. The normal CRT is statically linked and its reachable startup includes `__patch_init`. Phase 0.7 accepts that exact process-local effect under ADR-0010/ADR-0011 and hardens the surrounding loader lifecycle. The freestanding question remains `BLOCKED`; the normal-CRT lifecycle is `READY_FOR_HARDENED_RUNTIME_DEPLOYMENT` offline only.