This is the mail archive of the gdb-cvs@sourceware.org mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[binutils-gdb] Change ptype/o to print bit offset


https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=9d3421afbb9f3cfc8e67366ba75ea12ed8f732a3

commit 9d3421afbb9f3cfc8e67366ba75ea12ed8f732a3
Author: Tom Tromey <tromey@adacore.com>
Date:   Mon Apr 29 09:55:56 2019 -0600

    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.

Diff:
---
 gdb/ChangeLog                            |  5 +++++
 gdb/doc/ChangeLog                        |  4 ++++
 gdb/doc/gdb.texinfo                      |  9 +++++----
 gdb/testsuite/ChangeLog                  |  4 ++++
 gdb/testsuite/gdb.base/ptype-offsets.exp | 30 +++++++++++++++---------------
 gdb/typeprint.c                          | 30 +++++++-----------------------
 6 files changed, 40 insertions(+), 42 deletions(-)

diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index c62998f..93641a0 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,5 +1,10 @@
 2019-05-08  Tom Tromey  <tromey@adacore.com>
 
+	* typeprint.c (print_offset_data::update): Print the bit offset,
+	not the number of bits remaining.
+
+2019-05-08  Tom Tromey  <tromey@adacore.com>
+
 	* typeprint.c (print_offset_data::maybe_print_hole): Add extra
 	padding at end of comment.
 
diff --git a/gdb/doc/ChangeLog b/gdb/doc/ChangeLog
index a26e20c..14c4462 100644
--- a/gdb/doc/ChangeLog
+++ b/gdb/doc/ChangeLog
@@ -1,3 +1,7 @@
+2019-05-08  Tom Tromey  <tromey@adacore.com>
+
+	* gdb.texinfo (Symbols): Document change to ptype/o.
+
 2019-05-03  Eli Zaretskii  <eliz@gnu.org>
 
 	* gdb.texinfo (Separate Debug Files): Document how the
diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo
index dd8ae91..b7f3b27 100644
--- a/gdb/doc/gdb.texinfo
+++ b/gdb/doc/gdb.texinfo
@@ -17861,15 +17861,16 @@ bitfields:
 /* XXX  3-bit hole   */
 /* XXX  4-byte hole  */
 /*    8      |     8 */    int64_t a5;
-/*   16:27   |     4 */    int a6 : 5;
-/*   16:56   |     8 */    int64_t a7 : 3;
+/*   16: 0   |     4 */    int a6 : 5;
+/*   16: 5   |     8 */    int64_t a7 : 3;
+"/* XXX  7-byte padding  */
 
                            /* total size (bytes):   24 */
                          @}
 @end smallexample
 
-Note how the offset information is now extended to also include how
-many bits are left to be used in each bitfield.
+Note how the offset information is now extended to also include the
+first bit of the bitfield.
 @end table
 
 @kindex ptype
diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog
index eb1110e..6b51db8 100644
--- a/gdb/testsuite/ChangeLog
+++ b/gdb/testsuite/ChangeLog
@@ -1,5 +1,9 @@
 2019-05-08  Tom Tromey  <tromey@adacore.com>
 
+	* gdb.base/ptype-offsets.exp: Update tests.
+
+2019-05-08  Tom Tromey  <tromey@adacore.com>
+
 	* gdb.base/ptype-offsets.exp: Use string_to_regexp.  Fix test
 	cases.
 	* gdb.base/ptype-offsets.cc (struct abc) <my_int_type>: Now
diff --git a/gdb/testsuite/gdb.base/ptype-offsets.exp b/gdb/testsuite/gdb.base/ptype-offsets.exp
index 12b3a74..6116520 100644
--- a/gdb/testsuite/gdb.base/ptype-offsets.exp
+++ b/gdb/testsuite/gdb.base/ptype-offsets.exp
@@ -38,7 +38,7 @@ gdb_test "ptype /o struct abc" \
 "/* offset    |  size */  type = struct abc \{" \
 "                         public:" \
 "/*    8      |     8 */    void *field1;" \
-"/*   16:31   |     4 */    unsigned int field2 : 1;" \
+"/*   16: 0   |     4 */    unsigned int field2 : 1;" \
 "/* XXX  7-bit hole   */" \
 "/* XXX  3-byte hole  */" \
 "/*   20      |     4 */    int field3;" \
