btf: Generate correct struct bitfield member types
For int types, the correct type size will be generated. For enum types, if the bit size is not 32, current BTF enum cannot represent it so a signed int type will be generated. For the following example: $ cat test.c enum A { A1, A2, A3 }; struct t { enum A a:3; volatile enum A b:4; } g; $ gcc -c -g -O2 test.c Without this patch, we will have: $ pahole -JV test.o [1] ENUM A size=4 vlen=3 A1 val=0 A2 val=1 A3 val=2 [2] STRUCT t size=4 vlen=2 a type_id=4 bits_offset=0 b type_id=6 bits_offset=3 [3] VOLATILE (anon) type_id=1 [4] ENUM A size=1 vlen=3 A1 val=0 A2 val=1 A3 val=2 [5] ENUM A size=1 vlen=3 A1 val=0 A2 val=1 A3 val=2 [6] VOLATILE (anon) type_id=5 [7] INT (anon) size=4 bit_offset=0 nr_bits=32 encoding=(none) There are two issues in the above. The struct "t" member "a" points to type [4]. But the nr_bits is lost in type [4]. The same for type [5] which is for struct "t" member "b". Since BTF ENUM type cannot encode nr_bits, this patch fixed the issue by generating a BTF INT type if the ENUM type number of bits in pahole is not 32. With this patch, the incorrect member nr_bits issue is fixed as below: $ pahole -JV test.o [1] ENUM A size=4 vlen=3 A1 val=0 A2 val=1 A3 val=2 [2] STRUCT t size=4 vlen=2 a type_id=4 bits_offset=0 b type_id=6 bits_offset=3 [3] VOLATILE (anon) type_id=1 [4] INT (anon) size=1 bit_offset=0 nr_bits=3 encoding=SIGNED [5] INT (anon) size=1 bit_offset=0 nr_bits=4 encoding=SIGNED [6] VOLATILE (anon) type_id=5 [7] INT (anon) size=4 bit_offset=0 nr_bits=32 encoding=(none) Signed-off-by: Yonghong Song <yhs@fb.com> Tested-by: Arnaldo Carvalho de Melo <acme@redhat.com> Acked-by: Martin KaFai Lau <kafai@fb.com> Cc: Alexei Starovoitov <ast@fb.com> Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
This commit is contained in:
parent
70ef8c7f07
commit
b18354f64c
@ -85,6 +85,15 @@ static int32_t enumeration_type__encode(struct btf *btf, struct tag *tag)
|
||||
struct enumerator *pos;
|
||||
int32_t type_id;
|
||||
|
||||
/* if enumerator bit_size is not 32, generate an int type instead. */
|
||||
if (etype->size != 32) {
|
||||
struct base_type bt = {};
|
||||
|
||||
bt.bit_size = etype->size;
|
||||
bt.is_signed = true;
|
||||
return btf__add_base_type(btf, &bt);
|
||||
}
|
||||
|
||||
type_id = btf__add_enum(btf, etype->namespace.name,
|
||||
etype->size, etype->nr_members);
|
||||
if (type_id < 0)
|
||||
|
Loading…
Reference in New Issue
Block a user