BPF Built-in Functions#
The following built-in functions are available for eBPF targets.
-
unsigned long long __builtin_bpf_load_byte(unsigned long long offset)#
Load a byte from the
struct sk_buff
packet data pointed by the register%r6
and return it.
-
unsigned long long __builtin_bpf_load_half(unsigned long long offset)#
Load 16-bits from the
struct sk_buff
packet data pointed by the register%r6
and return it.
-
unsigned long long __builtin_bpf_load_word(unsigned long long offset)#
Load 32-bits from the
struct sk_buff
packet data pointed by the register%r6
and return it.
-
void *__builtin_preserve_access_index(expr)#
BPF Compile Once-Run Everywhere (CO-RE) support. Instruct GCC to generate CO-RE relocation records for any accesses to aggregate data structures (struct, union, array types) in
expr
. This builtin is otherwise transparent, the return value is whateverexpr
evaluates to. It is also overloaded:expr
may be of any type (not necessarily a pointer), the return type is the same. Has no effect if-mco-re
is not in effect (either specified or implied).
-
unsigned int __builtin_preserve_field_info(expr, unsigned int kind)#
BPF Compile Once-Run Everywhere (CO-RE) support. This builtin is used to extract information to aid in struct/union relocations.
expr
is an access to a field of a struct or union. Depending onkind
, different information is returned to the program. A CO-RE relocation for the access inexpr
with kindkind
is recorded if-mco-re
is in effect.The following values are supported for
kind
:FIELD_BYTE_OFFSET = 0
The returned value is the offset, in bytes, of the field from the beginning of the containing structure. For bitfields, the byte offset of the containing word.
FIELD_BYTE_SIZE = 1
The returned value is the size, in bytes, of the field. For bitfields, the size in bytes of the containing word.
FIELD_EXISTENCE = 2
The returned value is 1 if the field exists, 0 otherwise. Always 1 at compile time.
FIELD_SIGNEDNESS = 3
The returned value is 1 if the field is signed, 0 otherwise.
FIELD_LSHIFT_U64 = 4
FIELD_RSHIFT_U64 = 5
The returned value is the number of bits of left- or right-shifting respectively needed in order to recover the original value of the field, after it has been loaded by a read of FIELD_BYTE_SIZE bytes into an unsigned 64-bit value. Primarily useful for reading bitfield values from structures which may change between kernel versions.
Note that the return value is a constant which is known at compile-time. If the field has a variable offset then FIELD_BYTE_OFFSET, FIELD_LSHIFT_U64 and FIELD_RSHIFT_U64 are not supported. Similarly, if the field has a variable size then FIELD_BYTE_SIZE, FIELD_LSHIFT_U64 and FIELD_RSHIFT_U64 are not supported.
For example, __builtin_preserve_field_info can be used to reliably extract bitfield values from a structure which may change between kernel versions:
struct S { short a; int x:7; int y:5; }; int read_y (struct S *arg) { unsigned long long val; unsigned int offset = __builtin_preserve_field_info (arg->y, FIELD_BYTE_OFFSET); unsigned int size = __builtin_presrve_field_info (arg->y, FIELD_BYTE_SIZE); /* Read size bytes from arg + offset into val. */ bpf_probe_read (&val, size, arg + offset); val <<= __builtin_preserve_field_info (arg->y, FIELD_LSHIFT_U64); if (__builtin_preserve_field_info (arg->y, FIELD_SIGNEDNESS)) val = ((long long) val >> __builtin_preserve_field_info (arg->y, FIELD_RSHIFT_U64)); else val >>= __builtin_preserve_field_info (arg->y, FIELD_RSHIFT_U64); return val; }