Skip to content

Commit

Permalink
Merge branch 'libbpf-field-existence'
Browse files Browse the repository at this point in the history
Andrii Nakryiko says:

====================
This patch set generalizes libbpf's CO-RE relocation support. In addition to
existing field's byte offset relocation, libbpf now supports field existence
relocations, which are emitted by Clang when using
__builtin_preserve_field_info(<field>, BPF_FIELD_EXISTS). A convenience
bpf_core_field_exists() macro is added to bpf_core_read.h BPF-side header,
along the bpf_field_info_kind enum containing currently supported types of
field information libbpf supports. This list will grow as libbpf gains support
for other relo kinds.

This patch set upgrades the format of .BTF.ext's relocation record to match
latest Clang's format (12 -> 16 bytes). This is not a breaking change, as the
previous format hasn't been released yet as part of official Clang version
release.

v1->v2:
- unify bpf_field_info_kind enum and naming changes (Alexei);
- added bpf_core_field_exists() to bpf_core_read.h.
====================

Signed-off-by: Alexei Starovoitov <ast@kernel.org>
  • Loading branch information
Alexei Starovoitov committed Oct 15, 2019
2 parents 14f2cf6 + c7566a6 commit da92746
Show file tree
Hide file tree
Showing 17 changed files with 392 additions and 85 deletions.
24 changes: 23 additions & 1 deletion tools/lib/bpf/bpf_core_read.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,28 @@
#ifndef __BPF_CORE_READ_H__
#define __BPF_CORE_READ_H__

/*
* enum bpf_field_info_kind is passed as a second argument into
* __builtin_preserve_field_info() built-in to get a specific aspect of
* a field, captured as a first argument. __builtin_preserve_field_info(field,
* info_kind) returns __u32 integer and produces BTF field relocation, which
* is understood and processed by libbpf during BPF object loading. See
* selftests/bpf for examples.
*/
enum bpf_field_info_kind {
BPF_FIELD_BYTE_OFFSET = 0, /* field byte offset */
BPF_FIELD_EXISTS = 2, /* field existence in target kernel */
};

/*
* Convenience macro to check that field actually exists in target kernel's.
* Returns:
* 1, if matching field is present in target kernel;
* 0, if no matching field found.
*/
#define bpf_core_field_exists(field) \
__builtin_preserve_field_info(field, BPF_FIELD_EXISTS)

/*
* bpf_core_read() abstracts away bpf_probe_read() call and captures offset
* relocation for source address using __builtin_preserve_access_index()
Expand All @@ -12,7 +34,7 @@
* a relocation, which records BTF type ID describing root struct/union and an
* accessor string which describes exact embedded field that was used to take
* an address. See detailed description of this relocation format and
* semantics in comments to struct bpf_offset_reloc in libbpf_internal.h.
* semantics in comments to struct bpf_field_reloc in libbpf_internal.h.
*
* This relocation allows libbpf to adjust BPF instruction to use correct
* actual field offset, based on target kernel BTF type that matches original
Expand Down
16 changes: 8 additions & 8 deletions tools/lib/bpf/btf.c
Original file line number Diff line number Diff line change
Expand Up @@ -888,14 +888,14 @@ static int btf_ext_setup_line_info(struct btf_ext *btf_ext)
return btf_ext_setup_info(btf_ext, &param);
}

static int btf_ext_setup_offset_reloc(struct btf_ext *btf_ext)
static int btf_ext_setup_field_reloc(struct btf_ext *btf_ext)
{
struct btf_ext_sec_setup_param param = {
.off = btf_ext->hdr->offset_reloc_off,
.len = btf_ext->hdr->offset_reloc_len,
.min_rec_size = sizeof(struct bpf_offset_reloc),
.ext_info = &btf_ext->offset_reloc_info,
.desc = "offset_reloc",
.off = btf_ext->hdr->field_reloc_off,
.len = btf_ext->hdr->field_reloc_len,
.min_rec_size = sizeof(struct bpf_field_reloc),
.ext_info = &btf_ext->field_reloc_info,
.desc = "field_reloc",
};

return btf_ext_setup_info(btf_ext, &param);
Expand Down Expand Up @@ -975,9 +975,9 @@ struct btf_ext *btf_ext__new(__u8 *data, __u32 size)
goto done;

if (btf_ext->hdr->hdr_len <
offsetofend(struct btf_ext_header, offset_reloc_len))
offsetofend(struct btf_ext_header, field_reloc_len))
goto done;
err = btf_ext_setup_offset_reloc(btf_ext);
err = btf_ext_setup_field_reloc(btf_ext);
if (err)
goto done;

Expand Down
4 changes: 2 additions & 2 deletions tools/lib/bpf/btf.h
Original file line number Diff line number Diff line change
Expand Up @@ -60,8 +60,8 @@ struct btf_ext_header {
__u32 line_info_len;

/* optional part of .BTF.ext header */
__u32 offset_reloc_off;
__u32 offset_reloc_len;
__u32 field_reloc_off;
__u32 field_reloc_len;
};

LIBBPF_API void btf__free(struct btf *btf);
Expand Down
Loading

0 comments on commit da92746

Please sign in to comment.