Commit 23bdb31
feat(dwarf): make --dwarf remap work on real DWARF + witness oracle (v0.20.0) (#209)
* feat(dwarf): make --dwarf remap work on real DWARF + witness oracle (#130)
Falsifying the v0.19.0 single-source remap against a real Rust component
(hello_rust.wasm) surfaced four address classes the synthetic oracle
missed, plus gimli's all-or-nothing failure mode. All fixed:
- low_pc is the function BODY START (locals-decl byte), not the first
instruction — the locals/prefix region now maps linearly (locals are
preserved verbatim). Previously every low_pc underflowed to a miss.
- Exclusive-end addresses (high_pc-as-addr, range ends, line
end_sequence) map to output_body_end.
- LLVM emits fixed-width zero-padded LEBs for relocatable indices, so
DWARF rows can land inside operand bytes — these resolve to the
CONTAINING operator (exact on boundaries) for correct line attribution.
- Linear-memory/data addresses (DW_OP_addr) at/beyond the code extent
pass through unchanged (correct under multi-memory fusion).
- Per-address tombstoning replaces all-or-nothing strip: gimli's
Dwarf::from aborts on a single unmappable address, which on real
modules (dead-code gaps) stripped ALL DWARF. convert_address is now
total — correct offset where mappable, identity for data/tombstones,
0xFFFF_FFFF for unmappable code. Guarantee strengthens to "every
emitted address is correct or an ignored tombstone, never wrong".
Witness oracle (tests/dwarf_remap_witness.rs, gimli dev-dep): fuses a
real Rust component with --dwarf remap and asserts every non-tombstone
subprogram low_pc equals some fused function's component-provenance
code_range.start (the pulseengine/witness contract, in-tree). On the
fixture all but 9 of 225 functions map exactly; the 9 are dead code.
LS-D-1 amended with the v0.20.0 hardening. Multi-source still strips
(gimli writer-API blocker, see #208).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* fix(dwarf): tombstone ambiguous function-boundary addresses (Mythos #209)
The Mythos auto-scan flagged that `AddressRemap::translate` could emit a
plausible-but-wrong address at a function boundary. Input bodies are
contiguous, so one address is both function A's exclusive end
(A.input_end) and the next function B's start (B.input_start); the
BTreeMap range lookup selects B and returned B.output_body_start, which
differs from A.output_body_end when A and B are not adjacent in the
fused output (interleaved / reordered functions). A's high_pc-as-addr,
range-list end, and end_sequence then mapped to a wrong offset.
`translate` now detects the divergent-boundary case (prev.output_body_end
!= span.output_body_start) and returns None so the caller tombstones the
address rather than emit a wrong one. When the two interpretations
coincide (input order preserved — the single-source case meld emits) the
boundary resolves cleanly. Pinned by
`translate_ambiguous_boundary_tombstones_when_reordered`; LS-D-1 amended.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* fix(dwarf): code_extent covers dropped functions, not just survivors (Mythos #209)
Second Mythos auto-scan finding: AddressRemap::code_extent used the max
input_end over REGISTERED spans, so a source module's dropped trailing
function (DCE'd, no span) has input addresses exceeding code_extent.
convert_address then classified them as linear-memory data and passed
them through as stale input-module offsets instead of tombstoning.
code_extent is now the input module's full code-section extent (every
input function, via module_function_layouts which parses them all), so a
dropped function's address stays in the code range and tombstones.
Pinned by `code_extent_covers_dropped_trailing_function`; LS-D-1 amended.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>1 parent b028e43 commit 23bdb31
7 files changed
Lines changed: 564 additions & 28 deletions
File tree
- meld-core
- src
- tests
- safety/stpa
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
4 | 4 | | |
5 | 5 | | |
6 | 6 | | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
7 | 59 | | |
8 | 60 | | |
9 | 61 | | |
| |||
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
10 | 10 | | |
11 | 11 | | |
12 | 12 | | |
13 | | - | |
| 13 | + | |
14 | 14 | | |
15 | 15 | | |
16 | 16 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
43 | 43 | | |
44 | 44 | | |
45 | 45 | | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
46 | 49 | | |
47 | 50 | | |
48 | 51 | | |
| |||
0 commit comments