[Bug gdb/34430] New: [gdb] value_from_mpz misplaces big-endian DW_AT_data_bit_offset values

firmiana402 at gmail dot com via Gdb-prs <[email protected]>
Newsgroups gmane.comp.gdb.bugs.discuss
Message-ID <[email protected]/bugzilla/>
https://sourceware.org/bugzilla/show_bug.cgi?id=34430

            Bug ID: 34430
           Summary: [gdb] value_from_mpz misplaces big-endian
                    DW_AT_data_bit_offset values
           Product: gdb
           Version: HEAD
            Status: UNCONFIRMED
          Severity: normal
          Priority: P2
         Component: gdb
          Assignee: unassigned at sourceware dot org
          Reporter: firmiana402 at gmail dot com
  Target Milestone: ---

In gdb/value.c, value_from_mpz writes bit-precise integers by shifting
the logical value by type->bit_offset () before storing it:

    if (type->bit_size_differs_p ())
      {
        unsigned bit_off = type->bit_offset ();
        unsigned bit_size = type->bit_size ();

        storage.mask (bit_size);
        storage <<= bit_off;
      }

Using the raw DW_AT_data_bit_offset as a low-bit shift is not correct
for big-endian storage.

For example, consider this base type:

    DW_TAG_base_type
      DW_AT_encoding         DW_ATE_unsigned
      DW_AT_byte_size        2
      DW_AT_bit_size         8
      DW_AT_data_bit_offset  8
      DW_AT_endianity        DW_END_big

DWARF v5 Section 5.1 defines DW_AT_data_bit_offset as an offset from
the beginning of the containing storage.  The logical value therefore
occupies the second byte of the two-byte big-endian storage.  In the
low-bit numbering used by the gdb_mpz storage value, the required
shift is:

    16 - 8 - 8 = 0

The current code instead shifts by 8.  Writing 0xbb therefore creates
the bytes [0xbb, 0x00] rather than [0x00, 0xbb].

The later gdb_mpz::truncate call, defined in gdb/gmp-utils.h, only
serializes the already-shifted integer in the requested byte order.
It has no bit-offset information and cannot correct this placement.

Before shifting, value_from_mpz should convert a big-endian data bit
offset to an offset from the least significant bit:

    if (type_byte_order (type) == BFD_ENDIAN_BIG)
      bit_off = (type->length () * TARGET_CHAR_BIT
                 - bit_off - bit_size);

-- 
You are receiving this mail because:
You are on the CC list for the bug.
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.