[PATCH pahole v2 2/4] dwarves: fix classification of byte/bit hole for aligned bitfield

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



From: Andrii Nakryiko <andriin@xxxxxx>

This patch fixes a bug in class__find_holes() with determining byte hole
as a bit hole in case where previous member is not bitfield, but current
one is aligned bitfield. See example below, notice hole classification
hw_stopped field..

$ cat test/bit_test.c
struct s {
        long unused: 62;
        /* 2 bit hole */
        int hw_stopped;
        /* 4 byte hole */
        long unused2: 55;
        /* 9 bit padding */
};

int main() {
        static struct s s;
        return 0;
}

$ clang -g test/bit_test.c -o test/bit_test

$ pahole -JV test/bit_test
File test/bit_test:
[1] STRUCT s kind_flag=1 size=24 vlen=3
        unused type_id=2 bitfield_size=62 bits_offset=0
        hw_stopped type_id=3 bitfield_size=0 bits_offset=64
        unused2 type_id=2 bitfield_size=55 bits_offset=128
[2] INT long int size=8 bit_offset=0 nr_bits=64 encoding=SIGNED
[3] INT int size=4 bit_offset=0 nr_bits=32 encoding=SIGNED

BEFORE:
$ pahole -F btf test/bit_test
struct s {
        long int                   unused:62;            /*     0: 0  8 */

        /* XXX 2 bits hole, try to pack */

        int                        hw_stopped;           /*     8     4 */

        /* XXX 32 bits hole, try to pack */

        long int                   unused2:55;           /*    16: 0  8 */

        /* size: 24, cachelines: 1, members: 3 */
        /* sum members: 4 */
        /* sum bitfield members: 117 bits, bit holes: 2, sum bit holes: 34 bits */
        /* bit_padding: 9 bits */
        /* last cacheline: 24 bytes */
};

AFTER:
$ pahole -F btf test/bit_test
struct s {
        long int                   unused:62;            /*     0: 0  8 */

        /* XXX 2 bits hole, try to pack */

        int                        hw_stopped;           /*     8     4 */

        /* XXX 4 bytes hole, try to pack */

        long int                   unused2:55;           /*    16: 0  8 */

        /* size: 24, cachelines: 1, members: 3 */
        /* sum members: 4, holes: 1, sum holes: 4 */
        /* sum bitfield members: 117 bits, bit holes: 1, sum bit holes: 2 bits */
        /* bit_padding: 9 bits */
        /* last cacheline: 24 bytes */
};

Signed-off-by: Andrii Nakryiko <andriin@xxxxxx>
---
 dwarves.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/dwarves.c b/dwarves.c
index efa58a9..5be50b0 100644
--- a/dwarves.c
+++ b/dwarves.c
@@ -1223,9 +1223,9 @@ void class__find_holes(struct class *class)
 		if (pos->bitfield_size) {
 			int aligned_start = pos->byte_offset * 8;
 			/* we can have some alignment byte padding left,
-			 * but we need to be carful about bitfield spanning
+			 * but we need to be careful about bitfield spanning
 			 * multiple aligned boundaries */
-			if (last_seen_bit < aligned_start && aligned_start < bit_start) {
+			if (last_seen_bit < aligned_start && aligned_start <= bit_start) {
 				byte_holes = pos->byte_offset - last_seen_bit / 8;
 				last_seen_bit = aligned_start;
 			}
-- 
2.17.1




[Index of Archives]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux