From b0cf845e02c6410025029455dd090533c9c1e76a Mon Sep 17 00:00:00 2001 From: Yonghong Song Date: Fri, 11 Jan 2019 16:19:53 -0800 Subject: [PATCH] dwarves: Change type of bitfield_offset from uint8_t to int8_t The dwarves class_member field bitfield_offset represents the dwarf tag DW_AT_bit_offset. For dwarf2, this field can be negative for little endian for bitfields in packed data structures which cross type boundary. -bash-4.4$ cat bitfield.c struct packed { char x1: 1; char x2: 3; char x3: 3; int y1: 7; int y2: 20; } __attribute__((packed)); struct packed g; -bash-4.4$ gcc -O2 -c -g bitfield.c -bash-4.4$ pahole -JV bitfield.o File bitfield.o: [1] STRUCT packed kind_flag=1 size=5 vlen=5 x1 type_id=2 bitfield_size=1 bits_offset=0 x2 type_id=2 bitfield_size=3 bits_offset=1 x3 type_id=2 bitfield_size=3 bits_offset=4 y1 type_id=3 bitfield_size=7 bits_offset=7 y2 type_id=3 bitfield_size=255 bits_offset=16776974 [2] INT char size=1 bit_offset=0 nr_bits=8 encoding=(none) [3] INT int size=4 bit_offset=0 nr_bits=32 encoding=SIGNED -bash-4.4$ The above large negative bits_offset and bitfield_size=255 results from negative bitfield_offset which is interpreted as positive value in btf encoding. With this fix, the pahole works properly for BTF: -bash-4.4$ pahole -JV bitfield.o File bitfield.o: [1] STRUCT packed kind_flag=1 size=5 vlen=5 x1 type_id=2 bitfield_size=1 bits_offset=0 x2 type_id=2 bitfield_size=3 bits_offset=1 x3 type_id=2 bitfield_size=3 bits_offset=4 y1 type_id=3 bitfield_size=7 bits_offset=7 y2 type_id=3 bitfield_size=20 bits_offset=14 [2] INT char size=1 bit_offset=0 nr_bits=8 encoding=(none) [3] INT int size=4 bit_offset=0 nr_bits=32 encoding=SIGNED -bash-4.4$ Note that change bitfield_offset from uint8_t to int8_t is safe as the maximum int type we support is __int128 and maximum bitfield_offset is 127. Signed-off-by: Yonghong Song Reported-by: Arnaldo Carvalho de Melo Cc: Alexei Starovoitov Cc: Andrii Nakryiko Cc: Martin KaFai Lau Cc: dwarves@vger.kernel.org Link: https://www.spinics.net/lists/dwarves/msg00199.html Signed-off-by: Arnaldo Carvalho de Melo --- dwarves.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dwarves.h b/dwarves.h index e6bffe8..e5f8347 100644 --- a/dwarves.h +++ b/dwarves.h @@ -831,7 +831,7 @@ struct class_member { uint32_t bit_size; uint32_t byte_offset; size_t byte_size; - uint8_t bitfield_offset; + int8_t bitfield_offset; uint8_t bitfield_size; uint8_t bit_hole; uint8_t bitfield_end:1;