Skip to content

meld fuse produces DWARF that fails llvm-dwarfdump --verify (534 out-of-parent + 480 overlapping ranges) while inputs verify clean #319

Description

@avrabe

Filed by the PulseEngine challenge harness (meld v0.37.0, aarch64-apple-darwin). Confirmed by a differential against llvm-dwarfdump --verify with a clean input baseline.

Defect

meld fuse produces a core module whose merged .debug_* sections fail llvm-dwarfdump --verify — hundreds of overlapping / out-of-parent DIE address ranges and invalid locations — even though the inputs' DWARF is valid. The DWARF .debug_* relocator/merger (#130, #208, #144, all closed) is emitting inconsistent address ranges for the fused/reduced code.

Repro

F=tests/wit_bindgen/fixtures
meld fuse $F/records.wasm $F/variants.wasm -o fused.wasm     # 41.4% reduction
llvm-dwarfdump --verify fused.wasm
error: Aggregated error counts:
error: DIE address ranges are not contained by parent ranges occurred 534 time(s).
error: DIEs have overlapping address ranges occurred 480 time(s).
error: Invalid DWARF expressions occurred 18 time(s).
error: Invalid DW_AT_location occurred 17 time(s).
Errors detected.

Single-component fusion is also affected: meld fuse records.wasm -o single.wasm (32.1% reduction) → 272 overlapping + 230 not-contained.

Clean-room baseline (rules out "inputs were already broken")

llvm-dwarfdump --verify can't read the component wrapper directly (reports a bogus invalid version number: 65549), so I extracted the inputs' inner core modules with wasm-tools (not meld) and verified those:

wasm-tools component unbundle $F/records.wasm --module-dir mods --output /dev/null
llvm-dwarfdump --verify mods/unbundled-module0.wasm   # -> No errors.
llvm-dwarfdump --verify mods/unbundled-module1.wasm   # -> No errors.

Both inner core modules verify clean. So the overlapping/uncontained ranges are introduced by meld's fuse transform, not inherited from the inputs.

Why it matters

The fused output is what Loom optimizes and Synth compiles; a debugger (or witness MC/DC / source-map tooling that consumes this DWARF) resolving an address to a DIE gets ambiguous or wrong results. For a toolchain aimed at source-level debugging of safety-critical firmware, silently-invalid DWARF after fusion defeats the purpose of the relocator feature.

Likely cause

The 41.4% / 32.1% size reductions indicate code is removed/merged during fusion, but the .debug_* address ranges are not consistently updated to the fused layout, so DIE ranges collide and escape their parents. The relocator needs to drop/rebuild ranges for removed/merged code (or the merge must preserve a 1:1 code mapping for the DWARF it keeps).

Note

Regression probe in the challenge harness: harness/meld_dwarf_fusion_probe.sh (differential vs unbundled-input baseline).

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions