diff --git a/.cargo/config.toml b/.cargo/config.toml index 0584e1b4..1ffba3d6 100644 --- a/.cargo/config.toml +++ b/.cargo/config.toml @@ -1,5 +1,5 @@ [alias] -xtask = "run --package xtask --" +xtask = "run --release --package xtask --" [target.armv7-unknown-linux-gnueabi] linker = "arm-linux-gnueabi-gcc" diff --git a/.github/scripts/download_kernel_images.sh b/.github/scripts/download_kernel_images.sh index da827460..7868953f 100755 --- a/.github/scripts/download_kernel_images.sh +++ b/.github/scripts/download_kernel_images.sh @@ -8,6 +8,12 @@ if [ "$#" -lt 3 ]; then exit 1 fi +escape_regex() { + # Escape characters that have special meaning in extended regular expressions so that + # we can safely interpolate package names into grep patterns. + printf '%s\n' "$1" | sed 's/[][(){}.^$*+?|\\-]/\\&/g' +} + OUTPUT_DIR=$1 ARCHITECTURE=$2 shift 2 @@ -25,6 +31,25 @@ for VERSION in "${VERSIONS[@]}"; do exit 1 } FILES+=("$match") + + # The debug package contains the actual System.map. Debian has transitioned + # between -dbg and -dbgsym suffixes, so match either for the specific kernel + # we just selected. + kernel_basename=$(basename "$match") + kernel_prefix=${kernel_basename%%_*} + kernel_suffix=${kernel_basename#${kernel_prefix}_} + base_prefix=${kernel_prefix%-unsigned} + + base_prefix_regex=$(escape_regex "$base_prefix") + kernel_suffix_regex=$(escape_regex "$kernel_suffix") + + DEBUG_REGEX="${base_prefix_regex}-dbg(sym)?_${kernel_suffix_regex}" + debug_match=$(printf '%s\n' "$URLS" | grep -E "$DEBUG_REGEX" | sort -V | tail -n1) || { + printf 'Failed to locate debug package matching %s\n%s\nVERSION=%s\nREGEX=%s\n' \ + "$kernel_basename" "$URLS" "$VERSION" "$DEBUG_REGEX" >&2 + exit 1 + } + FILES+=("$debug_match") done # Note: `--etag-{compare,save}` are not idempotent until curl 8.9.0 which included diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 76b32427..a628c02c 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -11,6 +11,8 @@ on: env: CARGO_TERM_COLOR: always +permissions: {} + jobs: #buildTestAyaDirect: # uses: melodium-tech/github-actions/.github/workflows/melodium-ubuntu.yml@v0.9.1 @@ -28,6 +30,14 @@ jobs: artifact-path: 'logs/' secrets: token: ${{ secrets.GITHUB_TOKEN }} + buildTestAyaEbpf: + uses: melodium-tech/github-actions/.github/workflows/melodium-local-distrib.yml@v0.9.1 + with: + command: | + run .melodium-ci/Compo.toml buildTestAyaEbpf --repository_clone_url='"${{ github.repositoryUrl }}"' --repository_clone_ref='"${{ github.ref_name }}"' --github_contexts='$''{{{{ { "github": ${{ toJSON(github) }}, "vars": ${{ toJSON(vars) }}, "secrets": { "GITHUB_TOKEN": "'"$GITHUB_TOKEN"'" } } }}}}' + artifact-path: 'logs/' + secrets: + token: ${{ secrets.GITHUB_TOKEN }} #runs-on: ubuntu-latest #steps: # - uses: actions/checkout@v5 @@ -41,3 +51,372 @@ jobs: # artifact-path: logs/ # secrets: # token: "${{ secrets.GITHUB_TOKEN }}" + lint: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v6 + + - uses: dtolnay/rust-toolchain@nightly + with: + components: clippy,miri,rustfmt,rust-src + + # Installed *after* nightly so it is the default. + - uses: dtolnay/rust-toolchain@stable + + - uses: Swatinem/rust-cache@v2 + + - uses: taiki-e/install-action@v2 + with: + tool: cargo-hack,taplo-cli + + - run: git ls-files -- '*.c' '*.h' | xargs clang-format --dry-run --Werror + + - uses: DavidAnson/markdownlint-cli2-action@v21 + + - run: taplo fmt --check + + - run: cargo +nightly fmt --all -- --check + + - run: ./clippy.sh + + # On the `aya-rs/aya` repository, regenerate the public API on a schedule. + # + # On all other events and repositories assert the public API is up to date. + - run: cargo xtask public-api + if: ${{ !(github.event_name == 'schedule' && github.repository == 'aya-rs/aya') }} + - run: cargo xtask public-api --bless + if: ${{ (github.event_name == 'schedule' && github.repository == 'aya-rs/aya') }} + - uses: peter-evans/create-pull-request@v7 + if: ${{ (github.event_name == 'schedule' && github.repository == 'aya-rs/aya') }} + with: + # GitHub actions aren't allowed to trigger other actions to prevent + # abuse; the canonical workaround is to use a sufficiently authorized + # token. + # + # See https://github.com/peter-evans/create-pull-request/blob/main/docs/concepts-guidelines.md#workarounds-to-trigger-further-workflow-runs. + token: ${{ secrets.CRABBY_GITHUB_TOKEN }} + branch: create-pull-request/public-api + commit-message: 'public-api: regenerate' + title: 'public-api: regenerate' + body: | + **Automated changes** + + - name: Run miri + run: | + set -euxo pipefail + cargo +nightly hack miri test --all-targets --feature-powerset \ + --exclude aya-ebpf \ + --exclude aya-ebpf-bindings \ + --exclude aya-log-ebpf \ + --exclude integration-ebpf \ + --exclude integration-test \ + --workspace + + build-test-aya: + strategy: + fail-fast: false + matrix: + arch: + - aarch64-unknown-linux-gnu + - armv7-unknown-linux-gnueabi + - loongarch64-unknown-linux-gnu + - powerpc64le-unknown-linux-gnu + - riscv64gc-unknown-linux-gnu + - s390x-unknown-linux-gnu + - x86_64-unknown-linux-gnu + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v6 + + - uses: dtolnay/rust-toolchain@stable + with: + targets: ${{ matrix.arch }} + + - uses: Swatinem/rust-cache@v2 + + - uses: taiki-e/install-action@cargo-hack + + # This is magic, it sets `$CARGO_BUILD_TARGET`. + - uses: taiki-e/setup-cross-toolchain-action@v1 + with: + target: ${{ matrix.arch }} + + - name: Build + run: | + set -euxo pipefail + cargo hack build --all-targets --feature-powerset \ + --exclude aya-ebpf \ + --exclude aya-ebpf-bindings \ + --exclude aya-log-ebpf \ + --exclude integration-ebpf \ + --exclude xtask \ + --workspace + + - name: Test + env: + RUST_BACKTRACE: full + run: | + set -euxo pipefail + cargo hack test --all-targets \ + --exclude aya-ebpf \ + --exclude aya-ebpf-bindings \ + --exclude aya-log-ebpf \ + --exclude integration-ebpf \ + --exclude integration-test \ + --feature-powerset + + - name: Doctests + env: + RUST_BACKTRACE: full + run: | + set -euxo pipefail + cargo hack test --doc \ + --exclude aya-ebpf \ + --exclude aya-ebpf-bindings \ + --exclude aya-log-ebpf \ + --exclude integration-ebpf \ + --exclude integration-test \ + --feature-powerset + + build-test-aya-ebpf: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v6 + + - uses: dtolnay/rust-toolchain@nightly + with: + components: rust-src + + # Installed *after* nightly so it is the default. + - uses: dtolnay/rust-toolchain@stable + + - uses: Swatinem/rust-cache@v2 + + - run: cargo install --git https://github.com/aya-rs/bpf-linker.git bpf-linker --features llvm-21 + + - uses: taiki-e/install-action@cargo-hack + + - name: Build & test for all BPF architectures + env: + RUST_BACKTRACE: full + run: | + set -euo pipefail + + failures=() + + # NB: this hand-rolled shell script is used instead of a matrix + # because the time spent doing useful work per target is about equal + # to the overhead of setting up the job - so this saves a bunch of + # machine time. + for arch in aarch64 arm loongarch64 mips powerpc64 riscv64 s390x x86_64; do + echo "::group::arch=$arch" + export RUSTFLAGS="--cfg bpf_target_arch=\"$arch\"" + for target in bpfeb-unknown-none bpfel-unknown-none; do + echo "::group::target=$target" + if ! ( + cargo +nightly hack build \ + --release \ + --target "$target" \ + -Z build-std=core \ + --package aya-ebpf \ + --package aya-ebpf-bindings \ + --package aya-log-ebpf \ + --package integration-ebpf \ + --feature-powerset + ); then + failures+=("build: $arch/$target") + fi + echo "::endgroup::" + done + if ! ( + RUSTDOCFLAGS=$RUSTFLAGS cargo +nightly hack test --doc \ + --package aya-ebpf \ + --package aya-ebpf-bindings \ + --package aya-log-ebpf \ + --package integration-ebpf \ + --feature-powerset + ); then + failures+=("doctests: $arch") + fi + echo "::endgroup::" + done + + if ((${#failures[@]})); then + echo "::error::Some builds/tests failed:" + printf ' %s\n' "${failures[@]}" + exit 1 + fi + + run-integration-test: + strategy: + fail-fast: false + matrix: + # We don't have a fast solution for running virtualized integration + # tests on arm64 because: + # - GitHub Ubuntu arm64 runners don't support nested virtualization (see + # https://github.com/orgs/community/discussions/148648#discussioncomment-11863547). + # - GitHub macOS arm64 runners don't support nested virtualization (see + # https://docs.github.com/en/actions/reference/runners/github-hosted-runners#limitations-for-arm64-macos-runners). + # + # So we spin a runner for every arm64 kernel to avoid waiting 20 minutes + # for CI. We use arm64 runners to avoid cross-compilation. + os: + - ubuntu-24.04-arm + download-kernel-images: + - arm64 5.10 + - arm64 6.1 + - arm64 6.12 + skip-local: + - true + include: + - os: macos-latest + # Just one kernel to keep things fast. We just want to keep things from rotting on + # macOS. We use amd64 because otherwise qemu tries to use HVF and hits a hard error: + # qemu-system-aarch64: -accel hvf: Error: ret = HV_UNSUPPORTED (0xfae9400f, at ../target/arm/hvf/hvf.c:956) + download-kernel-images: amd64 5.10 + + # We don't use ubuntu-latest because we care about the apt packages available. + - os: ubuntu-24.04 + download-kernel-images: amd64 5.10 6.1 6.12 + - os: ubuntu-24.04-arm + # Native arm runner for local tests only; arm runners don't support + # nested virtualization so running them here would be slow. + download-kernel-images: local + + runs-on: ${{ matrix.os }} + steps: + - uses: actions/checkout@v6 + with: + submodules: recursive + + - name: Install prerequisites + if: runner.os == 'Linux' + run: | + set -euxo pipefail + + # https://github.blog/changelog/2023-02-23-hardware-accelerated-android-virtualization-on-actions-windows-and-linux-larger-hosted-runners/ + echo 'KERNEL=="kvm", GROUP="kvm", MODE="0666", OPTIONS+="static_node=kvm"' | sudo tee /etc/udev/rules.d/99-kvm4all.rules + sudo udevadm control --reload-rules + sudo udevadm trigger --name-match=kvm || true # kvm is not available on arm64. + + sudo apt update + sudo apt -y install \ + liblzma-dev \ + lynx \ + musl-tools \ + qemu-system-{arm,x86} + + - name: Install prerequisites + if: runner.os == 'macOS' + run: | + set -euxo pipefail + # Dependencies are tracked in `Brewfile`. + brew bundle + echo $(brew --prefix curl)/bin >> $GITHUB_PATH + echo $(brew --prefix llvm)/bin >> $GITHUB_PATH + + # https://github.com/actions/setup-python/issues/577 + find /usr/local/bin -type l -exec sh -c 'readlink -f "$1" \ + | grep -q ^/Library/Frameworks/Python.framework/Versions/' _ {} \; -exec rm -v {} \; + + - uses: dtolnay/rust-toolchain@nightly + with: + components: rust-src + + # Installed *after* nightly so it is the default. + - uses: dtolnay/rust-toolchain@stable + with: + targets: aarch64-unknown-linux-musl,x86_64-unknown-linux-musl + + - uses: Swatinem/rust-cache@v2 + + - name: Install libLLVM + # Download libLLVM from Rust CI to ensure that the libLLVM version + # matches exactly with the version used by the current Rust nightly. A + # mismatch between libLLVM (used by bpf-linker) and Rust's LLVM version + # can lead to linking issues. + run: | + set -euxo pipefail + # Get the partial SHA from Rust nightly. + rustc_sha=$(rustc +nightly --version | grep -oE '[a-f0-9]{7,40}') + # Get the full SHA from GitHub. + rustc_sha=$(curl -sfSL https://api.github.com/repos/rust-lang/rust/commits/$rustc_sha \ + --header 'authorization: Bearer ${{ secrets.GITHUB_TOKEN }}' \ + --header 'content-type: application/json' \ + | jq -r '.sha') + mkdir -p /tmp/rustc-llvm + case "${{ runner.arch }}" in + ARM64) + arch=aarch64 + ;; + X64) + arch=x86_64 + ;; + *) + echo "::error::Unsupported runner architecture: ${{ runner.arch }}" + exit 1 + ;; + esac + case "${{ runner.os }}" in + Linux) + target=${arch}-unknown-linux-gnu + ;; + macOS) + target=${arch}-apple-darwin + ;; + *) + echo "::error::Unsupported runner OS: ${{ runner.os }}" + exit 1 + ;; + esac + curl -sfSL https://ci-artifacts.rust-lang.org/rustc-builds/$rustc_sha/rust-dev-nightly-${target}.tar.xz | \ + tar -xJ --strip-components 2 -C /tmp/rustc-llvm + echo /tmp/rustc-llvm/bin >> $GITHUB_PATH + + # NB: rustc doesn't ship libLLVM.so on macOS, so disable proxying (default feature). We also + # --force so that bpf-linker gets always relinked against the latest LLVM downloaded above. + # + # Do this on all system (not just macOS) to avoid relying on rustc-provided libLLVM.so. + - run: cargo install --git https://github.com/aya-rs/bpf-linker.git bpf-linker --no-default-features --features llvm-21 --force + + - uses: actions/cache@v4 + with: + path: test/.tmp + key: ${{ runner.arch }}-${{ runner.os }}-test-cache-${{ matrix.download-kernel-images }} + + - name: Download debian kernels + if: matrix.download-kernel-images != 'local' + run: | + set -euxo pipefail + + .github/scripts/download_kernel_images.sh test/.tmp/debian-kernels ${{ matrix.download-kernel-images }} + + - name: Cleanup stale kernels and modules + run: rm -rf test/.tmp/boot test/.tmp/lib + + - name: Run local integration tests + if: runner.os == 'Linux' && matrix.skip-local != true + run: cargo xtask integration-test local + + - name: Run virtualized integration tests + if: matrix.download-kernel-images != 'local' + run: | + set -euxo pipefail + find test/.tmp -name '*.deb' -print0 | sort -Vz | xargs -t -0 \ + cargo xtask integration-test vm --cache-dir test/.tmp \ + --github-api-token ${{ secrets.GITHUB_TOKEN }} + + check: + if: always() + needs: + - lint + - build-test-aya + - build-test-aya-ebpf + - run-integration-test + runs-on: ubuntu-latest + steps: + - uses: re-actors/alls-green@release/v1 + with: + jobs: ${{ toJSON(needs) }} diff --git a/.github/workflows/gen.yml b/.github/workflows/gen.yml index e63ccc1b..6919d8a1 100644 --- a/.github/workflows/gen.yml +++ b/.github/workflows/gen.yml @@ -10,12 +10,14 @@ on: workflow_dispatch: +permissions: {} + jobs: codegen: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v5 + - uses: actions/checkout@v6 with: submodules: recursive @@ -47,7 +49,7 @@ jobs: # abuse; the canonical workaround is to use a sufficiently authorized # token. # - # See https://github.com/peter-evans/create-pull-request/issues/48. + # See https://github.com/peter-evans/create-pull-request/blob/main/docs/concepts-guidelines.md#workarounds-to-trigger-further-workflow-runs. token: ${{ secrets.CRABBY_GITHUB_TOKEN }} branch: create-pull-request/codegen commit-message: | diff --git a/Brewfile b/Brewfile index 356453a7..285773b9 100644 --- a/Brewfile +++ b/Brewfile @@ -1,10 +1,18 @@ # Keep this congruent with `.github/workflows/ci.yml`. +# The curl shipped on macOS doesn't contain +# https://github.com/curl/curl/commit/85efbb92b8e6679705e122cee45ce76c56414a3e +# which is needed for proper handling of `--etag-{compare,save}`. brew "curl" + +# The clang shipped on macOS doesn't support BPF, so we need LLVM from brew. brew "llvm" + brew "lynx" brew "pkg-config" brew "qemu" +# We need a musl C toolchain to compile our `test-distro` since some of our +# dependencies have build scripts that compile C code (i.e xz2). tap "filosottile/musl-cross" brew "filosottile/musl-cross/musl-cross" diff --git a/Cargo.toml b/Cargo.toml index 73f71433..5c61670f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -57,7 +57,7 @@ edition = "2024" homepage = "https://aya-rs.dev" license = "MIT OR Apache-2.0" repository = "https://github.com/aya-rs/aya" -rust-version = "1.85.0" +rust-version = "1.87.0" # NOTE(vadorovsky): Neither cargo-udeps nor cargo-machete are able to detect # unused crates defined in this section. It would be nice to teach either of @@ -86,7 +86,7 @@ log = { version = "0.4", default-features = false } network-types = { version = "0.1.0", default-features = false } nix = { version = "0.30.1", default-features = false } num_enum = { version = "0.7", default-features = false } -object = { version = "0.37", default-features = false } +object = { version = "0.38", default-features = false } once_cell = { version = "1.20.1", default-features = false } proc-macro2 = { version = "1", default-features = false } proc-macro2-diagnostics = { version = "0.10.1", default-features = false } diff --git a/RELEASE.md b/RELEASE.md new file mode 100644 index 00000000..0e0438e0 --- /dev/null +++ b/RELEASE.md @@ -0,0 +1,74 @@ +# Releasing the aya project + +This document describes the process of releasing the aya project. + +## Release process + +### 0. Who can release? + +Only members of [aya-rs/owners][owners-team] have the permissions to: + +- Push packages to crates.io +- Make the necessary changes in GitHub to create a release + +### 1. Create a release branch and run cargo smart-release + +This project uses [cargo-smart-release] to automate the release process. Start +from the default branch, create a fresh release branch, and run the command +below on that branch. As soon as the command succeeds it will publish each crate +and push the branch plus tags to the remote automatically, so double-check that +everything is ready before invoking +it. + +> [!IMPORTANT] +> The `--execute` flag is used to actually perform the release. +> Remove it to do a dry-run first. + +```sh +git checkout -b my-release-branch +cargo smart-release \ + aya \ + aya-build \ + aya-ebpf \ + aya-log \ + aya-log-ebpf \ + --execute \ + --no-changelog-github-release \ + --signoff +``` + +### 2. Open a pull request + +Because the release branch gets pushed automatically on success, open a PR +against the default branch and merge it once everything looks good. This keeps +git history auditable even though crates.io already has the freshly published +artifacts. + +> [!IMPORTANT] +> Use a fast-forward merge to ensure the tags are reachable from the default +> branch. + +## Release Debugging + +Sometimes the release process can fail. + +Here are some common issues and how to fix them: + +### `cargo smart-release` doesn't compute the correct version + +You can manually specify the version to release by passing the `--bump` flag +and specifying either `major`, `minor`, or `patch`. This *should* be computed +from the commits in the changelog, but sometimes it doesn't work as expected. + +### WOULD stop release after commit as the changelog entry is empty for crate + +If you see the message ☝ in the output of `cargo smart-release`, it means that +the generated changelog entry for the crate is empty. This can happen if, for +example, the only change is a dependency update. In this case, you can manually +edit the changelog entry in the crate's `CHANGELOG.md` file to include a note +about the dependency update under the `## Unreleased` section. +[c3f0c7dc] is an example of such a commit. + +[cargo-smart-release]: https://github.com/Byron/cargo-smart-release +[owners-team]: https://github.com/orgs/aya-rs/teams/owners +[c3f0c7dc]: https://github.com/aya-rs/aya/commit/c3f0c7dc3fb285da091454426eeda0723389f0f1 diff --git a/aya-build/Cargo.toml b/aya-build/Cargo.toml index 5acc53c8..247c2d2e 100644 --- a/aya-build/Cargo.toml +++ b/aya-build/Cargo.toml @@ -1,7 +1,7 @@ [package] description = "Build-time support for aya projects" name = "aya-build" -version = "0.1.2" +version = "0.1.3" authors.workspace = true edition.workspace = true diff --git a/aya-build/src/lib.rs b/aya-build/src/lib.rs index b2f7c679..4caf28a6 100644 --- a/aya-build/src/lib.rs +++ b/aya-build/src/lib.rs @@ -11,21 +11,19 @@ use std::{ use anyhow::{Context as _, Result, anyhow}; use cargo_metadata::{Artifact, CompilerMessage, Message, Target}; +#[derive(Default)] pub struct Package<'a> { pub name: &'a str, pub root_dir: &'a str, + pub no_default_features: bool, + pub features: &'a [&'a str], } -fn target_arch() -> Cow<'static, str> { - const TARGET_ARCH: &str = "CARGO_CFG_TARGET_ARCH"; - let target_arch = env::var_os(TARGET_ARCH).unwrap_or_else(|| panic!("{TARGET_ARCH} not set")); - let target_arch = target_arch.into_encoded_bytes(); - let target_arch = String::from_utf8(target_arch) - .unwrap_or_else(|err| panic!("String::from_utf8({TARGET_ARCH}): {err:?}")); +fn target_arch_fixup(target_arch: Cow<'_, str>) -> Cow<'_, str> { if target_arch.starts_with("riscv64") { "riscv64".into() } else { - target_arch.into() + target_arch } } @@ -58,10 +56,22 @@ pub fn build_ebpf<'a>( return Err(anyhow!("unsupported endian={endian:?}")); }; - let arch = target_arch(); + const TARGET_ARCH: &str = "CARGO_CFG_TARGET_ARCH"; + let bpf_target_arch = + env::var_os(TARGET_ARCH).unwrap_or_else(|| panic!("{TARGET_ARCH} not set")); + let bpf_target_arch = bpf_target_arch + .into_string() + .unwrap_or_else(|err| panic!("OsString::into_string({TARGET_ARCH}): {err:?}")); + let bpf_target_arch = target_arch_fixup(bpf_target_arch.into()); let target = format!("{target}-unknown-none"); - for Package { name, root_dir } in packages { + for Package { + name, + root_dir, + no_default_features, + features, + } in packages + { // We have a build-dependency on `name`, so cargo will automatically rebuild us if `name`'s // *library* target or any of its dependencies change. Since we depend on `name`'s *binary* // targets, that only gets us half of the way. This stanza ensures cargo will rebuild us on @@ -84,6 +94,10 @@ pub fn build_ebpf<'a>( "--target", &target, ]); + if no_default_features { + cmd.arg("--no-default-features"); + } + cmd.args(["--features", &features.join(",")]); { const SEPARATOR: &str = "\x1f"; @@ -92,7 +106,7 @@ pub fn build_ebpf<'a>( for s in [ "--cfg=bpf_target_arch=\"", - &arch, + &bpf_target_arch, "\"", SEPARATOR, "-Cdebuginfo=2", @@ -202,16 +216,45 @@ impl<'a> Toolchain<'a> { /// Emit cfg flags that describe the desired BPF target architecture. pub fn emit_bpf_target_arch_cfg() { - const RUSTFLAGS: &str = "CARGO_ENCODED_RUSTFLAGS"; - - println!("cargo:rerun-if-env-changed={RUSTFLAGS}"); - let rustc_cfgs = std::env::var_os(RUSTFLAGS).unwrap_or_else(|| panic!("{RUSTFLAGS} not set")); - let rustc_cfgs = rustc_cfgs - .to_str() - .unwrap_or_else(|| panic!("{RUSTFLAGS}={rustc_cfgs:?} not unicode")); - if !rustc_cfgs.contains("bpf_target_arch") { - let arch = target_arch(); - println!("cargo:rustc-cfg=bpf_target_arch=\"{arch}\""); + // The presence of this environment variable indicates that `--cfg + // bpf_target_arch="..."` was passed to the compiler, so we don't need to + // emit it again. Note that we cannot *set* this environment variable - it + // is set by cargo. + const BPF_TARGET_ARCH: &str = "CARGO_CFG_BPF_TARGET_ARCH"; + println!("cargo:rerun-if-env-changed={BPF_TARGET_ARCH}"); + + // Users may directly set this environment variable in situations where + // using RUSTFLAGS to set `--cfg bpf_target_arch="..."` is not possible or + // not ergonomic. In contrast to RUSTFLAGS this mechanism reuses the target + // cache for all values, producing many more invalidations. + const AYA_BPF_TARGET_ARCH: &str = "AYA_BPF_TARGET_ARCH"; + println!("cargo:rerun-if-env-changed={AYA_BPF_TARGET_ARCH}"); + + const HOST: &str = "HOST"; + println!("cargo:rerun-if-env-changed={HOST}"); + + if std::env::var_os(BPF_TARGET_ARCH).is_none() { + let host = std::env::var_os(HOST).unwrap_or_else(|| panic!("{HOST} not set")); + let host = host + .into_string() + .unwrap_or_else(|err| panic!("OsString::into_string({HOST}): {err:?}")); + let host = host.as_str(); + + let bpf_target_arch = if let Some(bpf_target_arch) = std::env::var_os(AYA_BPF_TARGET_ARCH) { + bpf_target_arch + .into_string() + .unwrap_or_else(|err| { + panic!("OsString::into_string({AYA_BPF_TARGET_ARCH}): {err:?}") + }) + .into() + } else { + target_arch_fixup( + host.split_once('-') + .map_or(host, |(arch, _rest)| arch) + .into(), + ) + }; + println!("cargo:rustc-cfg=bpf_target_arch=\"{bpf_target_arch}\""); } print!("cargo::rustc-check-cfg=cfg(bpf_target_arch, values("); diff --git a/aya-ebpf-macros/CHANGELOG.md b/aya-ebpf-macros/CHANGELOG.md index 4e1df55f..92071845 100644 --- a/aya-ebpf-macros/CHANGELOG.md +++ b/aya-ebpf-macros/CHANGELOG.md @@ -5,6 +5,19 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [Unreleased] + +## v0.1.2 (2025-11-17) + +### New Features + + - Added Flow Dissector macro support so attaching those programs no longer requires manual boilerplate. + - Switched error reporting to `proc-macro2-diagnostics`, providing richer compiler output when macro expansion fails. + +### Maintenance + + - Dropped the stale dev-dependency on `aya-ebpf` and kept the crate in sync with the workspace lint/edition configuration. + ## v0.1.1 (2024-10-09) ### Chore diff --git a/aya-ebpf-macros/Cargo.toml b/aya-ebpf-macros/Cargo.toml index 55a76f2c..f5753c66 100644 --- a/aya-ebpf-macros/Cargo.toml +++ b/aya-ebpf-macros/Cargo.toml @@ -1,7 +1,7 @@ [package] description = "Proc macros used by aya-ebpf" name = "aya-ebpf-macros" -version = "0.1.1" +version = "0.1.2" authors.workspace = true edition.workspace = true diff --git a/aya-ebpf-macros/src/kprobe.rs b/aya-ebpf-macros/src/kprobe.rs index ba5ea31b..97cd53b3 100644 --- a/aya-ebpf-macros/src/kprobe.rs +++ b/aya-ebpf-macros/src/kprobe.rs @@ -15,10 +15,9 @@ pub(crate) enum KProbeKind { impl std::fmt::Display for KProbeKind { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - use KProbeKind::*; match self { - KProbe => write!(f, "kprobe"), - KRetProbe => write!(f, "kretprobe"), + Self::KProbe => write!(f, "kprobe"), + Self::KRetProbe => write!(f, "kretprobe"), } } } diff --git a/aya-ebpf-macros/src/lib.rs b/aya-ebpf-macros/src/lib.rs index bbd4fdc3..5c9878b0 100644 --- a/aya-ebpf-macros/src/lib.rs +++ b/aya-ebpf-macros/src/lib.rs @@ -216,14 +216,11 @@ pub fn cgroup_skb(attrs: TokenStream, item: TokenStream) -> TokenStream { /// pub fn connect4(ctx: SockAddrContext) -> i32 { /// match try_connect4(ctx) { /// Ok(ret) => ret, -/// Err(ret) => match ret.try_into() { -/// Ok(rt) => rt, -/// Err(_) => 1, -/// }, +/// Err(ret) => ret, /// } /// } /// -/// fn try_connect4(ctx: SockAddrContext) -> Result { +/// fn try_connect4(ctx: SockAddrContext) -> Result { /// Ok(0) /// } /// ``` @@ -440,7 +437,7 @@ pub fn btf_tracepoint(attrs: TokenStream, item: TokenStream) -> TokenStream { /// ///#[stream_parser] ///fn stream_parser(ctx: SkBuffContext) -> u32 { -/// match { try_stream_parser(ctx) } { +/// match try_stream_parser(ctx) { /// Ok(ret) => ret, /// Err(ret) => ret, /// } @@ -470,7 +467,7 @@ pub fn stream_parser(attrs: TokenStream, item: TokenStream) -> TokenStream { /// ///#[stream_verdict] ///fn stream_verdict(ctx: SkBuffContext) -> u32 { -/// match { try_stream_verdict(ctx) } { +/// match try_stream_verdict(ctx) { /// Ok(ret) => ret, /// Err(ret) => ret, /// } @@ -507,7 +504,7 @@ fn sk_skb(kind: SkSkbKind, attrs: TokenStream, item: TokenStream) -> TokenStream /// /// #[socket_filter] /// pub fn accept_all(_ctx: SkBuffContext) -> i64 { -/// return 0 +/// 0 /// } /// ``` #[proc_macro_attribute] @@ -531,9 +528,10 @@ pub fn socket_filter(attrs: TokenStream, item: TokenStream) -> TokenStream { /// # Examples /// /// ```no_run -/// # #![expect(non_camel_case_types)] /// use aya_ebpf::{macros::fentry, programs::FEntryContext}; +/// # #[expect(non_camel_case_types)] /// # type filename = u32; +/// # #[expect(non_camel_case_types)] /// # type path = u32; /// /// #[fentry(function = "filename_lookup")] @@ -573,9 +571,10 @@ pub fn fentry(attrs: TokenStream, item: TokenStream) -> TokenStream { /// # Examples /// /// ```no_run -/// # #![expect(non_camel_case_types)] /// use aya_ebpf::{macros::fexit, programs::FExitContext}; +/// # #[expect(non_camel_case_types)] /// # type filename = u32; +/// # #[expect(non_camel_case_types)] /// # type path = u32; /// /// #[fexit(function = "filename_lookup")] @@ -658,7 +657,7 @@ pub fn flow_dissector(attrs: TokenStream, item: TokenStream) -> TokenStream { /// #[sk_lookup] /// pub fn accept_all(_ctx: SkLookupContext) -> u32 { /// // use sk_assign to redirect -/// return 0 +/// 0 /// } /// ``` #[proc_macro_attribute] @@ -688,7 +687,7 @@ pub fn sk_lookup(attrs: TokenStream, item: TokenStream) -> TokenStream { /// #[cgroup_device] /// pub fn cgroup_dev(ctx: DeviceContext) -> i32 { /// // Reject all device access -/// return 0; +/// 0 /// } /// ``` #[proc_macro_attribute] diff --git a/aya-ebpf-macros/src/perf_event.rs b/aya-ebpf-macros/src/perf_event.rs index 6b693f5a..1575495a 100644 --- a/aya-ebpf-macros/src/perf_event.rs +++ b/aya-ebpf-macros/src/perf_event.rs @@ -29,7 +29,7 @@ impl PerfEvent { #[unsafe(no_mangle)] #[unsafe(link_section = "perf_event")] #vis fn #fn_name(ctx: *mut ::core::ffi::c_void) -> u32 { - let _ = #fn_name(::aya_ebpf::programs::PerfEventContext::new(ctx)); + let _ = #fn_name(::aya_ebpf::programs::PerfEventContext::new(ctx.cast())); return 0; #item @@ -60,7 +60,7 @@ mod tests { #[unsafe(no_mangle)] #[unsafe(link_section = "perf_event")] fn foo(ctx: *mut ::core::ffi::c_void) -> u32 { - let _ = foo(::aya_ebpf::programs::PerfEventContext::new(ctx)); + let _ = foo(::aya_ebpf::programs::PerfEventContext::new(ctx.cast())); return 0; fn foo(ctx: PerfEventContext) -> i32 { diff --git a/aya-ebpf-macros/src/uprobe.rs b/aya-ebpf-macros/src/uprobe.rs index bc748635..8005c50c 100644 --- a/aya-ebpf-macros/src/uprobe.rs +++ b/aya-ebpf-macros/src/uprobe.rs @@ -15,10 +15,9 @@ pub(crate) enum UProbeKind { impl std::fmt::Display for UProbeKind { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - use UProbeKind::*; match self { - UProbe => write!(f, "uprobe"), - URetProbe => write!(f, "uretprobe"), + Self::UProbe => write!(f, "uprobe"), + Self::URetProbe => write!(f, "uretprobe"), } } } diff --git a/aya-log-common/CHANGELOG.md b/aya-log-common/CHANGELOG.md index e2e10823..4931914a 100644 --- a/aya-log-common/CHANGELOG.md +++ b/aya-log-common/CHANGELOG.md @@ -5,6 +5,23 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [Unreleased] + +## v0.1.16 (2025-11-17) + +### Breaking Changes + + - Updated the shared types for the new ring-buffer transport used by `aya-log`, aligning the user- and eBPF-side structures. + - Sealed the `Argument` trait so downstream crates can no longer implement log argument types. + +### New Features + + - Added support for logging raw pointer values, mirroring the new host-side formatting capabilities. + +### Maintenance + + - , General lint, edition, and formatting cleanups to keep the crate in line with the workspace standards. + ## 0.1.15 (2024-10-09) diff --git a/aya-log-common/Cargo.toml b/aya-log-common/Cargo.toml index 4ee9d9b2..246ff6e6 100644 --- a/aya-log-common/Cargo.toml +++ b/aya-log-common/Cargo.toml @@ -3,7 +3,7 @@ description = "A logging library for eBPF programs." documentation = "https://docs.rs/aya-log" keywords = ["bpf", "ebpf", "log", "logging"] name = "aya-log-common" -version = "0.1.15" +version = "0.1.16" authors.workspace = true edition.workspace = true diff --git a/aya-log-ebpf-macros/CHANGELOG.md b/aya-log-ebpf-macros/CHANGELOG.md index eb24e948..65e69800 100644 --- a/aya-log-ebpf-macros/CHANGELOG.md +++ b/aya-log-ebpf-macros/CHANGELOG.md @@ -5,6 +5,25 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [Unreleased] + +## v0.1.1 (2025-11-17) + +### Breaking Changes + + - Macros now emit ring-buffer based logging code to match the host transport, which requires kernel 5.8 or newer. + +### New Features + + - Added a load-time log level mask so unnecessary log calls can be compiled out entirely. + - Macros may now be used in expression position, simplifying complex logging statements. + - The generated code performs zero-copy writes into the ring buffer where possible, reducing instruction count inside probes. + - Added raw-pointer formatting support so eBPF logs can mirror host-side diagnostics. + +### Maintenance + + - , Tidied the macro support module and aligned the crate with the workspace lint/edition settings. + ## v0.1.0 (2024-04-12) diff --git a/aya-log-ebpf-macros/Cargo.toml b/aya-log-ebpf-macros/Cargo.toml index ff6aee04..40b3ec48 100644 --- a/aya-log-ebpf-macros/Cargo.toml +++ b/aya-log-ebpf-macros/Cargo.toml @@ -1,7 +1,7 @@ [package] description = "Proc macros used by aya-log-ebpf" name = "aya-log-ebpf-macros" -version = "0.1.0" +version = "0.1.1" authors.workspace = true edition.workspace = true @@ -14,8 +14,8 @@ rust-version.workspace = true workspace = true [dependencies] -aya-log-common = { path = "../aya-log-common", version = "^0.1.14", default-features = false } -aya-log-parser = { path = "../aya-log-parser", version = "^0.1.13", default-features = false } +aya-log-common = { path = "../aya-log-common", version = "^0.1.16", default-features = false } +aya-log-parser = { path = "../aya-log-parser", version = "^0.1.14", default-features = false } proc-macro2 = { workspace = true } quote = { workspace = true } syn = { workspace = true } diff --git a/aya-log-parser/CHANGELOG.md b/aya-log-parser/CHANGELOG.md index c419a2ab..f7df19fb 100644 --- a/aya-log-parser/CHANGELOG.md +++ b/aya-log-parser/CHANGELOG.md @@ -5,6 +5,19 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [Unreleased] + +## v0.1.14 (2025-11-17) + +### Improvements + + - Simplified the parser’s parameter handling so formatting errors are surfaced earlier and with clearer context. + - Added raw-pointer format support to stay in sync with the new logging capabilities. + +### Maintenance + + - , Bumped the edition and refreshed lint/formatting settings alongside the rest of the workspace. + ## v0.1.13 (2024-04-12) diff --git a/aya-log-parser/Cargo.toml b/aya-log-parser/Cargo.toml index 502ef3e1..24a7c0a1 100644 --- a/aya-log-parser/Cargo.toml +++ b/aya-log-parser/Cargo.toml @@ -1,7 +1,7 @@ [package] description = "A parser for the aya log format strings" name = "aya-log-parser" -version = "0.1.13" +version = "0.1.14" authors.workspace = true edition.workspace = true @@ -14,7 +14,7 @@ rust-version.workspace = true workspace = true [dependencies] -aya-log-common = { path = "../aya-log-common", version = "^0.1.14", default-features = false } +aya-log-common = { path = "../aya-log-common", version = "^0.1.16", default-features = false } [dev-dependencies] assert_matches = { workspace = true } diff --git a/aya-log/CHANGELOG.md b/aya-log/CHANGELOG.md index 5508046d..19581d2a 100644 --- a/aya-log/CHANGELOG.md +++ b/aya-log/CHANGELOG.md @@ -7,19 +7,18 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] -### New Features - -- Add eBPF-side log level `AYA_LOG_LEVEL` allowing selective disabling of log - levels at load-time. Disabled levels are eliminated by the verifier, reducing - instruction count and avoiding program size limits when extensive logging is - present. +## v0.2.2 (2025-11-17) ### Breaking Changes -- The implementation is now backed by a ring buffer rather than a perf event array. This should - improve performance but increases the minimum supported kernel version to 5.8. + - Host-side logging now rides on a ring buffer instead of a perf array. This improves throughput but requires Linux ≥ 5.8. + - Dropped the built-in `tokio` dependency. Consumers must bring their own async runtime when forwarding log records. + +### New Features -- Drop the built-in `tokio` dependency. Users must now BYOR (bring your own runtime). + - Added the `AYA_LOG_LEVEL` mask so unwanted log levels can be disabled at load time and optimised away by the verifier. + - `EbpfLogger` now implements `AsFd`, simplifying integration with selectors and event loops. + - Added support for logging raw pointer types, which unlocks richer debugging output from probes. ## v0.2.1 (2024-10-09) diff --git a/aya-log/Cargo.toml b/aya-log/Cargo.toml index d1e7234c..c9c438af 100644 --- a/aya-log/Cargo.toml +++ b/aya-log/Cargo.toml @@ -4,7 +4,7 @@ documentation = "https://docs.rs/aya-log" keywords = ["bpf", "ebpf", "log", "logging"] name = "aya-log" readme = "README.md" -version = "0.2.1" +version = "0.2.2" authors.workspace = true edition.workspace = true @@ -17,8 +17,8 @@ rust-version.workspace = true workspace = true [dependencies] -aya = { path = "../aya", version = "^0.13.1", default-features = false } -aya-log-common = { path = "../aya-log-common", version = "^0.1.15", default-features = false } +aya = { path = "../aya", version = "^0.13.2", default-features = false } +aya-log-common = { path = "../aya-log-common", version = "^0.1.16", default-features = false } log = { workspace = true } thiserror = { workspace = true } diff --git a/aya-obj/CHANGELOG.md b/aya-obj/CHANGELOG.md index ceadbb1c..fea33bb5 100644 --- a/aya-obj/CHANGELOG.md +++ b/aya-obj/CHANGELOG.md @@ -5,6 +5,25 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [Unreleased] + +## v0.2.2 (2025-11-17) + +### New Features + + - Updated the loader to understand Flow Dissector programs so objects containing those sections can now be parsed and attached. + - , Regenerated libbpf bindings, bringing in MIPS and LoongArch64 support. + - , Switched to generated constants and helper APIs (e.g. `CStr::from_bytes_until_nul`) for safer symbol handling. + +### Bug Fixes + + - , Fixed BTF relocations involving zero-sized sections and 64-bit enums so objects built with newer clang/jit toolchains load correctly. + - , Promoted BTF loading failures (and diagnostic output) to proper errors instead of panics/unreachable paths. + +### Maintenance + + - , Cached feature-probed info fields and preserved pointer provenance, plus the usual lint/edition updates to stay aligned with the workspace. + ## 0.2.1 (2024-11-01) ### New Features diff --git a/aya-obj/Cargo.toml b/aya-obj/Cargo.toml index c3056fe5..3a24ed5d 100644 --- a/aya-obj/Cargo.toml +++ b/aya-obj/Cargo.toml @@ -4,7 +4,7 @@ documentation = "https://docs.rs/aya-obj" keywords = ["bpf", "btf", "ebpf", "elf", "object"] name = "aya-obj" readme = "README.md" -version = "0.2.1" +version = "0.2.2" authors.workspace = true edition.workspace = true diff --git a/aya-obj/LICENSE-APACHE b/aya-obj/LICENSE-APACHE new file mode 120000 index 00000000..965b606f --- /dev/null +++ b/aya-obj/LICENSE-APACHE @@ -0,0 +1 @@ +../LICENSE-APACHE \ No newline at end of file diff --git a/aya-obj/LICENSE-MIT b/aya-obj/LICENSE-MIT new file mode 120000 index 00000000..76219eb7 --- /dev/null +++ b/aya-obj/LICENSE-MIT @@ -0,0 +1 @@ +../LICENSE-MIT \ No newline at end of file diff --git a/aya-obj/include/linux_wrapper.h b/aya-obj/include/linux_wrapper.h index fe9498f8..9123cf02 100644 --- a/aya-obj/include/linux_wrapper.h +++ b/aya-obj/include/linux_wrapper.h @@ -1,5 +1,6 @@ #include #include +#include #include #include #include diff --git a/aya-obj/src/generated/linux_bindings_aarch64.rs b/aya-obj/src/generated/linux_bindings_aarch64.rs index b76ed850..aff50e13 100644 --- a/aya-obj/src/generated/linux_bindings_aarch64.rs +++ b/aya-obj/src/generated/linux_bindings_aarch64.rs @@ -2105,6 +2105,22 @@ pub struct btf_var_secinfo { pub struct btf_decl_tag { pub component_idx: __s32, } +pub const HW_BREAKPOINT_LEN_1: _bindgen_ty_44 = 1; +pub const HW_BREAKPOINT_LEN_2: _bindgen_ty_44 = 2; +pub const HW_BREAKPOINT_LEN_3: _bindgen_ty_44 = 3; +pub const HW_BREAKPOINT_LEN_4: _bindgen_ty_44 = 4; +pub const HW_BREAKPOINT_LEN_5: _bindgen_ty_44 = 5; +pub const HW_BREAKPOINT_LEN_6: _bindgen_ty_44 = 6; +pub const HW_BREAKPOINT_LEN_7: _bindgen_ty_44 = 7; +pub const HW_BREAKPOINT_LEN_8: _bindgen_ty_44 = 8; +pub type _bindgen_ty_44 = ::core::ffi::c_uint; +pub const HW_BREAKPOINT_EMPTY: _bindgen_ty_45 = 0; +pub const HW_BREAKPOINT_R: _bindgen_ty_45 = 1; +pub const HW_BREAKPOINT_W: _bindgen_ty_45 = 2; +pub const HW_BREAKPOINT_RW: _bindgen_ty_45 = 3; +pub const HW_BREAKPOINT_X: _bindgen_ty_45 = 4; +pub const HW_BREAKPOINT_INVALID: _bindgen_ty_45 = 7; +pub type _bindgen_ty_45 = ::core::ffi::c_uint; impl nlmsgerr_attrs { pub const NLMSGERR_ATTR_MAX: nlmsgerr_attrs = nlmsgerr_attrs::NLMSGERR_ATTR_COOKIE; } @@ -2117,17 +2133,17 @@ pub enum nlmsgerr_attrs { NLMSGERR_ATTR_COOKIE = 3, __NLMSGERR_ATTR_MAX = 4, } -pub const IFLA_XDP_UNSPEC: _bindgen_ty_92 = 0; -pub const IFLA_XDP_FD: _bindgen_ty_92 = 1; -pub const IFLA_XDP_ATTACHED: _bindgen_ty_92 = 2; -pub const IFLA_XDP_FLAGS: _bindgen_ty_92 = 3; -pub const IFLA_XDP_PROG_ID: _bindgen_ty_92 = 4; -pub const IFLA_XDP_DRV_PROG_ID: _bindgen_ty_92 = 5; -pub const IFLA_XDP_SKB_PROG_ID: _bindgen_ty_92 = 6; -pub const IFLA_XDP_HW_PROG_ID: _bindgen_ty_92 = 7; -pub const IFLA_XDP_EXPECTED_FD: _bindgen_ty_92 = 8; -pub const __IFLA_XDP_MAX: _bindgen_ty_92 = 9; -pub type _bindgen_ty_92 = ::core::ffi::c_uint; +pub const IFLA_XDP_UNSPEC: _bindgen_ty_94 = 0; +pub const IFLA_XDP_FD: _bindgen_ty_94 = 1; +pub const IFLA_XDP_ATTACHED: _bindgen_ty_94 = 2; +pub const IFLA_XDP_FLAGS: _bindgen_ty_94 = 3; +pub const IFLA_XDP_PROG_ID: _bindgen_ty_94 = 4; +pub const IFLA_XDP_DRV_PROG_ID: _bindgen_ty_94 = 5; +pub const IFLA_XDP_SKB_PROG_ID: _bindgen_ty_94 = 6; +pub const IFLA_XDP_HW_PROG_ID: _bindgen_ty_94 = 7; +pub const IFLA_XDP_EXPECTED_FD: _bindgen_ty_94 = 8; +pub const __IFLA_XDP_MAX: _bindgen_ty_94 = 9; +pub type _bindgen_ty_94 = ::core::ffi::c_uint; impl nf_inet_hooks { pub const NF_INET_INGRESS: nf_inet_hooks = nf_inet_hooks::NF_INET_NUMHOOKS; } @@ -2141,16 +2157,16 @@ pub enum nf_inet_hooks { NF_INET_POST_ROUTING = 4, NF_INET_NUMHOOKS = 5, } -pub const NFPROTO_UNSPEC: _bindgen_ty_99 = 0; -pub const NFPROTO_INET: _bindgen_ty_99 = 1; -pub const NFPROTO_IPV4: _bindgen_ty_99 = 2; -pub const NFPROTO_ARP: _bindgen_ty_99 = 3; -pub const NFPROTO_NETDEV: _bindgen_ty_99 = 5; -pub const NFPROTO_BRIDGE: _bindgen_ty_99 = 7; -pub const NFPROTO_IPV6: _bindgen_ty_99 = 10; -pub const NFPROTO_DECNET: _bindgen_ty_99 = 12; -pub const NFPROTO_NUMPROTO: _bindgen_ty_99 = 13; -pub type _bindgen_ty_99 = ::core::ffi::c_uint; +pub const NFPROTO_UNSPEC: _bindgen_ty_101 = 0; +pub const NFPROTO_INET: _bindgen_ty_101 = 1; +pub const NFPROTO_IPV4: _bindgen_ty_101 = 2; +pub const NFPROTO_ARP: _bindgen_ty_101 = 3; +pub const NFPROTO_NETDEV: _bindgen_ty_101 = 5; +pub const NFPROTO_BRIDGE: _bindgen_ty_101 = 7; +pub const NFPROTO_IPV6: _bindgen_ty_101 = 10; +pub const NFPROTO_DECNET: _bindgen_ty_101 = 12; +pub const NFPROTO_NUMPROTO: _bindgen_ty_101 = 13; +pub type _bindgen_ty_101 = ::core::ffi::c_uint; #[repr(u32)] #[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] pub enum perf_type_id { @@ -4111,20 +4127,20 @@ pub enum perf_event_type { PERF_RECORD_AUX_OUTPUT_HW_ID = 21, PERF_RECORD_MAX = 22, } -pub const TCA_BPF_UNSPEC: _bindgen_ty_154 = 0; -pub const TCA_BPF_ACT: _bindgen_ty_154 = 1; -pub const TCA_BPF_POLICE: _bindgen_ty_154 = 2; -pub const TCA_BPF_CLASSID: _bindgen_ty_154 = 3; -pub const TCA_BPF_OPS_LEN: _bindgen_ty_154 = 4; -pub const TCA_BPF_OPS: _bindgen_ty_154 = 5; -pub const TCA_BPF_FD: _bindgen_ty_154 = 6; -pub const TCA_BPF_NAME: _bindgen_ty_154 = 7; -pub const TCA_BPF_FLAGS: _bindgen_ty_154 = 8; -pub const TCA_BPF_FLAGS_GEN: _bindgen_ty_154 = 9; -pub const TCA_BPF_TAG: _bindgen_ty_154 = 10; -pub const TCA_BPF_ID: _bindgen_ty_154 = 11; -pub const __TCA_BPF_MAX: _bindgen_ty_154 = 12; -pub type _bindgen_ty_154 = ::core::ffi::c_uint; +pub const TCA_BPF_UNSPEC: _bindgen_ty_156 = 0; +pub const TCA_BPF_ACT: _bindgen_ty_156 = 1; +pub const TCA_BPF_POLICE: _bindgen_ty_156 = 2; +pub const TCA_BPF_CLASSID: _bindgen_ty_156 = 3; +pub const TCA_BPF_OPS_LEN: _bindgen_ty_156 = 4; +pub const TCA_BPF_OPS: _bindgen_ty_156 = 5; +pub const TCA_BPF_FD: _bindgen_ty_156 = 6; +pub const TCA_BPF_NAME: _bindgen_ty_156 = 7; +pub const TCA_BPF_FLAGS: _bindgen_ty_156 = 8; +pub const TCA_BPF_FLAGS_GEN: _bindgen_ty_156 = 9; +pub const TCA_BPF_TAG: _bindgen_ty_156 = 10; +pub const TCA_BPF_ID: _bindgen_ty_156 = 11; +pub const __TCA_BPF_MAX: _bindgen_ty_156 = 12; +pub type _bindgen_ty_156 = ::core::ffi::c_uint; #[repr(C)] #[derive(Debug, Copy, Clone)] pub struct ifinfomsg { @@ -4146,22 +4162,22 @@ pub struct tcmsg { pub tcm_parent: __u32, pub tcm_info: __u32, } -pub const TCA_UNSPEC: _bindgen_ty_174 = 0; -pub const TCA_KIND: _bindgen_ty_174 = 1; -pub const TCA_OPTIONS: _bindgen_ty_174 = 2; -pub const TCA_STATS: _bindgen_ty_174 = 3; -pub const TCA_XSTATS: _bindgen_ty_174 = 4; -pub const TCA_RATE: _bindgen_ty_174 = 5; -pub const TCA_FCNT: _bindgen_ty_174 = 6; -pub const TCA_STATS2: _bindgen_ty_174 = 7; -pub const TCA_STAB: _bindgen_ty_174 = 8; -pub const TCA_PAD: _bindgen_ty_174 = 9; -pub const TCA_DUMP_INVISIBLE: _bindgen_ty_174 = 10; -pub const TCA_CHAIN: _bindgen_ty_174 = 11; -pub const TCA_HW_OFFLOAD: _bindgen_ty_174 = 12; -pub const TCA_INGRESS_BLOCK: _bindgen_ty_174 = 13; -pub const TCA_EGRESS_BLOCK: _bindgen_ty_174 = 14; -pub const TCA_DUMP_FLAGS: _bindgen_ty_174 = 15; -pub const TCA_EXT_WARN_MSG: _bindgen_ty_174 = 16; -pub const __TCA_MAX: _bindgen_ty_174 = 17; -pub type _bindgen_ty_174 = ::core::ffi::c_uint; +pub const TCA_UNSPEC: _bindgen_ty_176 = 0; +pub const TCA_KIND: _bindgen_ty_176 = 1; +pub const TCA_OPTIONS: _bindgen_ty_176 = 2; +pub const TCA_STATS: _bindgen_ty_176 = 3; +pub const TCA_XSTATS: _bindgen_ty_176 = 4; +pub const TCA_RATE: _bindgen_ty_176 = 5; +pub const TCA_FCNT: _bindgen_ty_176 = 6; +pub const TCA_STATS2: _bindgen_ty_176 = 7; +pub const TCA_STAB: _bindgen_ty_176 = 8; +pub const TCA_PAD: _bindgen_ty_176 = 9; +pub const TCA_DUMP_INVISIBLE: _bindgen_ty_176 = 10; +pub const TCA_CHAIN: _bindgen_ty_176 = 11; +pub const TCA_HW_OFFLOAD: _bindgen_ty_176 = 12; +pub const TCA_INGRESS_BLOCK: _bindgen_ty_176 = 13; +pub const TCA_EGRESS_BLOCK: _bindgen_ty_176 = 14; +pub const TCA_DUMP_FLAGS: _bindgen_ty_176 = 15; +pub const TCA_EXT_WARN_MSG: _bindgen_ty_176 = 16; +pub const __TCA_MAX: _bindgen_ty_176 = 17; +pub type _bindgen_ty_176 = ::core::ffi::c_uint; diff --git a/aya-obj/src/generated/linux_bindings_armv7.rs b/aya-obj/src/generated/linux_bindings_armv7.rs index 08b3a162..ae0a1da4 100644 --- a/aya-obj/src/generated/linux_bindings_armv7.rs +++ b/aya-obj/src/generated/linux_bindings_armv7.rs @@ -2105,6 +2105,22 @@ pub struct btf_var_secinfo { pub struct btf_decl_tag { pub component_idx: __s32, } +pub const HW_BREAKPOINT_LEN_1: _bindgen_ty_44 = 1; +pub const HW_BREAKPOINT_LEN_2: _bindgen_ty_44 = 2; +pub const HW_BREAKPOINT_LEN_3: _bindgen_ty_44 = 3; +pub const HW_BREAKPOINT_LEN_4: _bindgen_ty_44 = 4; +pub const HW_BREAKPOINT_LEN_5: _bindgen_ty_44 = 5; +pub const HW_BREAKPOINT_LEN_6: _bindgen_ty_44 = 6; +pub const HW_BREAKPOINT_LEN_7: _bindgen_ty_44 = 7; +pub const HW_BREAKPOINT_LEN_8: _bindgen_ty_44 = 8; +pub type _bindgen_ty_44 = ::core::ffi::c_uint; +pub const HW_BREAKPOINT_EMPTY: _bindgen_ty_45 = 0; +pub const HW_BREAKPOINT_R: _bindgen_ty_45 = 1; +pub const HW_BREAKPOINT_W: _bindgen_ty_45 = 2; +pub const HW_BREAKPOINT_RW: _bindgen_ty_45 = 3; +pub const HW_BREAKPOINT_X: _bindgen_ty_45 = 4; +pub const HW_BREAKPOINT_INVALID: _bindgen_ty_45 = 7; +pub type _bindgen_ty_45 = ::core::ffi::c_uint; impl nlmsgerr_attrs { pub const NLMSGERR_ATTR_MAX: nlmsgerr_attrs = nlmsgerr_attrs::NLMSGERR_ATTR_COOKIE; } @@ -2117,17 +2133,17 @@ pub enum nlmsgerr_attrs { NLMSGERR_ATTR_COOKIE = 3, __NLMSGERR_ATTR_MAX = 4, } -pub const IFLA_XDP_UNSPEC: _bindgen_ty_92 = 0; -pub const IFLA_XDP_FD: _bindgen_ty_92 = 1; -pub const IFLA_XDP_ATTACHED: _bindgen_ty_92 = 2; -pub const IFLA_XDP_FLAGS: _bindgen_ty_92 = 3; -pub const IFLA_XDP_PROG_ID: _bindgen_ty_92 = 4; -pub const IFLA_XDP_DRV_PROG_ID: _bindgen_ty_92 = 5; -pub const IFLA_XDP_SKB_PROG_ID: _bindgen_ty_92 = 6; -pub const IFLA_XDP_HW_PROG_ID: _bindgen_ty_92 = 7; -pub const IFLA_XDP_EXPECTED_FD: _bindgen_ty_92 = 8; -pub const __IFLA_XDP_MAX: _bindgen_ty_92 = 9; -pub type _bindgen_ty_92 = ::core::ffi::c_uint; +pub const IFLA_XDP_UNSPEC: _bindgen_ty_94 = 0; +pub const IFLA_XDP_FD: _bindgen_ty_94 = 1; +pub const IFLA_XDP_ATTACHED: _bindgen_ty_94 = 2; +pub const IFLA_XDP_FLAGS: _bindgen_ty_94 = 3; +pub const IFLA_XDP_PROG_ID: _bindgen_ty_94 = 4; +pub const IFLA_XDP_DRV_PROG_ID: _bindgen_ty_94 = 5; +pub const IFLA_XDP_SKB_PROG_ID: _bindgen_ty_94 = 6; +pub const IFLA_XDP_HW_PROG_ID: _bindgen_ty_94 = 7; +pub const IFLA_XDP_EXPECTED_FD: _bindgen_ty_94 = 8; +pub const __IFLA_XDP_MAX: _bindgen_ty_94 = 9; +pub type _bindgen_ty_94 = ::core::ffi::c_uint; impl nf_inet_hooks { pub const NF_INET_INGRESS: nf_inet_hooks = nf_inet_hooks::NF_INET_NUMHOOKS; } @@ -2141,16 +2157,16 @@ pub enum nf_inet_hooks { NF_INET_POST_ROUTING = 4, NF_INET_NUMHOOKS = 5, } -pub const NFPROTO_UNSPEC: _bindgen_ty_99 = 0; -pub const NFPROTO_INET: _bindgen_ty_99 = 1; -pub const NFPROTO_IPV4: _bindgen_ty_99 = 2; -pub const NFPROTO_ARP: _bindgen_ty_99 = 3; -pub const NFPROTO_NETDEV: _bindgen_ty_99 = 5; -pub const NFPROTO_BRIDGE: _bindgen_ty_99 = 7; -pub const NFPROTO_IPV6: _bindgen_ty_99 = 10; -pub const NFPROTO_DECNET: _bindgen_ty_99 = 12; -pub const NFPROTO_NUMPROTO: _bindgen_ty_99 = 13; -pub type _bindgen_ty_99 = ::core::ffi::c_uint; +pub const NFPROTO_UNSPEC: _bindgen_ty_101 = 0; +pub const NFPROTO_INET: _bindgen_ty_101 = 1; +pub const NFPROTO_IPV4: _bindgen_ty_101 = 2; +pub const NFPROTO_ARP: _bindgen_ty_101 = 3; +pub const NFPROTO_NETDEV: _bindgen_ty_101 = 5; +pub const NFPROTO_BRIDGE: _bindgen_ty_101 = 7; +pub const NFPROTO_IPV6: _bindgen_ty_101 = 10; +pub const NFPROTO_DECNET: _bindgen_ty_101 = 12; +pub const NFPROTO_NUMPROTO: _bindgen_ty_101 = 13; +pub type _bindgen_ty_101 = ::core::ffi::c_uint; #[repr(u32)] #[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] pub enum perf_type_id { @@ -4111,20 +4127,20 @@ pub enum perf_event_type { PERF_RECORD_AUX_OUTPUT_HW_ID = 21, PERF_RECORD_MAX = 22, } -pub const TCA_BPF_UNSPEC: _bindgen_ty_154 = 0; -pub const TCA_BPF_ACT: _bindgen_ty_154 = 1; -pub const TCA_BPF_POLICE: _bindgen_ty_154 = 2; -pub const TCA_BPF_CLASSID: _bindgen_ty_154 = 3; -pub const TCA_BPF_OPS_LEN: _bindgen_ty_154 = 4; -pub const TCA_BPF_OPS: _bindgen_ty_154 = 5; -pub const TCA_BPF_FD: _bindgen_ty_154 = 6; -pub const TCA_BPF_NAME: _bindgen_ty_154 = 7; -pub const TCA_BPF_FLAGS: _bindgen_ty_154 = 8; -pub const TCA_BPF_FLAGS_GEN: _bindgen_ty_154 = 9; -pub const TCA_BPF_TAG: _bindgen_ty_154 = 10; -pub const TCA_BPF_ID: _bindgen_ty_154 = 11; -pub const __TCA_BPF_MAX: _bindgen_ty_154 = 12; -pub type _bindgen_ty_154 = ::core::ffi::c_uint; +pub const TCA_BPF_UNSPEC: _bindgen_ty_156 = 0; +pub const TCA_BPF_ACT: _bindgen_ty_156 = 1; +pub const TCA_BPF_POLICE: _bindgen_ty_156 = 2; +pub const TCA_BPF_CLASSID: _bindgen_ty_156 = 3; +pub const TCA_BPF_OPS_LEN: _bindgen_ty_156 = 4; +pub const TCA_BPF_OPS: _bindgen_ty_156 = 5; +pub const TCA_BPF_FD: _bindgen_ty_156 = 6; +pub const TCA_BPF_NAME: _bindgen_ty_156 = 7; +pub const TCA_BPF_FLAGS: _bindgen_ty_156 = 8; +pub const TCA_BPF_FLAGS_GEN: _bindgen_ty_156 = 9; +pub const TCA_BPF_TAG: _bindgen_ty_156 = 10; +pub const TCA_BPF_ID: _bindgen_ty_156 = 11; +pub const __TCA_BPF_MAX: _bindgen_ty_156 = 12; +pub type _bindgen_ty_156 = ::core::ffi::c_uint; #[repr(C)] #[derive(Debug, Copy, Clone)] pub struct ifinfomsg { @@ -4146,22 +4162,22 @@ pub struct tcmsg { pub tcm_parent: __u32, pub tcm_info: __u32, } -pub const TCA_UNSPEC: _bindgen_ty_174 = 0; -pub const TCA_KIND: _bindgen_ty_174 = 1; -pub const TCA_OPTIONS: _bindgen_ty_174 = 2; -pub const TCA_STATS: _bindgen_ty_174 = 3; -pub const TCA_XSTATS: _bindgen_ty_174 = 4; -pub const TCA_RATE: _bindgen_ty_174 = 5; -pub const TCA_FCNT: _bindgen_ty_174 = 6; -pub const TCA_STATS2: _bindgen_ty_174 = 7; -pub const TCA_STAB: _bindgen_ty_174 = 8; -pub const TCA_PAD: _bindgen_ty_174 = 9; -pub const TCA_DUMP_INVISIBLE: _bindgen_ty_174 = 10; -pub const TCA_CHAIN: _bindgen_ty_174 = 11; -pub const TCA_HW_OFFLOAD: _bindgen_ty_174 = 12; -pub const TCA_INGRESS_BLOCK: _bindgen_ty_174 = 13; -pub const TCA_EGRESS_BLOCK: _bindgen_ty_174 = 14; -pub const TCA_DUMP_FLAGS: _bindgen_ty_174 = 15; -pub const TCA_EXT_WARN_MSG: _bindgen_ty_174 = 16; -pub const __TCA_MAX: _bindgen_ty_174 = 17; -pub type _bindgen_ty_174 = ::core::ffi::c_uint; +pub const TCA_UNSPEC: _bindgen_ty_176 = 0; +pub const TCA_KIND: _bindgen_ty_176 = 1; +pub const TCA_OPTIONS: _bindgen_ty_176 = 2; +pub const TCA_STATS: _bindgen_ty_176 = 3; +pub const TCA_XSTATS: _bindgen_ty_176 = 4; +pub const TCA_RATE: _bindgen_ty_176 = 5; +pub const TCA_FCNT: _bindgen_ty_176 = 6; +pub const TCA_STATS2: _bindgen_ty_176 = 7; +pub const TCA_STAB: _bindgen_ty_176 = 8; +pub const TCA_PAD: _bindgen_ty_176 = 9; +pub const TCA_DUMP_INVISIBLE: _bindgen_ty_176 = 10; +pub const TCA_CHAIN: _bindgen_ty_176 = 11; +pub const TCA_HW_OFFLOAD: _bindgen_ty_176 = 12; +pub const TCA_INGRESS_BLOCK: _bindgen_ty_176 = 13; +pub const TCA_EGRESS_BLOCK: _bindgen_ty_176 = 14; +pub const TCA_DUMP_FLAGS: _bindgen_ty_176 = 15; +pub const TCA_EXT_WARN_MSG: _bindgen_ty_176 = 16; +pub const __TCA_MAX: _bindgen_ty_176 = 17; +pub type _bindgen_ty_176 = ::core::ffi::c_uint; diff --git a/aya-obj/src/generated/linux_bindings_loongarch64.rs b/aya-obj/src/generated/linux_bindings_loongarch64.rs index b76ed850..aff50e13 100644 --- a/aya-obj/src/generated/linux_bindings_loongarch64.rs +++ b/aya-obj/src/generated/linux_bindings_loongarch64.rs @@ -2105,6 +2105,22 @@ pub struct btf_var_secinfo { pub struct btf_decl_tag { pub component_idx: __s32, } +pub const HW_BREAKPOINT_LEN_1: _bindgen_ty_44 = 1; +pub const HW_BREAKPOINT_LEN_2: _bindgen_ty_44 = 2; +pub const HW_BREAKPOINT_LEN_3: _bindgen_ty_44 = 3; +pub const HW_BREAKPOINT_LEN_4: _bindgen_ty_44 = 4; +pub const HW_BREAKPOINT_LEN_5: _bindgen_ty_44 = 5; +pub const HW_BREAKPOINT_LEN_6: _bindgen_ty_44 = 6; +pub const HW_BREAKPOINT_LEN_7: _bindgen_ty_44 = 7; +pub const HW_BREAKPOINT_LEN_8: _bindgen_ty_44 = 8; +pub type _bindgen_ty_44 = ::core::ffi::c_uint; +pub const HW_BREAKPOINT_EMPTY: _bindgen_ty_45 = 0; +pub const HW_BREAKPOINT_R: _bindgen_ty_45 = 1; +pub const HW_BREAKPOINT_W: _bindgen_ty_45 = 2; +pub const HW_BREAKPOINT_RW: _bindgen_ty_45 = 3; +pub const HW_BREAKPOINT_X: _bindgen_ty_45 = 4; +pub const HW_BREAKPOINT_INVALID: _bindgen_ty_45 = 7; +pub type _bindgen_ty_45 = ::core::ffi::c_uint; impl nlmsgerr_attrs { pub const NLMSGERR_ATTR_MAX: nlmsgerr_attrs = nlmsgerr_attrs::NLMSGERR_ATTR_COOKIE; } @@ -2117,17 +2133,17 @@ pub enum nlmsgerr_attrs { NLMSGERR_ATTR_COOKIE = 3, __NLMSGERR_ATTR_MAX = 4, } -pub const IFLA_XDP_UNSPEC: _bindgen_ty_92 = 0; -pub const IFLA_XDP_FD: _bindgen_ty_92 = 1; -pub const IFLA_XDP_ATTACHED: _bindgen_ty_92 = 2; -pub const IFLA_XDP_FLAGS: _bindgen_ty_92 = 3; -pub const IFLA_XDP_PROG_ID: _bindgen_ty_92 = 4; -pub const IFLA_XDP_DRV_PROG_ID: _bindgen_ty_92 = 5; -pub const IFLA_XDP_SKB_PROG_ID: _bindgen_ty_92 = 6; -pub const IFLA_XDP_HW_PROG_ID: _bindgen_ty_92 = 7; -pub const IFLA_XDP_EXPECTED_FD: _bindgen_ty_92 = 8; -pub const __IFLA_XDP_MAX: _bindgen_ty_92 = 9; -pub type _bindgen_ty_92 = ::core::ffi::c_uint; +pub const IFLA_XDP_UNSPEC: _bindgen_ty_94 = 0; +pub const IFLA_XDP_FD: _bindgen_ty_94 = 1; +pub const IFLA_XDP_ATTACHED: _bindgen_ty_94 = 2; +pub const IFLA_XDP_FLAGS: _bindgen_ty_94 = 3; +pub const IFLA_XDP_PROG_ID: _bindgen_ty_94 = 4; +pub const IFLA_XDP_DRV_PROG_ID: _bindgen_ty_94 = 5; +pub const IFLA_XDP_SKB_PROG_ID: _bindgen_ty_94 = 6; +pub const IFLA_XDP_HW_PROG_ID: _bindgen_ty_94 = 7; +pub const IFLA_XDP_EXPECTED_FD: _bindgen_ty_94 = 8; +pub const __IFLA_XDP_MAX: _bindgen_ty_94 = 9; +pub type _bindgen_ty_94 = ::core::ffi::c_uint; impl nf_inet_hooks { pub const NF_INET_INGRESS: nf_inet_hooks = nf_inet_hooks::NF_INET_NUMHOOKS; } @@ -2141,16 +2157,16 @@ pub enum nf_inet_hooks { NF_INET_POST_ROUTING = 4, NF_INET_NUMHOOKS = 5, } -pub const NFPROTO_UNSPEC: _bindgen_ty_99 = 0; -pub const NFPROTO_INET: _bindgen_ty_99 = 1; -pub const NFPROTO_IPV4: _bindgen_ty_99 = 2; -pub const NFPROTO_ARP: _bindgen_ty_99 = 3; -pub const NFPROTO_NETDEV: _bindgen_ty_99 = 5; -pub const NFPROTO_BRIDGE: _bindgen_ty_99 = 7; -pub const NFPROTO_IPV6: _bindgen_ty_99 = 10; -pub const NFPROTO_DECNET: _bindgen_ty_99 = 12; -pub const NFPROTO_NUMPROTO: _bindgen_ty_99 = 13; -pub type _bindgen_ty_99 = ::core::ffi::c_uint; +pub const NFPROTO_UNSPEC: _bindgen_ty_101 = 0; +pub const NFPROTO_INET: _bindgen_ty_101 = 1; +pub const NFPROTO_IPV4: _bindgen_ty_101 = 2; +pub const NFPROTO_ARP: _bindgen_ty_101 = 3; +pub const NFPROTO_NETDEV: _bindgen_ty_101 = 5; +pub const NFPROTO_BRIDGE: _bindgen_ty_101 = 7; +pub const NFPROTO_IPV6: _bindgen_ty_101 = 10; +pub const NFPROTO_DECNET: _bindgen_ty_101 = 12; +pub const NFPROTO_NUMPROTO: _bindgen_ty_101 = 13; +pub type _bindgen_ty_101 = ::core::ffi::c_uint; #[repr(u32)] #[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] pub enum perf_type_id { @@ -4111,20 +4127,20 @@ pub enum perf_event_type { PERF_RECORD_AUX_OUTPUT_HW_ID = 21, PERF_RECORD_MAX = 22, } -pub const TCA_BPF_UNSPEC: _bindgen_ty_154 = 0; -pub const TCA_BPF_ACT: _bindgen_ty_154 = 1; -pub const TCA_BPF_POLICE: _bindgen_ty_154 = 2; -pub const TCA_BPF_CLASSID: _bindgen_ty_154 = 3; -pub const TCA_BPF_OPS_LEN: _bindgen_ty_154 = 4; -pub const TCA_BPF_OPS: _bindgen_ty_154 = 5; -pub const TCA_BPF_FD: _bindgen_ty_154 = 6; -pub const TCA_BPF_NAME: _bindgen_ty_154 = 7; -pub const TCA_BPF_FLAGS: _bindgen_ty_154 = 8; -pub const TCA_BPF_FLAGS_GEN: _bindgen_ty_154 = 9; -pub const TCA_BPF_TAG: _bindgen_ty_154 = 10; -pub const TCA_BPF_ID: _bindgen_ty_154 = 11; -pub const __TCA_BPF_MAX: _bindgen_ty_154 = 12; -pub type _bindgen_ty_154 = ::core::ffi::c_uint; +pub const TCA_BPF_UNSPEC: _bindgen_ty_156 = 0; +pub const TCA_BPF_ACT: _bindgen_ty_156 = 1; +pub const TCA_BPF_POLICE: _bindgen_ty_156 = 2; +pub const TCA_BPF_CLASSID: _bindgen_ty_156 = 3; +pub const TCA_BPF_OPS_LEN: _bindgen_ty_156 = 4; +pub const TCA_BPF_OPS: _bindgen_ty_156 = 5; +pub const TCA_BPF_FD: _bindgen_ty_156 = 6; +pub const TCA_BPF_NAME: _bindgen_ty_156 = 7; +pub const TCA_BPF_FLAGS: _bindgen_ty_156 = 8; +pub const TCA_BPF_FLAGS_GEN: _bindgen_ty_156 = 9; +pub const TCA_BPF_TAG: _bindgen_ty_156 = 10; +pub const TCA_BPF_ID: _bindgen_ty_156 = 11; +pub const __TCA_BPF_MAX: _bindgen_ty_156 = 12; +pub type _bindgen_ty_156 = ::core::ffi::c_uint; #[repr(C)] #[derive(Debug, Copy, Clone)] pub struct ifinfomsg { @@ -4146,22 +4162,22 @@ pub struct tcmsg { pub tcm_parent: __u32, pub tcm_info: __u32, } -pub const TCA_UNSPEC: _bindgen_ty_174 = 0; -pub const TCA_KIND: _bindgen_ty_174 = 1; -pub const TCA_OPTIONS: _bindgen_ty_174 = 2; -pub const TCA_STATS: _bindgen_ty_174 = 3; -pub const TCA_XSTATS: _bindgen_ty_174 = 4; -pub const TCA_RATE: _bindgen_ty_174 = 5; -pub const TCA_FCNT: _bindgen_ty_174 = 6; -pub const TCA_STATS2: _bindgen_ty_174 = 7; -pub const TCA_STAB: _bindgen_ty_174 = 8; -pub const TCA_PAD: _bindgen_ty_174 = 9; -pub const TCA_DUMP_INVISIBLE: _bindgen_ty_174 = 10; -pub const TCA_CHAIN: _bindgen_ty_174 = 11; -pub const TCA_HW_OFFLOAD: _bindgen_ty_174 = 12; -pub const TCA_INGRESS_BLOCK: _bindgen_ty_174 = 13; -pub const TCA_EGRESS_BLOCK: _bindgen_ty_174 = 14; -pub const TCA_DUMP_FLAGS: _bindgen_ty_174 = 15; -pub const TCA_EXT_WARN_MSG: _bindgen_ty_174 = 16; -pub const __TCA_MAX: _bindgen_ty_174 = 17; -pub type _bindgen_ty_174 = ::core::ffi::c_uint; +pub const TCA_UNSPEC: _bindgen_ty_176 = 0; +pub const TCA_KIND: _bindgen_ty_176 = 1; +pub const TCA_OPTIONS: _bindgen_ty_176 = 2; +pub const TCA_STATS: _bindgen_ty_176 = 3; +pub const TCA_XSTATS: _bindgen_ty_176 = 4; +pub const TCA_RATE: _bindgen_ty_176 = 5; +pub const TCA_FCNT: _bindgen_ty_176 = 6; +pub const TCA_STATS2: _bindgen_ty_176 = 7; +pub const TCA_STAB: _bindgen_ty_176 = 8; +pub const TCA_PAD: _bindgen_ty_176 = 9; +pub const TCA_DUMP_INVISIBLE: _bindgen_ty_176 = 10; +pub const TCA_CHAIN: _bindgen_ty_176 = 11; +pub const TCA_HW_OFFLOAD: _bindgen_ty_176 = 12; +pub const TCA_INGRESS_BLOCK: _bindgen_ty_176 = 13; +pub const TCA_EGRESS_BLOCK: _bindgen_ty_176 = 14; +pub const TCA_DUMP_FLAGS: _bindgen_ty_176 = 15; +pub const TCA_EXT_WARN_MSG: _bindgen_ty_176 = 16; +pub const __TCA_MAX: _bindgen_ty_176 = 17; +pub type _bindgen_ty_176 = ::core::ffi::c_uint; diff --git a/aya-obj/src/generated/linux_bindings_mips.rs b/aya-obj/src/generated/linux_bindings_mips.rs index 349653d7..f3ae9b95 100644 --- a/aya-obj/src/generated/linux_bindings_mips.rs +++ b/aya-obj/src/generated/linux_bindings_mips.rs @@ -2105,6 +2105,22 @@ pub struct btf_var_secinfo { pub struct btf_decl_tag { pub component_idx: __s32, } +pub const HW_BREAKPOINT_LEN_1: _bindgen_ty_44 = 1; +pub const HW_BREAKPOINT_LEN_2: _bindgen_ty_44 = 2; +pub const HW_BREAKPOINT_LEN_3: _bindgen_ty_44 = 3; +pub const HW_BREAKPOINT_LEN_4: _bindgen_ty_44 = 4; +pub const HW_BREAKPOINT_LEN_5: _bindgen_ty_44 = 5; +pub const HW_BREAKPOINT_LEN_6: _bindgen_ty_44 = 6; +pub const HW_BREAKPOINT_LEN_7: _bindgen_ty_44 = 7; +pub const HW_BREAKPOINT_LEN_8: _bindgen_ty_44 = 8; +pub type _bindgen_ty_44 = ::core::ffi::c_uint; +pub const HW_BREAKPOINT_EMPTY: _bindgen_ty_45 = 0; +pub const HW_BREAKPOINT_R: _bindgen_ty_45 = 1; +pub const HW_BREAKPOINT_W: _bindgen_ty_45 = 2; +pub const HW_BREAKPOINT_RW: _bindgen_ty_45 = 3; +pub const HW_BREAKPOINT_X: _bindgen_ty_45 = 4; +pub const HW_BREAKPOINT_INVALID: _bindgen_ty_45 = 7; +pub type _bindgen_ty_45 = ::core::ffi::c_uint; impl nlmsgerr_attrs { pub const NLMSGERR_ATTR_MAX: nlmsgerr_attrs = nlmsgerr_attrs::NLMSGERR_ATTR_COOKIE; } @@ -2117,17 +2133,17 @@ pub enum nlmsgerr_attrs { NLMSGERR_ATTR_COOKIE = 3, __NLMSGERR_ATTR_MAX = 4, } -pub const IFLA_XDP_UNSPEC: _bindgen_ty_92 = 0; -pub const IFLA_XDP_FD: _bindgen_ty_92 = 1; -pub const IFLA_XDP_ATTACHED: _bindgen_ty_92 = 2; -pub const IFLA_XDP_FLAGS: _bindgen_ty_92 = 3; -pub const IFLA_XDP_PROG_ID: _bindgen_ty_92 = 4; -pub const IFLA_XDP_DRV_PROG_ID: _bindgen_ty_92 = 5; -pub const IFLA_XDP_SKB_PROG_ID: _bindgen_ty_92 = 6; -pub const IFLA_XDP_HW_PROG_ID: _bindgen_ty_92 = 7; -pub const IFLA_XDP_EXPECTED_FD: _bindgen_ty_92 = 8; -pub const __IFLA_XDP_MAX: _bindgen_ty_92 = 9; -pub type _bindgen_ty_92 = ::core::ffi::c_uint; +pub const IFLA_XDP_UNSPEC: _bindgen_ty_94 = 0; +pub const IFLA_XDP_FD: _bindgen_ty_94 = 1; +pub const IFLA_XDP_ATTACHED: _bindgen_ty_94 = 2; +pub const IFLA_XDP_FLAGS: _bindgen_ty_94 = 3; +pub const IFLA_XDP_PROG_ID: _bindgen_ty_94 = 4; +pub const IFLA_XDP_DRV_PROG_ID: _bindgen_ty_94 = 5; +pub const IFLA_XDP_SKB_PROG_ID: _bindgen_ty_94 = 6; +pub const IFLA_XDP_HW_PROG_ID: _bindgen_ty_94 = 7; +pub const IFLA_XDP_EXPECTED_FD: _bindgen_ty_94 = 8; +pub const __IFLA_XDP_MAX: _bindgen_ty_94 = 9; +pub type _bindgen_ty_94 = ::core::ffi::c_uint; impl nf_inet_hooks { pub const NF_INET_INGRESS: nf_inet_hooks = nf_inet_hooks::NF_INET_NUMHOOKS; } @@ -2141,16 +2157,16 @@ pub enum nf_inet_hooks { NF_INET_POST_ROUTING = 4, NF_INET_NUMHOOKS = 5, } -pub const NFPROTO_UNSPEC: _bindgen_ty_99 = 0; -pub const NFPROTO_INET: _bindgen_ty_99 = 1; -pub const NFPROTO_IPV4: _bindgen_ty_99 = 2; -pub const NFPROTO_ARP: _bindgen_ty_99 = 3; -pub const NFPROTO_NETDEV: _bindgen_ty_99 = 5; -pub const NFPROTO_BRIDGE: _bindgen_ty_99 = 7; -pub const NFPROTO_IPV6: _bindgen_ty_99 = 10; -pub const NFPROTO_DECNET: _bindgen_ty_99 = 12; -pub const NFPROTO_NUMPROTO: _bindgen_ty_99 = 13; -pub type _bindgen_ty_99 = ::core::ffi::c_uint; +pub const NFPROTO_UNSPEC: _bindgen_ty_101 = 0; +pub const NFPROTO_INET: _bindgen_ty_101 = 1; +pub const NFPROTO_IPV4: _bindgen_ty_101 = 2; +pub const NFPROTO_ARP: _bindgen_ty_101 = 3; +pub const NFPROTO_NETDEV: _bindgen_ty_101 = 5; +pub const NFPROTO_BRIDGE: _bindgen_ty_101 = 7; +pub const NFPROTO_IPV6: _bindgen_ty_101 = 10; +pub const NFPROTO_DECNET: _bindgen_ty_101 = 12; +pub const NFPROTO_NUMPROTO: _bindgen_ty_101 = 13; +pub type _bindgen_ty_101 = ::core::ffi::c_uint; #[repr(u32)] #[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] pub enum perf_type_id { @@ -4111,20 +4127,20 @@ pub enum perf_event_type { PERF_RECORD_AUX_OUTPUT_HW_ID = 21, PERF_RECORD_MAX = 22, } -pub const TCA_BPF_UNSPEC: _bindgen_ty_154 = 0; -pub const TCA_BPF_ACT: _bindgen_ty_154 = 1; -pub const TCA_BPF_POLICE: _bindgen_ty_154 = 2; -pub const TCA_BPF_CLASSID: _bindgen_ty_154 = 3; -pub const TCA_BPF_OPS_LEN: _bindgen_ty_154 = 4; -pub const TCA_BPF_OPS: _bindgen_ty_154 = 5; -pub const TCA_BPF_FD: _bindgen_ty_154 = 6; -pub const TCA_BPF_NAME: _bindgen_ty_154 = 7; -pub const TCA_BPF_FLAGS: _bindgen_ty_154 = 8; -pub const TCA_BPF_FLAGS_GEN: _bindgen_ty_154 = 9; -pub const TCA_BPF_TAG: _bindgen_ty_154 = 10; -pub const TCA_BPF_ID: _bindgen_ty_154 = 11; -pub const __TCA_BPF_MAX: _bindgen_ty_154 = 12; -pub type _bindgen_ty_154 = ::core::ffi::c_uint; +pub const TCA_BPF_UNSPEC: _bindgen_ty_156 = 0; +pub const TCA_BPF_ACT: _bindgen_ty_156 = 1; +pub const TCA_BPF_POLICE: _bindgen_ty_156 = 2; +pub const TCA_BPF_CLASSID: _bindgen_ty_156 = 3; +pub const TCA_BPF_OPS_LEN: _bindgen_ty_156 = 4; +pub const TCA_BPF_OPS: _bindgen_ty_156 = 5; +pub const TCA_BPF_FD: _bindgen_ty_156 = 6; +pub const TCA_BPF_NAME: _bindgen_ty_156 = 7; +pub const TCA_BPF_FLAGS: _bindgen_ty_156 = 8; +pub const TCA_BPF_FLAGS_GEN: _bindgen_ty_156 = 9; +pub const TCA_BPF_TAG: _bindgen_ty_156 = 10; +pub const TCA_BPF_ID: _bindgen_ty_156 = 11; +pub const __TCA_BPF_MAX: _bindgen_ty_156 = 12; +pub type _bindgen_ty_156 = ::core::ffi::c_uint; #[repr(C)] #[derive(Debug, Copy, Clone)] pub struct ifinfomsg { @@ -4146,22 +4162,22 @@ pub struct tcmsg { pub tcm_parent: __u32, pub tcm_info: __u32, } -pub const TCA_UNSPEC: _bindgen_ty_174 = 0; -pub const TCA_KIND: _bindgen_ty_174 = 1; -pub const TCA_OPTIONS: _bindgen_ty_174 = 2; -pub const TCA_STATS: _bindgen_ty_174 = 3; -pub const TCA_XSTATS: _bindgen_ty_174 = 4; -pub const TCA_RATE: _bindgen_ty_174 = 5; -pub const TCA_FCNT: _bindgen_ty_174 = 6; -pub const TCA_STATS2: _bindgen_ty_174 = 7; -pub const TCA_STAB: _bindgen_ty_174 = 8; -pub const TCA_PAD: _bindgen_ty_174 = 9; -pub const TCA_DUMP_INVISIBLE: _bindgen_ty_174 = 10; -pub const TCA_CHAIN: _bindgen_ty_174 = 11; -pub const TCA_HW_OFFLOAD: _bindgen_ty_174 = 12; -pub const TCA_INGRESS_BLOCK: _bindgen_ty_174 = 13; -pub const TCA_EGRESS_BLOCK: _bindgen_ty_174 = 14; -pub const TCA_DUMP_FLAGS: _bindgen_ty_174 = 15; -pub const TCA_EXT_WARN_MSG: _bindgen_ty_174 = 16; -pub const __TCA_MAX: _bindgen_ty_174 = 17; -pub type _bindgen_ty_174 = ::core::ffi::c_uint; +pub const TCA_UNSPEC: _bindgen_ty_176 = 0; +pub const TCA_KIND: _bindgen_ty_176 = 1; +pub const TCA_OPTIONS: _bindgen_ty_176 = 2; +pub const TCA_STATS: _bindgen_ty_176 = 3; +pub const TCA_XSTATS: _bindgen_ty_176 = 4; +pub const TCA_RATE: _bindgen_ty_176 = 5; +pub const TCA_FCNT: _bindgen_ty_176 = 6; +pub const TCA_STATS2: _bindgen_ty_176 = 7; +pub const TCA_STAB: _bindgen_ty_176 = 8; +pub const TCA_PAD: _bindgen_ty_176 = 9; +pub const TCA_DUMP_INVISIBLE: _bindgen_ty_176 = 10; +pub const TCA_CHAIN: _bindgen_ty_176 = 11; +pub const TCA_HW_OFFLOAD: _bindgen_ty_176 = 12; +pub const TCA_INGRESS_BLOCK: _bindgen_ty_176 = 13; +pub const TCA_EGRESS_BLOCK: _bindgen_ty_176 = 14; +pub const TCA_DUMP_FLAGS: _bindgen_ty_176 = 15; +pub const TCA_EXT_WARN_MSG: _bindgen_ty_176 = 16; +pub const __TCA_MAX: _bindgen_ty_176 = 17; +pub type _bindgen_ty_176 = ::core::ffi::c_uint; diff --git a/aya-obj/src/generated/linux_bindings_powerpc64.rs b/aya-obj/src/generated/linux_bindings_powerpc64.rs index 50d01b86..7d8294f7 100644 --- a/aya-obj/src/generated/linux_bindings_powerpc64.rs +++ b/aya-obj/src/generated/linux_bindings_powerpc64.rs @@ -2105,6 +2105,22 @@ pub struct btf_var_secinfo { pub struct btf_decl_tag { pub component_idx: __s32, } +pub const HW_BREAKPOINT_LEN_1: _bindgen_ty_44 = 1; +pub const HW_BREAKPOINT_LEN_2: _bindgen_ty_44 = 2; +pub const HW_BREAKPOINT_LEN_3: _bindgen_ty_44 = 3; +pub const HW_BREAKPOINT_LEN_4: _bindgen_ty_44 = 4; +pub const HW_BREAKPOINT_LEN_5: _bindgen_ty_44 = 5; +pub const HW_BREAKPOINT_LEN_6: _bindgen_ty_44 = 6; +pub const HW_BREAKPOINT_LEN_7: _bindgen_ty_44 = 7; +pub const HW_BREAKPOINT_LEN_8: _bindgen_ty_44 = 8; +pub type _bindgen_ty_44 = ::core::ffi::c_uint; +pub const HW_BREAKPOINT_EMPTY: _bindgen_ty_45 = 0; +pub const HW_BREAKPOINT_R: _bindgen_ty_45 = 1; +pub const HW_BREAKPOINT_W: _bindgen_ty_45 = 2; +pub const HW_BREAKPOINT_RW: _bindgen_ty_45 = 3; +pub const HW_BREAKPOINT_X: _bindgen_ty_45 = 4; +pub const HW_BREAKPOINT_INVALID: _bindgen_ty_45 = 7; +pub type _bindgen_ty_45 = ::core::ffi::c_uint; impl nlmsgerr_attrs { pub const NLMSGERR_ATTR_MAX: nlmsgerr_attrs = nlmsgerr_attrs::NLMSGERR_ATTR_COOKIE; } @@ -2117,17 +2133,17 @@ pub enum nlmsgerr_attrs { NLMSGERR_ATTR_COOKIE = 3, __NLMSGERR_ATTR_MAX = 4, } -pub const IFLA_XDP_UNSPEC: _bindgen_ty_92 = 0; -pub const IFLA_XDP_FD: _bindgen_ty_92 = 1; -pub const IFLA_XDP_ATTACHED: _bindgen_ty_92 = 2; -pub const IFLA_XDP_FLAGS: _bindgen_ty_92 = 3; -pub const IFLA_XDP_PROG_ID: _bindgen_ty_92 = 4; -pub const IFLA_XDP_DRV_PROG_ID: _bindgen_ty_92 = 5; -pub const IFLA_XDP_SKB_PROG_ID: _bindgen_ty_92 = 6; -pub const IFLA_XDP_HW_PROG_ID: _bindgen_ty_92 = 7; -pub const IFLA_XDP_EXPECTED_FD: _bindgen_ty_92 = 8; -pub const __IFLA_XDP_MAX: _bindgen_ty_92 = 9; -pub type _bindgen_ty_92 = ::core::ffi::c_uint; +pub const IFLA_XDP_UNSPEC: _bindgen_ty_94 = 0; +pub const IFLA_XDP_FD: _bindgen_ty_94 = 1; +pub const IFLA_XDP_ATTACHED: _bindgen_ty_94 = 2; +pub const IFLA_XDP_FLAGS: _bindgen_ty_94 = 3; +pub const IFLA_XDP_PROG_ID: _bindgen_ty_94 = 4; +pub const IFLA_XDP_DRV_PROG_ID: _bindgen_ty_94 = 5; +pub const IFLA_XDP_SKB_PROG_ID: _bindgen_ty_94 = 6; +pub const IFLA_XDP_HW_PROG_ID: _bindgen_ty_94 = 7; +pub const IFLA_XDP_EXPECTED_FD: _bindgen_ty_94 = 8; +pub const __IFLA_XDP_MAX: _bindgen_ty_94 = 9; +pub type _bindgen_ty_94 = ::core::ffi::c_uint; impl nf_inet_hooks { pub const NF_INET_INGRESS: nf_inet_hooks = nf_inet_hooks::NF_INET_NUMHOOKS; } @@ -2141,16 +2157,16 @@ pub enum nf_inet_hooks { NF_INET_POST_ROUTING = 4, NF_INET_NUMHOOKS = 5, } -pub const NFPROTO_UNSPEC: _bindgen_ty_99 = 0; -pub const NFPROTO_INET: _bindgen_ty_99 = 1; -pub const NFPROTO_IPV4: _bindgen_ty_99 = 2; -pub const NFPROTO_ARP: _bindgen_ty_99 = 3; -pub const NFPROTO_NETDEV: _bindgen_ty_99 = 5; -pub const NFPROTO_BRIDGE: _bindgen_ty_99 = 7; -pub const NFPROTO_IPV6: _bindgen_ty_99 = 10; -pub const NFPROTO_DECNET: _bindgen_ty_99 = 12; -pub const NFPROTO_NUMPROTO: _bindgen_ty_99 = 13; -pub type _bindgen_ty_99 = ::core::ffi::c_uint; +pub const NFPROTO_UNSPEC: _bindgen_ty_101 = 0; +pub const NFPROTO_INET: _bindgen_ty_101 = 1; +pub const NFPROTO_IPV4: _bindgen_ty_101 = 2; +pub const NFPROTO_ARP: _bindgen_ty_101 = 3; +pub const NFPROTO_NETDEV: _bindgen_ty_101 = 5; +pub const NFPROTO_BRIDGE: _bindgen_ty_101 = 7; +pub const NFPROTO_IPV6: _bindgen_ty_101 = 10; +pub const NFPROTO_DECNET: _bindgen_ty_101 = 12; +pub const NFPROTO_NUMPROTO: _bindgen_ty_101 = 13; +pub type _bindgen_ty_101 = ::core::ffi::c_uint; #[repr(u32)] #[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] pub enum perf_type_id { @@ -4111,20 +4127,20 @@ pub enum perf_event_type { PERF_RECORD_AUX_OUTPUT_HW_ID = 21, PERF_RECORD_MAX = 22, } -pub const TCA_BPF_UNSPEC: _bindgen_ty_154 = 0; -pub const TCA_BPF_ACT: _bindgen_ty_154 = 1; -pub const TCA_BPF_POLICE: _bindgen_ty_154 = 2; -pub const TCA_BPF_CLASSID: _bindgen_ty_154 = 3; -pub const TCA_BPF_OPS_LEN: _bindgen_ty_154 = 4; -pub const TCA_BPF_OPS: _bindgen_ty_154 = 5; -pub const TCA_BPF_FD: _bindgen_ty_154 = 6; -pub const TCA_BPF_NAME: _bindgen_ty_154 = 7; -pub const TCA_BPF_FLAGS: _bindgen_ty_154 = 8; -pub const TCA_BPF_FLAGS_GEN: _bindgen_ty_154 = 9; -pub const TCA_BPF_TAG: _bindgen_ty_154 = 10; -pub const TCA_BPF_ID: _bindgen_ty_154 = 11; -pub const __TCA_BPF_MAX: _bindgen_ty_154 = 12; -pub type _bindgen_ty_154 = ::core::ffi::c_uint; +pub const TCA_BPF_UNSPEC: _bindgen_ty_156 = 0; +pub const TCA_BPF_ACT: _bindgen_ty_156 = 1; +pub const TCA_BPF_POLICE: _bindgen_ty_156 = 2; +pub const TCA_BPF_CLASSID: _bindgen_ty_156 = 3; +pub const TCA_BPF_OPS_LEN: _bindgen_ty_156 = 4; +pub const TCA_BPF_OPS: _bindgen_ty_156 = 5; +pub const TCA_BPF_FD: _bindgen_ty_156 = 6; +pub const TCA_BPF_NAME: _bindgen_ty_156 = 7; +pub const TCA_BPF_FLAGS: _bindgen_ty_156 = 8; +pub const TCA_BPF_FLAGS_GEN: _bindgen_ty_156 = 9; +pub const TCA_BPF_TAG: _bindgen_ty_156 = 10; +pub const TCA_BPF_ID: _bindgen_ty_156 = 11; +pub const __TCA_BPF_MAX: _bindgen_ty_156 = 12; +pub type _bindgen_ty_156 = ::core::ffi::c_uint; #[repr(C)] #[derive(Debug, Copy, Clone)] pub struct ifinfomsg { @@ -4146,22 +4162,22 @@ pub struct tcmsg { pub tcm_parent: __u32, pub tcm_info: __u32, } -pub const TCA_UNSPEC: _bindgen_ty_174 = 0; -pub const TCA_KIND: _bindgen_ty_174 = 1; -pub const TCA_OPTIONS: _bindgen_ty_174 = 2; -pub const TCA_STATS: _bindgen_ty_174 = 3; -pub const TCA_XSTATS: _bindgen_ty_174 = 4; -pub const TCA_RATE: _bindgen_ty_174 = 5; -pub const TCA_FCNT: _bindgen_ty_174 = 6; -pub const TCA_STATS2: _bindgen_ty_174 = 7; -pub const TCA_STAB: _bindgen_ty_174 = 8; -pub const TCA_PAD: _bindgen_ty_174 = 9; -pub const TCA_DUMP_INVISIBLE: _bindgen_ty_174 = 10; -pub const TCA_CHAIN: _bindgen_ty_174 = 11; -pub const TCA_HW_OFFLOAD: _bindgen_ty_174 = 12; -pub const TCA_INGRESS_BLOCK: _bindgen_ty_174 = 13; -pub const TCA_EGRESS_BLOCK: _bindgen_ty_174 = 14; -pub const TCA_DUMP_FLAGS: _bindgen_ty_174 = 15; -pub const TCA_EXT_WARN_MSG: _bindgen_ty_174 = 16; -pub const __TCA_MAX: _bindgen_ty_174 = 17; -pub type _bindgen_ty_174 = ::core::ffi::c_uint; +pub const TCA_UNSPEC: _bindgen_ty_176 = 0; +pub const TCA_KIND: _bindgen_ty_176 = 1; +pub const TCA_OPTIONS: _bindgen_ty_176 = 2; +pub const TCA_STATS: _bindgen_ty_176 = 3; +pub const TCA_XSTATS: _bindgen_ty_176 = 4; +pub const TCA_RATE: _bindgen_ty_176 = 5; +pub const TCA_FCNT: _bindgen_ty_176 = 6; +pub const TCA_STATS2: _bindgen_ty_176 = 7; +pub const TCA_STAB: _bindgen_ty_176 = 8; +pub const TCA_PAD: _bindgen_ty_176 = 9; +pub const TCA_DUMP_INVISIBLE: _bindgen_ty_176 = 10; +pub const TCA_CHAIN: _bindgen_ty_176 = 11; +pub const TCA_HW_OFFLOAD: _bindgen_ty_176 = 12; +pub const TCA_INGRESS_BLOCK: _bindgen_ty_176 = 13; +pub const TCA_EGRESS_BLOCK: _bindgen_ty_176 = 14; +pub const TCA_DUMP_FLAGS: _bindgen_ty_176 = 15; +pub const TCA_EXT_WARN_MSG: _bindgen_ty_176 = 16; +pub const __TCA_MAX: _bindgen_ty_176 = 17; +pub type _bindgen_ty_176 = ::core::ffi::c_uint; diff --git a/aya-obj/src/generated/linux_bindings_riscv64.rs b/aya-obj/src/generated/linux_bindings_riscv64.rs index b76ed850..aff50e13 100644 --- a/aya-obj/src/generated/linux_bindings_riscv64.rs +++ b/aya-obj/src/generated/linux_bindings_riscv64.rs @@ -2105,6 +2105,22 @@ pub struct btf_var_secinfo { pub struct btf_decl_tag { pub component_idx: __s32, } +pub const HW_BREAKPOINT_LEN_1: _bindgen_ty_44 = 1; +pub const HW_BREAKPOINT_LEN_2: _bindgen_ty_44 = 2; +pub const HW_BREAKPOINT_LEN_3: _bindgen_ty_44 = 3; +pub const HW_BREAKPOINT_LEN_4: _bindgen_ty_44 = 4; +pub const HW_BREAKPOINT_LEN_5: _bindgen_ty_44 = 5; +pub const HW_BREAKPOINT_LEN_6: _bindgen_ty_44 = 6; +pub const HW_BREAKPOINT_LEN_7: _bindgen_ty_44 = 7; +pub const HW_BREAKPOINT_LEN_8: _bindgen_ty_44 = 8; +pub type _bindgen_ty_44 = ::core::ffi::c_uint; +pub const HW_BREAKPOINT_EMPTY: _bindgen_ty_45 = 0; +pub const HW_BREAKPOINT_R: _bindgen_ty_45 = 1; +pub const HW_BREAKPOINT_W: _bindgen_ty_45 = 2; +pub const HW_BREAKPOINT_RW: _bindgen_ty_45 = 3; +pub const HW_BREAKPOINT_X: _bindgen_ty_45 = 4; +pub const HW_BREAKPOINT_INVALID: _bindgen_ty_45 = 7; +pub type _bindgen_ty_45 = ::core::ffi::c_uint; impl nlmsgerr_attrs { pub const NLMSGERR_ATTR_MAX: nlmsgerr_attrs = nlmsgerr_attrs::NLMSGERR_ATTR_COOKIE; } @@ -2117,17 +2133,17 @@ pub enum nlmsgerr_attrs { NLMSGERR_ATTR_COOKIE = 3, __NLMSGERR_ATTR_MAX = 4, } -pub const IFLA_XDP_UNSPEC: _bindgen_ty_92 = 0; -pub const IFLA_XDP_FD: _bindgen_ty_92 = 1; -pub const IFLA_XDP_ATTACHED: _bindgen_ty_92 = 2; -pub const IFLA_XDP_FLAGS: _bindgen_ty_92 = 3; -pub const IFLA_XDP_PROG_ID: _bindgen_ty_92 = 4; -pub const IFLA_XDP_DRV_PROG_ID: _bindgen_ty_92 = 5; -pub const IFLA_XDP_SKB_PROG_ID: _bindgen_ty_92 = 6; -pub const IFLA_XDP_HW_PROG_ID: _bindgen_ty_92 = 7; -pub const IFLA_XDP_EXPECTED_FD: _bindgen_ty_92 = 8; -pub const __IFLA_XDP_MAX: _bindgen_ty_92 = 9; -pub type _bindgen_ty_92 = ::core::ffi::c_uint; +pub const IFLA_XDP_UNSPEC: _bindgen_ty_94 = 0; +pub const IFLA_XDP_FD: _bindgen_ty_94 = 1; +pub const IFLA_XDP_ATTACHED: _bindgen_ty_94 = 2; +pub const IFLA_XDP_FLAGS: _bindgen_ty_94 = 3; +pub const IFLA_XDP_PROG_ID: _bindgen_ty_94 = 4; +pub const IFLA_XDP_DRV_PROG_ID: _bindgen_ty_94 = 5; +pub const IFLA_XDP_SKB_PROG_ID: _bindgen_ty_94 = 6; +pub const IFLA_XDP_HW_PROG_ID: _bindgen_ty_94 = 7; +pub const IFLA_XDP_EXPECTED_FD: _bindgen_ty_94 = 8; +pub const __IFLA_XDP_MAX: _bindgen_ty_94 = 9; +pub type _bindgen_ty_94 = ::core::ffi::c_uint; impl nf_inet_hooks { pub const NF_INET_INGRESS: nf_inet_hooks = nf_inet_hooks::NF_INET_NUMHOOKS; } @@ -2141,16 +2157,16 @@ pub enum nf_inet_hooks { NF_INET_POST_ROUTING = 4, NF_INET_NUMHOOKS = 5, } -pub const NFPROTO_UNSPEC: _bindgen_ty_99 = 0; -pub const NFPROTO_INET: _bindgen_ty_99 = 1; -pub const NFPROTO_IPV4: _bindgen_ty_99 = 2; -pub const NFPROTO_ARP: _bindgen_ty_99 = 3; -pub const NFPROTO_NETDEV: _bindgen_ty_99 = 5; -pub const NFPROTO_BRIDGE: _bindgen_ty_99 = 7; -pub const NFPROTO_IPV6: _bindgen_ty_99 = 10; -pub const NFPROTO_DECNET: _bindgen_ty_99 = 12; -pub const NFPROTO_NUMPROTO: _bindgen_ty_99 = 13; -pub type _bindgen_ty_99 = ::core::ffi::c_uint; +pub const NFPROTO_UNSPEC: _bindgen_ty_101 = 0; +pub const NFPROTO_INET: _bindgen_ty_101 = 1; +pub const NFPROTO_IPV4: _bindgen_ty_101 = 2; +pub const NFPROTO_ARP: _bindgen_ty_101 = 3; +pub const NFPROTO_NETDEV: _bindgen_ty_101 = 5; +pub const NFPROTO_BRIDGE: _bindgen_ty_101 = 7; +pub const NFPROTO_IPV6: _bindgen_ty_101 = 10; +pub const NFPROTO_DECNET: _bindgen_ty_101 = 12; +pub const NFPROTO_NUMPROTO: _bindgen_ty_101 = 13; +pub type _bindgen_ty_101 = ::core::ffi::c_uint; #[repr(u32)] #[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] pub enum perf_type_id { @@ -4111,20 +4127,20 @@ pub enum perf_event_type { PERF_RECORD_AUX_OUTPUT_HW_ID = 21, PERF_RECORD_MAX = 22, } -pub const TCA_BPF_UNSPEC: _bindgen_ty_154 = 0; -pub const TCA_BPF_ACT: _bindgen_ty_154 = 1; -pub const TCA_BPF_POLICE: _bindgen_ty_154 = 2; -pub const TCA_BPF_CLASSID: _bindgen_ty_154 = 3; -pub const TCA_BPF_OPS_LEN: _bindgen_ty_154 = 4; -pub const TCA_BPF_OPS: _bindgen_ty_154 = 5; -pub const TCA_BPF_FD: _bindgen_ty_154 = 6; -pub const TCA_BPF_NAME: _bindgen_ty_154 = 7; -pub const TCA_BPF_FLAGS: _bindgen_ty_154 = 8; -pub const TCA_BPF_FLAGS_GEN: _bindgen_ty_154 = 9; -pub const TCA_BPF_TAG: _bindgen_ty_154 = 10; -pub const TCA_BPF_ID: _bindgen_ty_154 = 11; -pub const __TCA_BPF_MAX: _bindgen_ty_154 = 12; -pub type _bindgen_ty_154 = ::core::ffi::c_uint; +pub const TCA_BPF_UNSPEC: _bindgen_ty_156 = 0; +pub const TCA_BPF_ACT: _bindgen_ty_156 = 1; +pub const TCA_BPF_POLICE: _bindgen_ty_156 = 2; +pub const TCA_BPF_CLASSID: _bindgen_ty_156 = 3; +pub const TCA_BPF_OPS_LEN: _bindgen_ty_156 = 4; +pub const TCA_BPF_OPS: _bindgen_ty_156 = 5; +pub const TCA_BPF_FD: _bindgen_ty_156 = 6; +pub const TCA_BPF_NAME: _bindgen_ty_156 = 7; +pub const TCA_BPF_FLAGS: _bindgen_ty_156 = 8; +pub const TCA_BPF_FLAGS_GEN: _bindgen_ty_156 = 9; +pub const TCA_BPF_TAG: _bindgen_ty_156 = 10; +pub const TCA_BPF_ID: _bindgen_ty_156 = 11; +pub const __TCA_BPF_MAX: _bindgen_ty_156 = 12; +pub type _bindgen_ty_156 = ::core::ffi::c_uint; #[repr(C)] #[derive(Debug, Copy, Clone)] pub struct ifinfomsg { @@ -4146,22 +4162,22 @@ pub struct tcmsg { pub tcm_parent: __u32, pub tcm_info: __u32, } -pub const TCA_UNSPEC: _bindgen_ty_174 = 0; -pub const TCA_KIND: _bindgen_ty_174 = 1; -pub const TCA_OPTIONS: _bindgen_ty_174 = 2; -pub const TCA_STATS: _bindgen_ty_174 = 3; -pub const TCA_XSTATS: _bindgen_ty_174 = 4; -pub const TCA_RATE: _bindgen_ty_174 = 5; -pub const TCA_FCNT: _bindgen_ty_174 = 6; -pub const TCA_STATS2: _bindgen_ty_174 = 7; -pub const TCA_STAB: _bindgen_ty_174 = 8; -pub const TCA_PAD: _bindgen_ty_174 = 9; -pub const TCA_DUMP_INVISIBLE: _bindgen_ty_174 = 10; -pub const TCA_CHAIN: _bindgen_ty_174 = 11; -pub const TCA_HW_OFFLOAD: _bindgen_ty_174 = 12; -pub const TCA_INGRESS_BLOCK: _bindgen_ty_174 = 13; -pub const TCA_EGRESS_BLOCK: _bindgen_ty_174 = 14; -pub const TCA_DUMP_FLAGS: _bindgen_ty_174 = 15; -pub const TCA_EXT_WARN_MSG: _bindgen_ty_174 = 16; -pub const __TCA_MAX: _bindgen_ty_174 = 17; -pub type _bindgen_ty_174 = ::core::ffi::c_uint; +pub const TCA_UNSPEC: _bindgen_ty_176 = 0; +pub const TCA_KIND: _bindgen_ty_176 = 1; +pub const TCA_OPTIONS: _bindgen_ty_176 = 2; +pub const TCA_STATS: _bindgen_ty_176 = 3; +pub const TCA_XSTATS: _bindgen_ty_176 = 4; +pub const TCA_RATE: _bindgen_ty_176 = 5; +pub const TCA_FCNT: _bindgen_ty_176 = 6; +pub const TCA_STATS2: _bindgen_ty_176 = 7; +pub const TCA_STAB: _bindgen_ty_176 = 8; +pub const TCA_PAD: _bindgen_ty_176 = 9; +pub const TCA_DUMP_INVISIBLE: _bindgen_ty_176 = 10; +pub const TCA_CHAIN: _bindgen_ty_176 = 11; +pub const TCA_HW_OFFLOAD: _bindgen_ty_176 = 12; +pub const TCA_INGRESS_BLOCK: _bindgen_ty_176 = 13; +pub const TCA_EGRESS_BLOCK: _bindgen_ty_176 = 14; +pub const TCA_DUMP_FLAGS: _bindgen_ty_176 = 15; +pub const TCA_EXT_WARN_MSG: _bindgen_ty_176 = 16; +pub const __TCA_MAX: _bindgen_ty_176 = 17; +pub type _bindgen_ty_176 = ::core::ffi::c_uint; diff --git a/aya-obj/src/generated/linux_bindings_s390x.rs b/aya-obj/src/generated/linux_bindings_s390x.rs index b76ed850..aff50e13 100644 --- a/aya-obj/src/generated/linux_bindings_s390x.rs +++ b/aya-obj/src/generated/linux_bindings_s390x.rs @@ -2105,6 +2105,22 @@ pub struct btf_var_secinfo { pub struct btf_decl_tag { pub component_idx: __s32, } +pub const HW_BREAKPOINT_LEN_1: _bindgen_ty_44 = 1; +pub const HW_BREAKPOINT_LEN_2: _bindgen_ty_44 = 2; +pub const HW_BREAKPOINT_LEN_3: _bindgen_ty_44 = 3; +pub const HW_BREAKPOINT_LEN_4: _bindgen_ty_44 = 4; +pub const HW_BREAKPOINT_LEN_5: _bindgen_ty_44 = 5; +pub const HW_BREAKPOINT_LEN_6: _bindgen_ty_44 = 6; +pub const HW_BREAKPOINT_LEN_7: _bindgen_ty_44 = 7; +pub const HW_BREAKPOINT_LEN_8: _bindgen_ty_44 = 8; +pub type _bindgen_ty_44 = ::core::ffi::c_uint; +pub const HW_BREAKPOINT_EMPTY: _bindgen_ty_45 = 0; +pub const HW_BREAKPOINT_R: _bindgen_ty_45 = 1; +pub const HW_BREAKPOINT_W: _bindgen_ty_45 = 2; +pub const HW_BREAKPOINT_RW: _bindgen_ty_45 = 3; +pub const HW_BREAKPOINT_X: _bindgen_ty_45 = 4; +pub const HW_BREAKPOINT_INVALID: _bindgen_ty_45 = 7; +pub type _bindgen_ty_45 = ::core::ffi::c_uint; impl nlmsgerr_attrs { pub const NLMSGERR_ATTR_MAX: nlmsgerr_attrs = nlmsgerr_attrs::NLMSGERR_ATTR_COOKIE; } @@ -2117,17 +2133,17 @@ pub enum nlmsgerr_attrs { NLMSGERR_ATTR_COOKIE = 3, __NLMSGERR_ATTR_MAX = 4, } -pub const IFLA_XDP_UNSPEC: _bindgen_ty_92 = 0; -pub const IFLA_XDP_FD: _bindgen_ty_92 = 1; -pub const IFLA_XDP_ATTACHED: _bindgen_ty_92 = 2; -pub const IFLA_XDP_FLAGS: _bindgen_ty_92 = 3; -pub const IFLA_XDP_PROG_ID: _bindgen_ty_92 = 4; -pub const IFLA_XDP_DRV_PROG_ID: _bindgen_ty_92 = 5; -pub const IFLA_XDP_SKB_PROG_ID: _bindgen_ty_92 = 6; -pub const IFLA_XDP_HW_PROG_ID: _bindgen_ty_92 = 7; -pub const IFLA_XDP_EXPECTED_FD: _bindgen_ty_92 = 8; -pub const __IFLA_XDP_MAX: _bindgen_ty_92 = 9; -pub type _bindgen_ty_92 = ::core::ffi::c_uint; +pub const IFLA_XDP_UNSPEC: _bindgen_ty_94 = 0; +pub const IFLA_XDP_FD: _bindgen_ty_94 = 1; +pub const IFLA_XDP_ATTACHED: _bindgen_ty_94 = 2; +pub const IFLA_XDP_FLAGS: _bindgen_ty_94 = 3; +pub const IFLA_XDP_PROG_ID: _bindgen_ty_94 = 4; +pub const IFLA_XDP_DRV_PROG_ID: _bindgen_ty_94 = 5; +pub const IFLA_XDP_SKB_PROG_ID: _bindgen_ty_94 = 6; +pub const IFLA_XDP_HW_PROG_ID: _bindgen_ty_94 = 7; +pub const IFLA_XDP_EXPECTED_FD: _bindgen_ty_94 = 8; +pub const __IFLA_XDP_MAX: _bindgen_ty_94 = 9; +pub type _bindgen_ty_94 = ::core::ffi::c_uint; impl nf_inet_hooks { pub const NF_INET_INGRESS: nf_inet_hooks = nf_inet_hooks::NF_INET_NUMHOOKS; } @@ -2141,16 +2157,16 @@ pub enum nf_inet_hooks { NF_INET_POST_ROUTING = 4, NF_INET_NUMHOOKS = 5, } -pub const NFPROTO_UNSPEC: _bindgen_ty_99 = 0; -pub const NFPROTO_INET: _bindgen_ty_99 = 1; -pub const NFPROTO_IPV4: _bindgen_ty_99 = 2; -pub const NFPROTO_ARP: _bindgen_ty_99 = 3; -pub const NFPROTO_NETDEV: _bindgen_ty_99 = 5; -pub const NFPROTO_BRIDGE: _bindgen_ty_99 = 7; -pub const NFPROTO_IPV6: _bindgen_ty_99 = 10; -pub const NFPROTO_DECNET: _bindgen_ty_99 = 12; -pub const NFPROTO_NUMPROTO: _bindgen_ty_99 = 13; -pub type _bindgen_ty_99 = ::core::ffi::c_uint; +pub const NFPROTO_UNSPEC: _bindgen_ty_101 = 0; +pub const NFPROTO_INET: _bindgen_ty_101 = 1; +pub const NFPROTO_IPV4: _bindgen_ty_101 = 2; +pub const NFPROTO_ARP: _bindgen_ty_101 = 3; +pub const NFPROTO_NETDEV: _bindgen_ty_101 = 5; +pub const NFPROTO_BRIDGE: _bindgen_ty_101 = 7; +pub const NFPROTO_IPV6: _bindgen_ty_101 = 10; +pub const NFPROTO_DECNET: _bindgen_ty_101 = 12; +pub const NFPROTO_NUMPROTO: _bindgen_ty_101 = 13; +pub type _bindgen_ty_101 = ::core::ffi::c_uint; #[repr(u32)] #[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] pub enum perf_type_id { @@ -4111,20 +4127,20 @@ pub enum perf_event_type { PERF_RECORD_AUX_OUTPUT_HW_ID = 21, PERF_RECORD_MAX = 22, } -pub const TCA_BPF_UNSPEC: _bindgen_ty_154 = 0; -pub const TCA_BPF_ACT: _bindgen_ty_154 = 1; -pub const TCA_BPF_POLICE: _bindgen_ty_154 = 2; -pub const TCA_BPF_CLASSID: _bindgen_ty_154 = 3; -pub const TCA_BPF_OPS_LEN: _bindgen_ty_154 = 4; -pub const TCA_BPF_OPS: _bindgen_ty_154 = 5; -pub const TCA_BPF_FD: _bindgen_ty_154 = 6; -pub const TCA_BPF_NAME: _bindgen_ty_154 = 7; -pub const TCA_BPF_FLAGS: _bindgen_ty_154 = 8; -pub const TCA_BPF_FLAGS_GEN: _bindgen_ty_154 = 9; -pub const TCA_BPF_TAG: _bindgen_ty_154 = 10; -pub const TCA_BPF_ID: _bindgen_ty_154 = 11; -pub const __TCA_BPF_MAX: _bindgen_ty_154 = 12; -pub type _bindgen_ty_154 = ::core::ffi::c_uint; +pub const TCA_BPF_UNSPEC: _bindgen_ty_156 = 0; +pub const TCA_BPF_ACT: _bindgen_ty_156 = 1; +pub const TCA_BPF_POLICE: _bindgen_ty_156 = 2; +pub const TCA_BPF_CLASSID: _bindgen_ty_156 = 3; +pub const TCA_BPF_OPS_LEN: _bindgen_ty_156 = 4; +pub const TCA_BPF_OPS: _bindgen_ty_156 = 5; +pub const TCA_BPF_FD: _bindgen_ty_156 = 6; +pub const TCA_BPF_NAME: _bindgen_ty_156 = 7; +pub const TCA_BPF_FLAGS: _bindgen_ty_156 = 8; +pub const TCA_BPF_FLAGS_GEN: _bindgen_ty_156 = 9; +pub const TCA_BPF_TAG: _bindgen_ty_156 = 10; +pub const TCA_BPF_ID: _bindgen_ty_156 = 11; +pub const __TCA_BPF_MAX: _bindgen_ty_156 = 12; +pub type _bindgen_ty_156 = ::core::ffi::c_uint; #[repr(C)] #[derive(Debug, Copy, Clone)] pub struct ifinfomsg { @@ -4146,22 +4162,22 @@ pub struct tcmsg { pub tcm_parent: __u32, pub tcm_info: __u32, } -pub const TCA_UNSPEC: _bindgen_ty_174 = 0; -pub const TCA_KIND: _bindgen_ty_174 = 1; -pub const TCA_OPTIONS: _bindgen_ty_174 = 2; -pub const TCA_STATS: _bindgen_ty_174 = 3; -pub const TCA_XSTATS: _bindgen_ty_174 = 4; -pub const TCA_RATE: _bindgen_ty_174 = 5; -pub const TCA_FCNT: _bindgen_ty_174 = 6; -pub const TCA_STATS2: _bindgen_ty_174 = 7; -pub const TCA_STAB: _bindgen_ty_174 = 8; -pub const TCA_PAD: _bindgen_ty_174 = 9; -pub const TCA_DUMP_INVISIBLE: _bindgen_ty_174 = 10; -pub const TCA_CHAIN: _bindgen_ty_174 = 11; -pub const TCA_HW_OFFLOAD: _bindgen_ty_174 = 12; -pub const TCA_INGRESS_BLOCK: _bindgen_ty_174 = 13; -pub const TCA_EGRESS_BLOCK: _bindgen_ty_174 = 14; -pub const TCA_DUMP_FLAGS: _bindgen_ty_174 = 15; -pub const TCA_EXT_WARN_MSG: _bindgen_ty_174 = 16; -pub const __TCA_MAX: _bindgen_ty_174 = 17; -pub type _bindgen_ty_174 = ::core::ffi::c_uint; +pub const TCA_UNSPEC: _bindgen_ty_176 = 0; +pub const TCA_KIND: _bindgen_ty_176 = 1; +pub const TCA_OPTIONS: _bindgen_ty_176 = 2; +pub const TCA_STATS: _bindgen_ty_176 = 3; +pub const TCA_XSTATS: _bindgen_ty_176 = 4; +pub const TCA_RATE: _bindgen_ty_176 = 5; +pub const TCA_FCNT: _bindgen_ty_176 = 6; +pub const TCA_STATS2: _bindgen_ty_176 = 7; +pub const TCA_STAB: _bindgen_ty_176 = 8; +pub const TCA_PAD: _bindgen_ty_176 = 9; +pub const TCA_DUMP_INVISIBLE: _bindgen_ty_176 = 10; +pub const TCA_CHAIN: _bindgen_ty_176 = 11; +pub const TCA_HW_OFFLOAD: _bindgen_ty_176 = 12; +pub const TCA_INGRESS_BLOCK: _bindgen_ty_176 = 13; +pub const TCA_EGRESS_BLOCK: _bindgen_ty_176 = 14; +pub const TCA_DUMP_FLAGS: _bindgen_ty_176 = 15; +pub const TCA_EXT_WARN_MSG: _bindgen_ty_176 = 16; +pub const __TCA_MAX: _bindgen_ty_176 = 17; +pub type _bindgen_ty_176 = ::core::ffi::c_uint; diff --git a/aya-obj/src/generated/linux_bindings_x86_64.rs b/aya-obj/src/generated/linux_bindings_x86_64.rs index b76ed850..aff50e13 100644 --- a/aya-obj/src/generated/linux_bindings_x86_64.rs +++ b/aya-obj/src/generated/linux_bindings_x86_64.rs @@ -2105,6 +2105,22 @@ pub struct btf_var_secinfo { pub struct btf_decl_tag { pub component_idx: __s32, } +pub const HW_BREAKPOINT_LEN_1: _bindgen_ty_44 = 1; +pub const HW_BREAKPOINT_LEN_2: _bindgen_ty_44 = 2; +pub const HW_BREAKPOINT_LEN_3: _bindgen_ty_44 = 3; +pub const HW_BREAKPOINT_LEN_4: _bindgen_ty_44 = 4; +pub const HW_BREAKPOINT_LEN_5: _bindgen_ty_44 = 5; +pub const HW_BREAKPOINT_LEN_6: _bindgen_ty_44 = 6; +pub const HW_BREAKPOINT_LEN_7: _bindgen_ty_44 = 7; +pub const HW_BREAKPOINT_LEN_8: _bindgen_ty_44 = 8; +pub type _bindgen_ty_44 = ::core::ffi::c_uint; +pub const HW_BREAKPOINT_EMPTY: _bindgen_ty_45 = 0; +pub const HW_BREAKPOINT_R: _bindgen_ty_45 = 1; +pub const HW_BREAKPOINT_W: _bindgen_ty_45 = 2; +pub const HW_BREAKPOINT_RW: _bindgen_ty_45 = 3; +pub const HW_BREAKPOINT_X: _bindgen_ty_45 = 4; +pub const HW_BREAKPOINT_INVALID: _bindgen_ty_45 = 7; +pub type _bindgen_ty_45 = ::core::ffi::c_uint; impl nlmsgerr_attrs { pub const NLMSGERR_ATTR_MAX: nlmsgerr_attrs = nlmsgerr_attrs::NLMSGERR_ATTR_COOKIE; } @@ -2117,17 +2133,17 @@ pub enum nlmsgerr_attrs { NLMSGERR_ATTR_COOKIE = 3, __NLMSGERR_ATTR_MAX = 4, } -pub const IFLA_XDP_UNSPEC: _bindgen_ty_92 = 0; -pub const IFLA_XDP_FD: _bindgen_ty_92 = 1; -pub const IFLA_XDP_ATTACHED: _bindgen_ty_92 = 2; -pub const IFLA_XDP_FLAGS: _bindgen_ty_92 = 3; -pub const IFLA_XDP_PROG_ID: _bindgen_ty_92 = 4; -pub const IFLA_XDP_DRV_PROG_ID: _bindgen_ty_92 = 5; -pub const IFLA_XDP_SKB_PROG_ID: _bindgen_ty_92 = 6; -pub const IFLA_XDP_HW_PROG_ID: _bindgen_ty_92 = 7; -pub const IFLA_XDP_EXPECTED_FD: _bindgen_ty_92 = 8; -pub const __IFLA_XDP_MAX: _bindgen_ty_92 = 9; -pub type _bindgen_ty_92 = ::core::ffi::c_uint; +pub const IFLA_XDP_UNSPEC: _bindgen_ty_94 = 0; +pub const IFLA_XDP_FD: _bindgen_ty_94 = 1; +pub const IFLA_XDP_ATTACHED: _bindgen_ty_94 = 2; +pub const IFLA_XDP_FLAGS: _bindgen_ty_94 = 3; +pub const IFLA_XDP_PROG_ID: _bindgen_ty_94 = 4; +pub const IFLA_XDP_DRV_PROG_ID: _bindgen_ty_94 = 5; +pub const IFLA_XDP_SKB_PROG_ID: _bindgen_ty_94 = 6; +pub const IFLA_XDP_HW_PROG_ID: _bindgen_ty_94 = 7; +pub const IFLA_XDP_EXPECTED_FD: _bindgen_ty_94 = 8; +pub const __IFLA_XDP_MAX: _bindgen_ty_94 = 9; +pub type _bindgen_ty_94 = ::core::ffi::c_uint; impl nf_inet_hooks { pub const NF_INET_INGRESS: nf_inet_hooks = nf_inet_hooks::NF_INET_NUMHOOKS; } @@ -2141,16 +2157,16 @@ pub enum nf_inet_hooks { NF_INET_POST_ROUTING = 4, NF_INET_NUMHOOKS = 5, } -pub const NFPROTO_UNSPEC: _bindgen_ty_99 = 0; -pub const NFPROTO_INET: _bindgen_ty_99 = 1; -pub const NFPROTO_IPV4: _bindgen_ty_99 = 2; -pub const NFPROTO_ARP: _bindgen_ty_99 = 3; -pub const NFPROTO_NETDEV: _bindgen_ty_99 = 5; -pub const NFPROTO_BRIDGE: _bindgen_ty_99 = 7; -pub const NFPROTO_IPV6: _bindgen_ty_99 = 10; -pub const NFPROTO_DECNET: _bindgen_ty_99 = 12; -pub const NFPROTO_NUMPROTO: _bindgen_ty_99 = 13; -pub type _bindgen_ty_99 = ::core::ffi::c_uint; +pub const NFPROTO_UNSPEC: _bindgen_ty_101 = 0; +pub const NFPROTO_INET: _bindgen_ty_101 = 1; +pub const NFPROTO_IPV4: _bindgen_ty_101 = 2; +pub const NFPROTO_ARP: _bindgen_ty_101 = 3; +pub const NFPROTO_NETDEV: _bindgen_ty_101 = 5; +pub const NFPROTO_BRIDGE: _bindgen_ty_101 = 7; +pub const NFPROTO_IPV6: _bindgen_ty_101 = 10; +pub const NFPROTO_DECNET: _bindgen_ty_101 = 12; +pub const NFPROTO_NUMPROTO: _bindgen_ty_101 = 13; +pub type _bindgen_ty_101 = ::core::ffi::c_uint; #[repr(u32)] #[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] pub enum perf_type_id { @@ -4111,20 +4127,20 @@ pub enum perf_event_type { PERF_RECORD_AUX_OUTPUT_HW_ID = 21, PERF_RECORD_MAX = 22, } -pub const TCA_BPF_UNSPEC: _bindgen_ty_154 = 0; -pub const TCA_BPF_ACT: _bindgen_ty_154 = 1; -pub const TCA_BPF_POLICE: _bindgen_ty_154 = 2; -pub const TCA_BPF_CLASSID: _bindgen_ty_154 = 3; -pub const TCA_BPF_OPS_LEN: _bindgen_ty_154 = 4; -pub const TCA_BPF_OPS: _bindgen_ty_154 = 5; -pub const TCA_BPF_FD: _bindgen_ty_154 = 6; -pub const TCA_BPF_NAME: _bindgen_ty_154 = 7; -pub const TCA_BPF_FLAGS: _bindgen_ty_154 = 8; -pub const TCA_BPF_FLAGS_GEN: _bindgen_ty_154 = 9; -pub const TCA_BPF_TAG: _bindgen_ty_154 = 10; -pub const TCA_BPF_ID: _bindgen_ty_154 = 11; -pub const __TCA_BPF_MAX: _bindgen_ty_154 = 12; -pub type _bindgen_ty_154 = ::core::ffi::c_uint; +pub const TCA_BPF_UNSPEC: _bindgen_ty_156 = 0; +pub const TCA_BPF_ACT: _bindgen_ty_156 = 1; +pub const TCA_BPF_POLICE: _bindgen_ty_156 = 2; +pub const TCA_BPF_CLASSID: _bindgen_ty_156 = 3; +pub const TCA_BPF_OPS_LEN: _bindgen_ty_156 = 4; +pub const TCA_BPF_OPS: _bindgen_ty_156 = 5; +pub const TCA_BPF_FD: _bindgen_ty_156 = 6; +pub const TCA_BPF_NAME: _bindgen_ty_156 = 7; +pub const TCA_BPF_FLAGS: _bindgen_ty_156 = 8; +pub const TCA_BPF_FLAGS_GEN: _bindgen_ty_156 = 9; +pub const TCA_BPF_TAG: _bindgen_ty_156 = 10; +pub const TCA_BPF_ID: _bindgen_ty_156 = 11; +pub const __TCA_BPF_MAX: _bindgen_ty_156 = 12; +pub type _bindgen_ty_156 = ::core::ffi::c_uint; #[repr(C)] #[derive(Debug, Copy, Clone)] pub struct ifinfomsg { @@ -4146,22 +4162,22 @@ pub struct tcmsg { pub tcm_parent: __u32, pub tcm_info: __u32, } -pub const TCA_UNSPEC: _bindgen_ty_174 = 0; -pub const TCA_KIND: _bindgen_ty_174 = 1; -pub const TCA_OPTIONS: _bindgen_ty_174 = 2; -pub const TCA_STATS: _bindgen_ty_174 = 3; -pub const TCA_XSTATS: _bindgen_ty_174 = 4; -pub const TCA_RATE: _bindgen_ty_174 = 5; -pub const TCA_FCNT: _bindgen_ty_174 = 6; -pub const TCA_STATS2: _bindgen_ty_174 = 7; -pub const TCA_STAB: _bindgen_ty_174 = 8; -pub const TCA_PAD: _bindgen_ty_174 = 9; -pub const TCA_DUMP_INVISIBLE: _bindgen_ty_174 = 10; -pub const TCA_CHAIN: _bindgen_ty_174 = 11; -pub const TCA_HW_OFFLOAD: _bindgen_ty_174 = 12; -pub const TCA_INGRESS_BLOCK: _bindgen_ty_174 = 13; -pub const TCA_EGRESS_BLOCK: _bindgen_ty_174 = 14; -pub const TCA_DUMP_FLAGS: _bindgen_ty_174 = 15; -pub const TCA_EXT_WARN_MSG: _bindgen_ty_174 = 16; -pub const __TCA_MAX: _bindgen_ty_174 = 17; -pub type _bindgen_ty_174 = ::core::ffi::c_uint; +pub const TCA_UNSPEC: _bindgen_ty_176 = 0; +pub const TCA_KIND: _bindgen_ty_176 = 1; +pub const TCA_OPTIONS: _bindgen_ty_176 = 2; +pub const TCA_STATS: _bindgen_ty_176 = 3; +pub const TCA_XSTATS: _bindgen_ty_176 = 4; +pub const TCA_RATE: _bindgen_ty_176 = 5; +pub const TCA_FCNT: _bindgen_ty_176 = 6; +pub const TCA_STATS2: _bindgen_ty_176 = 7; +pub const TCA_STAB: _bindgen_ty_176 = 8; +pub const TCA_PAD: _bindgen_ty_176 = 9; +pub const TCA_DUMP_INVISIBLE: _bindgen_ty_176 = 10; +pub const TCA_CHAIN: _bindgen_ty_176 = 11; +pub const TCA_HW_OFFLOAD: _bindgen_ty_176 = 12; +pub const TCA_INGRESS_BLOCK: _bindgen_ty_176 = 13; +pub const TCA_EGRESS_BLOCK: _bindgen_ty_176 = 14; +pub const TCA_DUMP_FLAGS: _bindgen_ty_176 = 15; +pub const TCA_EXT_WARN_MSG: _bindgen_ty_176 = 16; +pub const __TCA_MAX: _bindgen_ty_176 = 17; +pub type _bindgen_ty_176 = ::core::ffi::c_uint; diff --git a/aya-obj/src/obj.rs b/aya-obj/src/obj.rs index b451595a..c3d0d107 100644 --- a/aya-obj/src/obj.rs +++ b/aya-obj/src/obj.rs @@ -1404,7 +1404,7 @@ pub fn parse_map_info(info: bpf_map_info, pinned: PinningType) -> Map { /// Copies a block of eBPF instructions pub fn copy_instructions(data: &[u8]) -> Result, ParseError> { - if data.len() % mem::size_of::() > 0 { + if !data.len().is_multiple_of(mem::size_of::()) { return Err(ParseError::InvalidProgramCode); } let instructions = data diff --git a/aya-obj/src/relocation.rs b/aya-obj/src/relocation.rs index 850eaaa3..d035339b 100644 --- a/aya-obj/src/relocation.rs +++ b/aya-obj/src/relocation.rs @@ -202,7 +202,7 @@ fn relocate_maps<'a, I: Iterator>( // make sure that the relocation offset is properly aligned let ins_offset = rel_offset - section_offset; - if ins_offset % INS_SIZE != 0 { + if !ins_offset.is_multiple_of(INS_SIZE) { return Err(RelocationError::InvalidRelocationOffset { offset: rel.offset, relocation_number: rel_n, diff --git a/aya/CHANGELOG.md b/aya/CHANGELOG.md index efd3d42e..6ed20f67 100644 --- a/aya/CHANGELOG.md +++ b/aya/CHANGELOG.md @@ -7,21 +7,35 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +## v0.13.2 (2025-11-17) + ### Breaking Changes - - Remove `AsyncPerfEventArray` and `AsyncPerfEventArrayBuffer` These types have been removed to - avoid maintaining support for multiple async runtimes. Use `PerfEventArrayBuffer`, which - implements `As{,Raw}Fd` for integration with async executors. - - Rename `EbpfLoader::map_pin_path` to `EbpfLoader::default_map_pin_directory`. - - Rename `EbpfLoader::set_global` to `EbpfLoader::override_global`. - - Rename `EbpfLoader::set_max_entries` to `EbpfLoader::map_max_entries`. + - Removed `AsyncPerfEventArray{,Buffer}` so Aya no longer needs to juggle multiple async runtimes. Use `PerfEventArrayBuffer`, which still implements `As{,Raw}Fd`, when integrating with an executor. + - `EbpfLoader::map_pin_path` is now `EbpfLoader::default_map_pin_directory`, clarifying that the value represents a base directory. + - The loader’s `set_*` helpers were renamed to builder-style APIs (`override_global`/`map_max_entries`). Deprecated shims remain for one release to ease migration. -### Other +### New Features + + - , Added the iterator program type and auto-generated `take_link`/`detach` helpers so iterator programs can be loaded and detached like any other attachment. + - , Added Flow Dissector program support, including ordered link attachment and full `FdLink` conversions for the new program type. + - , , Made pinned maps easier to manage with `Map::from_map_data()`, `XskMap::unset()`, and the ability to pick a custom map pin directory. + - , , Exposed additional metadata and handles: `LinkInfo`/`loaded_links` are now public, program names can be `&'static str`, and ring buffers implement `AsFd`. + - , , Expanded and cached feature probing, reducing redundant syscalls and adding built-in support for `BPF_MAP_TYPE_SK_STORAGE`. + - , Added `Ebpf::maps_disjoint_mut()` plus perf-event hardware breakpoint support to give loaders safer and more capable instrumentation hooks. + +### Bug Fixes + + - Netlink helpers now surface the kernel’s error message instead of returning opaque failures. + - Fixed `PerCpuHashMap::get()` returning `KeyNotFound` when CPU slots were missing; Flow Dissector links now always convert into `FdLink` thanks to . + - Stabilised ring-buffer producer tracking so first events are no longer dropped, and `/proc/$pid/maps` parsing now tolerates trailing newlines (, ). + - , Map names are forced to be NULL-terminated and `construct_debuglink_path()` no longer fails due to missing components. + +### Maintenance + + - , , Documented the exact bpf/perf syscall contracts inside Aya and automatically raise `RLIMIT_MEMLOCK` on kernels <5.11 to smooth out program loading. + - Continued to invest in documentation, resolver clean-ups, and lint/clippy hygiene across the crate so day-to-day maintenance stays manageable. - - Provide deprecated aliases to ease migration, these will be removed in a future release; - - `EbpfLoader::set_global` calls `EbpfLoader::override_global`, and - - `EbpfLoader::set_max_entries` calls `EbpfLoader::map_max_entries`. - ## 0.13.1 (2024-11-01) ### Chore diff --git a/aya/Cargo.toml b/aya/Cargo.toml index ad431440..1fce9f64 100644 --- a/aya/Cargo.toml +++ b/aya/Cargo.toml @@ -4,7 +4,7 @@ documentation = "https://docs.rs/aya" keywords = ["bpf", "ebpf", "kernel", "linux"] name = "aya" readme = "README.md" -version = "0.13.1" +version = "0.13.2" authors.workspace = true edition.workspace = true @@ -18,7 +18,7 @@ workspace = true [dependencies] assert_matches = { workspace = true } -aya-obj = { path = "../aya-obj", version = "^0.2.1", features = ["std"] } +aya-obj = { path = "../aya-obj", version = "^0.2.2", features = ["std"] } bitflags = { workspace = true } bytes = { workspace = true } hashbrown = { workspace = true } diff --git a/aya/src/bpf.rs b/aya/src/bpf.rs index 6280d070..3e1d4404 100644 --- a/aya/src/bpf.rs +++ b/aya/src/bpf.rs @@ -293,8 +293,13 @@ impl<'a> EbpfLoader<'a> { /// Override the value of a global variable. #[deprecated(since = "0.13.2", note = "please use `override_global` instead")] - pub fn set_global>>(&mut self, name: &'a str, value: T) -> &mut Self { - self.override_global(name, value, false) + pub fn set_global>>( + &mut self, + name: &'a str, + value: T, + must_exist: bool, + ) -> &mut Self { + self.override_global(name, value, must_exist) } /// Set the max_entries for specified map. @@ -593,11 +598,11 @@ impl<'a> EbpfLoader<'a> { match §ion { ProgramSection::KProbe => Program::KProbe(KProbe { data: ProgramData::new(prog_name, obj, btf_fd, *verifier_log_level), - kind: ProbeKind::KProbe, + kind: ProbeKind::Entry, }), ProgramSection::KRetProbe => Program::KProbe(KProbe { data: ProgramData::new(prog_name, obj, btf_fd, *verifier_log_level), - kind: ProbeKind::KRetProbe, + kind: ProbeKind::Return, }), ProgramSection::UProbe { sleepable } => { let mut data = @@ -607,7 +612,7 @@ impl<'a> EbpfLoader<'a> { } Program::UProbe(UProbe { data, - kind: ProbeKind::UProbe, + kind: ProbeKind::Entry, }) } ProgramSection::URetProbe { sleepable } => { @@ -618,7 +623,7 @@ impl<'a> EbpfLoader<'a> { } Program::UProbe(UProbe { data, - kind: ProbeKind::URetProbe, + kind: ProbeKind::Return, }) } ProgramSection::TracePoint => Program::TracePoint(TracePoint { @@ -1050,6 +1055,35 @@ impl Ebpf { self.maps.iter_mut().map(|(name, map)| (name.as_str(), map)) } + /// Attempts to get mutable references to `N` maps at once. + /// + /// Returns an array of length `N` with the results of each query, in the same order + /// as the requested map names. For soundness, at most one mutable reference will be + /// returned to any map. `None` will be used if a map with the given name is missing. + /// + /// This method performs a check to ensure that there are no duplicate map names, + /// which currently has a time-complexity of *O(n²)*. Be careful when passing a large + /// number of names. + /// + /// # Panics + /// + /// Panics if any names are duplicated. + /// + /// # Examples + /// ```no_run + /// # let mut bpf = aya::Ebpf::load(&[])?; + /// match bpf.maps_disjoint_mut(["MAP1", "MAP2"]) { + /// [Some(m1), Some(m2)] => println!("Got MAP1 and MAP2"), + /// [Some(m1), None] => println!("Got only MAP1"), + /// [None, Some(m2)] => println!("Got only MAP2"), + /// [None, None] => println!("No maps"), + /// } + /// # Ok::<(), aya::EbpfError>(()) + /// ``` + pub fn maps_disjoint_mut(&mut self, names: [&str; N]) -> [Option<&mut Map>; N] { + self.maps.get_disjoint_mut(names) + } + /// Returns a reference to the program with the given name. /// /// You can use this to inspect a program and its properties. To load and attach a program, use diff --git a/aya/src/maps/array/program_array.rs b/aya/src/maps/array/program_array.rs index 9f8f9340..3b88fe11 100644 --- a/aya/src/maps/array/program_array.rs +++ b/aya/src/maps/array/program_array.rs @@ -36,13 +36,13 @@ use crate::{ /// let flags = 0; /// /// // bpf_tail_call(ctx, JUMP_TABLE, 0) will jump to prog_0 -/// prog_array.set(0, &prog_0_fd, flags); +/// prog_array.set(0, prog_0_fd, flags); /// /// // bpf_tail_call(ctx, JUMP_TABLE, 1) will jump to prog_1 -/// prog_array.set(1, &prog_1_fd, flags); +/// prog_array.set(1, prog_1_fd, flags); /// /// // bpf_tail_call(ctx, JUMP_TABLE, 2) will jump to prog_2 -/// prog_array.set(2, &prog_2_fd, flags); +/// prog_array.set(2, prog_2_fd, flags); /// # Ok::<(), aya::EbpfError>(()) /// ``` #[doc(alias = "BPF_MAP_TYPE_PROG_ARRAY")] diff --git a/aya/src/maps/perf/perf_buffer.rs b/aya/src/maps/perf/perf_buffer.rs index df0e4974..464262e3 100644 --- a/aya/src/maps/perf/perf_buffer.rs +++ b/aya/src/maps/perf/perf_buffer.rs @@ -6,7 +6,7 @@ use std::{ }; use aya_obj::generated::{ - perf_event_header, perf_event_mmap_page, + PERF_FLAG_FD_CLOEXEC, perf_event_header, perf_event_mmap_page, perf_event_type::{PERF_RECORD_LOST, PERF_RECORD_SAMPLE}, }; use bytes::BytesMut; @@ -14,7 +14,10 @@ use libc::{MAP_SHARED, PROT_READ, PROT_WRITE}; use thiserror::Error; use crate::{ - sys::{PerfEventIoctlRequest, SyscallError, perf_event_ioctl, perf_event_open_bpf}, + programs::perf_event::{ + PerfEventConfig, PerfEventScope, SamplePolicy, SoftwareEvent, WakeupPolicy, + }, + sys::{PerfEventIoctlRequest, SyscallError, perf_event_ioctl, perf_event_open}, util::MMap, }; @@ -92,7 +95,7 @@ pub(crate) struct PerfBuffer { impl PerfBuffer { pub(crate) fn open( - cpu_id: u32, + cpu: u32, page_size: usize, page_count: usize, ) -> Result { @@ -100,8 +103,15 @@ impl PerfBuffer { return Err(PerfBufferError::InvalidPageCount { page_count }); } - let fd = perf_event_open_bpf(cpu_id as i32) - .map_err(|io_error| PerfBufferError::OpenError { io_error })?; + let fd = perf_event_open( + PerfEventConfig::Software(SoftwareEvent::BpfOutput), + PerfEventScope::AllProcessesOneCpu { cpu }, + SamplePolicy::Period(1), + WakeupPolicy::Events(1), + false, + PERF_FLAG_FD_CLOEXEC, + ) + .map_err(|io_error| PerfBufferError::OpenError { io_error })?; let size = page_size * page_count; let mmap = MMap::new( fd.as_fd(), diff --git a/aya/src/programs/kprobe.rs b/aya/src/programs/kprobe.rs index 46158ce6..3e30be27 100644 --- a/aya/src/programs/kprobe.rs +++ b/aya/src/programs/kprobe.rs @@ -1,6 +1,7 @@ //! Kernel space probes. use std::{ ffi::OsStr, + fmt::{self, Write}, io, os::fd::AsFd as _, path::{Path, PathBuf}, @@ -15,7 +16,7 @@ use crate::{ FdLink, LinkError, ProgramData, ProgramError, ProgramType, define_link_wrapper, impl_try_into_fdlink, load_program, perf_attach::{PerfLinkIdInner, PerfLinkInner}, - probe::{ProbeKind, attach}, + probe::{Probe, ProbeKind, attach}, }, sys::bpf_link_get_info_by_fd, }; @@ -59,8 +60,8 @@ impl KProbe { load_program(BPF_PROG_TYPE_KPROBE, &mut self.data) } - /// Returns `KProbe` if the program is a `kprobe`, or `KRetProbe` if the - /// program is a `kretprobe`. + /// Returns [`ProbeKind::Entry`] if the program is a `kprobe`, or + /// [`ProbeKind::Return`] if the program is a `kretprobe`. pub fn kind(&self) -> ProbeKind { self.kind } @@ -81,9 +82,10 @@ impl KProbe { fn_name: T, offset: u64, ) -> Result { - attach( - &mut self.data, - self.kind, + let Self { data, kind } = self; + attach::( + data, + *kind, fn_name.as_ref(), offset, None, // pid @@ -103,6 +105,23 @@ impl KProbe { } } +impl Probe for KProbe { + const PMU: &'static str = "kprobe"; + + type Error = KProbeError; + + fn file_error(filename: PathBuf, io_error: io::Error) -> Self::Error { + KProbeError::FileError { filename, io_error } + } + + fn write_offset(w: &mut W, kind: ProbeKind, offset: u64) -> fmt::Result { + match kind { + ProbeKind::Entry => write!(w, "+{offset}"), + ProbeKind::Return => Ok(()), + } + } +} + define_link_wrapper!( KProbeLink, KProbeLinkId, diff --git a/aya/src/programs/mod.rs b/aya/src/programs/mod.rs index 2a9c0fda..9e151ad8 100644 --- a/aya/src/programs/mod.rs +++ b/aya/src/programs/mod.rs @@ -111,7 +111,7 @@ pub use crate::programs::{ lirc_mode2::LircMode2, lsm::Lsm, lsm_cgroup::LsmCgroup, - perf_event::{PerfEvent, PerfEventScope, SamplePolicy}, + perf_event::PerfEvent, probe::ProbeKind, raw_trace_point::RawTracePoint, sk_lookup::SkLookup, @@ -1229,9 +1229,8 @@ impl_info!( /// use aya::programs::loaded_links; /// /// for info in loaded_links() { -/// if let Ok(info) = info { -/// println!("loaded link: {}", info.id()); -/// } +/// let info = info.unwrap(); +/// println!("loaded link: {}", info.id()); /// } /// ``` pub fn loaded_links() -> impl Iterator> { diff --git a/aya/src/programs/perf_attach.rs b/aya/src/programs/perf_attach.rs index 00cddbd1..d6ed6676 100644 --- a/aya/src/programs/perf_attach.rs +++ b/aya/src/programs/perf_attach.rs @@ -8,10 +8,7 @@ use aya_obj::generated::bpf_attach_type::BPF_PERF_EVENT; use crate::{ FEATURES, - programs::{ - FdLink, Link, ProgramError, id_as_key, - probe::{ProbeEvent, detach_debug_fs}, - }, + programs::{FdLink, Link, ProgramError, id_as_key, probe::ProbeEvent}, sys::{ BpfLinkCreateArgs, LinkTarget, PerfEventIoctlRequest, SyscallError, bpf_link_create, is_bpf_cookie_supported, perf_event_ioctl, @@ -56,7 +53,7 @@ pub struct PerfLinkId(RawFd); /// The attachment type of PerfEvent programs. #[derive(Debug)] -pub struct PerfLink { +pub(crate) struct PerfLink { perf_fd: crate::MockableFd, event: Option, } @@ -72,7 +69,7 @@ impl Link for PerfLink { let Self { perf_fd, event } = self; let _: io::Result<()> = perf_event_ioctl(perf_fd.as_fd(), PerfEventIoctlRequest::Disable); if let Some(event) = event { - let _: Result<_, _> = detach_debug_fs(event); + let _: Result<(), ProgramError> = event.detach(); } Ok(()) @@ -83,7 +80,7 @@ id_as_key!(PerfLink, PerfLinkId); pub(crate) fn perf_attach( prog_fd: BorrowedFd<'_>, - fd: crate::MockableFd, + perf_fd: crate::MockableFd, cookie: Option, ) -> Result { if cookie.is_some() && (!is_bpf_cookie_supported() || !FEATURES.bpf_perf_link()) { @@ -92,7 +89,7 @@ pub(crate) fn perf_attach( if FEATURES.bpf_perf_link() { let link_fd = bpf_link_create( prog_fd, - LinkTarget::Fd(fd.as_fd()), + LinkTarget::Fd(perf_fd.as_fd()), BPF_PERF_EVENT, 0, cookie.map(|bpf_cookie| BpfLinkCreateArgs::PerfEvent { bpf_cookie }), @@ -103,35 +100,39 @@ pub(crate) fn perf_attach( })?; Ok(PerfLinkInner::Fd(FdLink::new(link_fd))) } else { - perf_attach_either(prog_fd, fd, None) + perf_attach_either(prog_fd, perf_fd, None) } } pub(crate) fn perf_attach_debugfs( prog_fd: BorrowedFd<'_>, - fd: crate::MockableFd, + perf_fd: crate::MockableFd, event: ProbeEvent, ) -> Result { - perf_attach_either(prog_fd, fd, Some(event)) + perf_attach_either(prog_fd, perf_fd, Some(event)) } fn perf_attach_either( prog_fd: BorrowedFd<'_>, - fd: crate::MockableFd, - event: Option, + perf_fd: crate::MockableFd, + mut event: Option, ) -> Result { - perf_event_ioctl(fd.as_fd(), PerfEventIoctlRequest::SetBpf(prog_fd)).map_err(|io_error| { - SyscallError { + perf_event_ioctl(perf_fd.as_fd(), PerfEventIoctlRequest::SetBpf(prog_fd)).map_err( + |io_error| SyscallError { call: "PERF_EVENT_IOC_SET_BPF", io_error, - } - })?; - perf_event_ioctl(fd.as_fd(), PerfEventIoctlRequest::Enable).map_err(|io_error| { + }, + )?; + perf_event_ioctl(perf_fd.as_fd(), PerfEventIoctlRequest::Enable).map_err(|io_error| { SyscallError { call: "PERF_EVENT_IOC_ENABLE", io_error, } })?; - Ok(PerfLinkInner::PerfLink(PerfLink { perf_fd: fd, event })) + if let Some(event) = event.as_mut() { + event.disarm(); + } + + Ok(PerfLinkInner::PerfLink(PerfLink { perf_fd, event })) } diff --git a/aya/src/programs/perf_event.rs b/aya/src/programs/perf_event.rs index 93d3dfe1..2e14918e 100644 --- a/aya/src/programs/perf_event.rs +++ b/aya/src/programs/perf_event.rs @@ -3,22 +3,18 @@ use std::os::fd::AsFd as _; use aya_obj::generated::{ - bpf_link_type, - bpf_prog_type::BPF_PROG_TYPE_PERF_EVENT, - perf_hw_cache_id, perf_hw_cache_op_id, perf_hw_cache_op_result_id, perf_hw_id, perf_sw_ids, - perf_type_id, - perf_type_id::{ - PERF_TYPE_BREAKPOINT, PERF_TYPE_HARDWARE, PERF_TYPE_HW_CACHE, PERF_TYPE_RAW, - PERF_TYPE_SOFTWARE, PERF_TYPE_TRACEPOINT, - }, + HW_BREAKPOINT_LEN_1, HW_BREAKPOINT_LEN_2, HW_BREAKPOINT_LEN_4, HW_BREAKPOINT_LEN_8, + HW_BREAKPOINT_R, HW_BREAKPOINT_RW, HW_BREAKPOINT_W, bpf_link_type, + bpf_prog_type::BPF_PROG_TYPE_PERF_EVENT, perf_hw_cache_id, perf_hw_cache_op_id, + perf_hw_cache_op_result_id, perf_hw_id, perf_sw_ids, perf_type_id, }; use crate::{ programs::{ FdLink, LinkError, ProgramData, ProgramError, ProgramType, impl_try_into_fdlink, links::define_link_wrapper, - load_program, perf_attach, - perf_attach::{PerfLinkIdInner, PerfLinkInner}, + load_program, + perf_attach::{PerfLinkIdInner, PerfLinkInner, perf_attach}, }, sys::{SyscallError, bpf_link_get_info_by_fd, perf_event_open}, }; @@ -58,12 +54,8 @@ pub enum PerfEventConfig { event_id: u64, }, /// A hardware breakpoint. - /// - /// Note: this variant is not fully implemented at the moment. - // TODO: Variant not fully implemented due to additional `perf_event_attr` fields like - // `bp_type`, `bp_addr`, etc. #[doc(alias = "PERF_TYPE_BREAKPOINT")] - Breakpoint, + Breakpoint(BreakpointConfig), /// The dynamic PMU (Performance Monitor Unit) event to report. /// /// Available PMU's may be found under `/sys/bus/event_source/devices`. @@ -84,7 +76,7 @@ pub enum PerfEventConfig { macro_rules! impl_to_u32 { ($($t:ty, $fn:ident),*) => { - $(const fn $fn(id: $t) -> u32 { + $(pub(crate) const fn $fn(id: $t) -> u32 { const _: [(); 4] = [(); std::mem::size_of::<$t>()]; id as u32 })* @@ -144,7 +136,7 @@ pub enum HardwareEvent { } impl HardwareEvent { - const fn into_primitive(self) -> u32 { + pub(crate) const fn into_primitive(self) -> u32 { const _: [(); 4] = [(); std::mem::size_of::()]; self as u32 } @@ -194,7 +186,7 @@ pub enum SoftwareEvent { } impl SoftwareEvent { - const fn into_primitive(self) -> u32 { + pub(crate) const fn into_primitive(self) -> u32 { const _: [(); 4] = [(); std::mem::size_of::()]; self as u32 } @@ -229,7 +221,7 @@ pub enum HwCacheEvent { } impl HwCacheEvent { - const fn into_primitive(self) -> u32 { + pub(crate) const fn into_primitive(self) -> u32 { const _: [(); 4] = [(); std::mem::size_of::()]; self as u32 } @@ -252,7 +244,7 @@ pub enum HwCacheOp { } impl HwCacheOp { - const fn into_primitive(self) -> u32 { + pub(crate) const fn into_primitive(self) -> u32 { const _: [(); 4] = [(); std::mem::size_of::()]; self as u32 } @@ -276,14 +268,82 @@ pub enum HwCacheResult { } impl HwCacheResult { - const fn into_primitive(self) -> u32 { + pub(crate) const fn into_primitive(self) -> u32 { const _: [(); 4] = [(); std::mem::size_of::()]; self as u32 } } +/// The breakpoint type. +#[repr(u32)] +#[derive(Debug, Clone, Copy)] +pub enum PerfBreakpointType { + /// HW_BREAKPOINT_R, trigger when we read the memory location. + #[doc(alias = "HW_BREAKPOINT_R")] + Read = HW_BREAKPOINT_R, + /// HW_BREAKPOINT_W, trigger when we write the memory location. + #[doc(alias = "HW_BREAKPOINT_W")] + Write = HW_BREAKPOINT_W, + /// HW_BREAKPOINT_RW, trigger when we read or write the memory location. + #[doc(alias = "HW_BREAKPOINT_RW")] + ReadWrite = HW_BREAKPOINT_RW, +} + +impl PerfBreakpointType { + pub(crate) const fn into_primitive(self) -> u32 { + const _: [(); 4] = [(); std::mem::size_of::()]; + self as u32 + } +} + +/// The number of bytes covered by a data breakpoint. +#[repr(u32)] +#[derive(Debug, Clone, Copy)] +pub enum PerfBreakpointLength { + /// HW_BREAKPOINT_LEN_1 + #[doc(alias = "HW_BREAKPOINT_LEN_1")] + Len1 = HW_BREAKPOINT_LEN_1, + /// HW_BREAKPOINT_LEN_2 + #[doc(alias = "HW_BREAKPOINT_LEN_2")] + Len2 = HW_BREAKPOINT_LEN_2, + /// HW_BREAKPOINT_LEN_4 + #[doc(alias = "HW_BREAKPOINT_LEN_4")] + Len4 = HW_BREAKPOINT_LEN_4, + /// HW_BREAKPOINT_LEN_8 + #[doc(alias = "HW_BREAKPOINT_LEN_8")] + Len8 = HW_BREAKPOINT_LEN_8, +} + +impl PerfBreakpointLength { + pub(crate) const fn into_primitive(self) -> u32 { + const _: [(); 4] = [(); std::mem::size_of::()]; + self as u32 + } +} + +/// Type of hardware breakpoint, determines if we break on read, write, or +/// execute, or if there should be no breakpoint on the given address. +#[derive(Debug, Clone, Copy)] +pub enum BreakpointConfig { + /// A memory access breakpoint. + Data { + /// The type of the breakpoint. + r#type: PerfBreakpointType, + /// The address of the breakpoint. + address: u64, + /// The contiguous byte window to monitor starting at `address`. + length: PerfBreakpointLength, + }, + /// A code execution breakpoint. + #[doc(alias = "HW_BREAKPOINT_X")] + Instruction { + /// The address of the breakpoint. + address: u64, + }, +} + /// Sample Policy -#[derive(Debug, Clone)] +#[derive(Debug, Clone, Copy)] pub enum SamplePolicy { /// Period Period(u64), @@ -291,27 +351,30 @@ pub enum SamplePolicy { Frequency(u64), } +/// Wakeup Policy +#[derive(Debug, Clone, Copy)] +pub(crate) enum WakeupPolicy { + /// Every N events + Events(u32), + /// Every N bytes + #[expect(dead_code)] + Watermark(u32), +} + /// The scope of a PerfEvent -#[derive(Debug, Clone)] +#[derive(Debug, Clone, Copy)] pub enum PerfEventScope { - /// Calling process, any cpu - CallingProcessAnyCpu, - /// calling process, one cpu - CallingProcessOneCpu { - /// cpu id - cpu: u32, + /// calling process + CallingProcess { + /// cpu id or any cpu if None + cpu: Option, }, - /// one process, any cpu - OneProcessAnyCpu { - /// process id - pid: u32, - }, - /// one process, one cpu - OneProcessOneCpu { - /// cpu id - cpu: u32, + /// one process + OneProcess { /// process id pid: u32, + /// cpu id or any cpu if None + cpu: Option, }, /// all processes, one cpu AllProcessesOneCpu { @@ -379,16 +442,13 @@ impl PerfEvent { /// Attaches to the given perf event. /// - /// [`perf_type`](PerfEventConfig) defines the event `type` and `config` of interest. - /// - /// [`scope`](PerfEventScope) determines which processes are sampled. If `inherit` is - /// `true`, any new processes spawned by those processes will also automatically be - /// sampled. + /// If `inherit` is `true`, any new processes spawned by those processes + /// will also automatically be sampled. /// - /// The returned value can be used to detach, see [PerfEvent::detach]. + /// The returned value can be used to detach, see [`Self::detach`]. pub fn attach( &mut self, - perf_type: PerfEventConfig, + config: PerfEventConfig, scope: PerfEventScope, sample_policy: SamplePolicy, inherit: bool, @@ -396,51 +456,11 @@ impl PerfEvent { let prog_fd = self.fd()?; let prog_fd = prog_fd.as_fd(); - let (perf_type, config) = match perf_type { - PerfEventConfig::Pmu { pmu_type, config } => (pmu_type, config), - PerfEventConfig::Hardware(hw_event) => ( - perf_type_id_to_u32(PERF_TYPE_HARDWARE), - u64::from(hw_event.into_primitive()), - ), - PerfEventConfig::Software(sw_event) => ( - perf_type_id_to_u32(PERF_TYPE_SOFTWARE), - u64::from(sw_event.into_primitive()), - ), - PerfEventConfig::TracePoint { event_id } => { - (perf_type_id_to_u32(PERF_TYPE_TRACEPOINT), event_id) - } - PerfEventConfig::HwCache { - event, - operation, - result, - } => ( - perf_type_id_to_u32(PERF_TYPE_HW_CACHE), - u64::from(event.into_primitive()) - | (u64::from(operation.into_primitive()) << 8) - | (u64::from(result.into_primitive()) << 16), - ), - PerfEventConfig::Raw { event_id } => (perf_type_id_to_u32(PERF_TYPE_RAW), event_id), - PerfEventConfig::Breakpoint => (perf_type_id_to_u32(PERF_TYPE_BREAKPOINT), 0), - }; - let (sample_period, sample_frequency) = match sample_policy { - SamplePolicy::Period(period) => (period, None), - SamplePolicy::Frequency(frequency) => (0, Some(frequency)), - }; - let (pid, cpu) = match scope { - PerfEventScope::CallingProcessAnyCpu => (0, -1), - PerfEventScope::CallingProcessOneCpu { cpu } => (0, cpu as i32), - PerfEventScope::OneProcessAnyCpu { pid } => (pid as i32, -1), - PerfEventScope::OneProcessOneCpu { cpu, pid } => (pid as i32, cpu as i32), - PerfEventScope::AllProcessesOneCpu { cpu } => (-1, cpu as i32), - }; - let fd = perf_event_open( - perf_type, + let perf_fd = perf_event_open( config, - pid, - cpu, - sample_period, - sample_frequency, - false, + scope, + sample_policy, + WakeupPolicy::Events(1), inherit, 0, ) @@ -449,7 +469,7 @@ impl PerfEvent { io_error, })?; - let link = perf_attach(prog_fd, fd, None /* cookie */)?; + let link = perf_attach(prog_fd, perf_fd, None /* cookie */)?; self.data.links.insert(PerfEventLink::new(link)) } } diff --git a/aya/src/programs/probe.rs b/aya/src/programs/probe.rs index 9f6eea90..0eecfc2c 100644 --- a/aya/src/programs/probe.rs +++ b/aya/src/programs/probe.rs @@ -1,6 +1,6 @@ use std::{ ffi::{OsStr, OsString}, - fmt::Write as _, + fmt::{self, Write}, fs::{self, OpenOptions}, io::{self, Write as _}, os::fd::AsFd as _, @@ -9,13 +9,10 @@ use std::{ sync::atomic::{AtomicUsize, Ordering}, }; -use libc::pid_t; - use crate::{ programs::{ - Link, ProgramData, ProgramError, kprobe::KProbeError, perf_attach, - perf_attach::PerfLinkInner, perf_attach_debugfs, trace_point::read_sys_fs_trace_point_id, - uprobe::UProbeError, utils::find_tracefs_path, + Link, ProgramData, ProgramError, perf_attach, perf_attach::PerfLinkInner, + perf_attach_debugfs, trace_point::read_sys_fs_trace_point_id, utils::find_tracefs_path, }, sys::{SyscallError, perf_event_open_probe, perf_event_open_trace_point}, util::KernelVersion, @@ -26,23 +23,20 @@ static PROBE_NAME_INDEX: AtomicUsize = AtomicUsize::new(0); /// Kind of probe program #[derive(Debug, Copy, Clone)] pub enum ProbeKind { - /// Kernel probe - KProbe, - /// Kernel return probe - KRetProbe, - /// User space probe - UProbe, - /// User space return probe - URetProbe, + /// Probe the entry of the function + Entry, + /// Probe the return of the function + Return, } -impl ProbeKind { - fn pmu(&self) -> &'static str { - match *self { - Self::KProbe | Self::KRetProbe => "kprobe", - Self::UProbe | Self::URetProbe => "uprobe", - } - } +pub(crate) trait Probe { + const PMU: &'static str; + + type Error: Into; + + fn file_error(filename: PathBuf, io_error: io::Error) -> Self::Error; + + fn write_offset(w: &mut W, kind: ProbeKind, offset: u64) -> fmt::Result; } pub(crate) fn lines(bytes: &[u8]) -> impl Iterator { @@ -94,13 +88,53 @@ impl OsStringExt for OsStr { } } +type DetachDebugFs = fn(&OsStr) -> Result<(), ProgramError>; + #[derive(Debug)] pub(crate) struct ProbeEvent { - kind: ProbeKind, event_alias: OsString, + detach_debug_fs: Option<(DetachDebugFs, bool)>, +} + +impl ProbeEvent { + pub(crate) fn disarm(&mut self) { + let Self { + event_alias: _, + detach_debug_fs, + } = self; + if let Some((_detach_debug_fs, is_guard)) = detach_debug_fs { + *is_guard = false; + } + } + + pub(crate) fn detach(mut self) -> Result<(), ProgramError> { + let Self { + event_alias, + detach_debug_fs, + } = &mut self; + detach_debug_fs + .take() + .map(|(detach_debug_fs, _is_guard)| detach_debug_fs(event_alias)) + .transpose()?; + Ok(()) + } } -pub(crate) fn attach>( +impl Drop for ProbeEvent { + fn drop(&mut self) { + let Self { + event_alias, + detach_debug_fs, + } = self; + if let Some((detach_debug_fs, is_guard)) = detach_debug_fs { + if *is_guard { + let _: Result<(), ProgramError> = detach_debug_fs(event_alias); + } + } + } +} + +pub(crate) fn attach>( program_data: &mut ProgramData, kind: ProbeKind, // NB: the meaning of this argument is different for kprobe/kretprobe and uprobe/uretprobe; in @@ -111,7 +145,7 @@ pub(crate) fn attach>( // separate argument. fn_name: &OsStr, offset: u64, - pid: Option, + pid: Option, cookie: Option, ) -> Result { // https://github.com/torvalds/linux/commit/e12f03d7031a977356e3d7b75a68c2185ff8d155 @@ -122,58 +156,37 @@ pub(crate) fn attach>( if cookie.is_some() { return Err(ProgramError::AttachCookieNotSupported); } - let (fd, event_alias) = create_as_trace_point(kind, fn_name, offset, pid)?; - perf_attach_debugfs(prog_fd, fd, ProbeEvent { kind, event_alias }) + let (perf_fd, event) = create_as_trace_point::

(kind, fn_name, offset, pid)?; + perf_attach_debugfs(prog_fd, perf_fd, event) } else { - let fd = create_as_probe(kind, fn_name, offset, pid)?; - perf_attach(prog_fd, fd, cookie) + let perf_fd = create_as_probe::

(kind, fn_name, offset, pid)?; + perf_attach(prog_fd, perf_fd, cookie) }?; program_data.links.insert(T::from(link)) } -pub(crate) fn detach_debug_fs(event: ProbeEvent) -> Result<(), ProgramError> { - use ProbeKind::*; - +fn detach_debug_fs(event_alias: &OsStr) -> Result<(), ProgramError> { let tracefs = find_tracefs_path()?; - let ProbeEvent { - kind, - event_alias: _, - } = &event; - let kind = *kind; - let result = delete_probe_event(tracefs, event); - - result.map_err(|(filename, io_error)| match kind { - KProbe | KRetProbe => KProbeError::FileError { filename, io_error }.into(), - UProbe | URetProbe => UProbeError::FileError { filename, io_error }.into(), - }) + delete_probe_event(tracefs, P::PMU, event_alias) + .map_err(|(filename, io_error)| P::file_error(filename, io_error).into()) } -fn create_as_probe( +fn create_as_probe( kind: ProbeKind, fn_name: &OsStr, offset: u64, - pid: Option, + pid: Option, ) -> Result { - use ProbeKind::*; - - let perf_ty = match kind { - KProbe | KRetProbe => read_sys_fs_perf_type(kind.pmu()) - .map_err(|(filename, io_error)| KProbeError::FileError { filename, io_error })?, - UProbe | URetProbe => read_sys_fs_perf_type(kind.pmu()) - .map_err(|(filename, io_error)| UProbeError::FileError { filename, io_error })?, - }; + let perf_ty = read_sys_fs_perf_type(P::PMU) + .map_err(|(filename, io_error)| P::file_error(filename, io_error).into())?; let ret_bit = match kind { - KRetProbe => Some( - read_sys_fs_perf_ret_probe(kind.pmu()) - .map_err(|(filename, io_error)| KProbeError::FileError { filename, io_error })?, - ), - URetProbe => Some( - read_sys_fs_perf_ret_probe(kind.pmu()) - .map_err(|(filename, io_error)| UProbeError::FileError { filename, io_error })?, + ProbeKind::Return => Some( + read_sys_fs_perf_ret_probe(P::PMU) + .map_err(|(filename, io_error)| P::file_error(filename, io_error).into())?, ), - _ => None, + ProbeKind::Entry => None, }; perf_event_open_probe(perf_ty, ret_bit, fn_name, offset, pid) @@ -184,47 +197,42 @@ fn create_as_probe( .map_err(Into::into) } -fn create_as_trace_point( +fn create_as_trace_point( kind: ProbeKind, name: &OsStr, offset: u64, - pid: Option, -) -> Result<(crate::MockableFd, OsString), ProgramError> { - use ProbeKind::*; - + pid: Option, +) -> Result<(crate::MockableFd, ProbeEvent), ProgramError> { let tracefs = find_tracefs_path()?; - let event_alias = match kind { - KProbe | KRetProbe => create_probe_event(tracefs, kind, name, offset) - .map_err(|(filename, io_error)| KProbeError::FileError { filename, io_error })?, - UProbe | URetProbe => create_probe_event(tracefs, kind, name, offset) - .map_err(|(filename, io_error)| UProbeError::FileError { filename, io_error })?, - }; + let event = create_probe_event::

(tracefs, kind, name, offset) + .map_err(|(filename, io_error)| P::file_error(filename, io_error).into())?; - let category = format!("{}s", kind.pmu()); + let ProbeEvent { + event_alias, + detach_debug_fs: _, + } = &event; + let category = format!("{}s", P::PMU); let tpid = read_sys_fs_trace_point_id(tracefs, &category, event_alias.as_ref())?; - let fd = perf_event_open_trace_point(tpid, pid).map_err(|io_error| SyscallError { + let perf_fd = perf_event_open_trace_point(tpid, pid).map_err(|io_error| SyscallError { call: "perf_event_open", io_error, })?; - Ok((fd, event_alias)) + Ok((perf_fd, event)) } -fn create_probe_event( +fn create_probe_event( tracefs: &Path, kind: ProbeKind, fn_name: &OsStr, offset: u64, -) -> Result { +) -> Result { use std::os::unix::ffi::OsStrExt as _; - use ProbeKind::*; - - let events_file_name = tracefs.join(format!("{}_events", kind.pmu())); let probe_type_prefix = match kind { - KProbe | UProbe => 'p', - KRetProbe | URetProbe => 'r', + ProbeKind::Entry => 'p', + ProbeKind::Return => 'r', }; let mut event_alias = OsString::new(); @@ -251,31 +259,34 @@ fn create_probe_event( .unwrap(); let mut probe = OsString::new(); - write!(&mut probe, "{}:{}s/", probe_type_prefix, kind.pmu()).unwrap(); + write!(&mut probe, "{}:{}s/", probe_type_prefix, P::PMU).unwrap(); probe.push(&event_alias); probe.push(" "); probe.push(fn_name); - match kind { - KProbe => write!(&mut probe, "+{offset}").unwrap(), - UProbe | URetProbe => write!(&mut probe, ":{offset:#x}").unwrap(), - _ => {} - }; + P::write_offset(&mut probe, kind, offset).unwrap(); probe.push("\n"); + let events_file_name = tracefs.join(format!("{}_events", P::PMU)); OpenOptions::new() .append(true) .open(&events_file_name) .and_then(|mut events_file| events_file.write_all(probe.as_bytes())) .map_err(|e| (events_file_name, e))?; - Ok(event_alias) + Ok(ProbeEvent { + event_alias, + detach_debug_fs: Some((detach_debug_fs::

, true)), + }) } -fn delete_probe_event(tracefs: &Path, event: ProbeEvent) -> Result<(), (PathBuf, io::Error)> { +fn delete_probe_event( + tracefs: &Path, + pmu: &str, + event_alias: &OsStr, +) -> Result<(), (PathBuf, io::Error)> { use std::os::unix::ffi::OsStrExt as _; - let ProbeEvent { kind, event_alias } = event; - let events_file_name = tracefs.join(format!("{}_events", kind.pmu())); + let events_file_name = tracefs.join(format!("{}_events", pmu)); fs::read(&events_file_name) .and_then(|events| { @@ -324,7 +335,7 @@ fn read_sys_fs_perf_type(pmu: &str) -> Result { .join("type"); fs::read_to_string(&file) - .and_then(|perf_ty| perf_ty.trim().parse::().map_err(io::Error::other)) + .and_then(|perf_ty| perf_ty.trim().parse().map_err(io::Error::other)) .map_err(|e| (file, e)) } @@ -340,7 +351,7 @@ fn read_sys_fs_perf_ret_probe(pmu: &str) -> Result { .next() .ok_or_else(|| io::Error::other("invalid format"))?; - config.parse::().map_err(io::Error::other) + config.parse().map_err(io::Error::other) }) .map_err(|e| (file, e)) } diff --git a/aya/src/programs/trace_point.rs b/aya/src/programs/trace_point.rs index 651e8b13..4fbc83b9 100644 --- a/aya/src/programs/trace_point.rs +++ b/aya/src/programs/trace_point.rs @@ -79,12 +79,12 @@ impl TracePoint { let prog_fd = prog_fd.as_fd(); let tracefs = find_tracefs_path()?; let id = read_sys_fs_trace_point_id(tracefs, category, name.as_ref())?; - let fd = perf_event_open_trace_point(id, None).map_err(|io_error| SyscallError { + let perf_fd = perf_event_open_trace_point(id, None).map_err(|io_error| SyscallError { call: "perf_event_open_trace_point", io_error, })?; - let link = perf_attach(prog_fd, fd, None /* cookie */)?; + let link = perf_attach(prog_fd, perf_fd, None /* cookie */)?; self.data.links.insert(TracePointLink::new(link)) } } @@ -115,14 +115,14 @@ pub(crate) fn read_sys_fs_trace_point_id( tracefs: &Path, category: &str, name: &Path, -) -> Result { +) -> Result { let filename = tracefs.join("events").join(category).join(name).join("id"); let id = match fs::read_to_string(&filename) { Ok(id) => id, Err(io_error) => return Err(TracePointError::FileError { filename, io_error }), }; - let id = match id.trim().parse::() { + let id = match id.trim().parse() { Ok(id) => id, Err(error) => { return Err(TracePointError::FileError { diff --git a/aya/src/programs/uprobe.rs b/aya/src/programs/uprobe.rs index 69378b8c..0e15fc39 100644 --- a/aya/src/programs/uprobe.rs +++ b/aya/src/programs/uprobe.rs @@ -2,6 +2,7 @@ use std::{ error::Error, ffi::{CStr, OsStr, OsString}, + fmt::{self, Write}, fs, io::{self, BufRead as _, Cursor, Read as _}, mem, @@ -11,7 +12,6 @@ use std::{ }; use aya_obj::generated::{bpf_link_type, bpf_prog_type::BPF_PROG_TYPE_KPROBE}; -use libc::pid_t; use object::{Object as _, ObjectSection as _, ObjectSymbol as _, Symbol}; use thiserror::Error; @@ -21,7 +21,7 @@ use crate::{ FdLink, LinkError, ProgramData, ProgramError, ProgramType, define_link_wrapper, impl_try_into_fdlink, load_program, perf_attach::{PerfLinkIdInner, PerfLinkInner}, - probe::{OsStringExt as _, ProbeKind, attach}, + probe::{OsStringExt as _, Probe, ProbeKind, attach}, }, sys::bpf_link_get_info_by_fd, util::MMap, @@ -81,8 +81,8 @@ impl UProbe { load_program(BPF_PROG_TYPE_KPROBE, &mut self.data) } - /// Returns `UProbe` if the program is a `uprobe`, or `URetProbe` if the - /// program is a `uretprobe`. + /// Returns [`ProbeKind::Entry`] if the program is a `uprobe`, or + /// [`ProbeKind::Return`] if the program is a `uretprobe`. pub fn kind(&self) -> ProbeKind { self.kind } @@ -109,7 +109,7 @@ impl UProbe { &mut self, location: Loc, target: T, - pid: Option, + pid: Option, cookie: Option, ) -> Result { let proc_map = pid.map(ProcMap::new).transpose()?; @@ -130,8 +130,9 @@ impl UProbe { offset }; + let Self { data, kind } = self; let path = path.as_os_str(); - attach(&mut self.data, self.kind, path, offset, pid, cookie) + attach::(data, *kind, path, offset, pid, cookie) } /// Creates a program from a pinned entry on a bpffs. @@ -146,6 +147,20 @@ impl UProbe { } } +impl Probe for UProbe { + const PMU: &'static str = "uprobe"; + + type Error = UProbeError; + + fn file_error(filename: PathBuf, io_error: io::Error) -> Self::Error { + UProbeError::FileError { filename, io_error } + } + + fn write_offset(w: &mut W, _: ProbeKind, offset: u64) -> fmt::Result { + write!(w, ":{offset:#x}") + } +} + fn resolve_attach_path<'a, 'b, 'c, T>( target: &'a Path, proc_map: Option<&'b ProcMap>, @@ -159,9 +174,10 @@ where .and_then(|proc_map| { proc_map .find_library_path_by_name(target) - .map_err(|source| UProbeError::ProcMap { - pid: proc_map.pid, - source, + .map_err(|source| { + let ProcMap { pid, data: _ } = proc_map; + let pid = *pid; + UProbeError::ProcMap { pid, source } }) .transpose() }) @@ -190,7 +206,7 @@ where )] fn test_resolve_attach_path() { // Look up the current process's pid. - let pid = std::process::id().try_into().unwrap(); + let pid = std::process::id(); let proc_map = ProcMap::new(pid).unwrap(); // Now let's resolve the path to libc. It should exist in the current process's memory map and @@ -208,6 +224,19 @@ fn test_resolve_attach_path() { Some(libc_path) if libc_path.contains("libc"), "libc_path: {}", libc_path.display() ); + + // If we pass an absolute path that doesn't match anything in /proc//maps, we should fall + // back to the provided path instead of erroring out. Using a synthetic absolute path keeps the + // test hermetic. + let synthetic_absolute = Path::new("/tmp/.aya-test-resolve-attach-absolute"); + let absolute_path = + resolve_attach_path(synthetic_absolute, Some(&proc_map)).unwrap_or_else(|err| { + match err.source() { + Some(source) => panic!("{err}: {source}"), + None => panic!("{err}"), + } + }); + assert_eq!(absolute_path, synthetic_absolute); } define_link_wrapper!( @@ -274,7 +303,7 @@ pub enum UProbeError { #[error("error fetching libs for {pid}")] ProcMap { /// The pid. - pid: i32, + pid: u32, /// The [`ProcMapError`] that caused the error. #[source] source: ProcMapError, @@ -406,12 +435,12 @@ impl<'a> ProcMapEntry<'a> { /// /// The information here may be used to resolve addresses to paths. struct ProcMap { - pid: pid_t, + pid: u32, data: T, } impl ProcMap> { - fn new(pid: pid_t) -> Result { + fn new(pid: u32) -> Result { let filename = PathBuf::from(format!("/proc/{pid}/maps")); let data = fs::read(&filename) .map_err(|io_error| UProbeError::FileError { filename, io_error })?; @@ -425,6 +454,8 @@ impl> ProcMap { data.as_ref() .split(|&b| b == b'\n') + // /proc//maps ends with '\n', so split() yields a trailing empty slice. + .filter(|line| !line.is_empty()) .map(ProcMapEntry::parse) } @@ -1010,8 +1041,7 @@ mod tests { 7f372288f000-7f3722899000 r--p 00027000 00:24 18097875 /usr/lib64/ld-linux-x86-64.so.2 7f3722899000-7f372289b000 r--p 00030000 00:24 18097875 /usr/lib64/ld-linux-x86-64.so.2 7f372289b000-7f372289d000 rw-p 00032000 00:24 18097875 /usr/lib64/ld-linux-x86-64.so.2 -"# - .trim_ascii(), +"#, }; assert_matches!( diff --git a/aya/src/sys/perf_event.rs b/aya/src/sys/perf_event.rs index afedefa9..c5592c83 100644 --- a/aya/src/sys/perf_event.rs +++ b/aya/src/sys/perf_event.rs @@ -1,62 +1,131 @@ use std::{ - ffi::{CString, OsStr, c_int}, + ffi::{CString, OsStr, c_long, c_uint}, io, mem, os::fd::{BorrowedFd, FromRawFd as _}, }; use aya_obj::generated::{ - PERF_FLAG_FD_CLOEXEC, perf_event_attr, + HW_BREAKPOINT_LEN_1, HW_BREAKPOINT_LEN_2, HW_BREAKPOINT_LEN_4, HW_BREAKPOINT_LEN_8, + HW_BREAKPOINT_X, PERF_FLAG_FD_CLOEXEC, perf_event_attr, perf_event_sample_format::PERF_SAMPLE_RAW, - perf_sw_ids::PERF_COUNT_SW_BPF_OUTPUT, - perf_type_id::{PERF_TYPE_SOFTWARE, PERF_TYPE_TRACEPOINT}, + perf_type_id::{ + PERF_TYPE_BREAKPOINT, PERF_TYPE_HARDWARE, PERF_TYPE_HW_CACHE, PERF_TYPE_RAW, + PERF_TYPE_SOFTWARE, PERF_TYPE_TRACEPOINT, + }, }; use libc::pid_t; use super::{PerfEventIoctlRequest, Syscall, syscall}; +use crate::programs::perf_event::{ + BreakpointConfig, PerfEventConfig, PerfEventScope, SamplePolicy, WakeupPolicy, + perf_type_id_to_u32, +}; -#[expect(clippy::too_many_arguments)] pub(crate) fn perf_event_open( - perf_type: u32, - config: u64, - pid: pid_t, - cpu: c_int, - sample_period: u64, - sample_frequency: Option, - wakeup: bool, + config: PerfEventConfig, + scope: PerfEventScope, + sample_policy: SamplePolicy, + wakeup_policy: WakeupPolicy, inherit: bool, flags: u32, ) -> io::Result { let mut attr = unsafe { mem::zeroed::() }; + let (perf_type, config) = match config { + PerfEventConfig::Pmu { pmu_type, config } => (pmu_type, config), + PerfEventConfig::Hardware(hw_event) => ( + perf_type_id_to_u32(PERF_TYPE_HARDWARE), + u64::from(hw_event.into_primitive()), + ), + PerfEventConfig::Software(sw_event) => ( + perf_type_id_to_u32(PERF_TYPE_SOFTWARE), + u64::from(sw_event.into_primitive()), + ), + PerfEventConfig::TracePoint { event_id } => { + (perf_type_id_to_u32(PERF_TYPE_TRACEPOINT), event_id) + } + PerfEventConfig::HwCache { + event, + operation, + result, + } => ( + perf_type_id_to_u32(PERF_TYPE_HW_CACHE), + u64::from(event.into_primitive()) + | (u64::from(operation.into_primitive()) << 8) + | (u64::from(result.into_primitive()) << 16), + ), + PerfEventConfig::Raw { event_id } => (perf_type_id_to_u32(PERF_TYPE_RAW), event_id), + PerfEventConfig::Breakpoint(breakpoint) => { + let (type_, address, length) = match breakpoint { + BreakpointConfig::Data { + r#type, + address, + length, + } => ( + r#type.into_primitive(), + address, + u64::from(length.into_primitive()), + ), + BreakpointConfig::Instruction { address } => { + const fn length(size: usize) -> c_uint { + match size { + 1 => HW_BREAKPOINT_LEN_1, + 2 => HW_BREAKPOINT_LEN_2, + 4 => HW_BREAKPOINT_LEN_4, + 8 => HW_BREAKPOINT_LEN_8, + // NB: cannot emit the value because: + // + // error[E0015]: cannot call non-const formatting macro in constant functions + _ => panic!("invalid hardware breakpoint size"), + } + } + const LENGTH: c_uint = length(std::mem::size_of::()); + (HW_BREAKPOINT_X, address, u64::from(LENGTH)) + } + }; + + attr.bp_type = type_; + attr.__bindgen_anon_3.bp_addr = address; + attr.__bindgen_anon_4.bp_len = length; + attr.set_precise_ip(2); + + (perf_type_id_to_u32(PERF_TYPE_BREAKPOINT), 0) + } + }; + attr.config = config; attr.size = mem::size_of::() as u32; attr.type_ = perf_type; attr.sample_type = PERF_SAMPLE_RAW as u64; attr.set_inherit(if inherit { 1 } else { 0 }); - attr.__bindgen_anon_2.wakeup_events = u32::from(wakeup); - if let Some(frequency) = sample_frequency { - attr.set_freq(1); - attr.__bindgen_anon_1.sample_freq = frequency; - } else { - attr.__bindgen_anon_1.sample_period = sample_period; + match sample_policy { + SamplePolicy::Period(period) => { + attr.__bindgen_anon_1.sample_period = period; + } + SamplePolicy::Frequency(frequency) => { + attr.set_freq(1); + attr.__bindgen_anon_1.sample_freq = frequency; + } } - perf_event_sys(attr, pid, cpu, flags) -} + match wakeup_policy { + WakeupPolicy::Events(events) => { + attr.__bindgen_anon_2.wakeup_events = events; + } + WakeupPolicy::Watermark(watermark) => { + attr.set_watermark(1); + attr.__bindgen_anon_2.wakeup_watermark = watermark; + } + } -pub(crate) fn perf_event_open_bpf(cpu: c_int) -> io::Result { - perf_event_open( - PERF_TYPE_SOFTWARE as u32, - PERF_COUNT_SW_BPF_OUTPUT as u64, - -1, - cpu, - 1, - None, - true, - false, - PERF_FLAG_FD_CLOEXEC, - ) + let (pid, cpu) = match scope { + PerfEventScope::CallingProcess { cpu } => (0, cpu.map_or(-1, |cpu| cpu as i32)), + PerfEventScope::OneProcess { pid, cpu } => (pid as i32, cpu.map_or(-1, |cpu| cpu as i32)), + PerfEventScope::AllProcessesOneCpu { cpu } => (-1, cpu as i32), + }; + + perf_event_sys(attr, pid, cpu, flags) } pub(crate) fn perf_event_open_probe( @@ -64,7 +133,7 @@ pub(crate) fn perf_event_open_probe( ret_bit: Option, name: &OsStr, offset: u64, - pid: Option, + pid: Option, ) -> io::Result { use std::os::unix::ffi::OsStrExt as _; @@ -81,26 +150,30 @@ pub(crate) fn perf_event_open_probe( attr.__bindgen_anon_3.config1 = c_name.as_ptr() as u64; attr.__bindgen_anon_4.config2 = offset; - let cpu = if pid.is_some() { -1 } else { 0 }; - let pid = pid.unwrap_or(-1); + let (pid, cpu) = match pid { + Some(pid) => (pid as i32, -1), + None => (-1, 0), + }; perf_event_sys(attr, pid, cpu, PERF_FLAG_FD_CLOEXEC) } pub(crate) fn perf_event_open_trace_point( - id: u32, - pid: Option, + event_id: u64, + pid: Option, ) -> io::Result { - let mut attr = unsafe { mem::zeroed::() }; - - attr.size = mem::size_of::() as u32; - attr.type_ = PERF_TYPE_TRACEPOINT as u32; - attr.config = u64::from(id); - - let cpu = if pid.is_some() { -1 } else { 0 }; - let pid = pid.unwrap_or(-1); - - perf_event_sys(attr, pid, cpu, PERF_FLAG_FD_CLOEXEC) + let scope = match pid { + Some(pid) => PerfEventScope::OneProcess { pid, cpu: None }, + None => PerfEventScope::AllProcessesOneCpu { cpu: 0 }, + }; + perf_event_open( + PerfEventConfig::TracePoint { event_id }, + scope, + SamplePolicy::Period(0), + WakeupPolicy::Events(1), + false, + PERF_FLAG_FD_CLOEXEC, + ) } pub(crate) fn perf_event_ioctl( diff --git a/aya/src/util.rs b/aya/src/util.rs index 3a04aa2a..200b80a1 100644 --- a/aya/src/util.rs +++ b/aya/src/util.rs @@ -323,7 +323,9 @@ fn parse_kernel_symbols(reader: impl BufRead) -> Result, i /// # Example /// /// ```no_run +/// # #[expect(deprecated)] /// use aya::util::syscall_prefix; +/// # #[expect(deprecated)] /// let prefix = syscall_prefix().unwrap(); /// let syscall_fname = format!("{prefix}exec"); /// ``` diff --git a/clippy.sh b/clippy.sh index ca314276..9641623b 100755 --- a/clippy.sh +++ b/clippy.sh @@ -4,12 +4,12 @@ set -eux # `-C panic=abort` because "unwinding panics are not supported without std"; integration-ebpf # contains `#[no_std]` binaries. -# +# # `-Zpanic_abort_tests` because "building tests with panic=abort is not supported without # `-Zpanic_abort_tests`"; Cargo does this automatically when panic=abort is set via profile but we # want to preserve unwinding at runtime - here we are just running clippy so we don't care about # unwinding behavior. -# +# # `+nightly` because "the option `Z` is only accepted on the nightly compiler". cargo +nightly hack clippy "$@" \ --all-targets \ @@ -18,17 +18,30 @@ cargo +nightly hack clippy "$@" \ -C panic=abort \ -Zpanic_abort_tests +export CLIPPY_ARGS='--deny=warnings' +export RUSTDOCFLAGS='--no-run -Z unstable-options --test-builder clippy-driver' + +cargo +nightly hack test --doc "$@" --feature-powerset for arch in aarch64 arm loongarch64 mips powerpc64 riscv64 s390x x86_64; do + export RUSTFLAGS="--cfg bpf_target_arch=\"$arch\"" + for target in bpfeb-unknown-none bpfel-unknown-none; do - RUSTFLAGS="--cfg bpf_target_arch=\"$arch\"" cargo +nightly hack clippy \ + cargo +nightly hack clippy \ --target "$target" \ -Zbuild-std=core \ - --package aya-ebpf-bindings \ --package aya-ebpf \ + --package aya-ebpf-bindings \ --package aya-log-ebpf \ --package integration-ebpf \ --feature-powerset \ -- --deny warnings - done + done + + RUSTDOCFLAGS="$RUSTDOCFLAGS $RUSTFLAGS" cargo +nightly hack test --doc "$@" \ + --package aya-ebpf \ + --package aya-ebpf-bindings \ + --package aya-log-ebpf \ + --package integration-ebpf \ + --feature-powerset done diff --git a/ebpf/aya-ebpf-bindings/CHANGELOG.md b/ebpf/aya-ebpf-bindings/CHANGELOG.md index 1bf9dac2..6dc862e8 100644 --- a/ebpf/aya-ebpf-bindings/CHANGELOG.md +++ b/ebpf/aya-ebpf-bindings/CHANGELOG.md @@ -5,6 +5,18 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [Unreleased] + +## v0.1.2 (2025-11-17) + +### New Features + + - , , Regenerated the bindings from libbpf 324f3c38…, pulling in MIPS and LoongArch64 support alongside the latest kernel constants. + +### Maintenance + + - , General lint/build fixes (including the riscv64 build) to keep the generated code warning-free. + ## v0.1.1 (2024-10-09) ### Other diff --git a/ebpf/aya-ebpf-bindings/Cargo.toml b/ebpf/aya-ebpf-bindings/Cargo.toml index a75b8d0a..f906ab5e 100644 --- a/ebpf/aya-ebpf-bindings/Cargo.toml +++ b/ebpf/aya-ebpf-bindings/Cargo.toml @@ -1,7 +1,7 @@ [package] description = "Bindings for Linux Kernel eBPF types and helpers" name = "aya-ebpf-bindings" -version = "0.1.1" +version = "0.1.2" authors.workspace = true edition.workspace = true @@ -13,7 +13,7 @@ repository.workspace = true workspace = true [dependencies] -aya-ebpf-cty = { version = "^0.2.2", path = "../aya-ebpf-cty" } +aya-ebpf-cty = { version = "^0.2.3", path = "../aya-ebpf-cty" } [build-dependencies] -aya-build = { version = "^0.1.2", path = "../../aya-build" } +aya-build = { version = "^0.1.3", path = "../../aya-build" } diff --git a/ebpf/aya-ebpf-bindings/include/bindings.h b/ebpf/aya-ebpf-bindings/include/bindings.h index aa831c57..ba2f9183 100644 --- a/ebpf/aya-ebpf-bindings/include/bindings.h +++ b/ebpf/aya-ebpf-bindings/include/bindings.h @@ -6,6 +6,7 @@ typedef __u32 __bitwise __wsum; #include #include +#include // needed for TC_ACT_* #include #include diff --git a/ebpf/aya-ebpf-bindings/src/aarch64/bindings.rs b/ebpf/aya-ebpf-bindings/src/aarch64/bindings.rs index 87ef0587..473db3c6 100644 --- a/ebpf/aya-ebpf-bindings/src/aarch64/bindings.rs +++ b/ebpf/aya-ebpf-bindings/src/aarch64/bindings.rs @@ -365,11 +365,6 @@ pub type __be32 = __u32; pub type __wsum = __u32; #[repr(C)] #[derive(Debug, Copy, Clone)] -pub struct bpf_perf_event_data { - _unused: [u8; 0], -} -#[repr(C)] -#[derive(Debug, Copy, Clone)] pub struct linux_binprm { _unused: [u8; 0], } @@ -2887,6 +2882,14 @@ pub struct user_pt_regs { pub pc: __u64, pub pstate: __u64, } +pub type bpf_user_pt_regs_t = user_pt_regs; +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct bpf_perf_event_data { + pub regs: bpf_user_pt_regs_t, + pub sample_period: __u64, + pub addr: __u64, +} pub type sa_family_t = ::aya_ebpf_cty::c_ushort; #[repr(C)] #[derive(Debug, Copy, Clone)] diff --git a/ebpf/aya-ebpf-bindings/src/armv7/bindings.rs b/ebpf/aya-ebpf-bindings/src/armv7/bindings.rs index 54140c49..50c1d6f7 100644 --- a/ebpf/aya-ebpf-bindings/src/armv7/bindings.rs +++ b/ebpf/aya-ebpf-bindings/src/armv7/bindings.rs @@ -365,11 +365,6 @@ pub type __be32 = __u32; pub type __wsum = __u32; #[repr(C)] #[derive(Debug, Copy, Clone)] -pub struct bpf_perf_event_data { - _unused: [u8; 0], -} -#[repr(C)] -#[derive(Debug, Copy, Clone)] pub struct linux_binprm { _unused: [u8; 0], } @@ -2896,6 +2891,14 @@ pub struct bpf_iter_num { pub struct pt_regs { pub uregs: [::aya_ebpf_cty::c_long; 18usize], } +pub type bpf_user_pt_regs_t = pt_regs; +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct bpf_perf_event_data { + pub regs: bpf_user_pt_regs_t, + pub sample_period: __u64, + pub addr: __u64, +} pub type sa_family_t = ::aya_ebpf_cty::c_ushort; #[repr(C)] #[derive(Debug, Copy, Clone)] diff --git a/ebpf/aya-ebpf-bindings/src/loongarch64/bindings.rs b/ebpf/aya-ebpf-bindings/src/loongarch64/bindings.rs index f769d7b9..4ffb76ce 100644 --- a/ebpf/aya-ebpf-bindings/src/loongarch64/bindings.rs +++ b/ebpf/aya-ebpf-bindings/src/loongarch64/bindings.rs @@ -365,11 +365,6 @@ pub type __be32 = __u32; pub type __wsum = __u32; #[repr(C)] #[derive(Debug, Copy, Clone)] -pub struct bpf_perf_event_data { - _unused: [u8; 0], -} -#[repr(C)] -#[derive(Debug, Copy, Clone)] pub struct linux_binprm { _unused: [u8; 0], } @@ -2888,6 +2883,14 @@ pub struct user_pt_regs { pub csr_badv: ::aya_ebpf_cty::c_ulong, pub reserved: [::aya_ebpf_cty::c_ulong; 10usize], } +pub type bpf_user_pt_regs_t = user_pt_regs; +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct bpf_perf_event_data { + pub regs: bpf_user_pt_regs_t, + pub sample_period: __u64, + pub addr: __u64, +} pub type sa_family_t = ::aya_ebpf_cty::c_ushort; #[repr(C)] #[derive(Debug, Copy, Clone)] diff --git a/ebpf/aya-ebpf-bindings/src/mips/bindings.rs b/ebpf/aya-ebpf-bindings/src/mips/bindings.rs index 65333c5c..1bacaa53 100644 --- a/ebpf/aya-ebpf-bindings/src/mips/bindings.rs +++ b/ebpf/aya-ebpf-bindings/src/mips/bindings.rs @@ -366,11 +366,6 @@ pub type __be32 = __u32; pub type __wsum = __u32; #[repr(C)] #[derive(Debug, Copy, Clone)] -pub struct bpf_perf_event_data { - _unused: [u8; 0], -} -#[repr(C)] -#[derive(Debug, Copy, Clone)] pub struct linux_binprm { _unused: [u8; 0], } @@ -2903,6 +2898,14 @@ pub struct pt_regs { pub cp0_status: __u64, pub cp0_cause: __u64, } +pub type bpf_user_pt_regs_t = pt_regs; +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct bpf_perf_event_data { + pub regs: bpf_user_pt_regs_t, + pub sample_period: __u64, + pub addr: __u64, +} pub type sa_family_t = ::aya_ebpf_cty::c_ushort; #[repr(C)] #[derive(Debug, Copy, Clone)] diff --git a/ebpf/aya-ebpf-bindings/src/powerpc64/bindings.rs b/ebpf/aya-ebpf-bindings/src/powerpc64/bindings.rs index bc1388bf..7e46bcb7 100644 --- a/ebpf/aya-ebpf-bindings/src/powerpc64/bindings.rs +++ b/ebpf/aya-ebpf-bindings/src/powerpc64/bindings.rs @@ -365,11 +365,6 @@ pub type __be32 = __u32; pub type __wsum = __u32; #[repr(C)] #[derive(Debug, Copy, Clone)] -pub struct bpf_perf_event_data { - _unused: [u8; 0], -} -#[repr(C)] -#[derive(Debug, Copy, Clone)] pub struct linux_binprm { _unused: [u8; 0], } @@ -2891,6 +2886,14 @@ pub struct pt_regs { pub dsisr: ::aya_ebpf_cty::c_ulong, pub result: ::aya_ebpf_cty::c_ulong, } +pub type bpf_user_pt_regs_t = pt_regs; +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct bpf_perf_event_data { + pub regs: bpf_user_pt_regs_t, + pub sample_period: __u64, + pub addr: __u64, +} pub type sa_family_t = ::aya_ebpf_cty::c_ushort; #[repr(C)] #[derive(Debug, Copy, Clone)] diff --git a/ebpf/aya-ebpf-bindings/src/riscv64/bindings.rs b/ebpf/aya-ebpf-bindings/src/riscv64/bindings.rs index 98b85819..c90a7d2a 100644 --- a/ebpf/aya-ebpf-bindings/src/riscv64/bindings.rs +++ b/ebpf/aya-ebpf-bindings/src/riscv64/bindings.rs @@ -365,11 +365,6 @@ pub type __be32 = __u32; pub type __wsum = __u32; #[repr(C)] #[derive(Debug, Copy, Clone)] -pub struct bpf_perf_event_data { - _unused: [u8; 0], -} -#[repr(C)] -#[derive(Debug, Copy, Clone)] pub struct linux_binprm { _unused: [u8; 0], } @@ -2915,6 +2910,14 @@ pub struct user_regs_struct { pub t5: ::aya_ebpf_cty::c_ulong, pub t6: ::aya_ebpf_cty::c_ulong, } +pub type bpf_user_pt_regs_t = user_regs_struct; +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct bpf_perf_event_data { + pub regs: bpf_user_pt_regs_t, + pub sample_period: __u64, + pub addr: __u64, +} pub type sa_family_t = ::aya_ebpf_cty::c_ushort; #[repr(C)] #[derive(Debug, Copy, Clone)] diff --git a/ebpf/aya-ebpf-bindings/src/s390x/bindings.rs b/ebpf/aya-ebpf-bindings/src/s390x/bindings.rs index 15804301..015cafe7 100644 --- a/ebpf/aya-ebpf-bindings/src/s390x/bindings.rs +++ b/ebpf/aya-ebpf-bindings/src/s390x/bindings.rs @@ -365,11 +365,6 @@ pub type __be32 = __u32; pub type __wsum = __u32; #[repr(C)] #[derive(Debug, Copy, Clone)] -pub struct bpf_perf_event_data { - _unused: [u8; 0], -} -#[repr(C)] -#[derive(Debug, Copy, Clone)] pub struct linux_binprm { _unused: [u8; 0], } @@ -3848,6 +3843,14 @@ pub struct user_regs_struct { pub per_info: per_struct, pub ieee_instruction_pointer: ::aya_ebpf_cty::c_ulong, } +pub type bpf_user_pt_regs_t = user_pt_regs; +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct bpf_perf_event_data { + pub regs: bpf_user_pt_regs_t, + pub sample_period: __u64, + pub addr: __u64, +} pub type sa_family_t = ::aya_ebpf_cty::c_ushort; #[repr(C)] #[derive(Debug, Copy, Clone)] diff --git a/ebpf/aya-ebpf-bindings/src/x86_64/bindings.rs b/ebpf/aya-ebpf-bindings/src/x86_64/bindings.rs index 89fec488..72c24b75 100644 --- a/ebpf/aya-ebpf-bindings/src/x86_64/bindings.rs +++ b/ebpf/aya-ebpf-bindings/src/x86_64/bindings.rs @@ -365,11 +365,6 @@ pub type __be32 = __u32; pub type __wsum = __u32; #[repr(C)] #[derive(Debug, Copy, Clone)] -pub struct bpf_perf_event_data { - _unused: [u8; 0], -} -#[repr(C)] -#[derive(Debug, Copy, Clone)] pub struct linux_binprm { _unused: [u8; 0], } @@ -2899,6 +2894,14 @@ pub struct pt_regs { pub rsp: ::aya_ebpf_cty::c_ulong, pub ss: ::aya_ebpf_cty::c_ulong, } +pub type bpf_user_pt_regs_t = pt_regs; +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct bpf_perf_event_data { + pub regs: bpf_user_pt_regs_t, + pub sample_period: __u64, + pub addr: __u64, +} pub type sa_family_t = ::aya_ebpf_cty::c_ushort; #[repr(C)] #[derive(Debug, Copy, Clone)] diff --git a/ebpf/aya-ebpf-cty/CHANGELOG.md b/ebpf/aya-ebpf-cty/CHANGELOG.md index 23c0b0a1..dd3d09d4 100644 --- a/ebpf/aya-ebpf-cty/CHANGELOG.md +++ b/ebpf/aya-ebpf-cty/CHANGELOG.md @@ -5,65 +5,15 @@ This project adheres to $[Semantic Versioning](http://semver.org/). ## [Unreleased] -## [v0.2.1] - 2019-11-16 +## v0.2.3 (2025-11-17) -### Added +### New Features -- Support for the `xtensa`, `riscv32` and `riscv64` architectures + - , Added the missing MIPS and LoongArch definitions so the cty shim covers every architecture supported by Aya. -## [v0.2.0] - 2019-02-06 +### Maintenance -### Changed - -- [breaking-change] `cty::c_void` is now a type alias of `core::ffi::c_void`. - -## [v0.1.5] - 2017-05-29 - -### Added - -- More types like `int32_t` - -## [v0.1.4] - 2017-05-29 - -### Added - -- Support for the `msp430` architecture. - -### Fixed - -- [breaking-change] The type definitions of `c_long` and `c_ulong`. - -## [v0.1.3] - 2017-05-29 - YANKED - -### Added - -- Support for the `nvptx` and `nvptx64` architectures. - -## [v0.1.2] - 2017-05-29 - YANKED - -### Fixed - -- [breaking-change] The type definitions of `c_int` and `c_uint`. - -## [v0.1.1] - 2017-05-29 - YANKED - -### Fixed - -- [breaking-change] The type definitions of `c_long`, `c_ulong` and - `c_longlong`. - -## v0.1.0 - 2017-05-24 - YANKED - -- Initial release - -[Unreleased]: https://github.com/japaric/cty/compare/v0.2.1...HEAD -[v0.2.1]: https://github.com/japaric/cty/compare/v0.2.0...v0.2.1 -[v0.2.0]: https://github.com/japaric/cty/compare/v0.1.5...v0.2.0 -[v0.1.5]: https://github.com/japaric/cty/compare/v0.1.4...v0.1.5 -[v0.1.4]: https://github.com/japaric/cty/compare/v0.1.3...v0.1.4 -[v0.1.3]: https://github.com/japaric/cty/compare/v0.1.2...v0.1.3 -[v0.1.2]: https://github.com/japaric/cty/compare/v0.1.1...v0.1.2 -[v0.1.1]: https://github.com/japaric/cty/compare/v0.1.0...v0.1.1 + - , Tidied the crate (removing the abandoned Travis setup) and refreshed the bindings so downstream riscv64 builds stay green. ## v0.2.2 (2024-10-09) diff --git a/ebpf/aya-ebpf-cty/Cargo.toml b/ebpf/aya-ebpf-cty/Cargo.toml index a848b6aa..fc695096 100644 --- a/ebpf/aya-ebpf-cty/Cargo.toml +++ b/ebpf/aya-ebpf-cty/Cargo.toml @@ -3,7 +3,7 @@ categories = ["embedded", "external-ffi-bindings", "no-std"] description = "Type aliases to C types like c_int for use with bindgen" documentation = "https://docs.rs/aya-bpf-cty" name = "aya-ebpf-cty" -version = "0.2.2" +version = "0.2.3" authors.workspace = true edition.workspace = true @@ -16,4 +16,4 @@ rust-version.workspace = true workspace = true [build-dependencies] -aya-build = { version = "^0.1.2", path = "../../aya-build" } +aya-build = { version = "^0.1.3", path = "../../aya-build" } diff --git a/ebpf/aya-ebpf/CHANGELOG.md b/ebpf/aya-ebpf/CHANGELOG.md index fb00292b..d8c155a8 100644 --- a/ebpf/aya-ebpf/CHANGELOG.md +++ b/ebpf/aya-ebpf/CHANGELOG.md @@ -5,6 +5,35 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [Unreleased] + +## v0.1.2 (2025-11-17) + +### Breaking Changes + + - Map helper functions now take `*mut c_void`, matching the kernel’s prototypes. Any out-of-tree helpers should update their signatures accordingly. + +### New Features + + - Added a `bpf_strncmp` helper binding. + - Raw tracepoints now expose their arguments so programs no longer need to guess register layouts. + - , Added mips/loongarch register helpers so those targets can implement `FromPtRegs`. + - `XdpContext` exposes the interface index, simplifying multi-interface programs. + - Added `Array::set()` to update array contents from eBPF code. + - Introduced Flow Dissector program support on the eBPF side. + - Added `RingBufBytes` so probes can emit raw byte slices efficiently. + - , Added BTF array definitions plus `Queue`/`Stack::peek()` helpers for safer data-structure inspection. + +### Bug Fixes + + - Fixed riscv64 builds by updating the generated bindings. + - Cleaned up ring-buffer code to avoid reliance on `as` casts, preventing UB on strict architectures. + - Guarded the libc `mem*` shims behind `cfg(target_arch = "bpf")`, ensuring CPU builds stay well-defined. + +### Maintenance + + - , Added configuration flags for `generic_const_exprs` and the loongarch target, plus the usual lint/documentation refresh. + ## v0.1.1 (2024-10-09) ### New Features diff --git a/ebpf/aya-ebpf/Cargo.toml b/ebpf/aya-ebpf/Cargo.toml index e2067982..b597f21f 100644 --- a/ebpf/aya-ebpf/Cargo.toml +++ b/ebpf/aya-ebpf/Cargo.toml @@ -1,7 +1,7 @@ [package] description = "A library for writing eBPF programs" name = "aya-ebpf" -version = "0.1.1" +version = "0.1.2" authors.workspace = true edition.workspace = true @@ -14,10 +14,10 @@ rust-version.workspace = true workspace = true [dependencies] -aya-ebpf-bindings = { version = "^0.1.1", path = "../aya-ebpf-bindings" } -aya-ebpf-cty = { version = "^0.2.2", path = "../aya-ebpf-cty" } -aya-ebpf-macros = { version = "^0.1.1", path = "../../aya-ebpf-macros" } +aya-ebpf-bindings = { version = "^0.1.2", path = "../aya-ebpf-bindings" } +aya-ebpf-cty = { version = "^0.2.3", path = "../aya-ebpf-cty" } +aya-ebpf-macros = { version = "^0.1.2", path = "../../aya-ebpf-macros" } [build-dependencies] -aya-build = { version = "^0.1.2", path = "../../aya-build" } +aya-build = { version = "^0.1.3", path = "../../aya-build" } rustversion = { workspace = true } diff --git a/ebpf/aya-ebpf/src/helpers.rs b/ebpf/aya-ebpf/src/helpers.rs index 6e23f1d3..44b61342 100644 --- a/ebpf/aya-ebpf/src/helpers.rs +++ b/ebpf/aya-ebpf/src/helpers.rs @@ -35,7 +35,6 @@ use crate::{ /// # Examples /// /// ```no_run -/// # #![expect(dead_code)] /// # use aya_ebpf::{cty::{c_int, c_long}, helpers::bpf_probe_read}; /// # fn try_test() -> Result<(), c_long> { /// # let kernel_ptr: *const c_int = 0 as _; @@ -74,7 +73,6 @@ pub unsafe fn bpf_probe_read(src: *const T) -> Result { /// # Examples /// /// ```no_run -/// # #![expect(dead_code)] /// # use aya_ebpf::{cty::{c_int, c_long}, helpers::bpf_probe_read_buf}; /// # fn try_test() -> Result<(), c_long> { /// # let ptr: *const u8 = 0 as _; @@ -103,7 +101,6 @@ pub unsafe fn bpf_probe_read_buf(src: *const u8, dst: &mut [u8]) -> Result<(), c /// # Examples /// /// ```no_run -/// # #![expect(dead_code)] /// # use aya_ebpf::{cty::{c_int, c_long}, helpers::bpf_probe_read_user}; /// # fn try_test() -> Result<(), c_long> { /// # let user_ptr: *const c_int = 0 as _; @@ -140,7 +137,6 @@ pub unsafe fn bpf_probe_read_user(src: *const T) -> Result { /// # Examples /// /// ```no_run -/// # #![expect(dead_code)] /// # use aya_ebpf::{cty::{c_int, c_long}, helpers::bpf_probe_read_user_buf}; /// # fn try_test() -> Result<(), c_long> { /// # let user_ptr: *const u8 = 0 as _; @@ -170,7 +166,6 @@ pub unsafe fn bpf_probe_read_user_buf(src: *const u8, dst: &mut [u8]) -> Result< /// # Examples /// /// ```no_run -/// # #![expect(dead_code)] /// # use aya_ebpf::{cty::{c_int, c_long}, helpers::bpf_probe_read_kernel}; /// # fn try_test() -> Result<(), c_long> { /// # let kernel_ptr: *const c_int = 0 as _; @@ -207,7 +202,6 @@ pub unsafe fn bpf_probe_read_kernel(src: *const T) -> Result { /// # Examples /// /// ```no_run -/// # #![expect(dead_code)] /// # use aya_ebpf::{cty::{c_int, c_long}, helpers::bpf_probe_read_kernel_buf}; /// # fn try_test() -> Result<(), c_long> { /// # let kernel_ptr: *const u8 = 0 as _; @@ -240,11 +234,12 @@ pub unsafe fn bpf_probe_read_kernel_buf(src: *const u8, dst: &mut [u8]) -> Resul /// # Examples /// /// ```no_run -/// # #![expect(dead_code)] +/// # #[expect(deprecated)] /// # use aya_ebpf::{cty::c_long, helpers::bpf_probe_read_str}; /// # fn try_test() -> Result<(), c_long> { /// # let kernel_ptr: *const u8 = 0 as _; /// let mut my_str = [0u8; 16]; +/// # #[expect(deprecated)] /// let num_read = unsafe { bpf_probe_read_str(kernel_ptr, &mut my_str)? }; /// /// // Do something with num_read and my_str @@ -276,11 +271,12 @@ pub unsafe fn bpf_probe_read_str(src: *const u8, dest: &mut [u8]) -> Result Result<(), c_long> { /// # let user_ptr: *const u8 = 0 as _; /// let mut my_str = [0u8; 16]; +/// # #[expect(deprecated)] /// let num_read = unsafe { bpf_probe_read_user_str(user_ptr, &mut my_str)? }; /// /// // Do something with num_read and my_str @@ -315,7 +311,6 @@ pub unsafe fn bpf_probe_read_user_str(src: *const u8, dest: &mut [u8]) -> Result /// eBPF stack limit is 512 bytes): /// /// ```no_run -/// # #![expect(dead_code)] /// # use aya_ebpf::{cty::c_long, helpers::bpf_probe_read_user_str_bytes}; /// # fn try_test() -> Result<(), c_long> { /// # let user_ptr: *const u8 = 0 as _; @@ -421,11 +416,12 @@ fn read_str_bytes(len: i64, dest: &[u8]) -> Result<&[u8], c_long> { /// # Examples /// /// ```no_run -/// # #![expect(dead_code)] +/// # #[expect(deprecated)] /// # use aya_ebpf::{cty::c_long, helpers::bpf_probe_read_kernel_str}; /// # fn try_test() -> Result<(), c_long> { /// # let kernel_ptr: *const u8 = 0 as _; /// let mut my_str = [0u8; 16]; +/// # #[expect(deprecated)] /// let num_read = unsafe { bpf_probe_read_kernel_str(kernel_ptr, &mut my_str)? }; /// /// // Do something with num_read and my_str @@ -464,7 +460,6 @@ pub unsafe fn bpf_probe_read_kernel_str(src: *const u8, dest: &mut [u8]) -> Resu /// eBPF stack limit is 512 bytes): /// /// ```no_run -/// # #![expect(dead_code)] /// # use aya_ebpf::{cty::c_long, helpers::bpf_probe_read_kernel_str_bytes}; /// # fn try_test() -> Result<(), c_long> { /// # let kernel_ptr: *const u8 = 0 as _; @@ -554,7 +549,6 @@ pub unsafe fn bpf_probe_read_kernel_str_bytes( /// # Examples /// /// ```no_run -/// # #![expect(dead_code)] /// # use aya_ebpf::{ /// # cty::{c_int, c_long}, /// # helpers::bpf_probe_write_user, @@ -587,7 +581,6 @@ pub unsafe fn bpf_probe_write_user(dst: *mut T, src: *const T) -> Result<(), /// # Examples /// /// ```no_run -/// # #![expect(dead_code)] /// # use aya_ebpf::helpers::bpf_get_current_comm; /// let comm = bpf_get_current_comm(); /// @@ -622,7 +615,6 @@ pub fn bpf_get_current_comm() -> Result<[u8; 16], c_long> { /// # Examples /// /// ```no_run -/// # #![expect(dead_code)] /// # use aya_ebpf::helpers::bpf_get_current_pid_tgid; /// let tgid = (bpf_get_current_pid_tgid() >> 32) as u32; /// let pid = bpf_get_current_pid_tgid() as u32; @@ -645,7 +637,6 @@ pub fn bpf_get_current_pid_tgid() -> u64 { /// # Examples /// /// ```no_run -/// # #![expect(dead_code)] /// # use aya_ebpf::helpers::bpf_get_current_uid_gid; /// let gid = (bpf_get_current_uid_gid() >> 32) as u32; /// let uid = bpf_get_current_uid_gid() as u32; diff --git a/ebpf/aya-ebpf/src/maps/program_array.rs b/ebpf/aya-ebpf/src/maps/program_array.rs index d56f076a..8241eed2 100644 --- a/ebpf/aya-ebpf/src/maps/program_array.rs +++ b/ebpf/aya-ebpf/src/maps/program_array.rs @@ -14,7 +14,6 @@ use crate::{ /// # Examples /// /// ```no_run -/// # #![expect(dead_code)] /// use aya_ebpf::{macros::map, maps::ProgramArray, cty::c_long}; /// # use aya_ebpf::{programs::LsmContext}; /// @@ -24,8 +23,8 @@ use crate::{ /// # unsafe fn try_test(ctx: &LsmContext) -> Result<(), c_long> { /// let index: u32 = 13; /// -/// if let Err(e) = JUMP_TABLE.tail_call(ctx, index) { -/// return Err(e); +/// unsafe { +/// JUMP_TABLE.tail_call(ctx, index)?; /// } /// /// # Err(-1) diff --git a/ebpf/aya-ebpf/src/programs/fentry.rs b/ebpf/aya-ebpf/src/programs/fentry.rs index b67fb35c..0e61236d 100644 --- a/ebpf/aya-ebpf/src/programs/fentry.rs +++ b/ebpf/aya-ebpf/src/programs/fentry.rs @@ -16,10 +16,10 @@ impl FEntryContext { /// # Examples /// /// ```no_run - /// # #![expect(non_camel_case_types)] - /// # #![expect(dead_code)] /// # use aya_ebpf::{cty::c_int, programs::FEntryContext}; + /// # #[expect(non_camel_case_types)] /// # type pid_t = c_int; + /// # #[expect(non_camel_case_types)] /// # struct task_struct { /// # pid: pid_t, /// # } diff --git a/ebpf/aya-ebpf/src/programs/fexit.rs b/ebpf/aya-ebpf/src/programs/fexit.rs index 20a4c3b5..d936c310 100644 --- a/ebpf/aya-ebpf/src/programs/fexit.rs +++ b/ebpf/aya-ebpf/src/programs/fexit.rs @@ -16,10 +16,10 @@ impl FExitContext { /// # Examples /// /// ```no_run - /// # #![expect(non_camel_case_types)] - /// # #![expect(dead_code)] /// # use aya_ebpf::{cty::c_int, programs::FExitContext}; + /// # #[expect(non_camel_case_types)] /// # type pid_t = c_int; + /// # #[expect(non_camel_case_types)] /// # struct task_struct { /// # pid: pid_t, /// # } diff --git a/ebpf/aya-ebpf/src/programs/lsm.rs b/ebpf/aya-ebpf/src/programs/lsm.rs index 741aa1b6..4e0111d5 100644 --- a/ebpf/aya-ebpf/src/programs/lsm.rs +++ b/ebpf/aya-ebpf/src/programs/lsm.rs @@ -25,7 +25,6 @@ impl LsmContext { /// # Examples /// /// ```no_run - /// # #![expect(dead_code)] /// # use aya_ebpf::{programs::LsmContext, cty::{c_int, c_ulong}}; /// unsafe fn try_lsm_mmap_addr(ctx: LsmContext) -> Result { /// // In the kernel, this hook is defined as: diff --git a/ebpf/aya-ebpf/src/programs/perf_event.rs b/ebpf/aya-ebpf/src/programs/perf_event.rs index d847fc31..f8de1c0a 100644 --- a/ebpf/aya-ebpf/src/programs/perf_event.rs +++ b/ebpf/aya-ebpf/src/programs/perf_event.rs @@ -1,19 +1,21 @@ use core::ffi::c_void; +use aya_ebpf_bindings::bindings::bpf_perf_event_data; + use crate::EbpfContext; pub struct PerfEventContext { - ctx: *mut c_void, + pub ctx: *mut bpf_perf_event_data, } impl PerfEventContext { - pub fn new(ctx: *mut c_void) -> Self { + pub fn new(ctx: *mut bpf_perf_event_data) -> Self { Self { ctx } } } impl EbpfContext for PerfEventContext { fn as_ptr(&self) -> *mut c_void { - self.ctx + self.ctx.cast() } } diff --git a/ebpf/aya-ebpf/src/programs/probe.rs b/ebpf/aya-ebpf/src/programs/probe.rs index 6c7266c6..e2ee6e0e 100644 --- a/ebpf/aya-ebpf/src/programs/probe.rs +++ b/ebpf/aya-ebpf/src/programs/probe.rs @@ -16,16 +16,18 @@ impl ProbeContext { /// # Examples /// /// ```no_run - /// # #![expect(non_camel_case_types)] - /// # #![expect(dead_code)] /// # use aya_ebpf::{programs::ProbeContext, cty::c_int, helpers::bpf_probe_read}; + /// # #[expect(non_camel_case_types)] /// # type pid_t = c_int; + /// # #[expect(non_camel_case_types)] /// # struct task_struct { /// # pid: pid_t, /// # } /// unsafe fn try_kprobe_try_to_wake_up(ctx: ProbeContext) -> Result { /// let tp: *const task_struct = ctx.arg(0).ok_or(1u32)?; - /// let pid = bpf_probe_read(&(*tp).pid as *const pid_t).map_err(|_| 1u32)?; + /// let pid = unsafe { + /// bpf_probe_read(core::ptr::addr_of!((*tp).pid)) + /// }.map_err(|err| err as u32)?; /// /// // Do something with pid or something else with tp /// diff --git a/ebpf/aya-ebpf/src/programs/retprobe.rs b/ebpf/aya-ebpf/src/programs/retprobe.rs index c2aec986..c669f25e 100644 --- a/ebpf/aya-ebpf/src/programs/retprobe.rs +++ b/ebpf/aya-ebpf/src/programs/retprobe.rs @@ -16,7 +16,6 @@ impl RetProbeContext { /// # Examples /// /// ```no_run - /// # #![expect(dead_code)] /// # use aya_ebpf::{programs::RetProbeContext, cty::c_int}; /// unsafe fn try_kretprobe_try_to_wake_up(ctx: RetProbeContext) -> Result { /// let retval: c_int = ctx.ret(); diff --git a/ebpf/aya-ebpf/src/programs/sk_buff.rs b/ebpf/aya-ebpf/src/programs/sk_buff.rs index 93b5f5e0..deb9654b 100644 --- a/ebpf/aya-ebpf/src/programs/sk_buff.rs +++ b/ebpf/aya-ebpf/src/programs/sk_buff.rs @@ -384,8 +384,8 @@ impl SkBuffContext { /// fn try_cgroup_skb(ctx: SkBuffContext) -> Result { /// let len = ETH_HLEN + IP_HLEN + UDP_HLEN; /// match ctx.pull_data(len as u32) { - /// Ok(()) => return Ok(0), - /// Err(ret) => return Err(ret as i32), + /// Ok(()) => Ok(0), + /// Err(ret) => Err(ret as i32), /// } /// } /// ``` diff --git a/ebpf/aya-ebpf/src/programs/tc.rs b/ebpf/aya-ebpf/src/programs/tc.rs index e9281d83..8304d58c 100644 --- a/ebpf/aya-ebpf/src/programs/tc.rs +++ b/ebpf/aya-ebpf/src/programs/tc.rs @@ -176,8 +176,8 @@ impl TcContext { /// fn try_classifier(ctx: TcContext) -> Result { /// let len = ETH_HLEN + IP_HLEN + UDP_HLEN; /// match ctx.pull_data(len as u32) { - /// Ok(()) => return Ok(0), - /// Err(ret) => return Err(ret as i32), + /// Ok(()) => Ok(0), + /// Err(ret) => Err(ret as i32), /// } /// } /// ``` diff --git a/ebpf/aya-ebpf/src/programs/tp_btf.rs b/ebpf/aya-ebpf/src/programs/tp_btf.rs index 9e39f2f0..c5daf637 100644 --- a/ebpf/aya-ebpf/src/programs/tp_btf.rs +++ b/ebpf/aya-ebpf/src/programs/tp_btf.rs @@ -19,7 +19,6 @@ impl BtfTracePointContext { /// # Examples /// /// ```no_run - /// # #![expect(dead_code)] /// # use aya_ebpf::{programs::BtfTracePointContext, cty::{c_int, c_ulong, c_char}}; /// unsafe fn try_tp_btf_sched_process_fork(ctx: BtfTracePointContext) -> Result { /// // Grab arguments diff --git a/ebpf/aya-log-ebpf/CHANGELOG.md b/ebpf/aya-log-ebpf/CHANGELOG.md index d25856d3..ac8b22e8 100644 --- a/ebpf/aya-log-ebpf/CHANGELOG.md +++ b/ebpf/aya-log-ebpf/CHANGELOG.md @@ -5,6 +5,24 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [Unreleased] + +## 0.1.2 (2025-11-17) + +### Breaking Changes + + - Logging from eBPF programs now writes into a ring buffer to match the host transport, requiring Linux 5.8 or later. + +### New Features + + - , Added a load-time log level mask and improved verifier hints so disabled log levels are optimised out entirely. + - Logging paths now use zero-copy writes into the ring buffer, lowering instruction counts inside probes. + - Added raw-pointer formatting so eBPF logs can mirror the new host-side diagnostics. + +### Maintenance + + - , Kept the crate in sync with the workspace edition/lint settings and tidied the macro support helpers. + ## 0.1.1 (2024-10-09) Maintenance release. Update to latest aya-ebpf version v0.1.1. diff --git a/ebpf/aya-log-ebpf/Cargo.toml b/ebpf/aya-log-ebpf/Cargo.toml index 90c54198..89c1ac10 100644 --- a/ebpf/aya-log-ebpf/Cargo.toml +++ b/ebpf/aya-log-ebpf/Cargo.toml @@ -1,7 +1,7 @@ [package] description = "Logging for eBPF programs" name = "aya-log-ebpf" -version = "0.1.1" +version = "0.1.2" authors.workspace = true edition.workspace = true @@ -14,6 +14,6 @@ rust-version.workspace = true workspace = true [dependencies] -aya-ebpf = { version = "^0.1.1", path = "../aya-ebpf" } -aya-log-common = { version = "^0.1.15", path = "../../aya-log-common" } -aya-log-ebpf-macros = { version = "^0.1.0", path = "../../aya-log-ebpf-macros" } +aya-ebpf = { version = "^0.1.2", path = "../aya-ebpf" } +aya-log-common = { version = "^0.1.16", path = "../../aya-log-common" } +aya-log-ebpf-macros = { version = "^0.1.1", path = "../../aya-log-ebpf-macros" } diff --git a/test/integration-ebpf/Cargo.toml b/test/integration-ebpf/Cargo.toml index cb52e728..33715cfb 100644 --- a/test/integration-ebpf/Cargo.toml +++ b/test/integration-ebpf/Cargo.toml @@ -103,3 +103,7 @@ path = "src/xdp_sec.rs" [[bin]] name = "uprobe_cookie" path = "src/uprobe_cookie.rs" + +[[bin]] +name = "perf_event_bp" +path = "src/perf_event_bp.rs" diff --git a/test/integration-ebpf/src/log.rs b/test/integration-ebpf/src/log.rs index 3e7bf5b8..b55b7276 100644 --- a/test/integration-ebpf/src/log.rs +++ b/test/integration-ebpf/src/log.rs @@ -115,10 +115,10 @@ fn test_log(ctx: ProbeContext) { let buf = &buf[..core::cmp::min(len, buf.len())]; info!(&ctx, "variable length buffer: {:x}", buf); - info!(&ctx, "2KiB array: {:x}", &TWO_KB_ARRAY); - info!(&ctx, "4KiB array: {:x}", &FOUR_KB_ARRAY); + info!(&ctx, "2KiB array: {:x}", TWO_KB_ARRAY.as_slice()); + info!(&ctx, "4KiB array: {:x}", FOUR_KB_ARRAY.as_slice()); // This one is too big and should be dropped. - info!(&ctx, "8KiB array: {:x}", &EIGHT_KB_ARRAY); + info!(&ctx, "8KiB array: {:x}", EIGHT_KB_ARRAY.as_slice()); } #[uprobe] diff --git a/test/integration-ebpf/src/map_test.rs b/test/integration-ebpf/src/map_test.rs index eac1823d..0135487a 100644 --- a/test/integration-ebpf/src/map_test.rs +++ b/test/integration-ebpf/src/map_test.rs @@ -3,9 +3,9 @@ #![expect(unused_crate_dependencies, reason = "used in other bins")] use aya_ebpf::{ - macros::{map, socket_filter}, + macros::{map, socket_filter, uprobe}, maps::{Array, HashMap}, - programs::SkBuffContext, + programs::{ProbeContext, SkBuffContext}, }; #[cfg(not(test))] extern crate ebpf_panic; @@ -35,3 +35,20 @@ fn simple_prog(_ctx: SkBuffContext) -> i64 { 0 } + +#[uprobe] +fn simple_prog_mut(_ctx: ProbeContext) -> i64 { + if let Some(array_value) = FOO.get_ptr_mut(0) { + unsafe { + *array_value += 1; + } + } + + if let Some(map_value) = BAZ.get_ptr_mut(0) { + unsafe { + *map_value += 1; + } + } + + 0 +} diff --git a/test/integration-ebpf/src/perf_event_bp.rs b/test/integration-ebpf/src/perf_event_bp.rs new file mode 100644 index 00000000..f6928c01 --- /dev/null +++ b/test/integration-ebpf/src/perf_event_bp.rs @@ -0,0 +1,24 @@ +#![no_std] +#![no_main] +#![expect(unused_crate_dependencies, reason = "used in other bins")] + +use aya_ebpf::{ + EbpfContext as _, + macros::{map, perf_event}, + maps::HashMap, + programs::PerfEventContext, +}; + +#[cfg(not(test))] +extern crate ebpf_panic; + +#[map] +static READERS: HashMap = HashMap::with_max_entries(1, 0); + +#[perf_event] +fn perf_event_bp(ctx: PerfEventContext) -> u32 { + let tgid = ctx.tgid(); + let addr = unsafe { (*ctx.ctx).addr }; + let _ = READERS.insert(tgid, addr, 0); + 0 +} diff --git a/test/integration-ebpf/src/ring_buf.rs b/test/integration-ebpf/src/ring_buf.rs index b6f12ac1..cac357f5 100644 --- a/test/integration-ebpf/src/ring_buf.rs +++ b/test/integration-ebpf/src/ring_buf.rs @@ -40,7 +40,7 @@ fn ring_buf_test(ctx: ProbeContext) { Some(arg) => arg, None => return, }; - if arg % 2 == 0 { + if arg.is_multiple_of(2) { entry.write(arg); entry.submit(0); } else { diff --git a/test/integration-test/Cargo.toml b/test/integration-test/Cargo.toml index e443af2f..e81d705c 100644 --- a/test/integration-test/Cargo.toml +++ b/test/integration-test/Cargo.toml @@ -14,13 +14,13 @@ rust-version.workspace = true workspace = true [dependencies] -aya = { path = "../../aya", version = "^0.13.1", default-features = false } +aya = { path = "../../aya", version = "^0.13.2", default-features = false } [dev-dependencies] anyhow = { workspace = true, features = ["std"] } assert_matches = { workspace = true } -aya-log = { path = "../../aya-log", version = "^0.2.1", default-features = false } -aya-obj = { path = "../../aya-obj", version = "^0.2.1", default-features = false } +aya-log = { path = "../../aya-log", version = "^0.2.2", default-features = false } +aya-obj = { path = "../../aya-obj", version = "^0.2.2", default-features = false } epoll = { workspace = true } futures = { workspace = true, features = ["alloc"] } integration-common = { path = "../integration-common", features = ["user"] } diff --git a/test/integration-test/build.rs b/test/integration-test/build.rs index 44a4783a..881cdd57 100644 --- a/test/integration-test/build.rs +++ b/test/integration-test/build.rs @@ -219,6 +219,7 @@ fn main() -> Result<()> { .parent() .ok_or_else(|| anyhow!("no parent for {manifest_path}"))? .as_str(), + ..Default::default() }; aya_build::build_ebpf([integration_ebpf_package], aya_build::Toolchain::default())?; } else { diff --git a/test/integration-test/src/lib.rs b/test/integration-test/src/lib.rs index 64f37d18..01e26f03 100644 --- a/test/integration-test/src/lib.rs +++ b/test/integration-test/src/lib.rs @@ -46,6 +46,7 @@ bpf_file!( MEMMOVE_TEST => "memmove_test", NAME_TEST => "name_test", PASS => "pass", + PERF_EVENT_BP => "perf_event_bp", RAW_TRACEPOINT => "raw_tracepoint", REDIRECT => "redirect", RELOCATIONS => "relocations", diff --git a/test/integration-test/src/tests.rs b/test/integration-test/src/tests.rs index b7d4d492..4de831aa 100644 --- a/test/integration-test/src/tests.rs +++ b/test/integration-test/src/tests.rs @@ -10,6 +10,8 @@ mod load; mod log; mod lsm; mod map_pin; +mod maps_disjoint; +mod perf_event_bp; mod raw_tracepoint; mod rbpf; mod relocations; diff --git a/test/integration-test/src/tests/info.rs b/test/integration-test/src/tests/info.rs index 9a4740c3..20c92c75 100644 --- a/test/integration-test/src/tests/info.rs +++ b/test/integration-test/src/tests/info.rs @@ -60,7 +60,7 @@ fn test_loaded_programs() { .unwrap(); let mut p: UProbe = unsafe { - UProbe::from_program_info(info, "test_uprobe".into(), aya::programs::ProbeKind::UProbe) + UProbe::from_program_info(info, "test_uprobe".into(), aya::programs::ProbeKind::Entry) .unwrap() }; diff --git a/test/integration-test/src/tests/load.rs b/test/integration-test/src/tests/load.rs index dd50fe2d..26046824 100644 --- a/test/integration-test/src/tests/load.rs +++ b/test/integration-test/src/tests/load.rs @@ -557,7 +557,7 @@ fn pin_lifecycle_kprobe() { let attach = |prog: &mut P| prog.attach("try_to_wake_up", 0).unwrap(); let program_pin = "/sys/fs/bpf/aya-kprobe-test-prog"; let link_pin = "/sys/fs/bpf/aya-kprobe-test-try-to-wake-up"; - let from_pin = |program_pin: &str| P::from_pin(program_pin, ProbeKind::KProbe).unwrap(); + let from_pin = |program_pin: &str| P::from_pin(program_pin, ProbeKind::Entry).unwrap(); run_pin_program_lifecycle_test( crate::TEST, program_name, @@ -587,7 +587,7 @@ fn pin_lifecycle_uprobe() { }; let program_pin = "/sys/fs/bpf/aya-uprobe-test-prog"; let link_pin = "/sys/fs/bpf/aya-uprobe-test-uprobe-function"; - let from_pin = |program_pin: &str| P::from_pin(program_pin, ProbeKind::UProbe).unwrap(); + let from_pin = |program_pin: &str| P::from_pin(program_pin, ProbeKind::Entry).unwrap(); run_pin_program_lifecycle_test( crate::TEST, program_name, diff --git a/test/integration-test/src/tests/maps_disjoint.rs b/test/integration-test/src/tests/maps_disjoint.rs new file mode 100644 index 00000000..79f6fe23 --- /dev/null +++ b/test/integration-test/src/tests/maps_disjoint.rs @@ -0,0 +1,44 @@ +use aya::{ + Ebpf, + maps::{Array, HashMap}, + programs::UProbe, +}; + +#[unsafe(no_mangle)] +#[inline(never)] +extern "C" fn trigger_ebpf_program_maps_disjoint() { + core::hint::black_box(trigger_ebpf_program_maps_disjoint); +} + +#[test_log::test] +fn test_maps_disjoint() { + let mut bpf: Ebpf = Ebpf::load(crate::MAP_TEST).unwrap(); + let prog: &mut UProbe = bpf + .program_mut("simple_prog_mut") + .unwrap() + .try_into() + .unwrap(); + + prog.load().unwrap(); + prog.attach( + "trigger_ebpf_program_maps_disjoint", + "/proc/self/exe", + None, + None, + ) + .unwrap(); + + let [foo, bar, baz] = bpf.maps_disjoint_mut(["FOO", "BAR", "BAZ"]); + + let mut foo: Array<_, u32> = Array::try_from(foo.unwrap()).unwrap(); + let mut bar: HashMap<_, u32, u8> = HashMap::try_from(bar.unwrap()).unwrap(); + assert!(baz.is_none()); + + foo.set(0, 5, 0).unwrap(); + bar.insert(0, 10, 0).unwrap(); + + trigger_ebpf_program_maps_disjoint(); + + assert_eq!(foo.get(&0, 0).unwrap(), 6); + assert_eq!(bar.get(&0, 0).unwrap(), 11); +} diff --git a/test/integration-test/src/tests/perf_event_bp.rs b/test/integration-test/src/tests/perf_event_bp.rs new file mode 100644 index 00000000..5667fdc5 --- /dev/null +++ b/test/integration-test/src/tests/perf_event_bp.rs @@ -0,0 +1,320 @@ +use std::{collections::HashMap, fs, io::ErrorKind, num::ParseIntError, path::PathBuf}; + +use assert_matches::assert_matches; +use aya::{ + Ebpf, maps, + programs::{ + ProgramError, + perf_event::{ + BreakpointConfig, PerfBreakpointLength, PerfBreakpointType, PerfEventConfig, + PerfEventScope, SamplePolicy, + }, + }, + sys::SyscallError, + util::online_cpus, +}; +use scopeguard::defer; + +fn find_system_map() -> Vec { + const BOOT_PATH: &str = "/boot/"; + const SYSTEM_MAP_PREFIX: &str = "System.map-"; + let mut system_maps = Vec::new(); + for (i, entry) in fs::read_dir(BOOT_PATH) + .unwrap_or_else(|error| panic!("fs::read_dir({BOOT_PATH}): {error:?}")) + .enumerate() + { + let entry = entry.unwrap_or_else(|error| { + panic!("fs::read_dir({BOOT_PATH}).enumerate().nth({i}): {error:?}") + }); + if !entry + .file_name() + .as_encoded_bytes() + .starts_with(SYSTEM_MAP_PREFIX.as_bytes()) + { + continue; + } + system_maps.push(entry.path()); + } + system_maps +} + +struct KernelSymbol<'a> { + address: u64, + #[expect(dead_code)] + r#type: &'a str, + name: &'a str, + #[expect(dead_code)] + module: Option<&'a str>, +} + +fn parse_kernel_symbol(line: &str) -> Option> { + let mut parts = line.splitn(4, char::is_whitespace); + let address = parts.next()?; + let r#type = parts.next()?; + let name = parts.next()?; + let module = parts.next(); + // TODO(https://github.com/rust-lang/rust-clippy/issues/14112): Remove this allowance + // when the lint behaves more sensibly. + #[expect(clippy::manual_ok_err)] + let address = match u64::from_str_radix(address, 16) { + Ok(address) => Some(address), + Err(ParseIntError { .. }) => None, + }?; + Some(KernelSymbol { + address, + r#type, + name, + module, + }) +} + +fn parse_kernel_symbols(content: &str) -> HashMap<&str, Vec> { + let mut kernel_symbols = HashMap::<_, Vec<_>>::new(); + for line in content.lines() { + let KernelSymbol { + address, + r#type: _, + name, + module: _, + } = parse_kernel_symbol(line).unwrap_or_else(|| panic!("parse_kernel_symbol({line})")); + kernel_symbols.entry(name).or_default().push(address); + } + kernel_symbols +} + +#[track_caller] +fn run_breakpoint_case(config: BreakpointConfig, mut trigger: F, expected_addr: u64) +where + F: FnMut(), +{ + let mut bpf = Ebpf::load(crate::PERF_EVENT_BP).unwrap(); + + let map: maps::HashMap<_, u32, u64> = bpf.take_map("READERS").unwrap().try_into().unwrap(); + + let prog: &mut aya::programs::PerfEvent = bpf + .program_mut("perf_event_bp") + .unwrap() + .try_into() + .unwrap(); + prog.load().unwrap(); + + // x86 debug registers cannot trigger on read-only watchpoints, so the + // kernel rejects `HW_BREAKPOINT_R` outright, see + // https://github.com/torvalds/linux/blob/v6.12/arch/x86/kernel/hw_breakpoint.c#L345-L377. + let type_supported = !(cfg!(target_arch = "x86_64") + && matches!( + config, + BreakpointConfig::Data { + r#type: PerfBreakpointType::Read, + .. + } + )); + + let mut calling_process_scopes = Vec::new(); + let mut one_process_scopes = Vec::new(); + let mut all_processes_one_cpu_scopes = Vec::new(); + + let pid = std::process::id(); + for cpu in online_cpus().unwrap() { + calling_process_scopes.push(PerfEventScope::CallingProcess { cpu: Some(cpu) }); + one_process_scopes.push(PerfEventScope::OneProcess { + pid, + cpu: Some(cpu), + }); + all_processes_one_cpu_scopes.push(PerfEventScope::AllProcessesOneCpu { cpu }); + } + + let scope_groups = &[ + &[PerfEventScope::CallingProcess { cpu: None }][..], + &[PerfEventScope::OneProcess { pid, cpu: None }][..], + calling_process_scopes.as_slice(), + one_process_scopes.as_slice(), + all_processes_one_cpu_scopes.as_slice(), + ]; + + for scope_group in scope_groups { + let mut link_ids = Vec::new(); + for scope in *scope_group { + // arm64 rejects per-task kernel breakpoints (the scopes that carry + // a PID) to avoid single-step bookkeeping, see + // https://github.com/torvalds/linux/blob/v6.12/arch/arm64/kernel/hw_breakpoint.c#L566-L571. + let scope_supported = type_supported + && (!cfg!(target_arch = "aarch64") + || matches!(scope, PerfEventScope::AllProcessesOneCpu { cpu: _ })); + let attach = prog.attach( + PerfEventConfig::Breakpoint(config), + *scope, + SamplePolicy::Period(1), + true, + ); + if scope_supported { + let link_id = attach.unwrap_or_else(|error| { + panic!("{config:?} {scope:?} attach failed: {error:?}") + }); + link_ids.push(link_id); + } else { + assert_matches!( + attach.unwrap_err(), + ProgramError::SyscallError(SyscallError { + call: "perf_event_open", + io_error, + }) => io_error.kind() == ErrorKind::InvalidInput + ); + } + } + let attached = !link_ids.is_empty(); + defer! { + for link_id in link_ids { + prog.detach(link_id).unwrap(); + } + } + + trigger(); + + let lookup = map.get(&pid, 0); + if attached { + let recorded = + lookup.unwrap_or_else(|error| panic!("{config:?} map lookup failed: {error:?}")); + assert_eq!( + recorded, expected_addr, + "{config:?} recorded unexpected address" + ); + } else { + assert_matches!(lookup.unwrap_err(), maps::MapError::KeyNotFound); + } + } +} + +fn get_address(symbols: &HashMap<&str, Vec>, name: &str) -> Option { + symbols.get(name).map(|addrs| match addrs.as_slice() { + [addr] => *addr, + [] => panic!("no address found for {name} in {symbols:?}"), + addrs => panic!("multiple addresses found for {name}: {addrs:?}"), + }) +} + +#[test_log::test] +fn perf_event_bp() { + // Search for the address of modprobe_path. Prefer to grab it directly from + // kallsyms, but if it's not there we can grab it from System.map and apply + // the kaslr offset. + const KALLSYMS_PATH: &str = "/proc/kallsyms"; + let kernel_symbols = fs::read_to_string(KALLSYMS_PATH) + .unwrap_or_else(|error| panic!("fs::read_to_string({KALLSYMS_PATH}): {error:?}")); + let kernel_symbols = parse_kernel_symbols(&kernel_symbols); + + let attach_addr = if let Some(addr) = get_address(&kernel_symbols, "modprobe_path") { + addr + } else { + let gunzip_addr = get_address(&kernel_symbols, "gunzip") + .unwrap_or_else(|| panic!("gunzip not found in {kernel_symbols:?}")); + + let system_map = find_system_map(); + let system_map = match system_map.as_slice() { + [system_map] => system_map, + [] => panic!("no system map found"), + system_maps => panic!("multiple system maps found: {:?}", system_maps), + }; + let system_map = fs::read_to_string(system_map).unwrap_or_else(|error| { + panic!("fs::read_to_string({}): {error:?}", system_map.display()) + }); + let system_map = parse_kernel_symbols(&system_map); + + let gunzip_debug_addr = get_address(&system_map, "gunzip") + .unwrap_or_else(|| panic!("gunzip not found in {system_map:?}")); + let modprobe_path_debug_addr = get_address(&system_map, "modprobe_path") + .unwrap_or_else(|| panic!("modprobe_path not found in {system_map:?}")); + + let kaslr_offset = gunzip_addr.wrapping_sub(gunzip_debug_addr); + modprobe_path_debug_addr.wrapping_add(kaslr_offset) + }; + + // Trigger the hardware breakpoint by reading or writing + // /proc/sys/kernel/modprobe, the sysctl connected to modprobe_path. + // + // See https://github.com/torvalds/linux/blob/v6.17/kernel/module/main.c#L132-L150. + const MODPROBE_PATH: &str = "/proc/sys/kernel/modprobe"; + + let read = |modprobe_contents: &mut Option| { + let contents = fs::read_to_string(MODPROBE_PATH) + .unwrap_or_else(|error| panic!("fs::read_to_string({MODPROBE_PATH}): {error:?}")); + if let Some(modprobe_contents) = modprobe_contents { + assert_eq!(*modprobe_contents, contents); + } + *modprobe_contents = Some(contents); + }; + + let write = |contents: &str| { + fs::write(MODPROBE_PATH, contents.as_bytes()) + .unwrap_or_else(|error| panic!("fs::write({MODPROBE_PATH}, ..): {error:?}")); + }; + + let mut modprobe_contents_before = None; + run_breakpoint_case( + BreakpointConfig::Data { + r#type: PerfBreakpointType::Read, + address: attach_addr, + length: PerfBreakpointLength::Len1, + }, + || read(&mut modprobe_contents_before), + attach_addr, + ); + let modprobe_contents_before = modprobe_contents_before.unwrap(); + + run_breakpoint_case( + BreakpointConfig::Data { + r#type: PerfBreakpointType::Write, + address: attach_addr, + length: PerfBreakpointLength::Len1, + }, + || write(&modprobe_contents_before), + attach_addr, + ); + + let mut modprobe_contents_after = None; + run_breakpoint_case( + BreakpointConfig::Data { + r#type: PerfBreakpointType::ReadWrite, + address: attach_addr, + length: PerfBreakpointLength::Len1, + }, + || read(&mut modprobe_contents_after), + attach_addr, + ); + let modprobe_contents_after = modprobe_contents_after.unwrap(); + + run_breakpoint_case( + BreakpointConfig::Data { + r#type: PerfBreakpointType::ReadWrite, + address: attach_addr, + length: PerfBreakpointLength::Len1, + }, + || write(&modprobe_contents_after), + attach_addr, + ); + + // Just for fun. + assert_eq!(modprobe_contents_before, modprobe_contents_after); + + let execute_addr = { + let getpgid_symbol = if cfg!(target_arch = "x86_64") { + "__x64_sys_getpgid" + } else if cfg!(target_arch = "aarch64") { + "__arm64_sys_getpgid" + } else { + panic!("unsupported architecture"); + }; + get_address(&kernel_symbols, getpgid_symbol) + .unwrap_or_else(|| panic!("{getpgid_symbol} not found in {kernel_symbols:?}")) + }; + + run_breakpoint_case( + BreakpointConfig::Instruction { + address: execute_addr, + }, + || { + nix::unistd::getpgid(None).unwrap(); + }, + execute_addr, + ); +} diff --git a/xtask/public-api/aya-build.txt b/xtask/public-api/aya-build.txt index a9fe663c..a5af3847 100644 --- a/xtask/public-api/aya-build.txt +++ b/xtask/public-api/aya-build.txt @@ -27,8 +27,12 @@ pub fn aya_build::Toolchain<'a>::borrow_mut(&mut self) -> &mut T impl core::convert::From for aya_build::Toolchain<'a> pub fn aya_build::Toolchain<'a>::from(t: T) -> T pub struct aya_build::Package<'a> +pub aya_build::Package::features: &'a [&'a str] pub aya_build::Package::name: &'a str +pub aya_build::Package::no_default_features: bool pub aya_build::Package::root_dir: &'a str +impl<'a> core::default::Default for aya_build::Package<'a> +pub fn aya_build::Package<'a>::default() -> aya_build::Package<'a> impl<'a> core::marker::Freeze for aya_build::Package<'a> impl<'a> core::marker::Send for aya_build::Package<'a> impl<'a> core::marker::Sync for aya_build::Package<'a> diff --git a/xtask/public-api/aya-ebpf-bindings.txt b/xtask/public-api/aya-ebpf-bindings.txt index 7a38ec39..00a60f70 100644 --- a/xtask/public-api/aya-ebpf-bindings.txt +++ b/xtask/public-api/aya-ebpf-bindings.txt @@ -4972,6 +4972,9 @@ pub unsafe fn aya_ebpf_bindings::bindings::bpf_map_info::clone_to_uninit(&self, impl core::convert::From for aya_ebpf_bindings::bindings::bpf_map_info pub fn aya_ebpf_bindings::bindings::bpf_map_info::from(t: T) -> T #[repr(C)] pub struct aya_ebpf_bindings::bindings::bpf_perf_event_data +pub aya_ebpf_bindings::bindings::bpf_perf_event_data::addr: aya_ebpf_bindings::bindings::__u64 +pub aya_ebpf_bindings::bindings::bpf_perf_event_data::regs: aya_ebpf_bindings::bindings::bpf_user_pt_regs_t +pub aya_ebpf_bindings::bindings::bpf_perf_event_data::sample_period: aya_ebpf_bindings::bindings::__u64 impl core::clone::Clone for aya_ebpf_bindings::bindings::bpf_perf_event_data pub fn aya_ebpf_bindings::bindings::bpf_perf_event_data::clone(&self) -> aya_ebpf_bindings::bindings::bpf_perf_event_data impl core::fmt::Debug for aya_ebpf_bindings::bindings::bpf_perf_event_data @@ -7057,6 +7060,7 @@ pub type aya_ebpf_bindings::bindings::_bindgen_ty_6 = aya_ebpf_cty::ad::c_uint pub type aya_ebpf_bindings::bindings::_bindgen_ty_7 = aya_ebpf_cty::ad::c_uint pub type aya_ebpf_bindings::bindings::_bindgen_ty_8 = aya_ebpf_cty::ad::c_uint pub type aya_ebpf_bindings::bindings::_bindgen_ty_9 = aya_ebpf_cty::ad::c_uint +pub type aya_ebpf_bindings::bindings::bpf_user_pt_regs_t = aya_ebpf_bindings::bindings::pt_regs pub type aya_ebpf_bindings::bindings::sa_family_t = aya_ebpf_cty::c_ushort pub mod aya_ebpf_bindings::helpers pub unsafe fn aya_ebpf_bindings::helpers::bpf_bind(ctx: *mut aya_ebpf_bindings::bindings::bpf_sock_addr, addr: *mut aya_ebpf_bindings::bindings::sockaddr, addr_len: aya_ebpf_cty::ad::c_int) -> aya_ebpf_cty::od::c_long diff --git a/xtask/public-api/aya-ebpf.txt b/xtask/public-api/aya-ebpf.txt index a78b1758..b8e672ee 100644 --- a/xtask/public-api/aya-ebpf.txt +++ b/xtask/public-api/aya-ebpf.txt @@ -1723,8 +1723,9 @@ impl core::convert::From for aya_ebpf::programs::lsm::LsmContext pub fn aya_ebpf::programs::lsm::LsmContext::from(t: T) -> T pub mod aya_ebpf::programs::perf_event pub struct aya_ebpf::programs::perf_event::PerfEventContext +pub aya_ebpf::programs::perf_event::PerfEventContext::ctx: *mut aya_ebpf_bindings::x86_64::bindings::bpf_perf_event_data impl aya_ebpf::programs::perf_event::PerfEventContext -pub fn aya_ebpf::programs::perf_event::PerfEventContext::new(ctx: *mut core::ffi::c_void) -> Self +pub fn aya_ebpf::programs::perf_event::PerfEventContext::new(ctx: *mut aya_ebpf_bindings::x86_64::bindings::bpf_perf_event_data) -> Self impl aya_ebpf::EbpfContext for aya_ebpf::programs::perf_event::PerfEventContext pub fn aya_ebpf::programs::perf_event::PerfEventContext::as_ptr(&self) -> *mut core::ffi::c_void impl core::marker::Freeze for aya_ebpf::programs::perf_event::PerfEventContext @@ -2461,8 +2462,9 @@ pub fn aya_ebpf::programs::lsm::LsmContext::borrow_mut(&mut self) -> &mut T impl core::convert::From for aya_ebpf::programs::lsm::LsmContext pub fn aya_ebpf::programs::lsm::LsmContext::from(t: T) -> T pub struct aya_ebpf::programs::PerfEventContext +pub aya_ebpf::programs::PerfEventContext::ctx: *mut aya_ebpf_bindings::x86_64::bindings::bpf_perf_event_data impl aya_ebpf::programs::perf_event::PerfEventContext -pub fn aya_ebpf::programs::perf_event::PerfEventContext::new(ctx: *mut core::ffi::c_void) -> Self +pub fn aya_ebpf::programs::perf_event::PerfEventContext::new(ctx: *mut aya_ebpf_bindings::x86_64::bindings::bpf_perf_event_data) -> Self impl aya_ebpf::EbpfContext for aya_ebpf::programs::perf_event::PerfEventContext pub fn aya_ebpf::programs::perf_event::PerfEventContext::as_ptr(&self) -> *mut core::ffi::c_void impl core::marker::Freeze for aya_ebpf::programs::perf_event::PerfEventContext diff --git a/xtask/public-api/aya-obj.txt b/xtask/public-api/aya-obj.txt index 8406f83a..5e59c5ea 100644 --- a/xtask/public-api/aya-obj.txt +++ b/xtask/public-api/aya-obj.txt @@ -8057,24 +8057,38 @@ pub const aya_obj::generated::BTF_KIND_VOLATILE: aya_obj::generated::_bindgen_ty pub const aya_obj::generated::BTF_VAR_GLOBAL_ALLOCATED: aya_obj::generated::_bindgen_ty_43 pub const aya_obj::generated::BTF_VAR_GLOBAL_EXTERN: aya_obj::generated::_bindgen_ty_43 pub const aya_obj::generated::BTF_VAR_STATIC: aya_obj::generated::_bindgen_ty_43 -pub const aya_obj::generated::IFLA_XDP_ATTACHED: aya_obj::generated::_bindgen_ty_92 -pub const aya_obj::generated::IFLA_XDP_DRV_PROG_ID: aya_obj::generated::_bindgen_ty_92 -pub const aya_obj::generated::IFLA_XDP_EXPECTED_FD: aya_obj::generated::_bindgen_ty_92 -pub const aya_obj::generated::IFLA_XDP_FD: aya_obj::generated::_bindgen_ty_92 -pub const aya_obj::generated::IFLA_XDP_FLAGS: aya_obj::generated::_bindgen_ty_92 -pub const aya_obj::generated::IFLA_XDP_HW_PROG_ID: aya_obj::generated::_bindgen_ty_92 -pub const aya_obj::generated::IFLA_XDP_PROG_ID: aya_obj::generated::_bindgen_ty_92 -pub const aya_obj::generated::IFLA_XDP_SKB_PROG_ID: aya_obj::generated::_bindgen_ty_92 -pub const aya_obj::generated::IFLA_XDP_UNSPEC: aya_obj::generated::_bindgen_ty_92 -pub const aya_obj::generated::NFPROTO_ARP: aya_obj::generated::_bindgen_ty_99 -pub const aya_obj::generated::NFPROTO_BRIDGE: aya_obj::generated::_bindgen_ty_99 -pub const aya_obj::generated::NFPROTO_DECNET: aya_obj::generated::_bindgen_ty_99 -pub const aya_obj::generated::NFPROTO_INET: aya_obj::generated::_bindgen_ty_99 -pub const aya_obj::generated::NFPROTO_IPV4: aya_obj::generated::_bindgen_ty_99 -pub const aya_obj::generated::NFPROTO_IPV6: aya_obj::generated::_bindgen_ty_99 -pub const aya_obj::generated::NFPROTO_NETDEV: aya_obj::generated::_bindgen_ty_99 -pub const aya_obj::generated::NFPROTO_NUMPROTO: aya_obj::generated::_bindgen_ty_99 -pub const aya_obj::generated::NFPROTO_UNSPEC: aya_obj::generated::_bindgen_ty_99 +pub const aya_obj::generated::HW_BREAKPOINT_EMPTY: aya_obj::generated::_bindgen_ty_45 +pub const aya_obj::generated::HW_BREAKPOINT_INVALID: aya_obj::generated::_bindgen_ty_45 +pub const aya_obj::generated::HW_BREAKPOINT_LEN_1: aya_obj::generated::_bindgen_ty_44 +pub const aya_obj::generated::HW_BREAKPOINT_LEN_2: aya_obj::generated::_bindgen_ty_44 +pub const aya_obj::generated::HW_BREAKPOINT_LEN_3: aya_obj::generated::_bindgen_ty_44 +pub const aya_obj::generated::HW_BREAKPOINT_LEN_4: aya_obj::generated::_bindgen_ty_44 +pub const aya_obj::generated::HW_BREAKPOINT_LEN_5: aya_obj::generated::_bindgen_ty_44 +pub const aya_obj::generated::HW_BREAKPOINT_LEN_6: aya_obj::generated::_bindgen_ty_44 +pub const aya_obj::generated::HW_BREAKPOINT_LEN_7: aya_obj::generated::_bindgen_ty_44 +pub const aya_obj::generated::HW_BREAKPOINT_LEN_8: aya_obj::generated::_bindgen_ty_44 +pub const aya_obj::generated::HW_BREAKPOINT_R: aya_obj::generated::_bindgen_ty_45 +pub const aya_obj::generated::HW_BREAKPOINT_RW: aya_obj::generated::_bindgen_ty_45 +pub const aya_obj::generated::HW_BREAKPOINT_W: aya_obj::generated::_bindgen_ty_45 +pub const aya_obj::generated::HW_BREAKPOINT_X: aya_obj::generated::_bindgen_ty_45 +pub const aya_obj::generated::IFLA_XDP_ATTACHED: aya_obj::generated::_bindgen_ty_94 +pub const aya_obj::generated::IFLA_XDP_DRV_PROG_ID: aya_obj::generated::_bindgen_ty_94 +pub const aya_obj::generated::IFLA_XDP_EXPECTED_FD: aya_obj::generated::_bindgen_ty_94 +pub const aya_obj::generated::IFLA_XDP_FD: aya_obj::generated::_bindgen_ty_94 +pub const aya_obj::generated::IFLA_XDP_FLAGS: aya_obj::generated::_bindgen_ty_94 +pub const aya_obj::generated::IFLA_XDP_HW_PROG_ID: aya_obj::generated::_bindgen_ty_94 +pub const aya_obj::generated::IFLA_XDP_PROG_ID: aya_obj::generated::_bindgen_ty_94 +pub const aya_obj::generated::IFLA_XDP_SKB_PROG_ID: aya_obj::generated::_bindgen_ty_94 +pub const aya_obj::generated::IFLA_XDP_UNSPEC: aya_obj::generated::_bindgen_ty_94 +pub const aya_obj::generated::NFPROTO_ARP: aya_obj::generated::_bindgen_ty_101 +pub const aya_obj::generated::NFPROTO_BRIDGE: aya_obj::generated::_bindgen_ty_101 +pub const aya_obj::generated::NFPROTO_DECNET: aya_obj::generated::_bindgen_ty_101 +pub const aya_obj::generated::NFPROTO_INET: aya_obj::generated::_bindgen_ty_101 +pub const aya_obj::generated::NFPROTO_IPV4: aya_obj::generated::_bindgen_ty_101 +pub const aya_obj::generated::NFPROTO_IPV6: aya_obj::generated::_bindgen_ty_101 +pub const aya_obj::generated::NFPROTO_NETDEV: aya_obj::generated::_bindgen_ty_101 +pub const aya_obj::generated::NFPROTO_NUMPROTO: aya_obj::generated::_bindgen_ty_101 +pub const aya_obj::generated::NFPROTO_UNSPEC: aya_obj::generated::_bindgen_ty_101 pub const aya_obj::generated::NLMSG_ALIGNTO: u32 pub const aya_obj::generated::NR_BTF_KINDS: aya_obj::generated::_bindgen_ty_42 pub const aya_obj::generated::PERF_EVENT_IOC_DISABLE: u32 @@ -8097,36 +8111,36 @@ pub const aya_obj::generated::PERF_MAX_CONTEXTS_PER_STACK: u32 pub const aya_obj::generated::PERF_MAX_STACK_DEPTH: u32 pub const aya_obj::generated::SO_ATTACH_BPF: u32 pub const aya_obj::generated::SO_DETACH_BPF: u32 -pub const aya_obj::generated::TCA_BPF_ACT: aya_obj::generated::_bindgen_ty_154 -pub const aya_obj::generated::TCA_BPF_CLASSID: aya_obj::generated::_bindgen_ty_154 -pub const aya_obj::generated::TCA_BPF_FD: aya_obj::generated::_bindgen_ty_154 -pub const aya_obj::generated::TCA_BPF_FLAGS: aya_obj::generated::_bindgen_ty_154 -pub const aya_obj::generated::TCA_BPF_FLAGS_GEN: aya_obj::generated::_bindgen_ty_154 +pub const aya_obj::generated::TCA_BPF_ACT: aya_obj::generated::_bindgen_ty_156 +pub const aya_obj::generated::TCA_BPF_CLASSID: aya_obj::generated::_bindgen_ty_156 +pub const aya_obj::generated::TCA_BPF_FD: aya_obj::generated::_bindgen_ty_156 +pub const aya_obj::generated::TCA_BPF_FLAGS: aya_obj::generated::_bindgen_ty_156 +pub const aya_obj::generated::TCA_BPF_FLAGS_GEN: aya_obj::generated::_bindgen_ty_156 pub const aya_obj::generated::TCA_BPF_FLAG_ACT_DIRECT: u32 -pub const aya_obj::generated::TCA_BPF_ID: aya_obj::generated::_bindgen_ty_154 -pub const aya_obj::generated::TCA_BPF_NAME: aya_obj::generated::_bindgen_ty_154 -pub const aya_obj::generated::TCA_BPF_OPS: aya_obj::generated::_bindgen_ty_154 -pub const aya_obj::generated::TCA_BPF_OPS_LEN: aya_obj::generated::_bindgen_ty_154 -pub const aya_obj::generated::TCA_BPF_POLICE: aya_obj::generated::_bindgen_ty_154 -pub const aya_obj::generated::TCA_BPF_TAG: aya_obj::generated::_bindgen_ty_154 -pub const aya_obj::generated::TCA_BPF_UNSPEC: aya_obj::generated::_bindgen_ty_154 -pub const aya_obj::generated::TCA_CHAIN: aya_obj::generated::_bindgen_ty_174 -pub const aya_obj::generated::TCA_DUMP_FLAGS: aya_obj::generated::_bindgen_ty_174 -pub const aya_obj::generated::TCA_DUMP_INVISIBLE: aya_obj::generated::_bindgen_ty_174 -pub const aya_obj::generated::TCA_EGRESS_BLOCK: aya_obj::generated::_bindgen_ty_174 -pub const aya_obj::generated::TCA_EXT_WARN_MSG: aya_obj::generated::_bindgen_ty_174 -pub const aya_obj::generated::TCA_FCNT: aya_obj::generated::_bindgen_ty_174 -pub const aya_obj::generated::TCA_HW_OFFLOAD: aya_obj::generated::_bindgen_ty_174 -pub const aya_obj::generated::TCA_INGRESS_BLOCK: aya_obj::generated::_bindgen_ty_174 -pub const aya_obj::generated::TCA_KIND: aya_obj::generated::_bindgen_ty_174 -pub const aya_obj::generated::TCA_OPTIONS: aya_obj::generated::_bindgen_ty_174 -pub const aya_obj::generated::TCA_PAD: aya_obj::generated::_bindgen_ty_174 -pub const aya_obj::generated::TCA_RATE: aya_obj::generated::_bindgen_ty_174 -pub const aya_obj::generated::TCA_STAB: aya_obj::generated::_bindgen_ty_174 -pub const aya_obj::generated::TCA_STATS: aya_obj::generated::_bindgen_ty_174 -pub const aya_obj::generated::TCA_STATS2: aya_obj::generated::_bindgen_ty_174 -pub const aya_obj::generated::TCA_UNSPEC: aya_obj::generated::_bindgen_ty_174 -pub const aya_obj::generated::TCA_XSTATS: aya_obj::generated::_bindgen_ty_174 +pub const aya_obj::generated::TCA_BPF_ID: aya_obj::generated::_bindgen_ty_156 +pub const aya_obj::generated::TCA_BPF_NAME: aya_obj::generated::_bindgen_ty_156 +pub const aya_obj::generated::TCA_BPF_OPS: aya_obj::generated::_bindgen_ty_156 +pub const aya_obj::generated::TCA_BPF_OPS_LEN: aya_obj::generated::_bindgen_ty_156 +pub const aya_obj::generated::TCA_BPF_POLICE: aya_obj::generated::_bindgen_ty_156 +pub const aya_obj::generated::TCA_BPF_TAG: aya_obj::generated::_bindgen_ty_156 +pub const aya_obj::generated::TCA_BPF_UNSPEC: aya_obj::generated::_bindgen_ty_156 +pub const aya_obj::generated::TCA_CHAIN: aya_obj::generated::_bindgen_ty_176 +pub const aya_obj::generated::TCA_DUMP_FLAGS: aya_obj::generated::_bindgen_ty_176 +pub const aya_obj::generated::TCA_DUMP_INVISIBLE: aya_obj::generated::_bindgen_ty_176 +pub const aya_obj::generated::TCA_EGRESS_BLOCK: aya_obj::generated::_bindgen_ty_176 +pub const aya_obj::generated::TCA_EXT_WARN_MSG: aya_obj::generated::_bindgen_ty_176 +pub const aya_obj::generated::TCA_FCNT: aya_obj::generated::_bindgen_ty_176 +pub const aya_obj::generated::TCA_HW_OFFLOAD: aya_obj::generated::_bindgen_ty_176 +pub const aya_obj::generated::TCA_INGRESS_BLOCK: aya_obj::generated::_bindgen_ty_176 +pub const aya_obj::generated::TCA_KIND: aya_obj::generated::_bindgen_ty_176 +pub const aya_obj::generated::TCA_OPTIONS: aya_obj::generated::_bindgen_ty_176 +pub const aya_obj::generated::TCA_PAD: aya_obj::generated::_bindgen_ty_176 +pub const aya_obj::generated::TCA_RATE: aya_obj::generated::_bindgen_ty_176 +pub const aya_obj::generated::TCA_STAB: aya_obj::generated::_bindgen_ty_176 +pub const aya_obj::generated::TCA_STATS: aya_obj::generated::_bindgen_ty_176 +pub const aya_obj::generated::TCA_STATS2: aya_obj::generated::_bindgen_ty_176 +pub const aya_obj::generated::TCA_UNSPEC: aya_obj::generated::_bindgen_ty_176 +pub const aya_obj::generated::TCA_XSTATS: aya_obj::generated::_bindgen_ty_176 pub const aya_obj::generated::TC_H_CLSACT: u32 pub const aya_obj::generated::TC_H_INGRESS: u32 pub const aya_obj::generated::TC_H_MAJ_MASK: u32 @@ -8143,10 +8157,10 @@ pub const aya_obj::generated::XDP_FLAGS_MODES: u32 pub const aya_obj::generated::XDP_FLAGS_REPLACE: u32 pub const aya_obj::generated::XDP_FLAGS_SKB_MODE: u32 pub const aya_obj::generated::XDP_FLAGS_UPDATE_IF_NOEXIST: u32 -pub const aya_obj::generated::__IFLA_XDP_MAX: aya_obj::generated::_bindgen_ty_92 +pub const aya_obj::generated::__IFLA_XDP_MAX: aya_obj::generated::_bindgen_ty_94 pub const aya_obj::generated::__MAX_BPF_REG: aya_obj::generated::_bindgen_ty_1 -pub const aya_obj::generated::__TCA_BPF_MAX: aya_obj::generated::_bindgen_ty_154 -pub const aya_obj::generated::__TCA_MAX: aya_obj::generated::_bindgen_ty_174 +pub const aya_obj::generated::__TCA_BPF_MAX: aya_obj::generated::_bindgen_ty_156 +pub const aya_obj::generated::__TCA_MAX: aya_obj::generated::_bindgen_ty_176 pub type aya_obj::generated::__s16 = core::ffi::primitives::c_short pub type aya_obj::generated::__s32 = core::ffi::primitives::c_int pub type aya_obj::generated::__s64 = core::ffi::primitives::c_longlong @@ -8155,14 +8169,15 @@ pub type aya_obj::generated::__u32 = core::ffi::primitives::c_uint pub type aya_obj::generated::__u64 = core::ffi::primitives::c_ulonglong pub type aya_obj::generated::__u8 = core::ffi::primitives::c_uchar pub type aya_obj::generated::_bindgen_ty_10 = core::ffi::primitives::c_uint +pub type aya_obj::generated::_bindgen_ty_101 = core::ffi::primitives::c_uint pub type aya_obj::generated::_bindgen_ty_11 = core::ffi::primitives::c_uint pub type aya_obj::generated::_bindgen_ty_12 = core::ffi::primitives::c_uint pub type aya_obj::generated::_bindgen_ty_13 = core::ffi::primitives::c_uint pub type aya_obj::generated::_bindgen_ty_14 = core::ffi::primitives::c_ulong pub type aya_obj::generated::_bindgen_ty_15 = core::ffi::primitives::c_int -pub type aya_obj::generated::_bindgen_ty_154 = core::ffi::primitives::c_uint +pub type aya_obj::generated::_bindgen_ty_156 = core::ffi::primitives::c_uint pub type aya_obj::generated::_bindgen_ty_17 = core::ffi::primitives::c_uint -pub type aya_obj::generated::_bindgen_ty_174 = core::ffi::primitives::c_uint +pub type aya_obj::generated::_bindgen_ty_176 = core::ffi::primitives::c_uint pub type aya_obj::generated::_bindgen_ty_19 = core::ffi::primitives::c_uint pub type aya_obj::generated::_bindgen_ty_2 = core::ffi::primitives::c_uint pub type aya_obj::generated::_bindgen_ty_21 = core::ffi::primitives::c_uint @@ -8174,13 +8189,14 @@ pub type aya_obj::generated::_bindgen_ty_4 = core::ffi::primitives::c_uint pub type aya_obj::generated::_bindgen_ty_41 = core::ffi::primitives::c_uint pub type aya_obj::generated::_bindgen_ty_42 = core::ffi::primitives::c_uint pub type aya_obj::generated::_bindgen_ty_43 = core::ffi::primitives::c_uint +pub type aya_obj::generated::_bindgen_ty_44 = core::ffi::primitives::c_uint +pub type aya_obj::generated::_bindgen_ty_45 = core::ffi::primitives::c_uint pub type aya_obj::generated::_bindgen_ty_5 = core::ffi::primitives::c_uint pub type aya_obj::generated::_bindgen_ty_6 = core::ffi::primitives::c_uint pub type aya_obj::generated::_bindgen_ty_7 = core::ffi::primitives::c_uint pub type aya_obj::generated::_bindgen_ty_8 = core::ffi::primitives::c_uint pub type aya_obj::generated::_bindgen_ty_9 = core::ffi::primitives::c_uint -pub type aya_obj::generated::_bindgen_ty_92 = core::ffi::primitives::c_uint -pub type aya_obj::generated::_bindgen_ty_99 = core::ffi::primitives::c_uint +pub type aya_obj::generated::_bindgen_ty_94 = core::ffi::primitives::c_uint pub mod aya_obj::links pub mod aya_obj::maps pub enum aya_obj::maps::Map diff --git a/xtask/public-api/aya.txt b/xtask/public-api/aya.txt index 60309344..3b6618be 100644 --- a/xtask/public-api/aya.txt +++ b/xtask/public-api/aya.txt @@ -4781,10 +4781,6 @@ impl aya::programs::links::Link for aya::programs::lsm_cgroup::LsmLink pub type aya::programs::lsm_cgroup::LsmLink::Id = aya::programs::lsm_cgroup::LsmLinkId pub fn aya::programs::lsm_cgroup::LsmLink::detach(self) -> core::result::Result<(), aya::programs::ProgramError> pub fn aya::programs::lsm_cgroup::LsmLink::id(&self) -> Self::Id -impl aya::programs::links::Link for aya::programs::perf_attach::PerfLink -pub type aya::programs::perf_attach::PerfLink::Id = aya::programs::perf_attach::PerfLinkId -pub fn aya::programs::perf_attach::PerfLink::detach(self) -> core::result::Result<(), aya::programs::ProgramError> -pub fn aya::programs::perf_attach::PerfLink::id(&self) -> Self::Id impl aya::programs::links::Link for aya::programs::perf_event::PerfEventLink pub type aya::programs::perf_event::PerfEventLink::Id = aya::programs::perf_event::PerfEventLinkId pub fn aya::programs::perf_event::PerfEventLink::detach(self) -> core::result::Result<(), aya::programs::ProgramError> @@ -5225,44 +5221,6 @@ pub fn aya::programs::lsm_cgroup::LsmLinkId::borrow_mut(&mut self) -> &mut T impl core::convert::From for aya::programs::lsm_cgroup::LsmLinkId pub fn aya::programs::lsm_cgroup::LsmLinkId::from(t: T) -> T pub mod aya::programs::perf_attach -pub struct aya::programs::perf_attach::PerfLink -impl aya::programs::links::Link for aya::programs::perf_attach::PerfLink -pub type aya::programs::perf_attach::PerfLink::Id = aya::programs::perf_attach::PerfLinkId -pub fn aya::programs::perf_attach::PerfLink::detach(self) -> core::result::Result<(), aya::programs::ProgramError> -pub fn aya::programs::perf_attach::PerfLink::id(&self) -> Self::Id -impl core::cmp::Eq for aya::programs::perf_attach::PerfLink -impl core::cmp::PartialEq for aya::programs::perf_attach::PerfLink -pub fn aya::programs::perf_attach::PerfLink::eq(&self, other: &Self) -> bool -impl core::fmt::Debug for aya::programs::perf_attach::PerfLink -pub fn aya::programs::perf_attach::PerfLink::fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result -impl core::hash::Hash for aya::programs::perf_attach::PerfLink -pub fn aya::programs::perf_attach::PerfLink::hash(&self, state: &mut H) -impl equivalent::Equivalent for aya::programs::perf_attach::PerfLinkId -pub fn aya::programs::perf_attach::PerfLinkId::equivalent(&self, key: &aya::programs::perf_attach::PerfLink) -> bool -impl core::marker::Freeze for aya::programs::perf_attach::PerfLink -impl core::marker::Send for aya::programs::perf_attach::PerfLink -impl core::marker::Sync for aya::programs::perf_attach::PerfLink -impl core::marker::Unpin for aya::programs::perf_attach::PerfLink -impl core::panic::unwind_safe::RefUnwindSafe for aya::programs::perf_attach::PerfLink -impl core::panic::unwind_safe::UnwindSafe for aya::programs::perf_attach::PerfLink -impl equivalent::Equivalent for aya::programs::perf_attach::PerfLink where Q: core::cmp::Eq + ?core::marker::Sized, K: core::borrow::Borrow + ?core::marker::Sized -pub fn aya::programs::perf_attach::PerfLink::equivalent(&self, key: &K) -> bool -impl core::convert::Into for aya::programs::perf_attach::PerfLink where U: core::convert::From -pub fn aya::programs::perf_attach::PerfLink::into(self) -> U -impl core::convert::TryFrom for aya::programs::perf_attach::PerfLink where U: core::convert::Into -pub type aya::programs::perf_attach::PerfLink::Error = core::convert::Infallible -pub fn aya::programs::perf_attach::PerfLink::try_from(value: U) -> core::result::Result>::Error> -impl core::convert::TryInto for aya::programs::perf_attach::PerfLink where U: core::convert::TryFrom -pub type aya::programs::perf_attach::PerfLink::Error = >::Error -pub fn aya::programs::perf_attach::PerfLink::try_into(self) -> core::result::Result>::Error> -impl core::any::Any for aya::programs::perf_attach::PerfLink where T: 'static + ?core::marker::Sized -pub fn aya::programs::perf_attach::PerfLink::type_id(&self) -> core::any::TypeId -impl core::borrow::Borrow for aya::programs::perf_attach::PerfLink where T: ?core::marker::Sized -pub fn aya::programs::perf_attach::PerfLink::borrow(&self) -> &T -impl core::borrow::BorrowMut for aya::programs::perf_attach::PerfLink where T: ?core::marker::Sized -pub fn aya::programs::perf_attach::PerfLink::borrow_mut(&mut self) -> &mut T -impl core::convert::From for aya::programs::perf_attach::PerfLink -pub fn aya::programs::perf_attach::PerfLink::from(t: T) -> T pub struct aya::programs::perf_attach::PerfLinkId(_) impl core::cmp::Eq for aya::programs::perf_attach::PerfLinkId impl core::cmp::PartialEq for aya::programs::perf_attach::PerfLinkId @@ -5272,8 +5230,6 @@ pub fn aya::programs::perf_attach::PerfLinkId::fmt(&self, f: &mut core::fmt::For impl core::hash::Hash for aya::programs::perf_attach::PerfLinkId pub fn aya::programs::perf_attach::PerfLinkId::hash<__H: core::hash::Hasher>(&self, state: &mut __H) impl core::marker::StructuralPartialEq for aya::programs::perf_attach::PerfLinkId -impl equivalent::Equivalent for aya::programs::perf_attach::PerfLinkId -pub fn aya::programs::perf_attach::PerfLinkId::equivalent(&self, key: &aya::programs::perf_attach::PerfLink) -> bool impl core::marker::Freeze for aya::programs::perf_attach::PerfLinkId impl core::marker::Send for aya::programs::perf_attach::PerfLinkId impl core::marker::Sync for aya::programs::perf_attach::PerfLinkId @@ -5299,6 +5255,46 @@ pub fn aya::programs::perf_attach::PerfLinkId::borrow_mut(&mut self) -> &mut T impl core::convert::From for aya::programs::perf_attach::PerfLinkId pub fn aya::programs::perf_attach::PerfLinkId::from(t: T) -> T pub mod aya::programs::perf_event +pub enum aya::programs::perf_event::BreakpointConfig +pub aya::programs::perf_event::BreakpointConfig::Data +pub aya::programs::perf_event::BreakpointConfig::Data::address: u64 +pub aya::programs::perf_event::BreakpointConfig::Data::length: aya::programs::perf_event::PerfBreakpointLength +pub aya::programs::perf_event::BreakpointConfig::Data::type: aya::programs::perf_event::PerfBreakpointType +pub aya::programs::perf_event::BreakpointConfig::Instruction +pub aya::programs::perf_event::BreakpointConfig::Instruction::address: u64 +impl core::clone::Clone for aya::programs::perf_event::BreakpointConfig +pub fn aya::programs::perf_event::BreakpointConfig::clone(&self) -> aya::programs::perf_event::BreakpointConfig +impl core::fmt::Debug for aya::programs::perf_event::BreakpointConfig +pub fn aya::programs::perf_event::BreakpointConfig::fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result +impl core::marker::Copy for aya::programs::perf_event::BreakpointConfig +impl core::marker::Freeze for aya::programs::perf_event::BreakpointConfig +impl core::marker::Send for aya::programs::perf_event::BreakpointConfig +impl core::marker::Sync for aya::programs::perf_event::BreakpointConfig +impl core::marker::Unpin for aya::programs::perf_event::BreakpointConfig +impl core::panic::unwind_safe::RefUnwindSafe for aya::programs::perf_event::BreakpointConfig +impl core::panic::unwind_safe::UnwindSafe for aya::programs::perf_event::BreakpointConfig +impl core::convert::Into for aya::programs::perf_event::BreakpointConfig where U: core::convert::From +pub fn aya::programs::perf_event::BreakpointConfig::into(self) -> U +impl core::convert::TryFrom for aya::programs::perf_event::BreakpointConfig where U: core::convert::Into +pub type aya::programs::perf_event::BreakpointConfig::Error = core::convert::Infallible +pub fn aya::programs::perf_event::BreakpointConfig::try_from(value: U) -> core::result::Result>::Error> +impl core::convert::TryInto for aya::programs::perf_event::BreakpointConfig where U: core::convert::TryFrom +pub type aya::programs::perf_event::BreakpointConfig::Error = >::Error +pub fn aya::programs::perf_event::BreakpointConfig::try_into(self) -> core::result::Result>::Error> +impl alloc::borrow::ToOwned for aya::programs::perf_event::BreakpointConfig where T: core::clone::Clone +pub type aya::programs::perf_event::BreakpointConfig::Owned = T +pub fn aya::programs::perf_event::BreakpointConfig::clone_into(&self, target: &mut T) +pub fn aya::programs::perf_event::BreakpointConfig::to_owned(&self) -> T +impl core::any::Any for aya::programs::perf_event::BreakpointConfig where T: 'static + ?core::marker::Sized +pub fn aya::programs::perf_event::BreakpointConfig::type_id(&self) -> core::any::TypeId +impl core::borrow::Borrow for aya::programs::perf_event::BreakpointConfig where T: ?core::marker::Sized +pub fn aya::programs::perf_event::BreakpointConfig::borrow(&self) -> &T +impl core::borrow::BorrowMut for aya::programs::perf_event::BreakpointConfig where T: ?core::marker::Sized +pub fn aya::programs::perf_event::BreakpointConfig::borrow_mut(&mut self) -> &mut T +impl core::clone::CloneToUninit for aya::programs::perf_event::BreakpointConfig where T: core::clone::Clone +pub unsafe fn aya::programs::perf_event::BreakpointConfig::clone_to_uninit(&self, dest: *mut u8) +impl core::convert::From for aya::programs::perf_event::BreakpointConfig +pub fn aya::programs::perf_event::BreakpointConfig::from(t: T) -> T #[repr(u32)] pub enum aya::programs::perf_event::HardwareEvent pub aya::programs::perf_event::HardwareEvent::BranchInstructions = 4 pub aya::programs::perf_event::HardwareEvent::BranchMisses = 5 @@ -5457,8 +5453,83 @@ impl core::clone::CloneToUninit for aya::programs::perf_event::HwCacheResult pub unsafe fn aya::programs::perf_event::HwCacheResult::clone_to_uninit(&self, dest: *mut u8) impl core::convert::From for aya::programs::perf_event::HwCacheResult pub fn aya::programs::perf_event::HwCacheResult::from(t: T) -> T +#[repr(u32)] pub enum aya::programs::perf_event::PerfBreakpointLength +pub aya::programs::perf_event::PerfBreakpointLength::Len1 = 1 +pub aya::programs::perf_event::PerfBreakpointLength::Len2 = 2 +pub aya::programs::perf_event::PerfBreakpointLength::Len4 = 4 +pub aya::programs::perf_event::PerfBreakpointLength::Len8 = 8 +impl core::clone::Clone for aya::programs::perf_event::PerfBreakpointLength +pub fn aya::programs::perf_event::PerfBreakpointLength::clone(&self) -> aya::programs::perf_event::PerfBreakpointLength +impl core::fmt::Debug for aya::programs::perf_event::PerfBreakpointLength +pub fn aya::programs::perf_event::PerfBreakpointLength::fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result +impl core::marker::Copy for aya::programs::perf_event::PerfBreakpointLength +impl core::marker::Freeze for aya::programs::perf_event::PerfBreakpointLength +impl core::marker::Send for aya::programs::perf_event::PerfBreakpointLength +impl core::marker::Sync for aya::programs::perf_event::PerfBreakpointLength +impl core::marker::Unpin for aya::programs::perf_event::PerfBreakpointLength +impl core::panic::unwind_safe::RefUnwindSafe for aya::programs::perf_event::PerfBreakpointLength +impl core::panic::unwind_safe::UnwindSafe for aya::programs::perf_event::PerfBreakpointLength +impl core::convert::Into for aya::programs::perf_event::PerfBreakpointLength where U: core::convert::From +pub fn aya::programs::perf_event::PerfBreakpointLength::into(self) -> U +impl core::convert::TryFrom for aya::programs::perf_event::PerfBreakpointLength where U: core::convert::Into +pub type aya::programs::perf_event::PerfBreakpointLength::Error = core::convert::Infallible +pub fn aya::programs::perf_event::PerfBreakpointLength::try_from(value: U) -> core::result::Result>::Error> +impl core::convert::TryInto for aya::programs::perf_event::PerfBreakpointLength where U: core::convert::TryFrom +pub type aya::programs::perf_event::PerfBreakpointLength::Error = >::Error +pub fn aya::programs::perf_event::PerfBreakpointLength::try_into(self) -> core::result::Result>::Error> +impl alloc::borrow::ToOwned for aya::programs::perf_event::PerfBreakpointLength where T: core::clone::Clone +pub type aya::programs::perf_event::PerfBreakpointLength::Owned = T +pub fn aya::programs::perf_event::PerfBreakpointLength::clone_into(&self, target: &mut T) +pub fn aya::programs::perf_event::PerfBreakpointLength::to_owned(&self) -> T +impl core::any::Any for aya::programs::perf_event::PerfBreakpointLength where T: 'static + ?core::marker::Sized +pub fn aya::programs::perf_event::PerfBreakpointLength::type_id(&self) -> core::any::TypeId +impl core::borrow::Borrow for aya::programs::perf_event::PerfBreakpointLength where T: ?core::marker::Sized +pub fn aya::programs::perf_event::PerfBreakpointLength::borrow(&self) -> &T +impl core::borrow::BorrowMut for aya::programs::perf_event::PerfBreakpointLength where T: ?core::marker::Sized +pub fn aya::programs::perf_event::PerfBreakpointLength::borrow_mut(&mut self) -> &mut T +impl core::clone::CloneToUninit for aya::programs::perf_event::PerfBreakpointLength where T: core::clone::Clone +pub unsafe fn aya::programs::perf_event::PerfBreakpointLength::clone_to_uninit(&self, dest: *mut u8) +impl core::convert::From for aya::programs::perf_event::PerfBreakpointLength +pub fn aya::programs::perf_event::PerfBreakpointLength::from(t: T) -> T +#[repr(u32)] pub enum aya::programs::perf_event::PerfBreakpointType +pub aya::programs::perf_event::PerfBreakpointType::Read = 1 +pub aya::programs::perf_event::PerfBreakpointType::ReadWrite = 3 +pub aya::programs::perf_event::PerfBreakpointType::Write = 2 +impl core::clone::Clone for aya::programs::perf_event::PerfBreakpointType +pub fn aya::programs::perf_event::PerfBreakpointType::clone(&self) -> aya::programs::perf_event::PerfBreakpointType +impl core::fmt::Debug for aya::programs::perf_event::PerfBreakpointType +pub fn aya::programs::perf_event::PerfBreakpointType::fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result +impl core::marker::Copy for aya::programs::perf_event::PerfBreakpointType +impl core::marker::Freeze for aya::programs::perf_event::PerfBreakpointType +impl core::marker::Send for aya::programs::perf_event::PerfBreakpointType +impl core::marker::Sync for aya::programs::perf_event::PerfBreakpointType +impl core::marker::Unpin for aya::programs::perf_event::PerfBreakpointType +impl core::panic::unwind_safe::RefUnwindSafe for aya::programs::perf_event::PerfBreakpointType +impl core::panic::unwind_safe::UnwindSafe for aya::programs::perf_event::PerfBreakpointType +impl core::convert::Into for aya::programs::perf_event::PerfBreakpointType where U: core::convert::From +pub fn aya::programs::perf_event::PerfBreakpointType::into(self) -> U +impl core::convert::TryFrom for aya::programs::perf_event::PerfBreakpointType where U: core::convert::Into +pub type aya::programs::perf_event::PerfBreakpointType::Error = core::convert::Infallible +pub fn aya::programs::perf_event::PerfBreakpointType::try_from(value: U) -> core::result::Result>::Error> +impl core::convert::TryInto for aya::programs::perf_event::PerfBreakpointType where U: core::convert::TryFrom +pub type aya::programs::perf_event::PerfBreakpointType::Error = >::Error +pub fn aya::programs::perf_event::PerfBreakpointType::try_into(self) -> core::result::Result>::Error> +impl alloc::borrow::ToOwned for aya::programs::perf_event::PerfBreakpointType where T: core::clone::Clone +pub type aya::programs::perf_event::PerfBreakpointType::Owned = T +pub fn aya::programs::perf_event::PerfBreakpointType::clone_into(&self, target: &mut T) +pub fn aya::programs::perf_event::PerfBreakpointType::to_owned(&self) -> T +impl core::any::Any for aya::programs::perf_event::PerfBreakpointType where T: 'static + ?core::marker::Sized +pub fn aya::programs::perf_event::PerfBreakpointType::type_id(&self) -> core::any::TypeId +impl core::borrow::Borrow for aya::programs::perf_event::PerfBreakpointType where T: ?core::marker::Sized +pub fn aya::programs::perf_event::PerfBreakpointType::borrow(&self) -> &T +impl core::borrow::BorrowMut for aya::programs::perf_event::PerfBreakpointType where T: ?core::marker::Sized +pub fn aya::programs::perf_event::PerfBreakpointType::borrow_mut(&mut self) -> &mut T +impl core::clone::CloneToUninit for aya::programs::perf_event::PerfBreakpointType where T: core::clone::Clone +pub unsafe fn aya::programs::perf_event::PerfBreakpointType::clone_to_uninit(&self, dest: *mut u8) +impl core::convert::From for aya::programs::perf_event::PerfBreakpointType +pub fn aya::programs::perf_event::PerfBreakpointType::from(t: T) -> T pub enum aya::programs::perf_event::PerfEventConfig -pub aya::programs::perf_event::PerfEventConfig::Breakpoint +pub aya::programs::perf_event::PerfEventConfig::Breakpoint(aya::programs::perf_event::BreakpointConfig) pub aya::programs::perf_event::PerfEventConfig::Hardware(aya::programs::perf_event::HardwareEvent) pub aya::programs::perf_event::PerfEventConfig::HwCache pub aya::programs::perf_event::PerfEventConfig::HwCache::event: aya::programs::perf_event::HwCacheEvent @@ -5508,18 +5579,16 @@ pub fn aya::programs::perf_event::PerfEventConfig::from(t: T) -> T pub enum aya::programs::perf_event::PerfEventScope pub aya::programs::perf_event::PerfEventScope::AllProcessesOneCpu pub aya::programs::perf_event::PerfEventScope::AllProcessesOneCpu::cpu: u32 -pub aya::programs::perf_event::PerfEventScope::CallingProcessAnyCpu -pub aya::programs::perf_event::PerfEventScope::CallingProcessOneCpu -pub aya::programs::perf_event::PerfEventScope::CallingProcessOneCpu::cpu: u32 -pub aya::programs::perf_event::PerfEventScope::OneProcessAnyCpu -pub aya::programs::perf_event::PerfEventScope::OneProcessAnyCpu::pid: u32 -pub aya::programs::perf_event::PerfEventScope::OneProcessOneCpu -pub aya::programs::perf_event::PerfEventScope::OneProcessOneCpu::cpu: u32 -pub aya::programs::perf_event::PerfEventScope::OneProcessOneCpu::pid: u32 +pub aya::programs::perf_event::PerfEventScope::CallingProcess +pub aya::programs::perf_event::PerfEventScope::CallingProcess::cpu: core::option::Option +pub aya::programs::perf_event::PerfEventScope::OneProcess +pub aya::programs::perf_event::PerfEventScope::OneProcess::cpu: core::option::Option +pub aya::programs::perf_event::PerfEventScope::OneProcess::pid: u32 impl core::clone::Clone for aya::programs::perf_event::PerfEventScope pub fn aya::programs::perf_event::PerfEventScope::clone(&self) -> aya::programs::perf_event::PerfEventScope impl core::fmt::Debug for aya::programs::perf_event::PerfEventScope pub fn aya::programs::perf_event::PerfEventScope::fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result +impl core::marker::Copy for aya::programs::perf_event::PerfEventScope impl core::marker::Freeze for aya::programs::perf_event::PerfEventScope impl core::marker::Send for aya::programs::perf_event::PerfEventScope impl core::marker::Sync for aya::programs::perf_event::PerfEventScope @@ -5555,6 +5624,7 @@ impl core::clone::Clone for aya::programs::perf_event::SamplePolicy pub fn aya::programs::perf_event::SamplePolicy::clone(&self) -> aya::programs::perf_event::SamplePolicy impl core::fmt::Debug for aya::programs::perf_event::SamplePolicy pub fn aya::programs::perf_event::SamplePolicy::fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result +impl core::marker::Copy for aya::programs::perf_event::SamplePolicy impl core::marker::Freeze for aya::programs::perf_event::SamplePolicy impl core::marker::Send for aya::programs::perf_event::SamplePolicy impl core::marker::Sync for aya::programs::perf_event::SamplePolicy @@ -5632,7 +5702,7 @@ pub fn aya::programs::perf_event::SoftwareEvent::from(t: T) -> T pub struct aya::programs::perf_event::PerfEvent impl aya::programs::perf_event::PerfEvent pub const aya::programs::perf_event::PerfEvent::PROGRAM_TYPE: aya::programs::ProgramType -pub fn aya::programs::perf_event::PerfEvent::attach(&mut self, perf_type: aya::programs::perf_event::PerfEventConfig, scope: aya::programs::perf_event::PerfEventScope, sample_policy: aya::programs::perf_event::SamplePolicy, inherit: bool) -> core::result::Result +pub fn aya::programs::perf_event::PerfEvent::attach(&mut self, config: aya::programs::perf_event::PerfEventConfig, scope: aya::programs::perf_event::PerfEventScope, sample_policy: aya::programs::perf_event::SamplePolicy, inherit: bool) -> core::result::Result pub fn aya::programs::perf_event::PerfEvent::load(&mut self) -> core::result::Result<(), aya::programs::ProgramError> impl aya::programs::perf_event::PerfEvent pub fn aya::programs::perf_event::PerfEvent::detach(&mut self, link_id: aya::programs::perf_event::PerfEventLinkId) -> core::result::Result<(), aya::programs::ProgramError> @@ -7304,7 +7374,7 @@ pub aya::programs::uprobe::UProbeError::InvalidLdSoCache::io_error: &'static std pub aya::programs::uprobe::UProbeError::InvalidTarget pub aya::programs::uprobe::UProbeError::InvalidTarget::path: std::path::PathBuf pub aya::programs::uprobe::UProbeError::ProcMap -pub aya::programs::uprobe::UProbeError::ProcMap::pid: i32 +pub aya::programs::uprobe::UProbeError::ProcMap::pid: u32 pub aya::programs::uprobe::UProbeError::ProcMap::source: aya::programs::uprobe::ProcMapError pub aya::programs::uprobe::UProbeError::SymbolError pub aya::programs::uprobe::UProbeError::SymbolError::error: alloc::boxed::Box<(dyn core::error::Error + core::marker::Send + core::marker::Sync)> @@ -7344,7 +7414,7 @@ pub fn aya::programs::uprobe::UProbeError::from(t: T) -> T pub struct aya::programs::uprobe::UProbe impl aya::programs::uprobe::UProbe pub const aya::programs::uprobe::UProbe::PROGRAM_TYPE: aya::programs::ProgramType -pub fn aya::programs::uprobe::UProbe::attach<'loc, T: core::convert::AsRef, Loc: core::convert::Into>>(&mut self, location: Loc, target: T, pid: core::option::Option, cookie: core::option::Option) -> core::result::Result +pub fn aya::programs::uprobe::UProbe::attach<'loc, T: core::convert::AsRef, Loc: core::convert::Into>>(&mut self, location: Loc, target: T, pid: core::option::Option, cookie: core::option::Option) -> core::result::Result pub fn aya::programs::uprobe::UProbe::from_pin>(path: P, kind: aya::programs::ProbeKind) -> core::result::Result pub fn aya::programs::uprobe::UProbe::kind(&self) -> aya::programs::ProbeKind pub fn aya::programs::uprobe::UProbe::load(&mut self) -> core::result::Result<(), aya::programs::ProgramError> @@ -7943,54 +8013,9 @@ impl core::clone::CloneToUninit for aya::programs::LsmAttachType where T: cor pub unsafe fn aya::programs::LsmAttachType::clone_to_uninit(&self, dest: *mut u8) impl core::convert::From for aya::programs::LsmAttachType pub fn aya::programs::LsmAttachType::from(t: T) -> T -pub enum aya::programs::PerfEventScope -pub aya::programs::PerfEventScope::AllProcessesOneCpu -pub aya::programs::PerfEventScope::AllProcessesOneCpu::cpu: u32 -pub aya::programs::PerfEventScope::CallingProcessAnyCpu -pub aya::programs::PerfEventScope::CallingProcessOneCpu -pub aya::programs::PerfEventScope::CallingProcessOneCpu::cpu: u32 -pub aya::programs::PerfEventScope::OneProcessAnyCpu -pub aya::programs::PerfEventScope::OneProcessAnyCpu::pid: u32 -pub aya::programs::PerfEventScope::OneProcessOneCpu -pub aya::programs::PerfEventScope::OneProcessOneCpu::cpu: u32 -pub aya::programs::PerfEventScope::OneProcessOneCpu::pid: u32 -impl core::clone::Clone for aya::programs::perf_event::PerfEventScope -pub fn aya::programs::perf_event::PerfEventScope::clone(&self) -> aya::programs::perf_event::PerfEventScope -impl core::fmt::Debug for aya::programs::perf_event::PerfEventScope -pub fn aya::programs::perf_event::PerfEventScope::fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result -impl core::marker::Freeze for aya::programs::perf_event::PerfEventScope -impl core::marker::Send for aya::programs::perf_event::PerfEventScope -impl core::marker::Sync for aya::programs::perf_event::PerfEventScope -impl core::marker::Unpin for aya::programs::perf_event::PerfEventScope -impl core::panic::unwind_safe::RefUnwindSafe for aya::programs::perf_event::PerfEventScope -impl core::panic::unwind_safe::UnwindSafe for aya::programs::perf_event::PerfEventScope -impl core::convert::Into for aya::programs::perf_event::PerfEventScope where U: core::convert::From -pub fn aya::programs::perf_event::PerfEventScope::into(self) -> U -impl core::convert::TryFrom for aya::programs::perf_event::PerfEventScope where U: core::convert::Into -pub type aya::programs::perf_event::PerfEventScope::Error = core::convert::Infallible -pub fn aya::programs::perf_event::PerfEventScope::try_from(value: U) -> core::result::Result>::Error> -impl core::convert::TryInto for aya::programs::perf_event::PerfEventScope where U: core::convert::TryFrom -pub type aya::programs::perf_event::PerfEventScope::Error = >::Error -pub fn aya::programs::perf_event::PerfEventScope::try_into(self) -> core::result::Result>::Error> -impl alloc::borrow::ToOwned for aya::programs::perf_event::PerfEventScope where T: core::clone::Clone -pub type aya::programs::perf_event::PerfEventScope::Owned = T -pub fn aya::programs::perf_event::PerfEventScope::clone_into(&self, target: &mut T) -pub fn aya::programs::perf_event::PerfEventScope::to_owned(&self) -> T -impl core::any::Any for aya::programs::perf_event::PerfEventScope where T: 'static + ?core::marker::Sized -pub fn aya::programs::perf_event::PerfEventScope::type_id(&self) -> core::any::TypeId -impl core::borrow::Borrow for aya::programs::perf_event::PerfEventScope where T: ?core::marker::Sized -pub fn aya::programs::perf_event::PerfEventScope::borrow(&self) -> &T -impl core::borrow::BorrowMut for aya::programs::perf_event::PerfEventScope where T: ?core::marker::Sized -pub fn aya::programs::perf_event::PerfEventScope::borrow_mut(&mut self) -> &mut T -impl core::clone::CloneToUninit for aya::programs::perf_event::PerfEventScope where T: core::clone::Clone -pub unsafe fn aya::programs::perf_event::PerfEventScope::clone_to_uninit(&self, dest: *mut u8) -impl core::convert::From for aya::programs::perf_event::PerfEventScope -pub fn aya::programs::perf_event::PerfEventScope::from(t: T) -> T pub enum aya::programs::ProbeKind -pub aya::programs::ProbeKind::KProbe -pub aya::programs::ProbeKind::KRetProbe -pub aya::programs::ProbeKind::UProbe -pub aya::programs::ProbeKind::URetProbe +pub aya::programs::ProbeKind::Entry +pub aya::programs::ProbeKind::Return impl core::clone::Clone for aya::programs::ProbeKind pub fn aya::programs::ProbeKind::clone(&self) -> aya::programs::ProbeKind impl core::fmt::Debug for aya::programs::ProbeKind @@ -8396,41 +8421,6 @@ impl core::clone::CloneToUninit for aya::programs::ProgramType where T: core: pub unsafe fn aya::programs::ProgramType::clone_to_uninit(&self, dest: *mut u8) impl core::convert::From for aya::programs::ProgramType pub fn aya::programs::ProgramType::from(t: T) -> T -pub enum aya::programs::SamplePolicy -pub aya::programs::SamplePolicy::Frequency(u64) -pub aya::programs::SamplePolicy::Period(u64) -impl core::clone::Clone for aya::programs::perf_event::SamplePolicy -pub fn aya::programs::perf_event::SamplePolicy::clone(&self) -> aya::programs::perf_event::SamplePolicy -impl core::fmt::Debug for aya::programs::perf_event::SamplePolicy -pub fn aya::programs::perf_event::SamplePolicy::fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result -impl core::marker::Freeze for aya::programs::perf_event::SamplePolicy -impl core::marker::Send for aya::programs::perf_event::SamplePolicy -impl core::marker::Sync for aya::programs::perf_event::SamplePolicy -impl core::marker::Unpin for aya::programs::perf_event::SamplePolicy -impl core::panic::unwind_safe::RefUnwindSafe for aya::programs::perf_event::SamplePolicy -impl core::panic::unwind_safe::UnwindSafe for aya::programs::perf_event::SamplePolicy -impl core::convert::Into for aya::programs::perf_event::SamplePolicy where U: core::convert::From -pub fn aya::programs::perf_event::SamplePolicy::into(self) -> U -impl core::convert::TryFrom for aya::programs::perf_event::SamplePolicy where U: core::convert::Into -pub type aya::programs::perf_event::SamplePolicy::Error = core::convert::Infallible -pub fn aya::programs::perf_event::SamplePolicy::try_from(value: U) -> core::result::Result>::Error> -impl core::convert::TryInto for aya::programs::perf_event::SamplePolicy where U: core::convert::TryFrom -pub type aya::programs::perf_event::SamplePolicy::Error = >::Error -pub fn aya::programs::perf_event::SamplePolicy::try_into(self) -> core::result::Result>::Error> -impl alloc::borrow::ToOwned for aya::programs::perf_event::SamplePolicy where T: core::clone::Clone -pub type aya::programs::perf_event::SamplePolicy::Owned = T -pub fn aya::programs::perf_event::SamplePolicy::clone_into(&self, target: &mut T) -pub fn aya::programs::perf_event::SamplePolicy::to_owned(&self) -> T -impl core::any::Any for aya::programs::perf_event::SamplePolicy where T: 'static + ?core::marker::Sized -pub fn aya::programs::perf_event::SamplePolicy::type_id(&self) -> core::any::TypeId -impl core::borrow::Borrow for aya::programs::perf_event::SamplePolicy where T: ?core::marker::Sized -pub fn aya::programs::perf_event::SamplePolicy::borrow(&self) -> &T -impl core::borrow::BorrowMut for aya::programs::perf_event::SamplePolicy where T: ?core::marker::Sized -pub fn aya::programs::perf_event::SamplePolicy::borrow_mut(&mut self) -> &mut T -impl core::clone::CloneToUninit for aya::programs::perf_event::SamplePolicy where T: core::clone::Clone -pub unsafe fn aya::programs::perf_event::SamplePolicy::clone_to_uninit(&self, dest: *mut u8) -impl core::convert::From for aya::programs::perf_event::SamplePolicy -pub fn aya::programs::perf_event::SamplePolicy::from(t: T) -> T pub enum aya::programs::SkSkbKind pub aya::programs::SkSkbKind::StreamParser pub aya::programs::SkSkbKind::StreamVerdict @@ -8635,7 +8625,7 @@ pub aya::programs::UProbeError::InvalidLdSoCache::io_error: &'static std::io::er pub aya::programs::UProbeError::InvalidTarget pub aya::programs::UProbeError::InvalidTarget::path: std::path::PathBuf pub aya::programs::UProbeError::ProcMap -pub aya::programs::UProbeError::ProcMap::pid: i32 +pub aya::programs::UProbeError::ProcMap::pid: u32 pub aya::programs::UProbeError::ProcMap::source: aya::programs::uprobe::ProcMapError pub aya::programs::UProbeError::SymbolError pub aya::programs::UProbeError::SymbolError::error: alloc::boxed::Box<(dyn core::error::Error + core::marker::Send + core::marker::Sync)> @@ -9582,7 +9572,7 @@ pub fn aya::programs::lsm_cgroup::LsmCgroup::from(t: T) -> T pub struct aya::programs::PerfEvent impl aya::programs::perf_event::PerfEvent pub const aya::programs::perf_event::PerfEvent::PROGRAM_TYPE: aya::programs::ProgramType -pub fn aya::programs::perf_event::PerfEvent::attach(&mut self, perf_type: aya::programs::perf_event::PerfEventConfig, scope: aya::programs::perf_event::PerfEventScope, sample_policy: aya::programs::perf_event::SamplePolicy, inherit: bool) -> core::result::Result +pub fn aya::programs::perf_event::PerfEvent::attach(&mut self, config: aya::programs::perf_event::PerfEventConfig, scope: aya::programs::perf_event::PerfEventScope, sample_policy: aya::programs::perf_event::SamplePolicy, inherit: bool) -> core::result::Result pub fn aya::programs::perf_event::PerfEvent::load(&mut self) -> core::result::Result<(), aya::programs::ProgramError> impl aya::programs::perf_event::PerfEvent pub fn aya::programs::perf_event::PerfEvent::detach(&mut self, link_id: aya::programs::perf_event::PerfEventLinkId) -> core::result::Result<(), aya::programs::ProgramError> @@ -10157,7 +10147,7 @@ pub fn aya::programs::trace_point::TracePoint::from(t: T) -> T pub struct aya::programs::UProbe impl aya::programs::uprobe::UProbe pub const aya::programs::uprobe::UProbe::PROGRAM_TYPE: aya::programs::ProgramType -pub fn aya::programs::uprobe::UProbe::attach<'loc, T: core::convert::AsRef, Loc: core::convert::Into>>(&mut self, location: Loc, target: T, pid: core::option::Option, cookie: core::option::Option) -> core::result::Result +pub fn aya::programs::uprobe::UProbe::attach<'loc, T: core::convert::AsRef, Loc: core::convert::Into>>(&mut self, location: Loc, target: T, pid: core::option::Option, cookie: core::option::Option) -> core::result::Result pub fn aya::programs::uprobe::UProbe::from_pin>(path: P, kind: aya::programs::ProbeKind) -> core::result::Result pub fn aya::programs::uprobe::UProbe::kind(&self) -> aya::programs::ProbeKind pub fn aya::programs::uprobe::UProbe::load(&mut self) -> core::result::Result<(), aya::programs::ProgramError> @@ -10446,10 +10436,6 @@ impl aya::programs::links::Link for aya::programs::lsm_cgroup::LsmLink pub type aya::programs::lsm_cgroup::LsmLink::Id = aya::programs::lsm_cgroup::LsmLinkId pub fn aya::programs::lsm_cgroup::LsmLink::detach(self) -> core::result::Result<(), aya::programs::ProgramError> pub fn aya::programs::lsm_cgroup::LsmLink::id(&self) -> Self::Id -impl aya::programs::links::Link for aya::programs::perf_attach::PerfLink -pub type aya::programs::perf_attach::PerfLink::Id = aya::programs::perf_attach::PerfLinkId -pub fn aya::programs::perf_attach::PerfLink::detach(self) -> core::result::Result<(), aya::programs::ProgramError> -pub fn aya::programs::perf_attach::PerfLink::id(&self) -> Self::Id impl aya::programs::links::Link for aya::programs::perf_event::PerfEventLink pub type aya::programs::perf_event::PerfEventLink::Id = aya::programs::perf_event::PerfEventLinkId pub fn aya::programs::perf_event::PerfEventLink::detach(self) -> core::result::Result<(), aya::programs::ProgramError> @@ -10708,6 +10694,7 @@ pub fn aya::Ebpf::load_file>(path: P) - pub fn aya::Ebpf::map(&self, name: &str) -> core::option::Option<&aya::maps::Map> pub fn aya::Ebpf::map_mut(&mut self, name: &str) -> core::option::Option<&mut aya::maps::Map> pub fn aya::Ebpf::maps(&self) -> impl core::iter::traits::iterator::Iterator +pub fn aya::Ebpf::maps_disjoint_mut(&mut self, names: [&str; N]) -> [core::option::Option<&mut aya::maps::Map>; N] pub fn aya::Ebpf::maps_mut(&mut self) -> impl core::iter::traits::iterator::Iterator pub fn aya::Ebpf::program(&self, name: &str) -> core::option::Option<&aya::programs::Program> pub fn aya::Ebpf::program_mut(&mut self, name: &str) -> core::option::Option<&mut aya::programs::Program> @@ -10750,7 +10737,7 @@ pub fn aya::EbpfLoader<'a>::map_max_entries(&mut self, name: &'a str, size: u32) pub fn aya::EbpfLoader<'a>::map_pin_path>>(&mut self, name: &'a str, path: P) -> &mut Self pub fn aya::EbpfLoader<'a>::new() -> Self pub fn aya::EbpfLoader<'a>::override_global>>(&mut self, name: &'a str, value: T, must_exist: bool) -> &mut Self -pub fn aya::EbpfLoader<'a>::set_global>>(&mut self, name: &'a str, value: T) -> &mut Self +pub fn aya::EbpfLoader<'a>::set_global>>(&mut self, name: &'a str, value: T, must_exist: bool) -> &mut Self pub fn aya::EbpfLoader<'a>::set_max_entries(&mut self, name: &'a str, size: u32) -> &mut Self pub fn aya::EbpfLoader<'a>::verifier_log_level(&mut self, level: aya::VerifierLogLevel) -> &mut Self impl core::default::Default for aya::EbpfLoader<'_> diff --git a/xtask/src/codegen/aya.rs b/xtask/src/codegen/aya.rs index b8330e83..042ea9d5 100644 --- a/xtask/src/codegen/aya.rs +++ b/xtask/src/codegen/aya.rs @@ -67,6 +67,8 @@ fn codegen_bindings(opts: &SysrootOptions, libbpf_dir: &Path) -> Result<()> { .constified_enum("IFLA_.*") .constified_enum("TCA_.*") .constified_enum("BPF_RINGBUF_.*") + // PERF + .constified_enum("HW_BREAKPOINT_.*") // NETFILTER .constified_enum("NFPROTO_.*"); @@ -141,6 +143,7 @@ fn codegen_bindings(opts: &SysrootOptions, libbpf_dir: &Path) -> Result<()> { "PERF_FLAG_.*", "PERF_EVENT_.*", "PERF_MAX_.*", + "HW_BREAKPOINT_.*", // NETLINK "NLMSG_ALIGNTO", "IFLA_XDP_FD", diff --git a/xtask/src/run.rs b/xtask/src/run.rs index efa79b54..fe1ed92d 100644 --- a/xtask/src/run.rs +++ b/xtask/src/run.rs @@ -1,6 +1,7 @@ use std::{ + collections::BTreeMap, ffi::{OsStr, OsString}, - fmt::Write as _, + fmt::{Debug, Write as _}, fs::{self, File, OpenOptions}, io::{BufRead as _, BufReader, Write as _}, ops::Deref as _, @@ -87,8 +88,8 @@ where } } Message::CompilerMessage(CompilerMessage { message, .. }) => { - for line in message.rendered.unwrap_or_default().split('\n') { - println!("cargo:warning={line}"); + if let Some(rendered) = message.rendered { + print!("{rendered}"); } } Message::TextLine(line) => { @@ -107,6 +108,103 @@ where Ok(executables) } +enum Disposition { + Skip, + Unpack(T), +} + +enum ControlFlow { + Continue, + Break, +} + +fn with_deb(archive: &Path, dest: &Path, mut state: S, mut select: F) -> Result +where + F: for<'state> FnMut( + &'state mut S, + &Path, + tar::EntryType, + ) -> Disposition<(Option<&'state mut Vec>, ControlFlow)>, +{ + fs::create_dir_all(dest).with_context(|| format!("failed to create {}", dest.display()))?; + + let archive_reader = File::open(archive) + .with_context(|| format!("failed to open the deb package {}", archive.display()))?; + let mut archive_reader = ar::Archive::new(archive_reader); + // `ar` entries are borrowed from the reader, so the reader + // cannot implement `Iterator` (because `Iterator::Item` is not + // a GAT). + // + // https://github.com/mdsteele/rust-ar/issues/15 + let mut data_tar_xz_entries = 0; + let start = std::time::Instant::now(); + while let Some(entry) = archive_reader.next_entry() { + let entry = entry.with_context(|| format!("({}).next_entry()", archive.display()))?; + const DATA_TAR_XZ: &str = "data.tar.xz"; + if entry.header().identifier() != DATA_TAR_XZ.as_bytes() { + continue; + } + data_tar_xz_entries += 1; + let entry_reader = xz2::read::XzDecoder::new(entry); + let mut entry_reader = tar::Archive::new(entry_reader); + let entries = entry_reader + .entries() + .with_context(|| format!("({}/{DATA_TAR_XZ}).entries()", archive.display()))?; + for (i, entry) in entries.enumerate() { + let mut entry = entry + .with_context(|| format!("({}/{DATA_TAR_XZ}).entries()[{i}]", archive.display()))?; + let path = entry.path().with_context(|| { + format!( + "({}/{DATA_TAR_XZ}).entries()[{i}].path()", + archive.display() + ) + })?; + let entry_type = entry.header().entry_type(); + let (selected, control_flow) = match select(&mut state, path.as_ref(), entry_type) { + Disposition::Skip => continue, + Disposition::Unpack(unpack) => unpack, + }; + if let Some(selected) = selected { + println!( + "{}[{}] in {:?}", + archive.display(), + path.display(), + start.elapsed() + ); + selected.push(dest.join(path)); + } + let unpacked = entry.unpack_in(dest).with_context(|| { + format!( + "({}/{DATA_TAR_XZ})[{i}].unpack_in({})", + archive.display(), + dest.display(), + ) + })?; + assert!( + unpacked, + "({}/{DATA_TAR_XZ})[{i}].unpack_in({})", + archive.display(), + dest.display(), + ); + match control_flow { + ControlFlow::Continue => continue, + ControlFlow::Break => break, + } + } + } + println!("{} in {:?}", archive.display(), start.elapsed()); + assert_eq!(data_tar_xz_entries, 1); + Ok(state) +} + +fn one(slice: &[T]) -> Result<&T> { + if let [item] = slice { + Ok(item) + } else { + bail!("expected [{}], got {slice:?}", std::any::type_name::()) + } +} + /// Build and run the project. pub(crate) fn run(opts: Options) -> Result<()> { let Options { @@ -210,7 +308,7 @@ pub(crate) fn run(opts: Options) -> Result<()> { })?; if dest_path_exists != etag_path_exists { println!( - "cargo:warning=({}).exists()={} != ({})={} (mismatch)", + "({}).exists()={} != ({})={} (mismatch)", dest_path.display(), dest_path_exists, etag_path.display(), @@ -239,7 +337,7 @@ pub(crate) fn run(opts: Options) -> Result<()> { if status.code() != Some(0) { if dest_path_exists { println!( - "cargo:warning={curl:?} failed ({status:?}); using cached {}", + "{curl:?} failed ({status:?}); using cached {}", dest_path.display() ); } else { @@ -292,124 +390,152 @@ pub(crate) fn run(opts: Options) -> Result<()> { } let extraction_root = tempfile::tempdir().context("tempdir failed")?; + + #[derive(Eq, PartialEq, Ord, PartialOrd)] + struct KernelPackageKey<'a> { + base: &'a [u8], + } + + #[derive(Default)] + struct KernelPackageGroup<'a> { + kernel: Vec<&'a Path>, + debug: Vec<&'a Path>, + } + + let mut package_groups = BTreeMap::new(); + for archive in &kernel_archives { + let file_name = archive.file_name().ok_or_else(|| { + anyhow!("archive path missing filename: {}", archive.display()) + })?; + let file_name = file_name.as_encoded_bytes(); + // TODO(https://github.com/rust-lang/rust/issues/112811): use split_once when stable. + let package_name = file_name + .split(|&byte| byte == b'_') + .next() + .ok_or_else(|| anyhow!("unexpected archive filename: {}", archive.display()))?; + let (base, is_debug) = if let Some(base) = package_name.strip_suffix(b"-dbg") { + (base, true) + } else if let Some(base) = package_name.strip_suffix(b"-dbgsym") { + (base, true) + } else if let Some(base) = package_name.strip_suffix(b"-unsigned") { + (base, false) + } else { + bail!("unexpected archive filename: {}", archive.display()) + }; + let KernelPackageGroup { kernel, debug } = + package_groups.entry(KernelPackageKey { base }).or_default(); + let dst = if is_debug { debug } else { kernel }; + dst.push(archive.as_path()); + } + let mut errors = Vec::new(); - for (index, archive) in kernel_archives.iter().enumerate() { - let archive_dir = extraction_root - .path() - .join(format!("kernel-archive-{index}")); - fs::create_dir_all(&archive_dir) - .with_context(|| format!("failed to create {}", archive_dir.display()))?; - - let archive_reader = File::open(archive).with_context(|| { - format!("failed to open the deb package {}", archive.display()) + for (index, (KernelPackageKey { base }, KernelPackageGroup { kernel, debug })) in + package_groups.into_iter().enumerate() + { + let base = { + use std::os::unix::ffi::OsStrExt as _; + OsStr::from_bytes(base) + }; + + let kernel_archive = one(kernel.as_slice()) + .with_context(|| format!("kernel archive for {}", base.display()))?; + let debug_archive = one(debug.as_slice()) + .with_context(|| format!("debug archive for {}", base.display()))?; + + let (kernel_images, configs, modules_dirs) = with_deb( + kernel_archive, + &extraction_root + .path() + .join(format!("kernel-archive-{index}-image")), + (Vec::new(), Vec::new(), Vec::new()), + |(kernel_images, configs, modules_dirs), path, entry_type| { + if let Some(path) = ["./lib/modules/", "./usr/lib/modules/"] + .into_iter() + .find_map(|modules_dir| { + // TODO(https://github.com/rust-lang/rust-clippy/issues/14112): Remove this + // allowance when the lint behaves more sensibly. + #[expect(clippy::manual_ok_err)] + match path.strip_prefix(modules_dir) { + Ok(path) => Some(path), + Err(path::StripPrefixError { .. }) => None, + } + }) + { + return Disposition::Unpack(( + (path.iter().count() == 1).then_some(modules_dirs), + ControlFlow::Continue, + )); + } + if !entry_type.is_file() { + return Disposition::Skip; + } + let name = match path.strip_prefix("./boot/") { + Ok(path) => { + if let Some(path::Component::Normal(name)) = + path.components().next() + { + name + } else { + return Disposition::Skip; + } + } + Err(path::StripPrefixError { .. }) => return Disposition::Skip, + }; + let name = name.as_encoded_bytes(); + if name.starts_with(b"vmlinuz-") { + Disposition::Unpack((Some(kernel_images), ControlFlow::Continue)) + } else if name.starts_with(b"config-") { + Disposition::Unpack((Some(configs), ControlFlow::Continue)) + } else { + Disposition::Skip + } + }, + )?; + let kernel_image = one(kernel_images.as_slice()) + .with_context(|| format!("kernel image in {}", kernel_archive.display()))?; + let config = one(configs.as_slice()) + .with_context(|| format!("config in {}", kernel_archive.display()))?; + let modules_dir = one(modules_dirs.as_slice()).with_context(|| { + format!("modules directory in {}", kernel_archive.display()) })?; - let mut archive_reader = ar::Archive::new(archive_reader); - // `ar` entries are borrowed from the reader, so the reader - // cannot implement `Iterator` (because `Iterator::Item` is not - // a GAT). - // - // https://github.com/mdsteele/rust-ar/issues/15 - let mut entries = 0; - while let Some(entry) = archive_reader.next_entry() { - let entry = entry.with_context(|| { - format!( - "failed to read an entry of the deb package {}", - archive.display() - ) - })?; - if entry.header().identifier() == b"data.tar.xz" { - let entry_reader = xz2::read::XzDecoder::new(entry); - let mut entry_reader = tar::Archive::new(entry_reader); - entry_reader.unpack(&archive_dir).with_context(|| { - format!( - "failed to unpack archive {} to {}", - archive.display(), - archive_dir.display() - ) - })?; - entries += 1; - } - } - assert_eq!(entries, 1); - let mut kernel_images = Vec::new(); - let mut configs = Vec::new(); - for entry in WalkDir::new(&archive_dir) { - let entry = entry.with_context(|| { - format!("failed to read entry in {}", archive_dir.display()) - })?; - if !entry.file_type().is_file() { - continue; - } - let path = entry.into_path(); - if let Some(file_name) = path.file_name() { - match file_name.as_encoded_bytes() { - // "vmlinuz-" - [ - b'v', - b'm', - b'l', - b'i', - b'n', - b'u', - b'z', - b'-', - kernel_version @ .., - ] => { - let kernel_version = - unsafe { OsStr::from_encoded_bytes_unchecked(kernel_version) } - .to_os_string(); - kernel_images.push((path, kernel_version)) + let system_maps = with_deb( + debug_archive, + &extraction_root + .path() + .join(format!("kernel-archive-{index}-debug")), + Vec::new(), + |system_maps: &mut Vec, path, entry_type| { + if entry_type != tar::EntryType::Regular { + return Disposition::Skip; + } + let name = match path.strip_prefix("./usr/lib/debug/boot/") { + Ok(path) => { + if let Some(path::Component::Normal(name)) = + path.components().next() + { + name + } else { + return Disposition::Skip; + } } - // "config-" - [b'c', b'o', b'n', b'f', b'i', b'g', b'-', ..] => { - configs.push(path); + Err(path::StripPrefixError { .. }) => { + return Disposition::Skip; } - _ => {} + }; + if name.as_encoded_bytes().starts_with(b"System.map-") { + // We only expect one System.map in the debug archive; ordinarily + // we'd walk the whole archive to assert this fact but it turns out + // that doing so takes around 10 seconds while stopping early takes + // around 1ms. + Disposition::Unpack((Some(system_maps), ControlFlow::Break)) + } else { + Disposition::Skip } - } - } - let (kernel_image, kernel_version) = match kernel_images.as_slice() { - [kernel_image] => kernel_image, - [] => bail!("no kernel images in {}", archive.display()), - kernel_images => bail!( - "multiple kernel images in {}: {:?}", - archive.display(), - kernel_images - ), - }; - let config = match configs.as_slice() { - [config] => config, - configs => bail!("multiple configs in {}: {:?}", archive.display(), configs), - }; - - let mut modules_dirs = Vec::new(); - for entry in WalkDir::new(&archive_dir) { - let entry = entry.with_context(|| { - format!("failed to read entry in {}", archive_dir.display()) - })?; - if !entry.file_type().is_dir() { - continue; - } - let path = entry.into_path(); - let mut components = path.components().rev(); - if components.next() != Some(path::Component::Normal(kernel_version)) { - continue; - } - if components.next() != Some(path::Component::Normal(OsStr::new("modules"))) { - continue; - } - modules_dirs.push(path); - } - let modules_dir = match modules_dirs.as_slice() { - [modules_dir] => modules_dir, - [] => bail!("no modules directories in {}", archive.display()), - modules_dirs => bail!( - "multiple modules directories in {}: {:?}", - archive.display(), - modules_dirs - ), - }; + }, + )?; + let system_map = one(system_maps.as_slice()) + .with_context(|| format!("System.map in {}", debug_archive.display()))?; // Guess the guest architecture. let mut file = Command::new("file"); @@ -441,8 +567,33 @@ pub(crate) fn run(opts: Options) -> Result<()> { let guest_arch = guest_arch.trim(); let (guest_arch, machine, cpu, console) = match guest_arch { - "ARM64" => ("aarch64", Some("virt"), Some("max"), "ttyAMA0"), - "x86" => ("x86_64", None, None, "ttyS0"), + "ARM64" => ( + "aarch64", + Some("virt"), + // NB: we'd prefer to write: + // + // ``` + // Some(if cfg!(target_arch = "aarch64") { + // "host" + // } else { + // "max" + // })) + // ``` + // + // but that only works in the presence of KVM or HVF and + // Github arm64 runners do not support nested + // virtualization. Since we aren't doing our own KVM/HVF + // detection (we let QEMU pick the best accelerator), we + // use "max" instead. + Some("max"), + "ttyAMA0", + ), + "x86" => ( + "x86_64", + None, + cfg!(target_arch = "x86_64").then_some("host"), + "ttyS0", + ), guest_arch => (guest_arch, None, None, "ttyS0"), }; @@ -520,6 +671,11 @@ pub(crate) fn run(opts: Options) -> Result<()> { write_file(&Path::new("/boot").join(name), config, "644 0 0"); } + write_file(Path::new("/boot/System.map"), system_map, "644 0 0"); + if let Some(name) = system_map.file_name() { + write_file(&Path::new("/boot").join(name), system_map, "644 0 0"); + } + test_distro.iter().for_each(|(name, path)| { if name == "init" { write_file(Path::new("/init"), path, "755 0 0");