2026-09-08 - The payload leg completes, and all three shapes run end to end

With the eboot leg fixed (161), the payload was the last shape that had never completed on hardware: ~9 records then SIGBUS at the first check, a garbled OBS|sink, and guard|on|not initialised. This session found why and fixed it. Documented in D327.

A wrong turn, and the diagnostic that corrected it

The garbled, run-varying sink read like an un-applied relocation, so the first attempt added an idempotent self-relocation to obscene_start. It changed nothing - the records came back identical. A direct diagnostic (base, and .data vs .bss read/write tests, over the working boot-note channel) settled it in one run: .data loads and writes fine, relocations are applied, but .bss comes up as garbage (bss init(exp 0)=0x7645304445457749). elfldr does not zero the p_memsz-beyond-p_filesz tail of the writable PT_LOAD, so every zero-initialised static starts as whatever was in the page - s_inited (the guard never installs), obs_sink_tried (the sink returns its uninitialised buffer), and the crash at check one, all the same cause.

The fix

obs_zero_bss() runs first in obscene_start: it takes the load base from __ehdr_start (link-time vaddr 0, so its PC-relative address is the base), walks the program headers, and zeroes [p_vaddr+p_filesz, p_vaddr+p_memsz) for each PT_LOAD. Gated by -DOBS_ZERO_BSS on the payload target only; the eboot and module keep their loader's own zeroing. The self-relocation was removed

Hardware, payload leg: OBS|sink|/mnt/usb0/obscene/report.txt, OBS|guard|on|installed (local setjmp) sa=1 spm=1 pex=1, no fault, OBS|tally|62|10|27|165|0, OBS|end - 3706 records, the whole suite, where it had never passed check one. make check green.

Where it stands

All three delivery shapes now run end to end: payload (D327), package, and native eboot (D326). ./bin/obscene sweep produces the six timestamped files, two per leg, in one command, and the teardown no longer hangs when a leg finishes fast (161).

Surprise worth keeping

guard|on|not initialised had been the answer from the start: s_available is .bss (read wrong) and s_detail is initialised .data (read right), and the two disagreeing is "the loader did not zero .bss", stated in the report. A contradiction in the output was a measurement, not noise.