001012.1 A D. Anderson Representation Factored Offset

Proposal: Factored Offset

A from-cfa offset is the offset from the cfa, such as in
DW_CFA_offset and DW_CFA_offset_extended.

An in-cfa offset is the offset in the cfa definition:
the offset in DW_CFA_def_cfa and DW_CFA_def_cfa_offset.

The existing .debug_frame description does not allow
for the 'offset' in-cfa or from-cfa to be negative.

Because of ambiguities in the 2.0.0 spec, some implementations
have decided to apply the data_alignment_offset where others
did not, and the ones that do apply it can have negative in-cfa
offset but have no way to make the in-cfa offset sign different
from the from-cfa offset sign.


  No change in version number.

  No new CIE or FDE fields.

  3 new operations, each with 'sf' to indicate signed and factored, making
  the offsets all be signed (SLEB128 numbers) as well as factored by

  UREG : ULEB128 register number
  SFOFF: SLEB128 signed factored offset.
         (factor being the existing data_alignment_factor in
          the CIE)

        DW_CFA_offset_extended_sf UREG SFOFF
        DW_CFA_def_cfa_sf UREG SFOFF
        DW_CFA_def_cfa_offset_sf SFOFF

  Using up opcodes 0x11 0x12 0x13.
  This leaves 0x14 up thru 0x1b unused and reserved for
  future specification revisions (see section 7.23
  in the July 20 draft, for complete existing set, including
  the two new ones already voted into the draft).

Exact text changes in the proposal,
applied to the July 20 2000 Draft.
Someone may have better phrasings, of course.

Section 6.4.2, Call Frame instructions
21. DW_CFA_offset_extended_sf
The DW_CFA_offset_extended_sf instruction takes two arguments:
an unsigned LEB128 register number and a signed LEB128 factored
offset. The offset(N) rule has has a value of (N = factored
offset * data_alignment_factor).

22. DW_CFA_def_cfa_sf
The DW_CFA_def_cfa_sf instruction takes two arguments: an
unsigned LEB128 argument representing a register number and a
signed LEB128 number representing a signed factored offset.
The required action is to define the current CFA rule to use
the provided register and an offset with a value of (N =
factored offset * data_alignment_factor).

23. DW_CFA_def_cfa_offset_sf
The DW_CFA_def_cfa_offset instruction takes a single signed
LEB128 argument representing a signed factored offset. The
required action is to define the current CFA rule to keep the
existing CFA register and to use an offset with a value of (N =
factored offset * data_alignment_factor).

Figure 36, add
DW_CFA_offset_extended_sf 0 0x11 ULEB128 register SLEB128 offset
DW_CFA_def_cfa_sf 0 0x12 ULEB128 register SLEB128 offset
DW_CFA_def_cfa_offset_sf 0 0x13 SLEB128 offset

The upper two bits in the call-frame-instructions are fully
used up, so there is no way to get a DW_CFA_offset_sf with
register encoded in a single byte, so no such thing is
defined. Instead the existing DW_CFA_offset plus
DW_CFA_offset_extended_sf suffice.

With care in the implementor's definition of
data-alignment-factor, this situation will have no practical
consequences as most of the time the existing DW_CFA_offset
instruction will be directly usable.

Not Proposed idea A:
I considered introducing a new data alignment factor for
DW_CFA_def_cfa and DW_CFA_def_cfa_offset: This seemed to
suggest a new .debug_frame version number was required. A new
field in the CIE was required and this made the document a)
either ignore the current version or b) become rather more
complicated and describe two versions at once. So this is not

Not Proposed idea B:
I considered making DW_CFA_def_cfa_offset_sf and
DW_CFA_def_cfa_sf have no data-factor, but thought the
conceptual consistency of using the data factor plus the
(small) space advantage made use of the data-factor

Not Proposed idea C:
Simply declaring DW_CFA_def_cfa and DW_CFA_def_cfa_offset to
have the data-alignment factor multiplied in. That this makes
the SGI and other implementations invalid is not such a big
problem. That it forces the from-cfa and in-cfa offsets to
have the same *sign* is a big problem (it does not work for
MIPS frames in a sensible way), and this problem is, I think,
the reason sgi interpreted .debug_frame as we did back in the
early 90's.

Not Proposed idea D:
Simply making the existing DW_CFA_offset DW_CFA_offset_extended
DW_CFA_def_cfa DW_CFA_def_cfa_offset offsets be SLEB numbers.
This is a compatibility issue if the version not changed. If
the version number is changed and both versions are not
documented, users of the old document will continue to be
confused. If the version number is changed and both versions
are documented, the result will be a hard to read document.

Not Proposed idea E:
Ron Brender. notes that DW_CFA_def_cfa_sf is not strictly
necessary. However, since using it saves one byte over the
DW_CFA_def_register DW_CFA_def_cfa_offset_sf pair that it is
worth having DW_CFA_def_cfa_sf, IMO.

Not Proposed idea F:
Felix Burton proposed that the return-address-register be
ULEB128, not ubyte. As I recall this was tabled till there was
reason to make an incompatible change, since the existing
approach is workable for all platforms anyway (the 'register
number' need not be a real physical register, it is a table
column). Since the proposal in hand does not request a version
number change there is no suggestion here to change the
return-address-register encoding.


Jason Merrill provided the key notion in his email Sept 24 2000.

This proposal adds DW_CFA_offset_extended_sf, DW_CFA_def_cfa_sf, and DW_CFA_def_cfa_offset_sf
operation to the Call Frame Instructions.  Using GNU glibc as a test, with 162K of frame description
(approx 5% of the dwarf data), there was a 13% size reduction using these operations.   Proposal adopted.