Skip to content

--native-pointer-abi + --shadow-stack-size refuses wit-bindgen buffer node: inline linmem statics not down-shifted into .data (VCR-MEM-001 layer-2) #678

Description

@avrabe

Summary

Dissolving a Component-Model composed node that carries buffers (wit-bindgen list<u8> across the seam — gale's gust:os syscall seam, the log capability) with --native-pointer-abi --shadow-stack-size <N> refuses:

Error: --shadow-stack-size: a native-pointer static access addends 1049612 into the
[0, sp_init) reservation (not the region base, not retargeted into .data);
down-shifting inline statics is the deferred general case. Refusing rather than
mis-addressing. VCR-MEM-001/#383.

1049612 = 0x10004C = the standard wasm linmem base 0x100000 + 0x4C — a data-segment constant (the canonical-ABI glue / a list<u8> literal) accessed as an inline static, which the native-pointer path can retarget to __synth_wasm_data only for the region-base case, not this addend-into-reservation case.

Why it matters (gale)

This is the exact blocker for buffer-carrying gust:os capabilities on a tiny MCU. The all-scalar path is perfect: gale's drivers and the gust:os time interface (u64/u32 only) dissolve to 0 SRAM cleanly. But the moment an interface carries a buffer (log: func(msg: list<u8>), and later channel/io), the wit-bindgen canonical ABI puts data/realloc in linmem, and --native-pointer-abi --shadow-stack-size (the F100 8-KiB-budget path, #383) refuses. Without it, synth reserves the full linmem page (64 KiB) → RAM-prohibitive on an 8-KiB part.

So: scalar CM nodes fit 8 KiB today; buffer-carrying CM nodes need the inline-static down-shift (retarget addend-into-linmem statics into the re-based .data/region) to fit. Larger-SRAM targets (64 KiB M3, M4) are unaffected — this is specifically the tiny-node budget path.

Ask

Implement the deferred general case in VCR-MEM-001/#383: down-shift inline linmem statics (addend-into-[0, sp_init)) into the re-based .data/__synth_wasm_data region under --native-pointer-abi --shadow-stack-size, so a buffer-carrying dissolved node links into an 8-KiB part.

Repro

gale gust:os step-2 node: app (imports gust:os/time+log) wac-plugged with time+log providers → meld fuse --memory shared → loom inline → synth compile --target cortex-m3 --all-exports --relocatable --native-pointer-abi --shadow-stack-size 2048. Happy to share the fused .wasm.

Kill-criterion: the above compile emits an ET_REL .o whose .data+.bss + declared shadow budget fits 8 KiB, and a semihosting run logs the expected bytes.

Activity

  1. avrabe commented on Jul 9, 2026

    @avrabe
    ContributorAuthor

    Broader than buffers: it's any linmem static, and it blocks the whole gust:os OS milestone on MCU. A spawn provider with a tiny cooperative task table — static mut DONE: [bool; 8] + static mut NEXT: usize — hits the identical refusal:

    Error: --shadow-stack-size: a native-pointer static access addends 1048584 into the
    [0, sp_init) reservation ... down-shifting inline statics is the deferred general case.
    Refusing rather than mis-addressing. VCR-MEM-001/#383.
    

    (1048584 = 0x100008 = linmem base 0x100000 + the static offset.)

    So it's not just wit-bindgen list<u8> buffers — a plain static mut array does it too. And since MCUs don't map RAM at 0x100000, every dissolved node that touches linmem needs --native-pointer-abi to relocate to real RAM, so this refusal gates all stateful/buffer CM nodes on any MCU target, not just the 8-KiB F100. Only pure-stateless-scalar nodes (gale's drivers, the gust:os time interface) escape it today.

    Impact: this is the blocker for gale's v0.4.0 gust:os syscall seam beyond the time capability — spawn/log/channel/io all need linmem statics. Bumping priority context: it's the critical path for the OS milestone, not a niche case. The inline-static down-shift (retarget addend-into-[0,sp_init) statics into the re-based .data/__synth_wasm_data) is what unblocks the whole layer.

  2. added 8 commits that reference this issue on Jul 10, 2026
  3. added a commit that references this issue on Sep 18, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions