Issue 191107.1: DW_OP_byte_swap

Author: Chirag Patel
Champion: Andrew Cagney
Date submitted: 2019-11-07
Date revised:
Date closed: 2021-11-01
Type: Enhancement
Status: Rejected
DWARF Version: 6
Section 2.5.1.7, pg 37


DW_OP_byte_swap to Byte Swap the data on top of the dwarf stack.
===============================================================================

Overview
------------

For debugging binary with bi-endian marked dwarf DIEs and the some calculation 
depending at runtime, the data needs to be loaded at runtime and needs to be 
byte swapped. the depended variable DIE here is marked as big-endian and the
host is little-endian. The DW_OP_byte_swap will byte swap the raw data stored
in top dwarf stack entry.


0x00000057:   DW_TAG_variable
                DW_AT_name      ("__gbloffset__")
                DW_AT_type      (0x000001e5 "int")
                DW_AT_external  (true)
                DW_AT_decl_file ("…")
                DW_AT_decl_line (8)
                DW_AT_location  (DW_OP_addr 0) // pre linkage
                DW_AT_linkage_name      ("_gblsection__")
                DW_AT_endianity (DW_END_big)

0x00000170:   DW_TAG_variable
                DW_AT_name      ("VAR1")
                DW_AT_type      (0x0000010b "fixed.dec.display.72")
                DW_AT_decl_file ("…")
                DW_AT_decl_line (10)
                DW_AT_location  (DW_OP_addr 0x0, DW_OP_call4 0x57, DW_OP_deref_size,
                 4, DW_OP_dup, DW_OP_constu 0xff, DW_OP_lit0, DW_OP_shl,
                 DW_OP_and, DW_OP_lit24, DW_OP_shl, DW_OP_swap,
                 DW_OP_dup, DW_OP_constu 0xff, DW_OP_lit8, DW_OP_shl,
                 DW_OP_and, DW_OP_lit8, DW_OP_shl, DW_OP_swap,
                 DW_OP_dup, DW_OP_constu 0xff, DW_OP_lit16, DW_OP_shl,
                 DW_OP_and, DW_OP_lit8, DW_OP_shr, DW_OP_swap,
                 DW_OP_constu 0xff, DW_OP_lit24, DW_OP_shl, DW_OP_and,
                 DW_OP_lit24, DW_OP_shr, DW_OP_swap, DW_OP_or, DW_OP_or,
                 DW_OP_or, DW_OP_plus)
                DW_AT_linkage_name      ("VAR1")

In above case DW_OP_byte_swap will replace 
                 DW_OP_dup, DW_OP_constu 0xff, DW_OP_lit0, DW_OP_shl,
                 DW_OP_and, DW_OP_lit24, DW_OP_shl, DW_OP_swap,
                 DW_OP_dup, DW_OP_constu 0xff, DW_OP_lit8, DW_OP_shl,
                 DW_OP_and, DW_OP_lit8, DW_OP_shl, DW_OP_swap,
                 DW_OP_dup, DW_OP_constu 0xff, DW_OP_lit16, DW_OP_shl,
                 DW_OP_and, DW_OP_lit8, DW_OP_shr, DW_OP_swap,
                 DW_OP_constu 0xff, DW_OP_lit24, DW_OP_shl, DW_OP_and,
                 DW_OP_lit24, DW_OP_shr, DW_OP_swap, DW_OP_or, DW_OP_or, DW_OP_or
operations.

Proposed changes to DWARF

2.5.1.7 Special Operation

Add

<n> DW_OP_byte_swap

    The DW_OP_byte_swap operation pops the top stack entry, byte swaps the value
    and pushes back the swapped value on dwarf stack.

    e.g. so 0x12345678 will become 0x78563412, useful to change endianity of raw
    data.

--
2021-11-01:  Rejected - use existing DWARF Version 5 expression:

With DWARF 5, byte swapping of a value so that it can be used in
arithmetic operations can be performed using DW_OP_deref_type (or
DW_OP_convert_type).  For instance

Assuming this base type definition:

  BIGENDIAN: DW_TAG_base_type
              DW_AT_byte_size  8
              DW_AT_encoding   DW_ATE_unsigned
              DW_AT_endianity  DW_END_big

Then this expression:

  DW_OP_addr __gbloffset__   // push address of __gbloffset__ pointer
  DW_OP_deref_type BIGENDIAN,   // loads __gbloffset__, BIGENDIAN type
  DW_OP_convert_type 0,   // convert BIGENDIAN value on stack to a generic type

Will load the contents of __gbloffset__ and convert it to host byte order.

Ref: 2.5.1.4  Arithmetic and Logical Operations: "... Operands of an
operation with two operands must have the same type, either the same
base type or the generic type."