Skip to content

Commit 068f6ed

Browse files
avrabeclaude
andauthored
chore(release): v0.12.0 — DWARF source-line debugging (VCR-DBG-001, #242, #394) (#440)
First release of the north-star verified-codegen campaign. Pin sweep 0.11.51 -> 0.12.0 (workspace + all path-dep versions + MODULE.bazel + Cargo.lock), CHANGELOG, and VCR-DBG-001 roadmap status -> implemented. Ships: - VCR-DBG-001 `--debug-line` DWARF emission (PR A #427 / B #429 / C #430): debugger-readable .debug_* mapping ARM .text -> wasm source lines, with .rel.debug_* relocations verified end-to-end against arm-none-eabi-ld. Purely additive; default build bit-identical. - VCR-MEM-001 layer-2 frozen-safe budget decision logic + oracles (#421-#425). - gimli 0.33 adaptation (#439) + wast 252 (#438). Minor bump: new user-facing `--debug-line` feature (semver-correct). Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
1 parent 9c4c005 commit 068f6ed

15 files changed

Lines changed: 237 additions & 139 deletions

File tree

CHANGELOG.md

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

88
## [Unreleased]
99

10+
## [0.12.0] - 2026-06-23
11+
12+
**DWARF SOURCE-LINE DEBUGGING — `--debug-line` (VCR-DBG-001, #394, epic #242).**
13+
The first release of the north-star verified-codegen campaign. `synth compile
14+
--debug-line` now emits debugger-readable DWARF (`.debug_info` / `.debug_abbrev`
15+
/ `.debug_str` / `.debug_line`) mapping ARM `.text` addresses back to the input
16+
wasm's source lines, so a synth-compiled relocatable object can be debugged at
17+
source level in gdb/lldb (and on-silicon via Renode) after linking. Built in
18+
three behavior-frozen steps — the feature is **purely additive**: with the flag
19+
off (the default) `.text`/`.data`/`.bss` and every frozen differential fixture
20+
stay **bit-identical**.
21+
22+
- **PR A (#427)** — capture a per-instruction `machine_offset → wasm_op_index`
23+
source map (`CompiledFunction.line_map`) during ARM encoding. Additive: the map
24+
is never serialized, so `.text` is byte-identical.
25+
- **PR B (#429)** — emit a full DWARF unit behind `--debug-line` (the CU's
26+
`DW_AT_stmt_list` reaches the line table the normal `dwarf.units()` way).
27+
Promotes `gimli` to a production dependency.
28+
- **PR C (#430)** — emit `.rel.debug_*` relocations against a `__synth_text_base`
29+
symbol so a host linker fixes up the embedded `.text` addresses to the final
30+
load address. Verified end-to-end with a real `arm-none-eabi-ld` link:
31+
`readelf --debug-dump=decodedline` resolves the relocated addresses to the
32+
correct source lines. Generalizes the ELF builder to per-section REL tables
33+
(frozen-safe: `.rel.text` stays byte-identical).
34+
- *Experimental caveat:* `__synth_text_base` is a global symbol, so linking
35+
more than one `--debug-line` object into a single image collides (fails loud
36+
with `multiple definition`); a local-section-symbol follow-up is tracked.
37+
- On a self-contained (`ET_EXEC`) or RISC-V build, `--debug-line` is a no-op
38+
and warns (DWARF is emitted only on the ARM relocatable-object path).
39+
40+
**VCR-MEM-001 layer-2 (frozen-safe scaffolding, #383/#242).** Added the
41+
scry-proven shadow-stack budget decision logic (`budget_from_bound` over a
42+
synth-owned `StackDepthBound`) plus its end-to-end and honest-fail oracles. Pure
43+
analysis/test code — no production wiring, no output change. The byte-changing
44+
`--shadow-stack-size auto` step remains separately gated.
45+
46+
### Internal
47+
48+
- Adapted the DWARF emitter to gimli 0.33's 6-argument `LineProgram::new`
49+
(dependabot #436; fix #439). Bumped `wast` to 252 (#438).
50+
1051
## [0.11.51] - 2026-06-22
1152

1253
**NATIVE-POINTER SHADOW-STACK SHRINK — #383 (VCR-MEM-001 layer-1): the

Cargo.lock

Lines changed: 27 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.51"
30+
version = "0.12.0"
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.51",
10+
version = "0.12.0",
1111
)
1212

1313
# Bazel dependencies

MODULE.bazel.lock

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

artifacts/verified-codegen-roadmap.yaml

Lines changed: 23 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1478,20 +1478,29 @@ artifacts:
14781478
silently-wrong source lines after host-link. The v0.12.0 TAG is HELD for
14791479
step 5c (advisor-confirmed: PR B in main is default-off + frozen-safe, so
14801480
it banks the work at zero risk; the tag waits for relocations).
1481-
- step (5c) RELOCATIONS — PR C, REQUIRED before the v0.12.0 tag:
1482-
C1 = generalize elf_builder's `.rel.text`-ONLY relocation machinery to
1483-
PER-SECTION relocations, **REL form (not RELA)** — synth/ARM32 uses REL
1484-
with the addend stored in-place (`.rel.debug_*`, matching the existing
1485-
`.rel.text` convention); frozen-safe, gated on the existing `.rel.text`
1486-
fixtures (cabi_arena_realloc_linkability_418) staying byte-identical.
1487-
C2 = emit DWARF addresses via gimli `Address::Symbol{text_sym, addend}`,
1488-
extract the relocations, emit `.rel.debug_line` / `.rel.debug_info`
1489-
against the `.text` symbol. The C2 ORACLE must APPLY the relocations at a
1490-
NONZERO `.text` base and verify the address resolves to the CORRECT
1491-
source line (not merely that a reloc record exists). Advisor caution:
1492-
"do NOT rush the addend math into a debug-info path — careful (even next
1493-
session) beats fast."
1494-
status: approved
1481+
- step (5c) RELOCATIONS LANDED (PR C #430, merged 9a34c8d; SHIPS in
1482+
v0.12.0): C1 generalized elf_builder's `.rel.text`-ONLY machinery to
1483+
PER-SECTION REL tables (`extra_relocations` + `add_section_relocations`;
1484+
`.rel.debug_*`, REL in-place addend); byte-identical when off — the
1485+
frozen gust whole-`.o` no-op oracle is the end-to-end proof, and
1486+
cabi_arena_realloc_linkability_418 `.rel.text` stays byte-identical.
1487+
C2: a custom gimli `write::Writer` (`RelocWriter`) overrides ONLY
1488+
`write_address`, so just the two `.text` references (line program
1489+
`DW_LNE_set_address` + CU `DW_AT_low_pc`) become `R_ARM_ABS32` against a
1490+
global `__synth_text_base` (st_shndx=.text, value 0); internal DWARF
1491+
cross-refs stay concrete (do NOT use gimli's blanket `RelocateWriter`).
1492+
Addend 0 ⇒ `.debug_*` bytes byte-identical to PR B. Oracle
1493+
`rel_debug_relocations_shift_addresses_to_correct_line_394` applies the
1494+
reloc at a NONZERO base and asserts every row shifts by exactly the base
1495+
with its source line preserved; CONFIRMED end-to-end with a real
1496+
`arm-none-eabi-ld -Ttext=0x08000000` link (readelf decodedline → correct
1497+
lines). FAST-FOLLOW: `__synth_text_base` is global ⇒ linking >1
1498+
`--debug-line` object collides (fails LOUD); local-STT_SECTION fix is
1499+
blocked by the hardcoded `.symtab` sh_info=1 — jumps priority iff a
1500+
consumer links multiple synth objects. GOTCHA recorded: dependabot #436
1501+
(gimli 0.31→0.33, `LineProgram::new` 5→6 args) broke main after PR C
1502+
merged textually-clean on a stale base; fixed in #439.
1503+
status: implemented
14951504
tags: [toolchain, dwarf, debuggability, elf, meld-coordination, feature-loop, release-v0.12.0, synth-394]
14961505
links:
14971506
- 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.51" }
14+
synth-core = { path = "../synth-core", version = "0.12.0" }
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.51" }
15-
synth-synthesis = { path = "../synth-synthesis", version = "0.11.51" }
14+
synth-core = { path = "../synth-core", version = "0.12.0" }
15+
synth-synthesis = { path = "../synth-synthesis", version = "0.12.0" }
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.51" }
14+
synth-core = { path = "../synth-core", version = "0.12.0" }
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.51" }
19-
synth-synthesis = { path = "../synth-synthesis", version = "0.11.51", optional = true }
18+
synth-core = { path = "../synth-core", version = "0.12.0" }
19+
synth-synthesis = { path = "../synth-synthesis", version = "0.12.0", optional = true }
2020
anyhow.workspace = true
2121
thiserror.workspace = true

0 commit comments

Comments
 (0)