> On Fri, Nov 18, 2022 at 10:30:50AM +0000, Per Sundström XP wrote: >> Hi, >> >> I don't know if this is the channel for reporting issues with the >> "bpftool dump .. format c" function. >> If this is not the one, please help me find the correct one. >> >> This bash script illustrates a problem where 'bpftool btf dump <file> >> format c': produces an incorrect 'h' file. >> I looked into it a bit, and the problem seem to be in the >> "libbpf/btfdump.c : btf_dump_emit_bit_padding()" function. >> >> I can dig into it more if you like, but first I want to report it as a >> bug. >> >> Regards, >> /Per >> >> ---- bad_padding bash script --- >> ---------------------------------------------------- >> # >> # Reproduction bash script for wrong offsets >> # >> cat >foo.h <<EOF >> #pragma clang attribute push (__attribute__((preserve_access_index)), >> apply_to = record) >> struct foo { >> struct { >> int aa; >> char ab; >> } a; >> long :64; >> int :4; >> char b; >> short c; >> }; >> #pragma clang attribute pop >> EOF >> >> cat >foo.c <<EOF >> #include "foo.h" >> >> #define offsetof(TYPE, MEMBER) ((long) &((TYPE*)0)->MEMBER) >> >> long foo() >> { >> long ret = 0; >> //ret += ((struct foo*)0)->a.ab; >> ret += ((struct foo*)0)->b; >> ret += ((struct foo*)0)->c; >> return ret; >> } >> EOF >> >> cat >main.c <<EOF >> #include <stdio.h> >> #include "foo.h" >> >> #define offsetof(TYPE, MEMBER) ((long) &((TYPE*)0)->MEMBER) >> >> void main(){ >> printf("offsetof(struct foo, c)=%ld\n", offsetof(struct foo, c)); >> } >> EOF >> >> # Vanilla header case >> printf "============ Vanilla ==========\n" >> cat foo.h | awk '/^struct foo/,/^}/' >> gcc -O0 -g -I. -o main main.c; ./main >> >> # Proudce a custom [minimized] header >> CFLAGS="-I. -ggdb -gdwarf -O2 -Wall -fpie -target bpf >> -D__TARGET_ARCH_x86" >> clang $CFLAGS -DBOOTSTRAP -c foo.c -o foo.o >> pahole --btf_encode_detached full.btf foo.o >> bpftool gen min_core_btf full.btf custom.btf foo.o >> bpftool btf dump file custom.btf format c > foo.h >> >> printf "\n============ Custom ==========\n" >> cat foo.h | awk '/^struct foo/,/^}/' >> gcc -O0 -g -I. -o main main.c; ./main >> >> printf "\n=== BTF offsets ===\n" >> printf "full : " >> /usr/sbin/bpftool btf dump file full.btf | grep "'c'" >> printf "custom : " >> /usr/sbin/bpftool btf dump file custom.btf | grep "'c'" >> >> #---------------------end of script ------------------------------- >> >> >> Output of ./bad_padding.sh: >> --- >> ============ Vanilla ========== >> struct foo { >> struct { >> int aa; >> char ab; >> } a; >> long :64; >> int :4; >> char b; >> short c; >> }; >> offsetof(struct foo, c)=18 >> >> ============ Custom ========== >> struct foo { >> long: 8; >> long: 64; >> long: 64; >> char b; >> short c; >> }; > > so I guess the issue is that the first 'long: 8' is padded to full long: 64 ? > > looks like btf_dump_emit_bit_padding did not take into accout the gap on the > begining of the struct > > on the other hand you generated that header file from 'min_core_btf' btf data, > which takes away all the unused fields.. it might not beeen considered as a > use case before > > jirka > That could be the case, but I think the 'emit_bit_padding()' will not really have a lot to do for the non sparse headers .. /Per > >> offsetof(struct foo, c)=26 >> >> === BTF offsets === >> full : 'c' type_id=6 bits_offset=144 >> custom : 'c' type_id=3 bits_offset=144 >>