Expand description
VCR-DBG-001 step 3 — compose the source-line table (the join half).
The DWARF Tier-1 bridge maps an ARM text offset back to a source file:line
through three established facts:
- each ARM instruction carries
source_line= the wasm OP INDEX (ArmInstruction.source_line); - step 1 (
FunctionOps.op_offsets) maps op-index → the wasm code BYTE OFFSET (module-relative); - step 2 parses the input wasm’s
.debug_line→ (code-section-relative address →file:line) rows.
This module is the join for the wasm half — op-index → source line —
which step 4 (emit) composes with the ARM layout (ARM-text-offset → op-index
is just source_line). It is pure plain-data (no gimli, no backend): the
caller parses the rows and supplies them, so the module is Bazel-clean and
unwired (frozen-safe) until the emitter consumes it.
The crux it encodes (validated on scripts/repro/dwarf_coherent.wasm,
VCR-DBG-001 step-3 fixture): op_offsets are MODULE-relative while DWARF
addresses are CODE-section-relative, and they differ by a single constant —
the code section’s payload start. So normalization is one subtraction:
dwarf_addr = op_offset - code_base.
Structs§
- Dwarf
Text Reloc - A relocation a
.debug_*section needs against the.textsymbol so a host linker fixes up the embedded.textaddress when.textis placed. REL form: the in-place bytes already hold the addend (always0for our text-base references), so only the site (offset) andsizetravel here. - Emitted
Dwarf Section - One emitted
.debug_*section: its ELF name, bytes, and the.text-symbol relocations it needs (empty for address-free sections like.debug_str). - Input
Dwarf Line - Result of reading the input wasm’s DWARF line table: the parsed rows plus the
code-section payload start (
code_base) the op-offset compose subtracts. - LineRow
- One
.debug_linerow: a code-section-relative address and its source line.fileis an opaque caller-supplied id (e.g. an index into the line program’s file table) so this stays gimli-free. - Source
Loc - A resolved source location for a wasm op.
Functions§
- emit_
debug_ sections - Emit an address-ordered
(arm_addr, line)table as a FULL minimal DWARF unit (gimli::write) and return EVERY non-empty.debug_*section it produces —.debug_info,.debug_abbrev,.debug_str,.debug_line(and.debug_line_str/.debug_rangesetc. when non-empty). The caller composes the table (one address-sorted, de-duped sequence covering every function); this produces the section bytes for non-ALLOC ELFPROGBITSsections. Returns an emptyVecfor an empty table (nothing to map ⇒ no sections ⇒ output stays byte-identical). - op_
offsets_ to_ source - Map each wasm op (by its module-relative
op_offsetsbyte offset) to a source location, by normalizing into the code-section-relative DWARF address space (op_offset - code_base) and taking the covering line-table row (the last row whose address is ≤ the op’s address — standard line-table lookup). - read_
input_ dwarf_ line - Read the input wasm’s
.debug_lineinto code-section-relative(addr → line)rows and reportcode_base. Returns an empty table (rows empty, the feature a no-op) when the input carries no.debug_*sections or no parseable line program — never an error for a DWARF-free module.