000217.1 | B | A | F. Burton | Processor | Dwarf procedures |
This is a proposal to add DW_OP_call and DW_TAG_dwarf_procedure.
This
allows for a compact way to describe complex locations expressions (for
example DW_AT_vtable_elem_location) where the majority of the expression is
common.
EXAMPLE OF PROBLEM:
The specification states:
"An entry for a virtual function also has a DW_AT_vtable_elem_location
attribute whose value contains a location description yielding the address
of the slot for the function within the virtual function table for the
enclosing class or structure."
I am assuming that the object pointer is placed on the evaluation stack
prior to evaluating the location expression.
Two typical DW_AT_vtable_elem_location are:
1. When the virtual function table pointer is directly accessible:
DW_TAG_subprogram
...
DW_AT_vtable_elem_location(DW_OP_plus_uconst(offset-to-virtual-function-tabl
e-pointer) DW_OP_deref
DW_OP_plus_uconst(<vtable-slot-size>*virtual-function-index))
2. When the virtual function table pointer is located in a base class:
DW_TAG_subprogram
...
DW_AT_vtable_elem_location(DW_OP_plus_uconst(offset-to-virtual-base-type-poi
nter) DW_OP_deref
DW_OP_plus_uconst(offset-to-virtual-function-table-pointer) DW_OP_deref
DW_OP_plus_uconst(<vtable-slot-size>*virtual-function-index))
Case 1 amounts to 5+ bytes and case 2 amounts to 7+ bytes. For classes with
many virtual functions this can become a significant part of the debug
information size.
PROPOSAL:
- Add to section 2.4.3.5:
DW_OP_call2 and DW_OP_call4
DW_OP_call2 and DW_OP_call4 evaluate the DW_AT_location expression for the
DIE referenced by the argument and then continues to evaluate op-codes after
the call. The single operand is a 2-byte or 4-byte unsigned offset relative
to the first byte of the compilation unit header for the compilation unit
containing the call.
- Add to figure 23:
DW_OP_call2 0x97 1 Two byte offset
DW_OP_call4 0x98 1 Four byte offset
- Add to figure 1:
DW_TAG_dwarf_procedure
- Add section 5.13:
5.13 Dwarf procedure entries
A dwarf procedure is represented by a debugging information entry with the
tag DW_TAG_dwarf_procedure. A dwarf procedure must have a DW_AT_location
attribute which contains the expression that is evaluated by a DW_OP_call.
- Add to figure 15:
DW_TAG_dwarf_procedure 0x36
- Add to table in appendix 1:
DW_TAG_dwarf_procedure DW_AT_location
EXPLANATION:
Here is will show how the above examples can be encoded if this proposal is
accepted.
Example 1:
<x>:
DW_TAG_dwarf_procedure
DW_AT_location(DW_OP_lit<vtable-slot-size> DW_OP_mul DW_OP_swap
DW_OP_plus_uconst(offset-to-virtual-function-table-pointer) DW_OP_deref DW_OP_add)
DW_TAG_subprogram
...
DW_AT_vtable_elem_location(DW_OP_lit<virtual-function-index>
DW_OP_call2(offset-to-<x>))
Example 2:
<y>:
DW_TAG_dwarf_procedure
DW_AT_location(DW_OP_lit<vtable-slot-size> DW_OP_mul DW_OP_swap
DW_OP_plus_uconst(offset-to-virtual-base-type-pointer)
DW_OP_deref
DW_OP_plus_uconst(offset-to-virtual-function-table-pointer) DW_OP_deref
DW_OP_add)
DW_TAG_subprogram
...
DW_AT_vtable_elem_location(DW_OP_lit<virtual-function-index>
DW_OP_call2(offset-to-<y>))
CREDIT:
The ideas behind this proposal come from the DWARF 1 design of OP_CALL by
Tom Pennello of MetaWare.
Approved with following extension: Add DW_OP_CALLI which
takes the value
at the top of the stack as the address of the DIE. If the addressed DIE
does not contain an AT_location, the call is a no op.