Skip to content

feat(dwarf): emit DWARF debug sections behind --debug-line (VCR-DBG-001, #242, #394)#429

Merged
avrabe merged 2 commits into
mainfrom
vcr-dbg-001-debug-line-emit
Jun 22, 2026
Merged

feat(dwarf): emit DWARF debug sections behind --debug-line (VCR-DBG-001, #242, #394)#429
avrabe merged 2 commits into
mainfrom
vcr-dbg-001-debug-line-emit

Conversation

@avrabe

@avrabe avrabe commented Jun 22, 2026

Copy link
Copy Markdown
Contributor

What — PR B of v0.12.0 (DWARF)

With --debug-line, synth emits a full DWARF unit (.debug_info/.debug_abbrev/.debug_str/.debug_line) into the relocatable ELF, mapping ARM .text addresses back to the input wasm's source lines via PR A's per-instruction line_map (#427).

Pipeline: read the input wasm's .debug_line (gimli, now a production dep of synth-core — auto-resolved by Bazel via from_cargo #422) → compose func_offset + machine_offset → op_offsets[op_idx] → op_offsets_to_source → source line → emit a real DW_TAG_compile_unit whose DW_AT_stmt_list points at .debug_line → add the sections as non-ALLOC trailing PROGBITS (after .text/.data/.bss, so the hardcoded with_section(4/5/6) symbol indices are undisturbed).

Frozen-safe

The entire emit is behind if debug_line (default off) → default build byte-identical. Two oracles (dwarf_debug_line_emit_394.rs), independently re-run:

  • Additivity (byte-diff): DWARF input (msgq) → .text/.data/.bss byte-identical with/without the flag, .debug_* present only under it; no-DWARF input (gust_kernel) → whole .o byte-identical.
  • Reachability (correctness): the emitted DWARF is walked via the normal gimli::Dwarf::units() → CU DW_AT_stmt_list → line-program path (the path a debugger uses), resolving 110 in-range .text addresses to non-zero source lines (e.g. .text+0x023c → line 175).

Experimental scope (honest boundary — gates the v0.12.0 tag, not this merge)

Addresses are object-relative (.text base 0) with no .rela.debug_* relocations yet — correct for the unlinked object, but they shift by the load base once linked against the TCB. The flag's help text says so. PR C (VCR-DBG-002) generalizes the elf_builder's .rel.text-only relocation machinery to emit .rela.debug_* against the .text symbol — required before v0.12.0 is tagged, so the flag is never released in the object-relative-only state.

ARM only; RISC-V carries an empty line_map (follow-up).

Verification

  • cargo test --workspace --exclude synth-verify green; the 3 oracles pass (independently re-run)
  • cargo fmt --check clean; cargo clippy --workspace --exclude synth-verify --all-targets -- -D warnings clean

Refs #242, #394. Builds on #427 (PR A).

🤖 Generated with Claude Code

avrabe and others added 2 commits June 22, 2026 22:09
…01, #242, #394)

PR B of v0.12.0: with `--debug-line`, synth emits a full DWARF unit
(`.debug_info`/`.debug_abbrev`/`.debug_str`/`.debug_line`) into the
relocatable ELF, mapping ARM `.text` addresses back to the input wasm's
source lines via PR A's per-instruction line_map.

Pipeline: read the input wasm's `.debug_line` (gimli, now a production dep of
synth-core — auto-resolved by Bazel via from_cargo), compose
`func_offset + machine_offset → op_offsets[op_idx] → op_offsets_to_source →
source line`, emit a real `DW_TAG_compile_unit` whose `DW_AT_stmt_list` points
at `.debug_line`, and add the sections as NON-ALLOC trailing PROGBITS (after
`.text`/`.data`/`.bss`, so the hardcoded `with_section(4/5/6)` symbol indices
are undisturbed).

Frozen-safe: the entire emit is behind `if debug_line` (default off), so the
default build is byte-identical. Oracles (dwarf_debug_line_emit_394.rs):
  - additivity: on a DWARF input (msgq) `.text`/`.data`/`.bss` are
    byte-identical with/without the flag and the `.debug_*` sections appear
    only under it; on a no-DWARF input (gust_kernel) the whole `.o` is
    byte-identical.
  - reachability: the emitted DWARF is walked via the NORMAL gimli
    `dwarf.units()` → CU `DW_AT_stmt_list` line-program path (the path a
    debugger uses), resolving 110 in-range `.text` addresses to non-zero
    source lines.

EXPERIMENTAL scope: addresses are object-relative (`.text` base 0) with no
`.rela.debug_*` yet, so they are correct for the unlinked object but shift by
the load base once linked. PR C (VCR-DBG-002) generalizes the elf_builder's
`.rel.text`-only relocation machinery to emit `.rela.debug_*` against the
`.text` symbol — required before v0.12.0 is tagged. ARM only; RISC-V is a
follow-up.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The hand-written rust_library `deps` in crates/BUILD.bazel are not generated
from Cargo.toml, so moving gimli to a production dependency of synth-core
(which cargo honours) left the Bazel target compiling synth-core without it →
`error[E0433]: unresolved crate gimli` in "Bazel Build & Proofs". from_cargo
makes the `@crates//:gimli` alias available; the manual target must still list
it. Verified `bazel build //crates:synth` green.
@codecov

codecov Bot commented Jun 22, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 93.88889% with 11 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
crates/synth-core/src/dwarf_line.rs 92.24% 9 Missing ⚠️
crates/synth-cli/src/main.rs 96.87% 2 Missing ⚠️

📢 Thoughts on this report? Let us know!

@avrabe avrabe merged commit a89ef28 into main Jun 22, 2026
15 checks passed
@avrabe avrabe deleted the vcr-dbg-001-debug-line-emit branch June 22, 2026 20:51
avrabe added a commit that referenced this pull request Jun 22, 2026
, #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>
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.

1 participant