|
DWARF Standard
|
211206.2 |
Markus Metzger |
Stack piece operators |
Enhancement |
Open |
Markus Metzger |
Section 2.6.12, pg 42
Arrays may be partially registerized such that the currently processed
elements are held in registers, whereas the remainder of the array remains
in memory. Consider the loop in this C function, for example:
extern void foo(uint32_t dst[], uint32_t src[], int len) {
for (int i = 0; i < len; ++i)
dst[i] += src[i];
}
Inside the loop body, the machine code would load src[i] and dst[i] into
registers, add them, and store the result back into dst[i].
Considering the location of dst and src, the elements dst[i] and src[i]
would be located in registers, all other elements are located in memory.
Since the location depends on the dynamic value of i, the location of src
and dst cannot be described using the existing DW_OP_piece operators.
We propose four new operators
DW_OP_piece_stack
DW_OP_bit_piece_stack
DW_OP_bit_piece_stack_offset
DW_OP_piece_rest
that extend the existing family of piece operators by variants that take
some or all of their operands from the DWARF stack, thus allowing them to
be computed. See below for detailed definitions.
Using the above new operators, we can now describe the location of dst in
three pieces. Let R0 contain the base address of dst, R1 contain i, and
R2 contain dst[i].
1. elements 0..i are located in memory
DW_OP_breg0 0
DW_OP_breg1 0
DW_OP_lit4
DW_OP_mul
DW_OP_piece_stack
2. element i is located in R2
DW_OP_reg2
DW_OP_piece 4
3. elements i+1.. are located in memory
DW_OP_breg0 0
DW_OP_breg1 4
DW_OP_lit4
DW_OP_mul
DW_OP_add
DW_OP_piece_rest
Proposed Changes
================
Section 2.6.1.2, pg. 42.
Add
3. DW_OP_piece_stack
The DW_OP_piece_stack operation works similar to DW_OP_piece except that
it takes its argument from the DWARF stack.
The DW_OP_piece_stack operation takes no operands. It pops the
topmost entry off the stack and interprets it as an unsigned
integer, which describes the size in bytes of the piece of the
object referenced by the preceding simple location description. If
the piece is located in a register, but does not occupy the entire
register, the placement of the piece within that register is
defined by the ABI.
4. DW_OP_bit_piece_stack
The DW_OP_bit_piece_stack operation works similar to DW_OP_bit_piece
except that it takes its arguments from the DWARF stack.
The DW_OP_bit_piece_stack operation takes no operands. It pops the
topmost entry off the stack and interprets it as unsigned integer
giving the size in bits of the piece. It then pops the next entry
off the stack and interprets it as unsigned integer giving the
offset in bits from the location defined by the preceding DWARF
location description.
5. DW_OP_bit_piece_stack_offset
The DW_OP_bit_piece_stack_offset operation works similar to
DW_OP_bit_piece except that it takes its offset argument from the
DWARF stack.
The DW_OP_bit_piece_stack_offset operation takes a single operand,
which is an unsigned LEB128 number. The number describes the size
in bits of the piece. It pops the topmost entry off the stack and
interprets it as unsigned integer giving the offset in bits from
the location defined by the preceding DWARF location description.
6. DW_OP_piece_rest
The DW_OP_piece_rest operation takes no operands. The preceding
simple location description occupies the remainder of the object.
This operator can be used when the size of the object is not known.
Section 7.7, p.223.
Add
DW_OP_piece_stack | TBD | 0 |
DW_OP_bit_piece_stack | TBD | 0 |
DW_OP_bit_piece_stack_offset | TBD | 1 | ULEB128 size
DW_OP_piece_rest | TBD | 0 |
to table 7.9.
Section D.17 (introduced in 211206.1)
Add
DW_TAG_formal_parameter
DW_AT_name "dst"
DW_AT_type .type.arr
DW_AT_location .loclist.2
...
DW_TAG_formal_parameter
DW_AT_name "src"
DW_AT_type .type.arr
DW_AT_location .loclist.3
...
DW_TAG_formal_parameter
DW_AT_name "len"
DW_AT_type int
DW_AT_location
DW_OP_regx r2
...
to figure D.75 at the end of the DW_TAG_subprogram DIE.
Add
.loclist.2:
range [.l0, .l1.1)
DW_OP_bregx r0, 0
range [.l1.1, .l1.3)
DW_OP_bregx r0, 0
DW_OP_bregx r3, 0
DW_OP_lit4
DW_OP_mul
DW_OP_piece_stack
DW_OP_regx v0
DW_OP_piece 32
DW_OP_bregx r0, 0
DW_OP_bregx r4, 0
DW_OP_lit4
DW_OP_mul
DW_OP_plus
DW_OP_piece_rest
range [.l1.3, .l4)
DW_OP_bregx r0, 0
range [.l2.1, .l2.3)
DW_OP_bregx r0, 0
DW_OP_bregx r3, 0
DW_OP_lit4
DW_OP_mul
DW_OP_piece_stack
DW_OP_regx r5
DW_OP_piece 4
DW_OP_bregx r0, 0
DW_OP_bregx r4, 0
DW_OP_lit4
DW_OP_mul
DW_OP_plus
DW_OP_piece_rest
end-of-list
.loclist.3:
range [.l0, .l4)
DW_OP_bregx r1, 0
range [.l1.2, .l1.3)
DW_OP_bregx r1, 0
DW_OP_bregx r3, 0
DW_OP_lit4
DW_OP_mul
DW_OP_piece_stack
DW_OP_regx v1
DW_OP_piece 32
DW_OP_bregx r1, 0
DW_OP_bregx r4, 0
DW_OP_lit4
DW_OP_mul
DW_OP_plus
DW_OP_piece_rest
range [.l2.2, .l1.3)
DW_OP_bregx r1, 0
DW_OP_bregx r3, 0
DW_OP_lit4
DW_OP_mul
DW_OP_piece_stack
DW_OP_regx r6
DW_OP_piece 4
DW_OP_bregx r1, 0
DW_OP_bregx r4, 0
DW_OP_lit4
DW_OP_mul
DW_OP_plus
DW_OP_piece_rest
end-of-list
to figure D.75 at the end of the loclist section.
--
2023-01-23 -- Revise: add Appendix text, revise op names.