From 229e28a6a061cb78d9f31c253ee8e741a093ab8d Mon Sep 17 00:00:00 2001 From: Daniel Thompson Date: Thu, 19 May 2022 09:23:45 +0000 Subject: bcc: Fixes to allow libbpf to be de-vendored De-vendoring libbpf resolves a SEGV everytime we run bpftrace. Unfortunately it is not currently possible to de-vendor libbpf because bcc does not build. Fix this with brute force and ignorance... and in a seperate patch so this can be treated as an explanation of the problem and ripped out in favour of the right fix. Signed-off-by: Daniel Thompson --- ...-enough-extra-headers-to-allow-libbpf-to-.patch | 124 +++++++++++++++++++++ .../recipes-devtools/bcc/bcc_0.24.0.bb | 1 + 2 files changed, 125 insertions(+) create mode 100644 dynamic-layers/openembedded-layer/recipes-devtools/bcc/bcc/0001-Vendor-just-enough-extra-headers-to-allow-libbpf-to-.patch (limited to 'dynamic-layers') diff --git a/dynamic-layers/openembedded-layer/recipes-devtools/bcc/bcc/0001-Vendor-just-enough-extra-headers-to-allow-libbpf-to-.patch b/dynamic-layers/openembedded-layer/recipes-devtools/bcc/bcc/0001-Vendor-just-enough-extra-headers-to-allow-libbpf-to-.patch new file mode 100644 index 0000000..946787c --- /dev/null +++ b/dynamic-layers/openembedded-layer/recipes-devtools/bcc/bcc/0001-Vendor-just-enough-extra-headers-to-allow-libbpf-to-.patch @@ -0,0 +1,124 @@ +From 6cffc195eca6b53a12865d325ff97e7b5ba8f22b Mon Sep 17 00:00:00 2001 +From: Daniel Thompson +Date: Thu, 19 May 2022 09:14:20 +0000 +Subject: [PATCH] Vendor just enough extra headers to allow libbpf to be + de-vendored + +Currently it is not possible to build the bcc recipe when we de-vendor +libbpf and adopt the packaged version. Ironically this is due to the +deliberate vendoring of some depreciated btf code that is being removed +upstream because bcc was the only user! In other words the vendored code +doesn't work the de-vendored libbpf because also ends up de-vendoring +one of the Linux uapi headers. + +This is obviously an OE specific issue (due to the current combination +of linux headers, libbpf and bcc). It's a bit of a mess and the right +solution is probably to update the system UAPI headers but I am committing +this for now simply so I can easily show why we must de-vendor libbpf in +the first place! + +Upstream-status: Inappropriate [other] + +Signed-off-by: Daniel Thompson +--- + src/cc/bcc_btf.cc | 87 +++++++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 87 insertions(+) + +diff --git a/src/cc/bcc_btf.cc b/src/cc/bcc_btf.cc +index 7f551ae8..cca3c6c3 100644 +--- a/src/cc/bcc_btf.cc ++++ b/src/cc/bcc_btf.cc +@@ -33,6 +33,93 @@ + + namespace btf_ext_vendored { + ++#ifdef HAVE_EXTERNAL_LIBBPF ++/* ++ * When we de-vendor libbpf we end up picking up an older version of ++ * [uapi/]linux/bpf.h which misses out some of the data structures needed ++ * to compile this file. Annoyingly the code that doesn't compile it ++ * a result of de-vendoring ++ * ++ * This section is a minimized re-vendoring to fix that. It is not robust ++ * against version skew: When the system linux/bpf.h is updated then this ++ * will break the build and the patch can be dropped. ++ */ ++ ++/* bpf_core_relo_kind encodes which aspect of captured field/type/enum value ++ * has to be adjusted by relocations. It is emitted by llvm and passed to ++ * libbpf and later to the kernel. ++ */ ++enum bpf_core_relo_kind { ++ BPF_CORE_FIELD_BYTE_OFFSET = 0, /* field byte offset */ ++ BPF_CORE_FIELD_BYTE_SIZE = 1, /* field size in bytes */ ++ BPF_CORE_FIELD_EXISTS = 2, /* field existence in target kernel */ ++ BPF_CORE_FIELD_SIGNED = 3, /* field signedness (0 - unsigned, 1 - signed) */ ++ BPF_CORE_FIELD_LSHIFT_U64 = 4, /* bitfield-specific left bitshift */ ++ BPF_CORE_FIELD_RSHIFT_U64 = 5, /* bitfield-specific right bitshift */ ++ BPF_CORE_TYPE_ID_LOCAL = 6, /* type ID in local BPF object */ ++ BPF_CORE_TYPE_ID_TARGET = 7, /* type ID in target kernel */ ++ BPF_CORE_TYPE_EXISTS = 8, /* type existence in target kernel */ ++ BPF_CORE_TYPE_SIZE = 9, /* type size in bytes */ ++ BPF_CORE_ENUMVAL_EXISTS = 10, /* enum value existence in target kernel */ ++ BPF_CORE_ENUMVAL_VALUE = 11, /* enum value integer value */ ++}; ++ ++/* ++ * "struct bpf_core_relo" is used to pass relocation data form LLVM to libbpf ++ * and from libbpf to the kernel. ++ * ++ * CO-RE relocation captures the following data: ++ * - insn_off - instruction offset (in bytes) within a BPF program that needs ++ * its insn->imm field to be relocated with actual field info; ++ * - type_id - BTF type ID of the "root" (containing) entity of a relocatable ++ * type or field; ++ * - access_str_off - offset into corresponding .BTF string section. String ++ * interpretation depends on specific relocation kind: ++ * - for field-based relocations, string encodes an accessed field using ++ * a sequence of field and array indices, separated by colon (:). It's ++ * conceptually very close to LLVM's getelementptr ([0]) instruction's ++ * arguments for identifying offset to a field. ++ * - for type-based relocations, strings is expected to be just "0"; ++ * - for enum value-based relocations, string contains an index of enum ++ * value within its enum type; ++ * - kind - one of enum bpf_core_relo_kind; ++ * ++ * Example: ++ * struct sample { ++ * int a; ++ * struct { ++ * int b[10]; ++ * }; ++ * }; ++ * ++ * struct sample *s = ...; ++ * int *x = &s->a; // encoded as "0:0" (a is field #0) ++ * int *y = &s->b[5]; // encoded as "0:1:0:5" (anon struct is field #1, ++ * // b is field #0 inside anon struct, accessing elem #5) ++ * int *z = &s[10]->b; // encoded as "10:1" (ptr is used as an array) ++ * ++ * type_id for all relocs in this example will capture BTF type id of ++ * `struct sample`. ++ * ++ * Such relocation is emitted when using __builtin_preserve_access_index() ++ * Clang built-in, passing expression that captures field address, e.g.: ++ * ++ * bpf_probe_read(&dst, sizeof(dst), ++ * __builtin_preserve_access_index(&src->a.b.c)); ++ * ++ * In this case Clang will emit field relocation recording necessary data to ++ * be able to find offset of embedded `a.b.c` field within `src` struct. ++ * ++ * [0] https://llvm.org/docs/LangRef.html#getelementptr-instruction ++ */ ++struct bpf_core_relo { ++ __u32 insn_off; ++ __u32 type_id; ++ __u32 access_str_off; ++ enum bpf_core_relo_kind kind; ++}; ++#endif /* HAVE_EXTERNAL_LIBBPF */ ++ + /* The minimum bpf_func_info checked by the loader */ + struct bpf_func_info_min { + uint32_t insn_off; diff --git a/dynamic-layers/openembedded-layer/recipes-devtools/bcc/bcc_0.24.0.bb b/dynamic-layers/openembedded-layer/recipes-devtools/bcc/bcc_0.24.0.bb index 9ad2d01..b5e3fe3 100644 --- a/dynamic-layers/openembedded-layer/recipes-devtools/bcc/bcc_0.24.0.bb +++ b/dynamic-layers/openembedded-layer/recipes-devtools/bcc/bcc_0.24.0.bb @@ -24,6 +24,7 @@ SRC_URI = "gitsm://github.com/iovisor/bcc;branch=master;protocol=https \ file://0001-python-CMakeLists.txt-Remove-check-for-host-etc-debi.patch \ file://0001-tools-trace.py-Fix-failing-to-exit.patch \ file://0001-CMakeLists.txt-override-the-PY_CMD_ESCAPED.patch \ + file://0001-Vendor-just-enough-extra-headers-to-allow-libbpf-to-.patch \ " SRCREV = "8f40d6f57a8d94e7aee74ce358572d34d31b4ed4" -- cgit v1.2.3-54-g00ecf