diff --git a/pkg/bpftrace/Dockerfile b/pkg/bpftrace/Dockerfile new file mode 100644 index 0000000000..c4cf28bf74 --- /dev/null +++ b/pkg/bpftrace/Dockerfile @@ -0,0 +1,33 @@ +# syntax=docker/dockerfile-upstream:1.5.0-rc2-labs + +# Copyright (c) 2024 Zededa, Inc. +# SPDX-License-Identifier: Apache-2.0 +FROM lfedge/eve-alpine:1f7685f95a475c6bbe682f0b976f12180b6c8726 AS build + +ENV BUILD_PKGS make gcc g++ git perl linux-headers musl-dev cmake zlib-dev bcc-dev libbpf-dev cereal flex bison llvm13-libs llvm13-dev llvm13-static clang-dev clang-static pahole gtest-dev bash + +RUN eve-alpine-deploy.sh + +RUN mkdir -p /usr/src +ADD https://github.com/bpftrace/bpftrace.git#v0.20.3 /usr/src/bpftrace +COPY patches /usr/src/bpftrace/patches +WORKDIR /usr/src/bpftrace +RUN for i in patches/*.patch; do git apply "$i"; done +RUN mkdir build +WORKDIR /usr/src/bpftrace/build +RUN cmake .. +RUN make -j "$(getconf _NPROCESSORS_ONLN)" +RUN make DESTDIR="/out/opt/zededa" install +# portability analyser is disabled, therefore skip those tests +# skip file exist test - probably broken because of container +RUN ./tests/bpftrace_test --gtest_filter=-"portability_analyser.*:utils.file_exists_and_ownedby_root" 2>/dev/null + + +FROM scratch +COPY --from=build /out/opt/zededa/usr/local/bin/bpftrace-aotrt /usr/bin/bpftrace-aotrt +COPY --from=build /usr/lib/libbpf.so.0 /usr/lib/libbpf.so.0 +COPY --from=build /usr/lib/libelf.so.1 /usr/lib/libelf.so.1 +COPY --from=build /lib/libz.so.1 /lib/libz.so.1 +COPY --from=build /usr/lib/libbcc_bpf.so.0 /usr/lib/libbcc_bpf.so.0 +COPY --from=build /usr/lib/libstdc++.so.6 /usr/lib/libstdc++.so.6 +COPY --from=build /usr/lib/libgcc_s.so.1 /usr/lib/libgcc_s.so.1 diff --git a/pkg/bpftrace/build.yml b/pkg/bpftrace/build.yml new file mode 100644 index 0000000000..e1eb21428a --- /dev/null +++ b/pkg/bpftrace/build.yml @@ -0,0 +1,6 @@ +# linuxkit build template +# +# SPDX-License-Identifier: Apache-2.0 +org: lfedge +image: eve-bpftrace +network: no diff --git a/pkg/bpftrace/patches/0001-AOT-keep-intermediate-code.patch b/pkg/bpftrace/patches/0001-AOT-keep-intermediate-code.patch new file mode 100644 index 0000000000..e91f3a66a3 --- /dev/null +++ b/pkg/bpftrace/patches/0001-AOT-keep-intermediate-code.patch @@ -0,0 +1,39 @@ +From bd8c7a1e1f8547e9756c817daf335693bec88d85 Mon Sep 17 00:00:00 2001 +From: Christoph Ostarek +Date: Wed, 28 Feb 2024 15:20:03 +0100 +Subject: [PATCH 1/3] AOT: keep intermediate code + +this code will be passed to bpftrace-aotrt + +Signed-off-by: Christoph Ostarek +--- + src/aot/aot.cpp | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/src/aot/aot.cpp b/src/aot/aot.cpp +index d0154781..0e2ef381 100644 +--- a/src/aot/aot.cpp ++++ b/src/aot/aot.cpp +@@ -26,7 +26,7 @@ + #define AOT_ELF_SECTION ".btaot" + static constexpr auto AOT_MAGIC = 0xA07; + static constexpr auto AOT_SHIM_NAME = "bpftrace-aotrt"; +-static constexpr auto AOT_SECDATA_TEMPFILE = ".temp_btaot"; ++static constexpr auto AOT_SECDATA_TEMPFILE = "temp_btaot"; + + // AOT payload will have this header at the beginning. We don't worry about + // versioning the header b/c we enforce that an AOT compiled script may only +@@ -221,8 +221,8 @@ bool build_binary(const std_filesystem::path &shim, + + ret = true; + out: +- if (!std_filesystem::remove(AOT_SECDATA_TEMPFILE, ec) || ec) +- LOG(ERROR) << "Failed to remove " << AOT_SECDATA_TEMPFILE << ": " << ec; ++ //if (!std_filesystem::remove(AOT_SECDATA_TEMPFILE, ec) || ec) ++ // LOG(ERROR) << "Failed to remove " << AOT_SECDATA_TEMPFILE << ": " << ec; + return ret; + } + +-- +2.45.1 + diff --git a/pkg/bpftrace/patches/0002-AOT-disable-compatability-restrictions.patch b/pkg/bpftrace/patches/0002-AOT-disable-compatability-restrictions.patch new file mode 100644 index 0000000000..cfa2efb55f --- /dev/null +++ b/pkg/bpftrace/patches/0002-AOT-disable-compatability-restrictions.patch @@ -0,0 +1,79 @@ +From 98e7fbe94420452d5274372340c78be2c3f4c62e Mon Sep 17 00:00:00 2001 +From: Christoph Ostarek +Date: Mon, 4 Mar 2024 16:26:32 +0100 +Subject: [PATCH 2/3] AOT: disable compatability restrictions + +these don't apply to EVE as we create the code on +the same kernel as on the destination device + +Signed-off-by: Christoph Ostarek +--- + src/ast/passes/portability_analyser.cpp | 13 +++++++++---- + 1 file changed, 9 insertions(+), 4 deletions(-) + +diff --git a/src/ast/passes/portability_analyser.cpp b/src/ast/passes/portability_analyser.cpp +index e83a6e44..05e39f0b 100644 +--- a/src/ast/passes/portability_analyser.cpp ++++ b/src/ast/passes/portability_analyser.cpp +@@ -47,11 +47,12 @@ void PortabilityAnalyser::visit(Builtin &builtin) + // `struct task_struct` is unstable across kernel versions and configurations. + // This makes it inherently unportable. We must block it until we support + // field access relocations. +- if (builtin.ident == "curtask") +- { ++ /* ++ if (builtin.ident == "curtask") { + LOG(ERROR, builtin.loc, err_) + << "AOT does not yet support accessing `curtask`"; + } ++ */ + } + + void PortabilityAnalyser::visit(Call &call) +@@ -71,11 +72,13 @@ void PortabilityAnalyser::visit(Call &call) + // resolved during codegen and the value embedded into the bytecode. For AOT + // to support cgroupid(), the cgroupid must be resolved at runtime and fixed + // up during load time. ++ /* + if (call.func == "kaddr" || call.func == "uaddr" || call.func == "cgroupid") + { + LOG(ERROR, call.loc, err_) + << "AOT does not yet support " << call.func << "()"; + } ++ */ + } + + void PortabilityAnalyser::visit(Cast &cast) +@@ -87,7 +90,7 @@ void PortabilityAnalyser::visit(Cast &cast) + // portable. `args` for k[ret]funcs are type checked by the kernel and may + // also be considered stable. For AOT to fully support field accesses, we + // need to relocate field access at runtime. +- LOG(ERROR, cast.loc, err_) << "AOT does not yet support struct casts"; ++// LOG(ERROR, cast.loc, err_) << "AOT does not yet support struct casts"; + } + + void PortabilityAnalyser::visit(AttachPoint &ap) +@@ -99,17 +102,19 @@ void PortabilityAnalyser::visit(AttachPoint &ap) + // and offsets and type information is embedded into the bytecode. For AOT + // support, this analyzing must be done during runtime and fixed up during + // load time. ++ /* + if (type == ProbeType::usdt) + { + LOG(ERROR, ap.loc, err_) << "AOT does not yet support USDT probes"; + } ++ */ + // While userspace watchpoint probes are technically portable from codegen + // point of view, they require a PID or path via cmdline to resolve address. + // watchpoint probes are also API-unstable and need a further change + // (see https://github.com/iovisor/bpftrace/issues/1683). + // + // So disable for now and re-evalulate at another point. +- else if (type == ProbeType::watchpoint || type == ProbeType::asyncwatchpoint) ++ if (type == ProbeType::watchpoint || type == ProbeType::asyncwatchpoint) + { + LOG(ERROR, ap.loc, err_) << "AOT does not yet support watchpoint probes"; + } +-- +2.45.1 + diff --git a/pkg/bpftrace/patches/0003-bpfbytecode-disable-BTF_KIND_ENUM64.patch b/pkg/bpftrace/patches/0003-bpfbytecode-disable-BTF_KIND_ENUM64.patch new file mode 100644 index 0000000000..0bbf8fa01c --- /dev/null +++ b/pkg/bpftrace/patches/0003-bpfbytecode-disable-BTF_KIND_ENUM64.patch @@ -0,0 +1,36 @@ +From ec81a44599c974b8882737918fb1643e9f3e008c Mon Sep 17 00:00:00 2001 +From: Christoph Ostarek +Date: Tue, 7 May 2024 18:18:57 +0200 +Subject: [PATCH 3/3] bpfbytecode: disable BTF_KIND_ENUM64 + +it is not supported yet by our kernel + +Signed-off-by: Christoph Ostarek +--- + src/bpfbytecode.cpp | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/src/bpfbytecode.cpp b/src/bpfbytecode.cpp +index c6291c8b..a0249401 100644 +--- a/src/bpfbytecode.cpp ++++ b/src/bpfbytecode.cpp +@@ -50,6 +50,7 @@ static int btf_type_size(const struct btf_type *t) + return base_size + sizeof(__u32); + case BTF_KIND_ENUM: + return base_size + vlen * sizeof(struct btf_enum); ++ #if 0 + case BTF_KIND_ENUM64: + /* struct btf_enum64 is not available in UAPI header until v6.0, + * calculate its size with array instead. Its definition is: +@@ -60,7 +61,7 @@ static int btf_type_size(const struct btf_type *t) + * __u32 val_hi32; + * }; + */ +- return base_size + vlen * sizeof(__u32[3]); ++ #endif + case BTF_KIND_ARRAY: + return base_size + sizeof(struct btf_array); + case BTF_KIND_STRUCT: +-- +2.45.1 + diff --git a/tools/parse-pkgs.sh b/tools/parse-pkgs.sh index 4903f3d660..250c2c0237 100755 --- a/tools/parse-pkgs.sh +++ b/tools/parse-pkgs.sh @@ -119,6 +119,7 @@ KVMTOOLS_TAG=${KVMTOOLS_TAG} IPXE_TAG=${IPXE_TAG} KEXEC_TAG=${KEXEC_TAG} KDUMP_TAG=${KDUMP_TAG} +BPFTRACE_TAG=${BPFTRACE_TAG} MEASURE_CONFIG_TAG=${MEASURE_CONFIG_TAG} BSP_IMX_TAG=${BSP_IMX_TAG} APPARMOR_TAG=${APPARMOR_TAG} @@ -171,6 +172,7 @@ KVMTOOLS_TAG=$(linuxkit_tag pkg/kvm-tools) IPXE_TAG=$(linuxkit_tag pkg/ipxe) KEXEC_TAG=$(linuxkit_tag pkg/kexec) KDUMP_TAG=$(linuxkit_tag pkg/kdump) +BPFTRACE_TAG=$(linuxkit_tag pkg/bpftrace) MEASURE_CONFIG_TAG=$(linuxkit_tag pkg/measure-config) BSP_IMX_TAG=$(linuxkit_tag pkg/bsp-imx) APPARMOR_TAG=$(linuxkit_tag pkg/apparmor)