010503.1 A T. Allen Representation Call references between shared library

PROBLEM:

With DWARF 2.0.0, our (Concurrent's) compilers implemented several attributes
which were intended to be "suffix" location descriptions, and were appended
to other location descriptions automatically by our debugger, which
recognized them. This was intended to reduce the space of the DWARF2
information by separating out location expression idioms, and representing
them only once in the program.

The DW_OP_call* operators provide a better mechanism.

To support our Ada compiler's approach of describing entities only once, the
only thing needed is the ability for a DW_OP_call* operator to reference a
subroutine in another shared object. This is analogous to the earlier
proposal (010322.2) for the ability for DW_FORM_ref_addr to reference a DIE
in another shared object.

The general consensus so far has been that using the expression stack to
convey section offsets in other shared objects is problematic, because
there's no way to encode any identification for the referenced shared object.
A "shadow stack" that paralleled the real stack could be imagined for this
purpose, but that seems too obscure. To avoid that, this proposal uses a new
operator. The DW_OP_call_ref operator takes a single argument which is
interpreted as an offset in a .debug_info section. In a program using shared
objects, the determination of which shared object is implementation-dependent
and analogous to the determination for DW_FORM_ref_addr (see proposal
010322.2).

WORDING CHANGES:

| 2.4.1.5 Control Flow Operations
|
| ...
|
| 4. DW_OP_call2, DW_OP_call4, DW_OP_calli, DW_OP_call_ref
|
| DW_OP_call2, DW_OP_call4, DW_OP_calli, and DW_OP_call_ref perform
| subroutine calls during evaluation of a DWARF expression. For DW_OP_call2
| and DW_OP_call4, the operand is a 2- or 4- byte unsigned offset,
| respectively, of a DIE in the current compilation unit. For DW_OP_calli,
| the top of stack is popped and the value used as the offset of a DIE in
| the .debug_info section of the current executable file or shared object.
| The DW_OP_call_ref operator has a single operand. In the 32-bit DWARF
| format, the operand is a 4-byte unsigned value; in the 64-bit DWARF
| format, it is an 8-byte unsigned value (see section 7.4). The operand is
| used as the offset of a DIE in a .dwarf_info section which may be
| contained in a shared object or executable other than that containing the
| operator. For references from one shared object or static executable file
| to another, the relocation must be performed by the consumer.
|
| <i>Operand interpretation of DW_OP_call2, DW_OP_call4, and DW_OP_call_ref
| is exactly like that for DW_FORM_ref2, DW_FORM_ref4, and DW_FORM_ref_addr,
| respectively. Operand interpretation of DW_OP_calli is like that for
| DW_FORM_ref_addr, except that the offset is guaranteed to be relative to
| the .dwarf_info section of the executable or shared object containing the
| operator.</i>

These operations transfer control of DWARF expression evaluation to the
DW_AT_location attribute of the referenced DIE. If there is no such
attribute, then there is no effect. Execution of the DWARF expression of
a DW_AT_location attribute may add to and/or remove from values on the
stack. Execution returns to the point following the call when the end of
the attribute is reached. Values on the stack at the time of the call may
be used as parameters by the called expression and values left on the
stack by the called expression may be used as return value by prior
agreement between the calling and called expressions.

...


Adopted.  DW_OP_calli now appears to be unnecessary.  Ron Brender will draft a proposal to remove it.