Issue 260127.1: Standardize Operation Headings

Author: Ben Woodard
Champion:
Date submitted: 2026-01-27
Date revised: 2026-05-11
Date closed: 2026-06-08
Type: Editorial
Status: Accepted
DWARF version: 6

Comparing 2026-05-11 with latest. [ Return to the latest version ]

Background
----------

This proposal is editorial in nature: it does not intend to change the
meaning of any DWARF constructs, but merely to standardize the
presentation of the existing DWARF operations to facilitate
understanding.

It is believed that tool authors referring to the the standard would
find it much easier to understand if each operand followed a standard
template, rather than explaining these in the textual description of
the operand. This issue proposes such a template and converts each
operand to that template.

DWARF operations potentially have three sources of input: inline
DWARF operations potentially have three sources of input: immediate
operands, which are encoded in their byte stream; operands on the
stack; and the context in which they are executed. They can also
modify the stack and leave items on the stack. For every operator each
of these sources of input, output, and side effects are specified in a
standardized format similar to how other stack machine operations have
been documented in the past.

Proposed Changes
----------------

In Chapter 3 replace the following paragraph:

> A DWARF expression is encoded as a stream of operations, each
> consisting of an opcode followed by zero or more literal operands. The
> number of operands is implied by the opcode.

With:

> A DWARF expression is encoded as a stream of operations, each
> operation consisting of an opcode followed by zero or more inline
> operation consisting of an opcode followed by zero or more immediate
> operands. The number of inline operands is implied by the
> operands. The number of immediate operands and their encodings are implied by the
> opcode. It may also receive operands from the stack and make use of
> opcode. It may also consume operands from the stack and make use of
> information from its evaluation context.

> The description of each operation begins with a heading that shows
> the name of the operation and its inline operands, if any, as a
> the name of the operation and its immediate operands, if any, as a
> C-like function prototype. Each inline operand has one of the
> following types:
> C-like function prototype. Each immediate operand is encoded according
> to one of the form codes given in Section 8.5.5 "Classes and Forms".
> (For improved readability, the form codes in these descriptions are
> given here without the `DW_FORM_` prefix.)
>
> - ubyte (unsigned 1-byte value)
> - uhalf (unsigned 2-byte value)
> - uword (unsigned 4-byte value)
> - ulong (unsigned 8-byte value)
> - sbyte (signed 1-byte value)
> - shalf (signed 2-byte value)
> - sword (signed 4-byte value)
> - slong (signed 8-byte value)
> - uleb (unsigned LEB128 value)
> - sleb (signed LEB128 value)
> - block (a block of bytes, encoded like `DW_FORM_block`)
> - block1 (a block of bytes, encoded like `DW_FORM_block1`)
> - address (an address in the default memory address space)
> - offset2 (2-byte offset to a DIE)
> - offset4 (4-byte offset to a DIE)
> - offset (4- or 8-byte offset to a DIE)
>
> Following the operation heading is a stack diagram, showing the
> Following the operation heading is a stack diagram showing the
> state of the stack before and after the operation, with the top of
> state of the stack before and after the operation. The top of
> the stack at the top of the diagram, and the base of the stack shown
> the stack is at the top of the diagram, and the base of the stack is shown
> as an open rectangle at the bottom of the diagram. In some cases,
> where the stack diagrams are the same for a group of operations, the
> diagram is given at the top of the section.
>
> *Symbolic names are often given to the stack arguments and the stack
> result when it is considered to be helpful or meaningful. In the
> cases where no sybolic name would be meaningful, the generic names A,
> B, C, and D are used.*
>

In Section 3.2, replace the operation headings and add stack diagrams, as follows:

> `DW_OP_dup`
>
> ![DW_OP_dup](../images/issue-260127-1/op-dup.png)

> `DW_OP_drop`
>
> ![DW_OP_drop](../images/issue-260127-1/op-drop.png)

> `DW_OP_pick` (ubyte N)
> `DW_OP_pick (unsigned data1 N)`
>
> ![DW_OP_pick](../images/issue-260127-1/op-pick.png)

> `DW_OP_over`
>
> ![DW_OP_over](../images/issue-260127-1/op-over.png)

> `DW_OP_swap`
>
> ![DW_OP_swap](../images/issue-260127-1/op-swap.png)

> `DW_OP_rot`
>
> ![DW_OP_rot](../images/issue-260127-1/op-rot.png)

In section 3.3, add a stack diagram for the section,
and replace the operation headings as follows:

> ![DW_OP_lit](../images/issue-260127-1/op-lit.png)
>
> `DW_OP_lit0`, `DW_OP_lit1`, ..., `DW_OP_lit31`
>
> `DW_OP_const1u (unsigned data1 VALUE)`
>
> `DW_OP_const2u (unsigned data2 VALUE)`
>
> `DW_OP_const4u (unsigned data4 VALUE)`
>
> `DW_OP_const8u (unsigned data8 VALUE)`
>
> `DW_OP_const1s (signed data1 VALUE)`
>
> `DW_OP_const2s (signed data2 VALUE)`
>
> `DW_OP_const4s (signed data4 VALUE)`
>
> `DW_OP_const8s (signed data8 VALUE)`
>
> `DW_OP_const1u` (ubyte VALUE)
> `DW_OP_constu (udata VALUE)`
>
> `DW_OP_const2u` (uhalf VALUE)
>
> `DW_OP_const4u` (uword VALUE)
>
> `DW_OP_const8u` (ulong VALUE)
>
> `DW_OP_const1s` (sbyte VALUE)
> `DW_OP_consts (sdata VALUE)`
>
> `DW_OP_const2s` (shalf VALUE)
>
> `DW_OP_const4s` (sword VALUE)
>
> `DW_OP_const8s` (slong VALUE)
>
> `DW_OP_constu` (uleb VALUE)
>
> `DW_OP_consts`(sleb VALUE)
>
> `DW_OP_constx` (uleb INDEX)
> `DW_OP_constx (addrx INDEX)`
>
> `DW_OP_const_type`(uleb DIE_REF, block1 VALUE)
> `DW_OP_const_type (ref_udata DIE_REF, block1 VALUE)`

In section 3.4, replace the operation headings and add stack diagrams, as follows:

> `DW_OP_regval_type` (uleb REG, uleb DIE_REF)
> `DW_OP_regval_type (udata REG, ref_udata DIE_REF)`
>
> ![DW_OP_regval-type](../images/issue-260127-1/op-regval-type.png)

> `DW_OP_regval_bits` (uleb NBITS)
> `DW_OP_regval_bits (udata NBITS)`
>
> ![DW_OP_regval-bits](../images/issue-260127-1/op-regval-bits.png)

In section 3.5, move the unary operations into a new subsection
"3.5.1 Unary Operations".
Add a stack diagram for the subsection, and replace the operation
headings as follows:

> ![DW_OP_unary](../images/issue-260127-1/op-unary.png)
>
> `DW_OP_abs`
>
> `DW_OP_neg`
>
> `DW_OP_not`

Move the binary operations into a new subsection
"3.5.2 Binary Operations".
Add a stack diagram for the subsection, and replace the operation
headings as follows:

> ![DW_OP_binary](../images/issue-260127-1/op-binary.png)
>
> `DW_OP_and`
>
> `DW_OP_div`
>
> `DW_OP_minus`
>
> `DW_OP_mod`
>
> `DW_OP_mul`
>
> `DW_OP_or`
>
> `DW_OP_plus`
>
> `DW_OP_shl`
>
> `DW_OP_shr`
>
> `DW_OP_shra`
>
> `DW_OP_xor`

Move the `DW_OP_plus_uconst` operation into a new subsection
"3.5.3 Add Constant Operation".
Replace the operation heading and add a stack diagram, as follows:

> `DW_OP_plus_uconst` (uleb B)
> `DW_OP_plus_uconst (udata B)`
>
> ![DW_OP_unary](../images/issue-260127-1/op-plus-uconst.png)

In section 3.6, replace the operation headings and add stack diagrams, as follows:

> `DW_OP_push_object_location`
>
> ![DW_OP_push_object_location](../images/issue-260127-1/op-push-loc.png)

> `DW_OP_form_tls_location`
>
> ![DW_OP_form_tls_location](../images/issue-260127-1/op-tls.png)

> `DW_OP_call_frame_cfa`
>
> ![DW_OP_call_frame_cfa](../images/issue-260127-1/op-push-loc.png)

> `DW_OP_push_lane`
>
> ![DW_OP_push_lane](../images/issue-260127-1/op-push-lane.png)

In section 3.7, replace the operation headings and add stack diagrams, as follows:

> `DW_OP_addr` (address A)
> `DW_OP_addr (addr A)`
>
> `DW_OP_addrx` (uleb INDEX)
> `DW_OP_addrx (addrx INDEX)`
>
> `DW_OP_fbreg` (sleb OFFSET)
> `DW_OP_fbreg (sdata OFFSET)`
>
> `DW_OP_breg<n>` (sleb OFFSET)
> `DW_OP_breg<n> (sdata OFFSET)`
>
> `DW_OP_bregx` (uleb REG, sleb OFFSET)
> `DW_OP_bregx (udata REG, sdata OFFSET)`
>
> ![DW_OP_addr](../images/issue-260127-1/op-mem.png)

In section 3.8, replace the operation headings and add stack diagrams, as follows:

> `DW_OP_reg<n>`
>
> `DW_OP_regx` (uleb REG)
> `DW_OP_regx (udata REG)`
>
> ![DW_OP_reg](../images/issue-260127-1/op-reg.png)

In section 3.9, replace the operation headings and add stack diagrams, as follows:

> `DW_OP_undefined`
>
> ![DW_OP_undefined](../images/issue-260127-1/op-undef.png)

In section 3.10, replace the operation headings and add stack diagrams, as follows:

> `DW_OP_implicit_value` (block VALUE)
> `DW_OP_implicit_value (block VALUE)`
>
> ![DW_OP_implicit_value](../images/issue-260127-1/op-implicit.png)

> `DW_OP_stack_value`
>
> ![DW_OP_stack_value](../images/issue-260127-1/op-stack-value.png)

In section 3.11, replace the operation heading and add a stack diagrams, as follows:

> `DW_OP_implicit_pointer` (offset DIE_REF, sleb OFFSET)
> `DW_OP_implicit_pointer (ref_addr DIE_REF, sdata OFFSET)`
>
> ![DW_OP_implicit_pointer](../images/issue-260127-1/op-implicit-ptr.png)

In section 3.12, replace the operation headings and add stack diagrams, as follows:

> `DW_OP_composite`
>
> ![DW_OP_composite](../images/issue-260127-1/op-composite.png)

> `DW_OP_piece` (uleb SIZE)
> `DW_OP_piece (udata SIZE)`
>
> `DW_OP_bit_piece` (uleb SIZE, uleb OFFSET)
> `DW_OP_bit_piece (udata SIZE, udata OFFSET)`
>
> ![DW_OP_piece](../images/issue-260127-1/op-piece.png)

In section 3.13, replace the operation headings and add stack diagrams, as follows:

> `DW_OP_deref`
>
> `DW_OP_deref_size` (ubyte SIZE)
> `DW_OP_deref_size (unsigned data1 SIZE)`
>
> `DW_OP_deref_type` (ubyte SIZE, uleb DIE_REF)
> `DW_OP_deref_type (unsigned data1 SIZE, ref_udata DIE_REF)`
>
> ![DW_OP_deref](../images/issue-260127-1/op-deref.png)

