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 > offsetof(struct foo, c)=26 > > === BTF offsets === > full : 'c' type_id=6 bits_offset=144 > custom : 'c' type_id=3 bits_offset=144 >