BTF CO-RE bitfield relocation: why is the load size rounded?

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

 



Hi Andrii,

I'm trying to understand the following code from
bpf_core_calc_field_relo in libbpf.c:

    if (bitfield) {
        byte_sz = mt->size;
        byte_off = bit_off / 8 / byte_sz * byte_sz;
        /* figure out smallest int size necessary for bitfield load */
        while (bit_off + bit_sz - byte_off * 8 > byte_sz * 8) {
            if (byte_sz >= 8) {
                ...
                return -E2BIG;
            }
            byte_sz *= 2;
            byte_off = bit_off / 8 / byte_sz * byte_sz;
        }
    }

It's used to calculate the load size (byte_sz) and load offset
(byte_off) for a bitfield member of a struct. Can you explain to me
why byte_off is rounded to byte_sz? Is it to preserve alignment?

It seems like the rounding can lead to reading past the end of a
struct. An example:

    struct foo {
        unsigned short boo:4;
    } __attribute__((packed));

    [2] STRUCT 'foo' size=1 vlen=1
        'boo' type_id=3 bits_offset=0 bitfield_size=4
    [3] INT 'unsigned short' size=2 bits_offset=0 nr_bits=16 encoding=(none)

The result of the calculation for this is byte_sz = 2 and byte_off =
0, but the structure is only 1 byte in length.

Would it be possible to replace the calculation with the following?

    byte_off = bit_off / 8
    byte_sz = ((bit_off + bit_sz + 7) - byte_off*8) / 8

Thanks
Lorenz

-- 
Lorenz Bauer  |  Systems Engineer
6th Floor, County Hall/The Riverside Building, SE1 7PB, UK

www.cloudflare.com



[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