> `DW_OP_xderef`
>
> `DW_OP_xderef_size` (ubyte SIZE)
> `DW_OP_xderef_size (unsigned data1 SIZE)`
>
> `DW_OP_xderef_type` (ubyte SIZE, uleb DIE_REF)
> `DW_OP_xderef_type (unsigned data1 SIZE, ref_udata DIE_REF)`
>
> ![DW_OP_xderef](../images/issue-260127-1/op-xderef.png)

In section 3.14, replace the operation headings and add stack diagrams, as follows:

> `DW_OP_offset`
>
> `DW_OP_bit_offset`
>
> ![DW_OP_offset](../images/issue-260127-1/op-offset.png)

In section 3.15, replace the operation headings and add stack diagrams, as follows:

> `DW_OP_le`, `DW_OP_ge`, `DW_OP_eq`, `DW_OP_lt`, `DW_OP_gt`, `DW_OP_ne`
>
> ![DW_OP_relational](../images/issue-260127-1/op-relational.png)

> `DW_OP_skip` (shalf SKIP)
> `DW_OP_skip (signed data2 SKIP)`
>
>  *no stack effects*
>
> `DW_OP_bra` (shalf SKIP)
> `DW_OP_bra (signed data2 SKIP)`
>
> ![DW_OP_bra](../images/issue-260127-1/op-bra.png)

> `DW_OP_call2` (uhalf DIE_REF)
> `DW_OP_call2 (ref2 DIE_REF)`
>
> `DW_OP_call4` (uword DIE_REF)
> `DW_OP_call4 (ref4 DIE_REF)`
>
> `DW_OP_call_ref` (offset DIE_REF)
> `DW_OP_call_ref (ref_addr DIE_REF)`
>
>  *stack effects by agreement*

In section 3.16, replace the operation headings and add stack diagrams, as follows:

> `DW_OP_convert` (uleb DIE_REF)
> `DW_OP_convert (ref_udata DIE_REF)`
>
> `DW_OP_reinterpret` (uleb DIE_REF)
> `DW_OP_reinterpret (ref_udata DIE_REF)`
>
> ![DW_OP_convert](../images/issue-260127-1/op-convert.png)

In section 3.17, replace the operation headings as follows:

> `DW_OP_nop`
>
>  *no stack effects*

> `DW_OP_entry_value` (block EXPR)
> `DW_OP_entry_value (block EXPR)`
>
>  *stack result by agreement*

> `DW_OP_extended` (uleb EXTENDED_OPCODE)
> `DW_OP_extended (udata EXTENDED_OPCODE)`
>
>  *stack effects defined by extended operation*
>

> `DW_OP_user_extended` (uleb EXTENDED_OPCODE)
> `DW_OP_user_extended (udata EXTENDED_OPCODE)`
>
>  *stack effects defined by extended operation*

---

2026-03-30: Accepted in principle; will revise to use drawings as shown in
[op-diagrams.pdf](../doc/Issue-260127-1-op-diagrams.pdf).

2026-04-29: [Updated][diff1] some of the introductory material and added
stack diagrams.

2026-05-10: Editorial correction: "inline parameters" should be
"inline operands".

2026-05-11: [Revised][diff2] operation headings and stack drawings.
Changed "parameters (on the stack)" to "operands".
Fixed type of `DIE_REF` operand for `DW_OP_const_type`.
Defined `block` and `block1` operand types the same as corresponding FORM codes.

2026-05-19: [Revised][diff3]: Change "inline operands" to "immediate operands".
Used form names for immediate operand representations.

2026-06-08: Accepted. A subsequent proposal may introduce signed/unsigned
variants of `DW_FORM_data[1248]`, which could replace the use of "signed data1",
etc., here.

2026-06-22: Errata: In `DW_OP_xderef*` operations, the "aspace" and
"location" stack operands were reversed. "location" should be the top-of-stack
entry.