@@ -63,7 +63,7 @@ gdb_test "ptype /oTM struct abc" \
 "/* offset    |  size */  type = struct abc \{" \
 "                         public:" \
 "/*    8      |     8 */    void *field1;" \
-"/*   16:31   |     4 */    unsigned int field2 : 1;" \
+"/*   16: 0   |     4 */    unsigned int field2 : 1;" \
 "/* XXX  7-bit hole   */" \
 "/* XXX  3-byte hole  */" \
 "/*   20      |     4 */    int field3;" \
@@ -93,7 +93,7 @@ gdb_test "ptype /TMo struct abc" \
 "/* offset    |  size */  type = struct abc \{" \
 "                         public:" \
 "/*    8      |     8 */    void *field1;" \
-"/*   16:31   |     4 */    unsigned int field2 : 1;" \
+"/*   16: 0   |     4 */    unsigned int field2 : 1;" \
 "/* XXX  7-bit hole   */" \
 "/* XXX  3-byte hole  */" \
 "/*   20      |     4 */    int field3;" \
@@ -264,15 +264,15 @@ gdb_test "ptype /o struct poi" \
 gdb_test "ptype /o struct tyu" \
     [string_to_regexp [multi_line \
 "/* offset    |  size */  type = struct tyu \{" \
-"/*    0:31   |     4 */    int a1 : 1;" \
-"/*    0:28   |     4 */    int a2 : 3;" \
-"/*    0: 5   |     4 */    int a3 : 23;" \
+"/*    0: 0   |     4 */    int a1 : 1;" \
+"/*    0: 1   |     4 */    int a2 : 3;" \
+"/*    0: 4   |     4 */    int a3 : 23;" \
 "/*    3: 3   |     1 */    signed char a4 : 2;" \
 "/* XXX  3-bit hole   */" \
 "/* XXX  4-byte hole  */" \
 "/*    8      |     8 */    int64_t a5;" \
-"/*   16:27   |     4 */    int a6 : 5;" \
-"/*   16:56   |     8 */    int64_t a7 : 3;" \
+"/*   16: 0   |     4 */    int a6 : 5;" \
+"/*   16: 5   |     8 */    int64_t a7 : 3;" \
 "/* XXX  7-byte padding  */" \
 "" \
 "                           /* total size (bytes):   24 */" \
@@ -293,8 +293,8 @@ gdb_test "ptype /o struct asd" \
 "" \
 "                                   /* total size (bytes):    8 */" \
 "                               \} f3;" \
-"/*   24:27   |     4 */        int f4 : 5;" \
-"/*   24:26   |     4 */        unsigned int f5 : 1;" \
+"/*   24: 0   |     4 */        int f4 : 5;" \
+"/*   24: 5   |     4 */        unsigned int f5 : 1;" \
 "/* XXX  2-bit hole   */" \
 "/* XXX  1-byte hole  */" \
 "/*   26      |     2 */        short f6;" \
@@ -304,11 +304,11 @@ gdb_test "ptype /o struct asd" \
 "                           \} f7;" \
 "/*   32      |     8 */    unsigned long f8;" \
 "/*   40      |     8 */    signed char *f9;" \
-"/*   48:28   |     4 */    int f10 : 4;" \
-"/*   48:27   |     4 */    unsigned int f11 : 1;" \
-"/*   48:26   |     4 */    unsigned int f12 : 1;" \
-"/*   48:25   |     4 */    unsigned int f13 : 1;" \
-"/*   48:24   |     4 */    unsigned int f14 : 1;" \
+"/*   48: 0   |     4 */    int f10 : 4;" \
+"/*   48: 4   |     4 */    unsigned int f11 : 1;" \
+"/*   48: 5   |     4 */    unsigned int f12 : 1;" \
+"/*   48: 6   |     4 */    unsigned int f13 : 1;" \
+"/*   48: 7   |     4 */    unsigned int f14 : 1;" \
 "/* XXX  7-byte hole  */" \
 "/*   56      |     8 */    void *f15;" \
 "/*   64      |     8 */    void *f16;" \
diff --git a/gdb/typeprint.c b/gdb/typeprint.c
index d1cdfe1..7a44dbd 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
     {


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]