Change ptype/o to print bit offset
authorTom Tromey <tromey@adacore.com>
Mon, 29 Apr 2019 15:55:56 +0000 (09:55 -0600)
committerTom Tromey <tromey@adacore.com>
Wed, 8 May 2019 16:15:51 +0000 (10:15 -0600)
commit9d3421afbb9f3cfc8e67366ba75ea12ed8f732a3
tree66eb6aba210e07f4f76b979c07687598d477dcea
parent844333e24966817fe4d622494a75c8ae0acdb91f
Change ptype/o to print bit offset

Consider this short C example:

    struct inner
    {
      unsigned x;
      unsigned y : 3;
      unsigned z : 3;
    };

    struct outer
    {
      unsigned char o : 3;
      struct inner i __attribute__ ((packed));
    };

When I use "ptype/o" on this, I get:

    (gdb) ptype/o struct outer
    /* offset    |  size */  type = struct outer {
    /*    0: 5   |     1 */    unsigned char o : 3;
    /* XXX  5-bit hole  */
    /*    1      |     8 */    struct inner {
    /*    1      |     4 */        unsigned int x;
    /*    5:29   |     4 */        unsigned int y : 3;
    /*    5:26   |     4 */        unsigned int z : 3;
    /* XXX  2-bit padding  */
    /* XXX  3-byte padding */

   /* total size (bytes):    8 */
       } i;

       /* total size (bytes):    9 */
     }

In the location of "o" ("0: 5"), the "5" means "there are 5 bits left
relative to the size of the underlying type.

I find this very difficult to follow.  On irc, Sergio said that this
choice came because it is what pahole does.  However, I think it's not
very useful, and maybe is just an artifact of the way that
DW_AT_bit_offset was defined in DWARF 3.

This patch changes ptype/o to print the offset of a bitfield in a more
natural way, that is, using the bit number according to the platform's
bit numbering.

With this patch, the output is now:

    (gdb) ptype/o struct outer
    /* offset    |  size */  type = struct outer {
    /*    0: 0   |     1 */    unsigned char o : 3;
    /* XXX  5-bit hole  */
    /*    1      |     8 */    struct inner {
    /*    1      |     4 */        unsigned int x;
    /*    5: 0   |     4 */        unsigned int y : 3;
    /*    5: 3   |     4 */        unsigned int z : 3;
    /* XXX  2-bit padding  */
    /* XXX  3-byte padding */

   /* total size (bytes):    8 */
       } i;

       /* total size (bytes):    9 */
     }

This is better, IMO, because now the "offset" of a bitfield is
consistent with the offset of an ordinary member, referring to its
offset from the start of the structure.

gdb/ChangeLog
2019-05-08  Tom Tromey  <tromey@adacore.com>

* typeprint.c (print_offset_data::update): Print the bit offset,
not the number of bits remaining.

gdb/doc/ChangeLog
2019-05-08  Tom Tromey  <tromey@adacore.com>

* gdb.texinfo (Symbols): Document change to ptype/o.

gdb/testsuite/ChangeLog
2019-05-08  Tom Tromey  <tromey@adacore.com>

* gdb.base/ptype-offsets.exp: Update tests.
gdb/ChangeLog
gdb/doc/ChangeLog
gdb/doc/gdb.texinfo
gdb/testsuite/ChangeLog
gdb/testsuite/gdb.base/ptype-offsets.exp
gdb/typeprint.c