bpftrace,bcc: Migrate recipe from meta-clang to meta-oe

These recipes depend on clang, and clang being on core
it is better place for these tools to be in a common
layer for now that is meta-oe

Signed-off-by: Khem Raj <raj.khem@gmail.com>
This commit is contained in:
Khem Raj
2025-07-15 12:39:58 -07:00
parent 2b9e429a24
commit 1db713b038
10 changed files with 559 additions and 0 deletions
@@ -0,0 +1,41 @@
From 4f64ed40e1ffea7ea278627f30a01018e57dcbcf Mon Sep 17 00:00:00 2001
From: Mingli Yu <mingli.yu@windriver.com>
Date: Wed, 9 Sep 2020 05:48:19 +0000
Subject: [PATCH] CMakeLists.txt: override the PY_CMD_ESCAPED
Override the PY_CMD_ESCAPED as the PY_CMD_ESCAPED is constructed by
the full path of the python3. In some cases, the path is so long and
result in the PY_CMD_ESCAPED exceeds 255 characters and comes below
do_configure error:
| CMake Error at src/python/CMakeLists.txt:18 (configure_file):
| configure_file Problem configuring file
|
| CMake Error: Could not open file for write in copy operation /buildarea1/test/wr_build/wr1020_20200909_bcc/bcc_long_Kernel/auto-standalone_next/200827/lxbuilds/Intel-Snow-Ridge-NS_platform_up/intel-x86-64-standard-glibc-std/wrlinux/build/tmp-glibc/work/corei7-64-wrs-linux/bcc/0.15.0-r0/build/src/python/bcc--buildarea1-test-wr_build-wr1020_20200909_bcc-bcc_long_Kernel-auto-standalone_next-200827-lxbuilds-Intel-Snow-Ridge-NS_platform_up-intel-x86-64-standard-glibc-std-wrlinux-build-tmp-glibc-work-corei7-64-wrs-linux-bcc-0.15.0-r0-recipe-sysroot-native-usr-bin-python3-native-python3/bcc/version.py.tmp
Upstream-Status: Pending
Signed-off-by: Mingli Yu <mingli.yu@windriver.com>
---
src/python/CMakeLists.txt | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
--- a/src/python/CMakeLists.txt
+++ b/src/python/CMakeLists.txt
@@ -16,7 +16,7 @@ file(GLOB_RECURSE PYTHON_INCLUDES RELATI
foreach(PY_CMD ${PYTHON_CMD})
string(REPLACE "/" "-" PY_CMD_ESCAPED ${PY_CMD})
- set(PY_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/bcc-${PY_CMD_ESCAPED})
+ set(PY_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/bcc-python3)
foreach(PY_SRC ${PYTHON_SOURCES})
configure_file(${PY_SRC} ${PY_DIRECTORY}/${PY_SRC} COPYONLY)
@@ -35,7 +35,7 @@ foreach(PY_CMD ${PYTHON_CMD})
DEPENDS ${PYTHON_SOURCES} ${PYTHON_INCLUDES}
COMMENT "Building sdist for ${PY_CMD}"
)
- add_custom_target(bcc_py_${PY_CMD_ESCAPED} ALL DEPENDS ${PIP_INSTALLABLE})
+ add_custom_target(bcc_py_python3 ALL DEPENDS ${PIP_INSTALLABLE})
if(NOT PYTHON_PREFIX)
set(PYTHON_PREFIX ${CMAKE_INSTALL_PREFIX})
@@ -0,0 +1,124 @@
From 6cffc195eca6b53a12865d325ff97e7b5ba8f22b Mon Sep 17 00:00:00 2001
From: Daniel Thompson <daniel.thompson@linaro.org>
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 <daniel.thompson@linaro.org>
---
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;
@@ -0,0 +1,16 @@
Upstream-Status: Submitted [https://github.com/iovisor/bcc/pull/5355]
Signed-off-by: Harish Sadineni <Harish.Sadineni@windriver.com>
diff --git a/tests/python/test_tools_memleak.py b/tests/python/test_tools_memleak.py
--- a/tests/python/test_tools_memleak.py
+++ b/tests/python/test_tools_memleak.py
@@ -26,7 +26,7 @@
# Build the memory leaking application.
c_src = 'test_tools_memleak_leaker_app.c'
tmp_dir = tempfile.mkdtemp(prefix='bcc-test-memleak-')
- c_src_full = os.path.dirname(sys.argv[0]) + os.path.sep + c_src
+ c_src_full = os.path.abspath(os.path.dirname(sys.argv[0])) + os.path.sep + c_src
exec_dst = tmp_dir + os.path.sep + 'leaker_app'
if subprocess.call(['gcc', '-g', '-O0', '-o', exec_dst, c_src_full]) != 0:
@@ -0,0 +1,16 @@
#!/bin/sh
# Simple OE specific wrapper for bcc python tests
name=$1
kind=$2
cmd=$3
shift 3
case $kind in
simple|sudo)
$cmd "$@"
;;
*)
echo "Invalid kind $kind of test $name"
exit 1
esac
@@ -0,0 +1,65 @@
#!/bin/sh
cd tests || exit 1
PASS_CNT=0
FAIL_CNT=0
FAILED=""
print_test_result() {
if [ $? -eq 0 ]; then
echo PASS: "$1"
PASS_CNT=$((PASS_CNT + 1))
else
echo FAIL: "$1"
FAIL_CNT=$((FAIL_CNT + 1))
FAILED="$FAILED $1;"
fi
}
ARCH=$(uname -m)
case "$ARCH" in
x86_64)
KDIR="x86"
;;
riscv64)
KDIR="riscv"
;;
aarch64)
KDIR="arm64"
;;
powerpc64le | ppc64le)
KDIR="powerpc"
;;
*)
echo "Architecture not present, Add the architecture in run-ptest: $ARCH"
exit 1
;;
esac
export BCC_KERNEL_SOURCE="/usr/src/kernel/arch/$KDIR"
# Run CC tests, set IFS as test names have spaces
IFS=$(printf '\n\t')
for test_name in $(./cc/test_libbcc_no_libbpf --list-test-names-only); do
./cc/test_libbcc_no_libbpf "$test_name" > /dev/null 2>&1
print_test_result "cc $test_name"
done
unset IFS
# Run python tests, skip namespace tests as they currently don't work
if cmake -DCMAKE_TESTING_ENABLED=ON -DTEST_WRAPPER="$(pwd)/ptest_wrapper.sh" python > /dev/null 2>&1; then
for test_name in $(awk -F '[( ]' '/^add_test/ && !/namespace/ {print $2}' CTestTestfile.cmake); do
ctest -Q -R "$test_name"
print_test_result "python $test_name"
done
else
print_test_result "cmake error, couldn't start python tests"
fi
echo "#### bcc tests summary ####"
echo "# TOTAL: $((PASS_CNT + FAIL_CNT))"
echo "# PASS: $PASS_CNT"
echo "# FAIL: $FAIL_CNT ($FAILED)"
echo "###########################"
@@ -0,0 +1,92 @@
SUMMARY = "BPF Compiler Collection (BCC)"
HOMEPAGE = "https://github.com/iovisor/bcc"
LICENSE = "Apache-2.0"
LIC_FILES_CHKSUM = "file://LICENSE.txt;md5=e3fc50a88d0a364313df4b21ef20c29e"
inherit cmake python3native manpages ptest
DEPENDS += "bison-native \
flex-native \
zip-native \
flex \
elfutils \
clang \
libbpf \
python3-setuptools-native \
"
RDEPENDS:${PN} += "bash python3 python3-core python3-setuptools xz"
RDEPENDS:${PN}-ptest = "kernel-devsrc packagegroup-core-buildessential cmake bash python3 python3-netaddr python3-pyroute2"
SRC_URI = "gitsm://github.com/iovisor/bcc;branch=master;protocol=https;tag=v${PV} \
file://0001-CMakeLists.txt-override-the-PY_CMD_ESCAPED.patch \
file://0001-Vendor-just-enough-extra-headers-to-allow-libbpf-to-.patch \
file://run-ptest \
file://ptest_wrapper.sh \
file://fix_for_memleak.patch \
"
SRCREV = "c31a1ca305f787ba53e001ead45ebf65233a32cf"
PACKAGECONFIG ??= "examples"
PACKAGECONFIG:remove:libc-musl = "examples"
PACKAGECONFIG[manpages] = "-DENABLE_MAN=ON,-DENABLE_MAN=OFF,"
PACKAGECONFIG[examples] = "-DENABLE_EXAMPLES=ON,-DENABLE_EXAMPLES=OFF,"
EXTRA_OECMAKE = " \
-DREVISION='${PV}' \
-DCMAKE_USE_LIBBPF_PACKAGE=ON \
-DENABLE_LLVM_SHARED=ON \
-DENABLE_CLANG_JIT=ON \
-DPY_SKIP_DEB_LAYOUT=ON \
-DPYTHON_CMD=${PYTHON} \
-DPYTHON_FLAGS=--install-lib=${PYTHON_SITEPACKAGES_DIR} \
"
# Avoid stripping debuginfo.so to fix some tests.
INHIBIT_PACKAGE_STRIP = "1"
INHIBIT_PACKAGE_DEBUG_SPLIT = "1"
do_install:append() {
sed -e 's@#!/usr/bin/env python@#!/usr/bin/env python3@g' \
-i $(find ${D}${datadir}/${PN} -type f)
sed -e 's@#!/usr/bin/python.*@#!/usr/bin/env python3@g' \
-i $(find ${D}${datadir}/${PN} -type f)
rm -rf ${D}${datadir}/bcc/examples/lua
}
do_install_ptest() {
install -d ${D}${PTEST_PATH}/tests/cc
# ptest searches for shared libs and archive files in the build folder.
# Hence, these files are copied to the image to fix these tests.
install -d ${D}${B}/tests/cc
install ${B}/tests/cc/archive.zip ${B}/tests/cc/libdebuginfo_test_lib.so ${B}/tests/cc/with_gnu_debuglink.so ${B}/tests/cc/with_gnu_debugdata.so ${B}/tests/cc/debuginfo.so ${D}${B}/tests/cc
install -d ${D}/opt
install ${B}/tests/cc/test_libbcc_no_libbpf ${B}/tests/cc/libusdt_test_lib.so ${D}${PTEST_PATH}/tests/cc
cp -rf ${S}/tests/python ${D}${PTEST_PATH}/tests/python
install ${UNPACKDIR}/ptest_wrapper.sh ${D}${PTEST_PATH}/tests
install ${S}/examples/networking/simulation.py ${D}${PTEST_PATH}/tests/python
find ${S}/tools/ -type f -name "*.py" -exec \
sed -i \
-e 's@^#! */usr/bin/env python$@#!/usr/bin/env python3@' \
-e 's@^#! */usr/bin/python.*@#!/usr/bin/env python3@' {} +
cp -rf ${S}/tools/ ${D}${PTEST_PATH}/../../tools/
}
FILES:${PN} += "${PYTHON_SITEPACKAGES_DIR}"
FILES:${PN} += "${B}/tests/cc"
FILES:${PN}-ptest += "${libdir}/libbcc.so"
FILES:${PN}-ptest += "${libdir}/tools/"
FILES:${PN}-ptest += "/opt/"
FILES:${PN}-doc += "${datadir}/${PN}/man"
COMPATIBLE_HOST = "(x86_64.*|aarch64.*|powerpc64.*|riscv64.*)-linux"
# WARNING: bcc-0.30.0+git-r0 do_package_qa: QA Issue: File /usr/lib/bcc/ptest/tests/cc/test_libbcc_no_libbpf in package bcc-ptest contains reference to TMPDIR [buildpaths]
# this one is difficult to resolve, because the tests use CMAKE_CURRENT_BINARY_DIR directly in .cc e.g.:
# https://github.com/iovisor/bcc/commit/7271bfc946a19413761be2e3c60c48bf72c5eea1#diff-233a0bfa490f3d7466c49935b64c86dd93956bbc0461f5af703b344cf6601461
# we would probably need to use separate variable for "runtime" path for test assets from the standard CMAKE_CURRENT_BINARY_DIR variable or use relative
# path from the test binary
WARN_QA:append = "${@bb.utils.contains('PTEST_ENABLED', '1', ' buildpaths', '', d)}"
ERROR_QA:remove = "${@bb.utils.contains('PTEST_ENABLED', '1', 'buildpaths', '', d)}"