Commit 73d0280f authored by Andrii Nakryiko's avatar Andrii Nakryiko Committed by Daniel Borkmann

libbpf: Improve usability of field-based CO-RE helpers

Allow to specify field reference in two ways:

  - if user has variable of necessary type, they can use variable-based
    reference (my_var.my_field or my_var_ptr->my_field). This was the
    only supported syntax up till now.
  - now, bpf_core_field_exists() and bpf_core_field_size() support also
    specifying field in a fashion similar to offsetof() macro, by
    specifying type of the containing struct/union separately and field
    name separately: bpf_core_field_exists(struct my_type, my_field).
    This forms is quite often more convenient in practice and it matches
    type-based CO-RE helpers that support specifying type by its name
    without requiring any variables.
Signed-off-by: default avatarAndrii Nakryiko <andrii@kernel.org>
Signed-off-by: default avatarDaniel Borkmann <daniel@iogearbox.net>
Link: https://lore.kernel.org/bpf/20220509004148.1801791-4-andrii@kernel.org
parent 8e2f618e
...@@ -110,21 +110,38 @@ enum bpf_enum_value_kind { ...@@ -110,21 +110,38 @@ enum bpf_enum_value_kind {
val; \ val; \
}) })
#define ___bpf_field_ref1(field) (field)
#define ___bpf_field_ref2(type, field) (((typeof(type) *)0)->field)
#define ___bpf_field_ref(args...) \
___bpf_apply(___bpf_field_ref, ___bpf_narg(args))(args)
/* /*
* Convenience macro to check that field actually exists in target kernel's. * Convenience macro to check that field actually exists in target kernel's.
* Returns: * Returns:
* 1, if matching field is present in target kernel; * 1, if matching field is present in target kernel;
* 0, if no matching field found. * 0, if no matching field found.
*
* Supports two forms:
* - field reference through variable access:
* bpf_core_field_exists(p->my_field);
* - field reference through type and field names:
* bpf_core_field_exists(struct my_type, my_field).
*/ */
#define bpf_core_field_exists(field) \ #define bpf_core_field_exists(field...) \
__builtin_preserve_field_info(field, BPF_FIELD_EXISTS) __builtin_preserve_field_info(___bpf_field_ref(field), BPF_FIELD_EXISTS)
/* /*
* Convenience macro to get the byte size of a field. Works for integers, * Convenience macro to get the byte size of a field. Works for integers,
* struct/unions, pointers, arrays, and enums. * struct/unions, pointers, arrays, and enums.
*
* Supports two forms:
* - field reference through variable access:
* bpf_core_field_size(p->my_field);
* - field reference through type and field names:
* bpf_core_field_size(struct my_type, my_field).
*/ */
#define bpf_core_field_size(field) \ #define bpf_core_field_size(field...) \
__builtin_preserve_field_info(field, BPF_FIELD_BYTE_SIZE) __builtin_preserve_field_info(___bpf_field_ref(field), BPF_FIELD_BYTE_SIZE)
/* /*
* Convenience macro to get BTF type ID of a specified type, using a local BTF * Convenience macro to get BTF type ID of a specified type, using a local BTF
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment