Found by the VCR-VER-003 phase-2 probe (#777, PR #797)
The RV32 backend uses a single-base scheme (s11 = __linear_memory_base, provided by the generated linker script at _bss_end, zeroed at reset). The relocatable object ships .text only — neither the object, the generated startup.c, nor linker.ld carries the wasm module's active data segments. A module like
(module
(memory 1)
(data (i32.const 16) "\01\02\03\04")
(func (export "get") (result i32) i32.const 16 i32.load))
compiles clean, and get returns 0 at runtime instead of 0x04030201 — the #757-family silent drop (worse: unconditional, not overlap-dependent).
What phase 2 landed (PR #797)
validate_served_image(segments, &[]) runs unconditionally on the RV32 emit path and WARNS LOUDLY per nonzero un-served initializer byte (later-wins semantics: all-zero / zero-overwritten runtime images are genuinely served by zeroed RAM and stay silent).
Why it is a warning, not a hard decline (yet)
The CI-pinned RV32 frozen fixture (control_step.wasm, frozen_fixtures_rv32_text_is_bit_identical_oracle_001) carries a nonzero active segment (11 B at 65536) that its differential never reads — a hard decline would break the frozen compile-success gate. Flipping to a decline needs the refreeze ritual (or the real fix below) in its own evidence-gated PR.
The real fix (RV32 analogue of #758)
- Emit the packed initializer image into the object (e.g.
.wasm_data PROGBITS, later-wins dense image or per-segment with offsets),
- place it via the generated linker script at
__linear_memory_base + off (load address in flash),
- copy ROM→RAM in the generated startup (the existing
_data_load/_data_start pattern),
- validate the shipped image with the existing
validate_served_image (turn the warning into the mixed-split-style hard error on mismatch),
- differential: an RV32 module that READS its data segment vs wasmtime.
Until then the honest end-state per the #615 expand-or-loud-reject rule is a hard decline for nonzero-initializer modules on -b riscv.
🤖 Generated with Claude Code
https://claude.ai/code/session_01YJK5LZZEkV5smCY1jKn18L
Found by the VCR-VER-003 phase-2 probe (#777, PR #797)
The RV32 backend uses a single-base scheme (
s11 = __linear_memory_base, provided by the generated linker script at_bss_end, zeroed at reset). The relocatable object ships.textonly — neither the object, the generatedstartup.c, norlinker.ldcarries the wasm module's active data segments. A module likecompiles clean, and
getreturns0at runtime instead of0x04030201— the #757-family silent drop (worse: unconditional, not overlap-dependent).What phase 2 landed (PR #797)
validate_served_image(segments, &[])runs unconditionally on the RV32 emit path and WARNS LOUDLY per nonzero un-served initializer byte (later-wins semantics: all-zero / zero-overwritten runtime images are genuinely served by zeroed RAM and stay silent).Why it is a warning, not a hard decline (yet)
The CI-pinned RV32 frozen fixture (
control_step.wasm,frozen_fixtures_rv32_text_is_bit_identical_oracle_001) carries a nonzero active segment (11 B at 65536) that its differential never reads — a hard decline would break the frozen compile-success gate. Flipping to a decline needs the refreeze ritual (or the real fix below) in its own evidence-gated PR.The real fix (RV32 analogue of #758)
.wasm_dataPROGBITS, later-wins dense image or per-segment with offsets),__linear_memory_base + off(load address in flash),_data_load/_data_startpattern),validate_served_image(turn the warning into the mixed-split-style hard error on mismatch),Until then the honest end-state per the #615 expand-or-loud-reject rule is a hard decline for nonzero-initializer modules on
-b riscv.🤖 Generated with Claude Code
https://claude.ai/code/session_01YJK5LZZEkV5smCY1jKn18L