summaryrefslogtreecommitdiff
path: root/gdb/typeprint.c
diff options
context:
space:
mode:
authorTom Tromey <tromey@adacore.com>2019-04-29 09:55:56 -0600
committerTom Tromey <tromey@adacore.com>2019-05-08 10:15:51 -0600
commit9d3421afbb9f3cfc8e67366ba75ea12ed8f732a3 (patch)
tree66eb6aba210e07f4f76b979c07687598d477dcea /gdb/typeprint.c
parent844333e24966817fe4d622494a75c8ae0acdb91f (diff)
downloadbinutils-gdb-9d3421afbb9f3cfc8e67366ba75ea12ed8f732a3.tar.gz
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.
Diffstat (limited to 'gdb/typeprint.c')
-rw-r--r--gdb/typeprint.c30
1 files changed, 7 insertions, 23 deletions
diff --git a/gdb/typeprint.c b/gdb/typeprint.c
index d1cdfe11cc0..7a44dbdb313 100644
--- a/gdb/typeprint.c
+++ b/gdb/typeprint.c
@@ -131,32 +131,16 @@ print_offset_data::update (struct type *type, unsigned int field_idx,
maybe_print_hole (stream, bitpos, "hole");
- if (TYPE_FIELD_PACKED (type, field_idx))
+ if (TYPE_FIELD_PACKED (type, field_idx)
+ || offset_bitpos % TARGET_CHAR_BIT != 0)
{
- /* We're dealing with a bitfield. Print how many bits are left
- to be used. */
- unsigned int bitsize = TYPE_FIELD_BITSIZE (type, field_idx);
- /* The bitpos relative to the beginning of our container
- field. */
- unsigned int relative_bitpos;
-
- /* The following was copied from
- value.c:value_primitive_field. */
- if ((bitpos % fieldsize_bit) + bitsize <= fieldsize_bit)
- relative_bitpos = bitpos % fieldsize_bit;
- else
- relative_bitpos = bitpos % TARGET_CHAR_BIT;
+ /* We're dealing with a bitfield. Print the bit offset. */
+ fieldsize_bit = TYPE_FIELD_BITSIZE (type, field_idx);
- /* This is the exact offset (in bits) of this bitfield. */
- unsigned int bit_offset
- = (bitpos - relative_bitpos) + offset_bitpos;
+ unsigned real_bitpos = bitpos + offset_bitpos;
- /* The position of the field, relative to the beginning of the
- struct, and how many bits are left to be used in this
- container. */
- fprintf_filtered (stream, "/* %4u:%2u", bit_offset / TARGET_CHAR_BIT,
- fieldsize_bit - (relative_bitpos + bitsize));
- fieldsize_bit = bitsize;
+ fprintf_filtered (stream, "/* %4u:%2u", real_bitpos / TARGET_CHAR_BIT,
+ real_bitpos % TARGET_CHAR_BIT);
}
else
{