<div dir="ltr">Added as Issue <a href="https://dwarfstd.org/issues/240626.1.html">240626.1</a>.<div><br></div><div>-cary</div><div><br></div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Wed, Jun 26, 2024 at 4:06 PM Matthew Lugg via Dwarf-discuss <<a href="mailto:dwarf-discuss@lists.dwarfstd.org">dwarf-discuss@lists.dwarfstd.org</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"># Add DW_LNS_indirect_line - update `line` to absolute value stored <br>
indirectly<br>
<br>
## Background<br>
<br>
In many source languages, it is possible for many program-counter <br>
addresses with arbitrary<br>
separation to correspond to the same source line due to features like <br>
templates/generics. When<br>
designing an incremental compiler, the line number program must be <br>
updated when line numbers within<br>
a source file are moved. It would be desirable to have the property that <br>
when moving a source line<br>
corresponding to a large amount of distinct program-counter addresses, <br>
only one line number value in<br>
the DWARF information needs to be updated. For this to be true, the <br>
regions of the line number<br>
program corresponding to each such address must include the line number <br>
of the source construct not<br>
directly, but through an indirect reference. This allows one line number <br>
value stored in the binary<br>
to be shared across arbitrarily many entries in the line number matrix.<br>
<br>
This is not currently possible: all modifications to the `line` register <br>
are given by relative<br>
offsets, and all of these offsets are directly included in the <br>
instruction (or implicit in the case<br>
of a special opcode).<br>
<br>
## Overview<br>
<br>
Introduce new fields to the line number program header, <br>
`indirect_lines_length` (ULEB128) and<br>
`indirect_lines` (opaque block of bytes containing ULEB128 values). The <br>
`indirect_lines_length`<br>
field is the length in bytes of the `indirect_lines` section, rather <br>
than the number of elements.<br>
Introduce a new standard opcode to the line number program, <br>
`DW_LNS_indirect_line`. This opcode<br>
takes a single ULEB128 operand, which represents a byte offset into the <br>
`indirect_lines` stored in<br>
the header. The effect of this instruction is to set the `line` register <br>
to the ULEB128 value stored<br>
at the given byte offset into `indirect_lines`. Note that <br>
`indirect_lines` is not itself validated<br>
to be a valid sequence of ULEB128 values; decoding only occurs when <br>
`DW_LNS_indirect_line` is used.<br>
This allows an incremental compiler to pre-allocate a large amount of <br>
padding space in<br>
`indirect_lines` to fill in later as needed.<br>
<br>
Note that an incremental compiler would not necessarily wish to use <br>
variable-length integers to<br>
represent this information, since certain changes of line numbers could <br>
cause a line number which<br>
was previously encoded using 1 byte to now require 2. However, since the <br>
stored values need not be<br>
densely packed, an implementation is free to reserve as much space as is <br>
necessary for each entry.<br>
For instance, the downstream Zig compiler (which is the original <br>
motivator for this proposal) may<br>
choose to reserve 4 or 5 bytes for each line number, as line numbers in <br>
Zig source files cannot<br>
exceed 1<<32. The use of ULEB128 allows the compiler to make an <br>
appropriate decision here instead of<br>
codifying such a restriction into the DWARF specification.<br>
<br>
## Proposed Changes<br>
<br>
Pages and line numbers are given for the 2024-06-16 working draft of <br>
DWARF Version 6, which is the<br>
latest draft at the time of writing.<br>
<br>
6.2.4 (pg 163; line 27)<br>
<br>
21. indirect_lines_length (ULEB128)<br>
     The length in bytes of the data stored in the `indirect_lines` field.<br>
22. indirect_lines (block containing ULEB128 entries)<br>
     A collection of line numbers, each stored as a ULEB128 integer. <br>
These values are referenced by<br>
     DW_LNS_indirect_line instructions to modify the state of the line <br>
number information state<br>
     machine.<br>
<br>
     The data stored in this field is not checked to be a valid sequence <br>
of ULEB128 entries. The<br>
     contained data may include padding bytes or otherwise invalid data. <br>
As such, it is expected that<br>
     bytes of this field be accessed only when a DW_LNS_indirect_line <br>
instruction references them.<br>
<br>
6.2.5.2 (pg 170; line 23)<br>
<br>
14. DW_LNS_indirect_line<br>
     The DW_LNS_indirect_line opcode takes a single unsigned LEB128 <br>
operand. This operand is<br>
     interpreted as a byte offset into the `indirect_lines` field of the <br>
line number program header.<br>
     An unsigned LEB128 value is read from `indirect_lines` at the given <br>
offset, and this value is<br>
     stored into the state machine's `line` register.<br>
<br>
7.22 (pg 246; table 7.25)<br>
<br>
  Opcode name          | Value<br>
----------------------+-------<br>
        ...            |  ...<br>
DW_LNS_indirect_line  | 0x0d<br>
<br>
-- <br>
Dwarf-discuss mailing list<br>
<a href="mailto:Dwarf-discuss@lists.dwarfstd.org" target="_blank">Dwarf-discuss@lists.dwarfstd.org</a><br>
<a href="https://lists.dwarfstd.org/mailman/listinfo/dwarf-discuss" rel="noreferrer" target="_blank">https://lists.dwarfstd.org/mailman/listinfo/dwarf-discuss</a><br>
</blockquote></div>