Skip to content

feat(core): explicit DWARF policy with Strip default (#130 phase 1.5)#135

Merged
avrabe merged 3 commits into
mainfrom
chore/dwarf-strip-default
May 11, 2026
Merged

feat(core): explicit DWARF policy with Strip default (#130 phase 1.5)#135
avrabe merged 3 commits into
mainfrom
chore/dwarf-strip-default

Conversation

@avrabe
Copy link
Copy Markdown
Contributor

@avrabe avrabe commented May 10, 2026

Summary

Phase 1.5 of issue #130. Today meld passes input .debug_* sections
through verbatim while it rewrites and renumbers function bodies into
the merged code section, so every DWARF address ends up referencing
the wrong instruction. Downstream MC/DC tooling (pulseengine/witness)
trusts what gimli reads and silently produces wrong source-line
attribution for every br_if.

This PR makes the policy explicit and defaults to dropping DWARF
until Phase 2 ships an actual address-remap pass — wrong attribution
is strictly worse than no attribution because witness has a graceful
no-DWARF fallback that the lossy passthrough subverts.

Changes

  • New DwarfHandling::{Strip, PassThrough} enum on FuserConfig,
    default Strip.
  • lib.rs::encode_output filters .debug_* when Strip.
  • Recorded in attestation tool_parameters as
    dwarf_handling = "strip" | "passthrough" so consumers can detect
    lossy emissions; SR-28 sentinel test extended.
  • Three integration tests in meld-core/tests/dwarf_strip.rs pin the
    default-strip / passthrough-preserves / default-is-strip contract.
  • LS-CP-4 added to safety/stpa/loss-scenarios.yaml (approved, H-7).
  • 12 existing call sites that struct-literal-construct FuserConfig
    updated with the new field.

Why draft

Logical follow-up to #131 (Phase 1 discovery, also draft). The whole
witness-mapping epic stays draft until at least Phase 2 (address remap)
lands so the changelog story is one coherent fix instead of a "we
silently turned DWARF off" surprise.

Test plan

  • cargo test -p meld-core — 73 passed (lib + integration)
  • cargo test -p meld-core --test dwarf_strip — 3 passed
  • cargo clippy -p meld-core --all-targets -- -D warnings
  • cargo fmt --all -- --check
  • CI green on smithy

Refs

🤖 Generated with Claude Code

avrabe and others added 3 commits May 10, 2026 14:18
meld passes input `.debug_*` sections through verbatim while it
rewrites and renumbers function bodies into a new merged code section.
Every DWARF address inside those passed-through sections then references
the wrong instruction (or nothing) in the fused output. Downstream MC/DC
tooling (`pulseengine/witness`) trusts the gimli-built `(code-offset ->
file, line)` map and silently produces wrong source-line attribution
for every `br_if`. Wrong attribution is strictly worse than no
attribution because witness has a graceful no-DWARF fallback that the
lossy passthrough subverts.

Phase 2 of issue #130 will add an actual address-remap pass over
`.debug_line` / `.debug_info` / `.debug_ranges`. Until that lands the
only non-corrupting policy is to drop `.debug_*`. Phase 1.5 makes that
choice explicit:

- New `DwarfHandling::{Strip, PassThrough}` enum on `FuserConfig`,
  default `Strip`.
- `lib.rs::encode_output` filters `.debug_*` when `Strip`.
- Recorded in attestation `tool_parameters` as
  `dwarf_handling = "strip" | "passthrough"` so consumers can detect
  lossy emissions; SR-28 sentinel test extended.
- Three integration tests in `meld-core/tests/dwarf_strip.rs` pin the
  default-strip / passthrough-preserves contract.
- LS-CP-4 added to `safety/stpa/loss-scenarios.yaml` (status approved,
  H-7).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@avrabe avrabe marked this pull request as ready for review May 11, 2026 03:54
@avrabe avrabe merged commit c7a2c0b into main May 11, 2026
11 of 17 checks passed
@avrabe avrabe deleted the chore/dwarf-strip-default branch May 11, 2026 03:54
@avrabe avrabe mentioned this pull request May 11, 2026
2 tasks
avrabe added a commit that referenced this pull request May 11, 2026
DWARF Phase 1.5 (#135 / sub-#130): switch the default DWARF policy
from silent passthrough to explicit Strip. Passing input `.debug_*`
sections through verbatim produces wrong source-line attribution
against the merged code section — strictly worse than no DWARF for
downstream MC/DC tooling. `DwarfHandling::PassThrough` remains
available for callers that knowingly accept the lossy mapping.

This is a behaviour-changing default but the change is contained:
non-debug-info input is unaffected, and PassThrough preserves the
prior shape for any callers that need it. LS-CP-4 added.
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