Previous work for BPF CO-RE (compile once, run everywhere)
tries to record structure, union and array accesses
in order to make addresses relocatable. Bitfield is
not handled as you cannot really take an address of
a bitfield.
Internally, for any bitfield access, llvm will generate
a GEP to the first bitfield for a contiguous run of
bitfields, and then perform proper load and bit
manipulation from that address.
In this patch, a clang intrinsic is introduced:
void * __builtin_preserve_bitfield_info(expr, unsigned *buf)
Given a bitfield access, the builtin will return the
address of the first bitfield for the contiguous run
of bitfields. The "buf" will have
. the signness of the bitfield . the size of bitfield . the offset within the contiguous run of bitfields
These information will be sufficient for bpf program
to retrieve or assign the bitfield values.
The BPF backend will generate an offset relocation
for the leading bitfield and also record all bitfield
accesses happening in this group. So if structure changed
outside the bitfield group, relocation will handle it.
If the structure changes inside the bitfield group,
the bpf loader may reject the program if it deems previous
bitfield extraction might get the wrong result.
For the case of bitfield access without
builtin_preserve_bitfield_info() to get an address,
builtin_preserve_access_index() can be used to enclose
the code. The same offset relocation will be generated.
Please see added tests on how to use the new intrinsic and
what the new offset relocation looks like.
TODO: due to IR intrinsic __builtin_preserve_struct_access_index()
signature change, most existing CORE tests failed. Will fix it later.