fix(dwarf): remap DW_AT_ranges lists to the fused layout (#319 inc 2)#321
Conversation
The residual "DIE address ranges are not contained in its parent's ranges" errors after inc 1 came from base-relative .debug_ranges offsets. Root cause: DWARF v4 .debug_ranges entries are offset pairs relative to a base (the CU's DW_AT_low_pc, which is nonzero for wasi-libc CUs). gimli parses them as AddressOrOffsetPair and routes the *offsets* through convert_address, which treats a small offset (e.g. 0x141) as an absolute code address and remaps it to an unrelated output location — so the resolved range escapes its parent (the .debug_ranges analogue of the inc-1 high_pc bug, one level down). The CU base (an address form) is remapped correctly, so consumer = out_base + garbage_offset → e.g. [0x1c439,..) outside the parent [0x133b6,0x1353d). Fix: correct_die_ranges — a post-convert pass that, walking read↔write DIEs in lockstep pre-order, resolves each DIE's absolute input ranges via gimli read `die_ranges` (base already applied), translates both endpoints to the fused layout, and re-emits them as OffsetPair relative to the output CU base. Sub-ranges whose endpoints can't be mapped (dropped/tombstoned code) are dropped; an emptied list deletes DW_AT_ranges — never a wrong or escaping range (LS-D-1). Effect: the "not contained" class is eliminated — records-only 4->0, records+variants 11->0 (cumulative with inc 1: 1049->35 multi, ~510->8 single). The remaining 35/8 are Cause #2 (.debug_loc tombstone vs base-address-selection escape) = inc 3. Test: inc2_die_ranges_stay_within_enclosing_subprogram — fuses records.wasm, re-parses the fused DWARF, asserts every DW_AT_ranges entry sits inside its enclosing subprogram (the invariant that failed). 2 witness + 24 dwarf unit tests pass. Refs: #319. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
LS-N verification gate✅ 58/58 approved LS entries verified
Approved Failed LS entries(none) Missing regression tests(none) Updated automatically by |
…c 2) Mythos delta-pass robustness: a degenerate begin==end OffsetPair is rejected by gimli's range writer (InvalidRange), which would abort the whole DWARF write and fall back to strip. Require strict oe > ob; a zero-length range carries no info, so dropping it is lossless. (No mis-attribution — this is a write-abort/reliability guard.) Refs: #319. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Mythos delta-pass — NO FINDINGS (meld-core/src/dwarf.rs)Ran the discover protocol on
Oracle: |
Mythos delta-pass (auto)✅ NO FINDINGS across 1 Tier-5 file(s)
Auto-run via |
What
Second increment for #319. Inc 1 fixed
DW_AT_high_pclengths; this fixes the residual "DIE address ranges are not contained in its parent's ranges" errors.Root cause
DWARF v4
.debug_rangesentries are offset pairs relative to a base (the CU'sDW_AT_low_pc, nonzero for wasi-libc CUs). gimli parses them asAddressOrOffsetPairand routes the offsets throughconvert_address, which treats a small offset (e.g.0x141) as an absolute code address and remaps it to an unrelated output location — so the resolved range escapes its parent (the.debug_rangesanalogue of the inc-1 high_pc bug, one level down). Verified empirically: input inlined child ranges resolve insidewrite[0xb398,0xb53c); output rendered[0x1c439,…]outside[0x133b6,0x1353d).Fix
correct_die_ranges— a post-convert pass that walks read↔write DIEs in lockstep pre-order, resolves each DIE's absolute input ranges via gimli'sdie_ranges(base already applied),translates both endpoints to the fused layout, and re-emits them asOffsetPairrelative to the output CU base. Unmappable sub-ranges (dropped/tombstoned code) are dropped; an emptied list deletesDW_AT_ranges— never a wrong/escaping range (LS-D-1).Effect
The not-contained class is eliminated: records-only 4→0, records+variants 11→0. Cumulative with inc 1: 1049→35 (records+variants), ~510→8 (records-only). The remaining 35/8 are Cause #2 (
.debug_loctombstone vs base-address-selection escape) = inc 3.Test
inc2_die_ranges_stay_within_enclosing_subprogram— fusesrecords.wasm, re-parses the fused DWARF, asserts everyDW_AT_rangesentry sits inside its enclosing subprogram (the invariant that failed). No llvm-dwarfdump dependency. 2 witness + 24 dwarf unit tests pass.Refs: #319.
🤖 Generated with Claude Code