Section 22.214.171.124.3, pg 27
Implicit pointer values in debug information
Optimized compilation can eliminate a pointer that exists in the
semantics of the source program (including C++ "references" and other
source language constructs with pointer-like semantics). These may be
pointer-typed variables, or portions of aggregate data structures that
are ordinarily represented as address values. While no actual address
will ever exist for these semantic pointers at runtime, often what they
"point to" has a known location in registers or discontiguous pieces, or
can be rematerialized from other information at runtime.
For example, consider the C function:
static void add_point (struct point *a, const struct point *b)
a->x += b->x;
a->y += b->y;
This may be inlined away in compilation such that all the members of the
two structures exist only in registers. A debugger cannot show the user
an address value for "a" or "b", but it can show a struct value for "*a"
or "*b", and it can evaluate "a->x" or "b->y". Another common example
is the "this" pointers and reference-typed arguments in C++ methods
handling class types with small amounts of data so they are inlined away
into using just registers. More complex examples can include pointers
into the middle of an array or other aggregate type, optimized-away
aggregates containing pointer-typed members, pointers to constants
optimized away, multiple levels of pointer indirection optimized away,
and combinations of all these.
Proposed changes to DWARF
New location expression operation (7.7.1, Figure 24):
DW_OP_implicit_pointer 0xa0 2 4- or 8-byte offset of DIE
followed by SLEB128 offset
Add to the enumerated list:
The DW_OP_implicit_pointer operation describes a pointer whose location does
not exist (perhaps because of compiler optimization), but where the contents
of the memory it would dereference does exist. It has two operands: a
debugging information entry reference referencing an object which contains
the contents of the memory the pointer logically would dereference, and a
signed LEB128 number which is the offset in bytes into the referenced object.
In the 32-bit DWARF format, the first 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 debugging information entry in a
.debug_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 executable to another, the relocation must be performed by the consumer.
The referenced debug information entry has either a DW_AT_location or
Addition or subtraction operations on a pointer object with a
DW_OP_implicit_pointer operator in its location effectively act as addition
or subtraction on the LEB128 offset.
7.4, paragraph 3:
DW_OP_implicit_pointer offset in .debug_info
into the table.
Appendix B, Figure 43:
Add DW_OP_implicit_pointer alongside DW_OP_call_ref.
Appendix B, in note (e) after Figure 43, after "the DW_OP_call_ref DWARF
expression operator", add "and the first operand of the
DW_OP_implicit_pointer DWARF location expression operator".