Re: [PATCH pahole 2/5] btf_loader: adjust negative bitfield offsets early on

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

 



Em Wed, Mar 13, 2019 at 11:07:36PM -0700, Andrii Nakryiko escreveu:
> Bitfield offsets can be negative, if field "borrows" few bits from
> following aligned field. This causes a bunch of surprises down the line
> in pahole's logic (e.g., for hole calculation logic), so instead of
> waiting till printf routines adjust this for display, adjust them early
> and keep less surprising semantics.

> +++ b/btf_loader.c
> @@ -482,6 +482,12 @@ static int class__fixup_btf_bitfields(struct tag *tag, struct cu *cu, struct btf
>  			pos->bitfield_offset = pos->bit_offset - pos->byte_offset * 8;
>  			if (!btfe->is_big_endian)
>  				pos->bitfield_offset = pos->bit_size - pos->bitfield_offset - pos->bitfield_size;
> +			/* re-adjust bitfield offset if it is negative */
> +			if (pos->bitfield_offset < 0) {
> +				pos->bitfield_offset += pos->bit_size;
> +				pos->byte_offset += pos->byte_size;
> +				pos->bit_offset = pos->byte_offset * 8 + pos->bitfield_offset;
> +			}
>  		} else {
>  			pos->byte_offset = pos->bit_offset / 8;
>  		}

While testing this one I noticed this output:

[acme@quaco pahole]$ pahole -F btf -C ieee80211_tx_rate examples/vmlinux-aarch64
struct ieee80211_tx_rate {
	s8                         idx;                  /*     0     1 */

	/* Bitfield combined with previous fields */

	u16                        count:5;              /*     0: 8  2 */
	u16                        flags:11;             /*     0:13  2 */

	/* size: 3, cachelines: 1, members: 3 */
	/* padding: 1 */
	/* last cacheline: 3 bytes */
};
[acme@quaco pahole]$

The message is confusing, as count:5 is not being combined with previous
fields, i.e. the previous field has 8 bits and all those bits are being
used by 'idx'.

The original struct definition in include/net/mac80211.h:

struct ieee80211_tx_rate {
        s8 idx;
        u16 count:5,
            flags:11;
} __packed;

So we could infer that this is a packed struct, because the next field
doesn't come u16 aligned, not that it is a bitfield combined with
previous fields.

The DWARF info:
 <1><27639>: Abbrev Number: 16 (DW_TAG_structure_type)
    <2763a>   DW_AT_name        : (indirect string, offset: 0x19d5a): ieee80211_tx_rate
    <2763e>   DW_AT_byte_size   : 3
    <27643>   DW_AT_sibling     : <0x27678>
 <2><27647>: Abbrev Number: 19 (DW_TAG_member)
    <27648>   DW_AT_name        : idx
    <27650>   DW_AT_type        : <0x11d>
    <27654>   DW_AT_data_member_location: 0
 <2><27655>: Abbrev Number: 30 (DW_TAG_member)
    <27656>   DW_AT_name        : (indirect string, offset: 0x1789d): count
    <2765e>   DW_AT_type        : <0x144>
    <27662>   DW_AT_byte_size   : 2
    <27663>   DW_AT_bit_size    : 5
    <27664>   DW_AT_bit_offset  : 8
    <27665>   DW_AT_data_member_location: 0
 <2><27666>: Abbrev Number: 30 (DW_TAG_member)
    <27667>   DW_AT_name        : (indirect string, offset: 0xc978): flags
    <2766f>   DW_AT_type        : <0x144>
    <27673>   DW_AT_byte_size   : 2
    <27674>   DW_AT_bit_size    : 11
    <27675>   DW_AT_bit_offset  : 5
    <27676>   DW_AT_data_member_location: 1


So the message has to take into account if the previous field has a
bitfield_size != 0, no?

I have to look at the other csets, perhaps you do this there?

I'm just trying to test it patch by patch to see what changes after each
one.

- Arnaldo



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

  Powered by Linux