Re: Bad padding with bpftool btf dump .. format c

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

 



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
> 



[Index of Archives]     [Linux Samsung SoC]     [Linux Rockchip SoC]     [Linux Actions SoC]     [Linux for Synopsys ARC Processors]     [Linux NFS]     [Linux NILFS]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]


  Powered by Linux