Re: btfdiff: struct desc_ptr

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

 



Em Thu, Jan 17, 2019 at 01:01:58PM -0300, Arnaldo Carvalho de Melo escreveu:
> Investigating this one now:
> 
>  struct desc_ptr {
>         short unsigned int         size;                 /*     0     2 */
> -       long unsigned int          address;              /*     2     8 */
> +       long unsigned int          address;              /*     0     8 */
> 
>         /* size: 10, cachelines: 1, members: 2 */
> +       /* padding: 2 */
>         /* last cacheline: 10 bytes */
> +
> +       /* BRAIN FART ALERT! 10 != 2 + 0(holes), diff = 8 */
>  };
> 
> 
> The original struct is this, at arch/x86/include/asm/desc_defs.h:
> 
> struct desc_ptr {
>         unsigned short size;
>         unsigned long address;
> } __attribute__((packed)) ;
> 
> So both DWARF and BTF have the size right, 10 bytes, but BTF gets the
> 'address' member offset wrong, from readelf:
> 
>  <1><28ed>: Abbrev Number: 17 (DW_TAG_structure_type)
>     <28ee>   DW_AT_name        : (indirect string, offset: 0x112bf): desc_ptr
>     <28f2>   DW_AT_byte_size   : 10
>     <28f3>   DW_AT_decl_file   : 101
>     <28f4>   DW_AT_decl_line   : 105
>     <28f5>   DW_AT_decl_column : 8
>     <28f6>   DW_AT_sibling     : <0x2915>
>  <2><28fa>: Abbrev Number: 1 (DW_TAG_member)
>     <28fb>   DW_AT_name        : (indirect string, offset: 0x8b12): size
>     <28ff>   DW_AT_decl_file   : 101
>     <2900>   DW_AT_decl_line   : 106
>     <2901>   DW_AT_decl_column : 17
>     <2902>   DW_AT_type        : <0xd0>
>     <2906>   DW_AT_data_member_location: 0
>  <2><2907>: Abbrev Number: 1 (DW_TAG_member)
>     <2908>   DW_AT_name        : (indirect string, offset: 0xfa9): address
>     <290c>   DW_AT_decl_file   : 101
>     <290d>   DW_AT_decl_line   : 107
>     <290e>   DW_AT_decl_column : 16
>     <290f>   DW_AT_type        : <0x2a>
>     <2913>   DW_AT_data_member_location: 2
> 
> If I isolate this in a file and then do the BTF encoding:
> 
> [acme@quaco pahole]$ cat examples/desc_ptr.c
> struct desc_ptr {
>         unsigned short size;
>         unsigned long address;
> } __attribute__((packed)) ;
> 
> struct desc_ptr foo;
> [acme@quaco pahole]$ gcc -c -g examples/desc_ptr.c -o examples/desc_ptr.o
> [acme@quaco pahole]$ pahole -JV examples/desc_ptr.o
> File examples/desc_ptr.o:
> [1] STRUCT desc_ptr kind_flag=0 size=10 vlen=2
> 	size type_id=2 bits_offset=0
> 	address type_id=3 bits_offset=16
> [2] INT short unsigned int size=2 bit_offset=0 nr_bits=16 encoding=(none)
> [3] INT long unsigned int size=8 bit_offset=0 nr_bits=64 encoding=(none)
> [4] INT (anon) size=4 bit_offset=0 nr_bits=32 encoding=(none)
> [acme@quaco pahole]$ 
> 
> Now going thru the code to see why [3] get that bit_offset=0, should be
> 16, no?

That was just a distraction, the BTF encoding is done right, the problem
is when loading the BTF section, in class__fixup_btf_bitfields(), first
we set it right:

                  pos->byte_offset = pos->bit_offset / 8;

But then, later, this is recalculated as:

                  pos->byte_offset = (((pos->bit_offset / integral_bit_size) * integral_bit_size) / 8);

Now trying to recall why this last recalc...

- Arnaldo



[Index of Archives]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux