Skip to content

fix(#359): native-pointer .bss sizing for Abs32 static accesses + v0.11.48 (silicon-confirmed)#375

Merged
avrabe merged 4 commits into
mainfrom
fix/359-368x354-retarget
Jun 18, 2026
Merged

fix(#359): native-pointer .bss sizing for Abs32 static accesses + v0.11.48 (silicon-confirmed)#375
avrabe merged 4 commits into
mainfrom
fix/359-368x354-retarget

Conversation

@avrabe

@avrabe avrabe commented Jun 18, 2026

Copy link
Copy Markdown
Contributor

Closes #359silicon-confirmed by gale on G474RE (rc=0, val=0xABCD, correct round-trip). Ships as v0.11.48. Clears msgq's last on-target blocker.

Root cause (the #354 × #368 interaction)

The dissolved k_msgq_put returned rc=-35: the action→ret lookup reads a zero word at offset 65552 (table tail, past the 16-byte init segment), but .bss was sized to the init-segment end → the access landed at __bss_end → garbage → queue-full on an empty queue. build_relocatable_elf's static_top/used_extent filtered RelocKind::MovwAbs, but the native-pointer path emits Abs32 literal-pool relocs — so it saw nothing and under-sized .bss. New static_top_abs32 reads C from each __synth_wasm_data Abs32 literal → .bss spans every accessed offset.

Not the retarget-completeness first assumed — the naive boundary tweak would have mis-pointed the access at __synth_globals. General native-pointer bug: native_pointer_bss (store@256, .bss was 4) grows 4→264 (.bss NOBITS, zero binary bloat; only the .bss sh_size changed, code byte-identical).

Verification

  • Post-link oracle (scripts/repro/postlink_359_oracle.py — links the real image, asserts no __synth_wasm_data literal resolves past __bss_end; the structural fix to the .o-only oracle that let fix(selector): #359 — relocate dynamic-index static-data accesses under native-pointer ABI #368 pass locally and fail on silicon): FAIL → PASS.
  • Three frozen fixtures byte-identical (control_step 0x00210A55, flight_seam 0x07FDF307, div_const 338/338); native-pointer numeric differential PASS; 32 cli tests green.
  • gale silicon (G474RE): rc=0, val=0xABCD, round-trip on an empty queue (was rc=-35/val=0x0).
  • Release: pin sweep 0.11.47→0.11.48, CHANGELOG falsification, rivet GI-NPA-005 → verified.

Closes #359.

🤖 Generated with Claude Code

avrabe and others added 4 commits June 18, 2026 07:56
…y mistake

#368 passed a unicorn-on-.o oracle but failed on silicon (rc=-35) because the
#354 link-time retargeting is invisible to a flat-memory .o model. This builds
the actual linked image (postlink.ld mimics Zephyr: __synth_wasm_seg_0 in .data,
__synth_wasm_data == __bss_start in .bss; zephyr_stubs.s for the 6 kernel undefs)
and asserts gale's invariant: no __synth_wasm_data + C literal in the STATIC
region (C >= wasm_data_base) may resolve into [__bss_start, __bss_end).

Pre-fix (v0.11.47) it FAILS with 4 violations: `__synth_wasm_data + 65552`
(the action->ret table accessed at offset 65552 = the EXCLUSIVE END of the
16-byte segment [65536,65552)) resolves into .bss instead of seg_0 (.data) —
the #354 retargeting's `c < off+len` check excludes the boundary. So the table
lookup reads .bss zero -> "queue full" on an empty queue -> rc=-35. Frame
accesses (C < wasm_data_base) correctly stay in .bss and are NOT flagged.

Necessary, not sufficient: gale's G474RE re-test stays the final gate (runtime
index + Thumb effects). Fix (next block): make #354 retargeting cover the
segment-boundary/end offset (and any static-region C) so it lands in seg_K.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
… x #368 root cause)

gale's msgq rc=-35: the action->ret table lookup reads a ZERO word at linmem
offset 65552 (the table tail, just past the 16-byte init segment), but the .bss
reservation was sized to exactly 65552 — so the access lands at __bss_end and
reads garbage, taking the queue-full branch on an empty queue.

Root cause: build_relocatable_elf's `static_top` (the .bss/used_extent sizing)
filtered `RelocKind::MovwAbs` relocs, but the native-pointer path relocates
static-data accesses as Abs32 LITERAL-POOL words (`S + A`). So static_top saw
nothing, used_extent fell back to the init-segment end, and EVERY high-offset
native-pointer access past that end read past the reservation. New
`static_top_abs32` reads the addend C from each `__synth_wasm_data` Abs32 literal
(in-place .text word, pre-retarget) so used_extent spans every offset the code
touches.

This is a GENERAL native-pointer .bss-undersizing bug, not msgq-specific:
native_pointer_bss.wat (`i32.store (i32.const 256) ...`) had .bss=4 while writing
at offset 256 — a latent past-reservation write; the fix grows its .bss 4->264
(NOBITS, no binary bloat). .bss is the only delta (code byte-identical).

Verified: scripts/repro/postlink_359_oracle.py (links the real image, asserts no
__synth_wasm_data literal resolves past __bss_end) FAIL->PASS; native_pointer_
shadow_stack differential PASS; 32 synth-cli tests pass; the three frozen fixtures
(control_step 0x00210A55, flight_seam 0x07FDF307, div_const 338/338) byte-identical.

NECESSARY-NOT-SUFFICIENT: the post-link oracle can't model the runtime msgq
round-trip — gale's G474RE rc=0 stays the final gate. HELD for silicon.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…onfirmed)

Pin sweep 0.11.47 -> 0.11.48 (workspace + 10 path-deps + MODULE.bazel +
Cargo.lock). CHANGELOG v0.11.48 with falsification. rivet GI-NPA-005 -> verified
(gale G474RE rc=0 + val=0xABCD round-trip). The #359 .bss-undersizing fix is in
870920d; this is the release bump.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@avrabe avrabe merged commit 636d95e into main Jun 18, 2026
14 checks passed
@avrabe avrabe deleted the fix/359-368x354-retarget branch June 18, 2026 22:08
@codecov

codecov Bot commented Jun 18, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 95.83333% with 1 line in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
crates/synth-cli/src/main.rs 95.83% 1 Missing ⚠️

📢 Thoughts on this report? Let us know!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Arg-register lowering drops/shifts the first arg for calls with 5 args + struct(sret) return (cortex-m4f, --native-pointer-abi)

1 participant