D432 - The fault report carries the faulting instruction, and what the shared wall actually is

measured - 2026-09-01 (user-directed)

A fault in a SELF/eboot guest was the one wall that could not be turned into an instruction by hand: image+0x… names an offset the ELF p_offset fields do not locate (only the loader's wrapper decode does), so there was no way to read the faulting instruction short of decoding the wrapper. The fault report already knew where the guest faulted; now it prints the bytes at the instruction pointer, and the window of bytes before it, read straight from the loaded image inside the handler. Two facts made this safe rather than a second fault: executable pages here are always PAGE_EXECUTE_READ (execute implies read - D065), and each read is clamped to the single page holding the IP (the end of it for the instruction, the start of it for the lead-up), so it can never reach an unmapped neighbour. No allocation, fixed stack buffers, one write - the async-safety the handler already keeps. Line's capacity rose to 1024 so the two hex runs cannot push the register and frame lines out.

What it found, immediately. The shared wall PPSA02664 and PPSA25872 both hit disassembles cleanly:

mov edx, 0x10 ; mov ecx, 0xc ; xor r8d, r8d ; mov dword [rsp], 0
call image+0x7b5890          ; returns rax
lea rsi/rdi/rdx, [rip+…]      ; the three exactly match the fault's rsi/rdi/rdx
mov [rax], rax               ; FAULT - rax is 0, the value the call returned
mov [rax+8], rax ; mov [rax+0x10], rax ; mov word [rax+0x18], 1

So it is not the memory-management calls that were "just before" it: the guest calls a function at image+0x7b5890, that function returns 0, and the guest dereferences the result without checking - initialising a self-referential structure ([P]=P; [P+8]=P - an empty circular-list sentinel, the shape a std::mutex/list/once head constructs to) through a null this. The register triple confirms the decode: the three lea [rip+…] compute exactly rsi, rdi, rdx as the dump shows them. And it ruled a hypothesis out honestly: ORBISTOUN_MAP_SHAPE=reserved-low (a non-zero physical base, the shape that exists because "real hardware does not hand a guest physical zero", D083/D218) changed nothing, so the null is not the direct-memory pool starting at zero.

The wall is now a precise question - why does image+0x7b5890 return zero - rather than an address, and the tool to answer it exists. Not chased further here: naming that function or tracing its own dependency (the top unimplemented imports _init_env and __cxa_decrement_exception_refcount are candidates) is the next drill, and blind-stubbing _init_env without its contract is exactly the pointer-versus-error-code guess the finding warns against.

And the furthest title's wall, from the same capability: the thread pointer is never installed. PPSA28061 (56 imports, the furthest measured) faults at image+0x43c4, which disassembles to mov rax, fs:[0] - a read through the fs segment base, the thread-self pointer at the top of the TLS block - and the read is of 0x0, so the fs base is zero. The mechanism to set it exists and is tested (orbistoun_abi::thread_pointer::install, the D061 layout work), but it "sat finished and unused" because no title examined had ever declared a thread-local: PPSA28061 is the title that needs it, and the run path installs no guest fs base, so its first fs:-relative access reads the host's (zero on Windows, which keeps its TEB in gs). This is the honest-failure case the module was written for - not silently running with a wrong pointer. Wiring it is the next subsystem: a per-thread TLS block (with the .tdata image copied and the self-pointer written at [TP]), the fs base installed and read back, on the main thread at entry and on every spawn (thread.rs's spawn body enters the guest with no install today). Recorded rather than half-built: a wrong fs base on the host thread destabilises every run, so this wants a clean start with its own tests, not the tail of a long session. The _sceUltUlthreadCreate calls in the same run (libSceUlt user-level threads, unimplemented) are a separate threading subsystem behind it, not the cause of this fault.