Skip to content

Commit 6795ab3

Browse files
avrabeclaude
andauthored
chore(release): v0.11.45 — #354 per-region .bss/.data split (pin sweep + changelog) (#357)
Feature release bundling gale #354 (#356): native-pointer mixed-memory modules (stack/msgq decides) now ship a bounded .data instead of a 64 KiB PROGBITS blob — per-region .bss/.data split with per-region symbols + in-place REL addend retargeting in build_relocatable_elf (selector untouched; safe-by-construction gate on offset >= wasm_data_base + Abs32-only static relocs). Pin sweep: workspace.package 0.11.44 -> 0.11.45 across all 11 publishable crate manifests + path-dep pins + MODULE.bazel + Cargo.lock. rivet GI-NPA-004 -> implemented. Non-mixed paths byte-identical (control_step, native_pointer_bss); four frozen differentials green. On-target gate is gale's silicon run. Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
1 parent ea5ee43 commit 6795ab3

14 files changed

Lines changed: 97 additions & 45 deletions

File tree

CHANGELOG.md

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,52 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
77

88
## [Unreleased]
99

10+
## [0.11.45] - 2026-06-14
11+
12+
**ON-TARGET SHIPPABILITY — gale #354: a high-offset init segment no longer
13+
defeats the `.bss` split. Native-pointer mixed-memory modules (`stack`/`msgq`
14+
decides) ship a bounded `.data` instead of a 64 KiB PROGBITS blob.**
15+
16+
- **#354 — per-region `.bss`/`.data` split for high-offset init segments**
17+
(#356): the #345 zero-init split was binary
18+
(`split_linmem_bss = native_layout.is_some() && data_segments.is_empty()`), so
19+
ANY initialized `(data)` segment fell to the one-PROGBITS arm. A small
20+
`.rodata` const at a HIGH linmem offset (gale's `stack_push`: a 12-byte
21+
`0xfffffff4` = -12/-ENOMEM at offset 65536, above the 64 KiB shadow stack)
22+
dragged the whole zero gap into a **65552-byte PROGBITS `.data`**
23+
(MCU-unshippable; `msgq` was 65556). `build_relocatable_elf` now splits the
24+
mixed case PER REGION using per-region **symbols**: the zero reservation is a
25+
NOBITS `.bss` (`__synth_wasm_data`); each init segment is packed into a small
26+
PROGBITS `.data` under its own `__synth_wasm_seg_K`; and every
27+
`__synth_wasm_data + C` static reloc whose addend `C` lands in segment K is
28+
retargeted to `__synth_wasm_seg_K + (C - seg_off_K)` — both the symbol AND the
29+
in-place REL addend word in `.text` (`R_ARM_ABS32` is `S + A`). Per-region
30+
*symbols* (not just sections) let the linker place the sections
31+
independently — a single base symbol + selector-baked addends can't span the
32+
link gap (the fragility the #345 code comment deferred). The selector is
33+
untouched. **Safe-by-construction gate:** the split fires only when every init
34+
segment sits at offset `>= wasm_data_base` (the SP-global init — the exact
35+
static-vs-frame boundary the selector already uses) AND every
36+
`__synth_wasm_data` reloc is the retargetable `Abs32` form; otherwise it falls
37+
back to the one-PROGBITS arm (fat but always correct, never mis-addressed).
38+
Measured on the `high_offset_init_segment_354` repro: `.data` **65552 → 16
39+
bytes**, `.bss` 65548 NOBITS; the reloc retargets to `__synth_wasm_seg_0` with
40+
the in-place addend rewritten 65544 → 8. This is the mixed-case deferred in the
41+
#345 comment coming due — NOT a v0.11.44 regression; #350 just made
42+
`stack_push` compile far enough to expose it.
43+
44+
**Falsification:** wrong if a native-pointer module with a `(data)` segment at
45+
offset `>= wasm_data_base` still emits a 64 KiB PROGBITS `.data`; or if the
46+
retargeted symbol/addend mis-resolves the const (the `native_pointer_shadow_stack`
47+
differential would drop below ORACLE PASS). The non-mixed paths stay
48+
byte-identical: `control_step` (non-native, `0x00210A55`) and
49+
`native_pointer_bss` (the #345 all-zero NOBITS `.bss` shape) compile to the
50+
same SHA with/without the change; the four frozen differentials (control_step
51+
`0x00210A55`, flight_seam `0x07FDF307`, div_const 338/338, mutex_pressure)
52+
stay green. **Closing gate is gale's on-target run**`stack`/`msgq` `.data`
53+
bounded + `stack_pop` shim+silicon end-to-end, to run when this tags; synth-side
54+
is not marked verified alone.
55+
1056
## [0.11.44] - 2026-06-14
1157

1258
**ENCODER ROBUSTNESS — gale #350: out-of-range `ADD #imm` now lowers instead of

Cargo.lock

Lines changed: 17 additions & 17 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ resolver = "2"
2727
# semver to publish, so the convention now catches up: workspace
2828
# version follows the release tag, bumped pre-tag in the release
2929
# checklist. See docs/release-process.md.
30-
version = "0.11.44"
30+
version = "0.11.45"
3131
edition = "2024"
3232
rust-version = "1.88"
3333
authors = ["PulseEngine Team"]

MODULE.bazel

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ module(
77
name = "synth",
88
# Kept in lockstep with [workspace.package] version in Cargo.toml.
99
# Both are bumped pre-tag — see docs/release-process.md.
10-
version = "0.11.44",
10+
version = "0.11.45",
1111
)
1212

1313
# Bazel dependencies

artifacts/gale-integration.yaml

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -541,9 +541,15 @@ artifacts:
541541
access against the symbol of the region the offset falls in. Sound
542542
only if init-data accesses are statically separable from the zero
543543
region (the rodata const is reached only by a static address, never by
544-
a dynamic pointer that also walks the shadow stack) — to be confirmed
545-
against gale's stack_push.loom.wasm before implementation.
546-
status: proposed
544+
a dynamic pointer that also walks the shadow stack) — the split fires
545+
only when every init segment sits at offset >= wasm_data_base (the
546+
SP-global init the selector uses for static-vs-frame), else it falls back
547+
to the one-PROGBITS arm (correct, never mis-addressed). Implemented in
548+
#356 (v0.11.45): per-region symbols (__synth_wasm_seg_K) + in-place REL
549+
addend retargeting in build_relocatable_elf; selector untouched. On-target
550+
confirmation (stack/msgq .data bounded + stack_pop shim+silicon) is gale's
551+
gate, run when v0.11.45 tags.
552+
status: implemented
547553
tags: [gale, native-pointer-abi, bss, elf, mcu-shippability, release-v0.11.45]
548554
links:
549555
- type: derives-from

crates/synth-backend-awsm/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,6 @@ categories.workspace = true
1111
description = "aWsm backend integration for the Synth compiler"
1212

1313
[dependencies]
14-
synth-core = { path = "../synth-core", version = "0.11.44" }
14+
synth-core = { path = "../synth-core", version = "0.11.45" }
1515
anyhow.workspace = true
1616
thiserror.workspace = true

crates/synth-backend-riscv/Cargo.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,8 @@ categories.workspace = true
1111
description = "RISC-V encoder, ELF builder, PMP allocator, and bare-metal startup for synth"
1212

1313
[dependencies]
14-
synth-core = { path = "../synth-core", version = "0.11.44" }
15-
synth-synthesis = { path = "../synth-synthesis", version = "0.11.44" }
14+
synth-core = { path = "../synth-core", version = "0.11.45" }
15+
synth-synthesis = { path = "../synth-synthesis", version = "0.11.45" }
1616
anyhow.workspace = true
1717
thiserror.workspace = true
1818
tracing.workspace = true

crates/synth-backend-wasker/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,6 @@ categories.workspace = true
1111
description = "Wasker backend integration for the Synth compiler"
1212

1313
[dependencies]
14-
synth-core = { path = "../synth-core", version = "0.11.44" }
14+
synth-core = { path = "../synth-core", version = "0.11.45" }
1515
anyhow.workspace = true
1616
thiserror.workspace = true

crates/synth-backend/Cargo.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ default = ["arm-cortex-m"]
1515
arm-cortex-m = ["synth-synthesis"]
1616

1717
[dependencies]
18-
synth-core = { path = "../synth-core", version = "0.11.44" }
19-
synth-synthesis = { path = "../synth-synthesis", version = "0.11.44", optional = true }
18+
synth-core = { path = "../synth-core", version = "0.11.45" }
19+
synth-synthesis = { path = "../synth-synthesis", version = "0.11.45", optional = true }
2020
anyhow.workspace = true
2121
thiserror.workspace = true

crates/synth-cli/Cargo.toml

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -27,18 +27,18 @@ verify = ["synth-verify"]
2727
# Path deps carry `version` so `cargo publish` rewrites them to the
2828
# crates.io coordinate. Bumping the workspace version requires
2929
# updating these in lockstep — see docs/release-process.md.
30-
synth-core = { path = "../synth-core", version = "0.11.44" }
31-
synth-frontend = { path = "../synth-frontend", version = "0.11.44" }
32-
synth-synthesis = { path = "../synth-synthesis", version = "0.11.44" }
33-
synth-backend = { path = "../synth-backend", version = "0.11.44" }
30+
synth-core = { path = "../synth-core", version = "0.11.45" }
31+
synth-frontend = { path = "../synth-frontend", version = "0.11.45" }
32+
synth-synthesis = { path = "../synth-synthesis", version = "0.11.45" }
33+
synth-backend = { path = "../synth-backend", version = "0.11.45" }
3434

3535
# Optional external backends
36-
synth-backend-awsm = { path = "../synth-backend-awsm", version = "0.11.44", optional = true }
37-
synth-backend-wasker = { path = "../synth-backend-wasker", version = "0.11.44", optional = true }
38-
synth-backend-riscv = { path = "../synth-backend-riscv", version = "0.11.44", optional = true }
36+
synth-backend-awsm = { path = "../synth-backend-awsm", version = "0.11.45", optional = true }
37+
synth-backend-wasker = { path = "../synth-backend-wasker", version = "0.11.45", optional = true }
38+
synth-backend-riscv = { path = "../synth-backend-riscv", version = "0.11.45", optional = true }
3939

4040
# Optional verification (requires z3)
41-
synth-verify = { path = "../synth-verify", version = "0.11.44", optional = true, features = ["z3-solver", "arm"] }
41+
synth-verify = { path = "../synth-verify", version = "0.11.45", optional = true, features = ["z3-solver", "arm"] }
4242

4343
# Optional PulseEngine WASM optimizer
4444
# Uncomment when loom crate is available:

0 commit comments

Comments
 (0)