bpf-linker aims to simplify building modern BPF programs while still supporting older, more restrictive kernels.
bpf-linker can be used to statically link multiple BPF object files together and optionally perform optimizations needed to target older kernels. It operates on LLVM bitcode, so the inputs must be bitcode files (.bc) or object files with embedded bitcode (.o), optionally stored inside ar archives (.a).
The linker requires LLVM 12. It can use the same LLVM used by the rust compiler, or it can use an external LLVM installation.
All you need to do is run:
sh
cargo install bpf-linker
On Debian based distributions you need to install the llvm-12-dev
and
libclang-12-dev
packages. If your distro doesn't have them you can get them
from the official LLVM repo at https://apt.llvm.org.
On rpm based distribution you need the llvm-devel
and clang-devel
packages.
If your distro doesn't have them you can get them from Fedora Rawhide.
Once you have installed LLVM 12 you can install the linker running:
sh
cargo install --git https://github.com/aya-rs/bpf-linker --tag v0.9.2 --no-default-features --features system-llvm -- bpf-linker
If you don't have cargo you can get it from https://rustup.rs or from your distro's package manager.
To compile your eBPF crate just run:
sh
cargo +nightly build --target=bpfel-unknown-none -Z build-std=core --release
If you don't want to have to pass the target
and build-std
options every
time, you can put them in .cargo/config.toml
under the crate's root folder:
```toml [build] target = "bpfel-unknown-none"
[unstable] build-std = ["core"] ```
If for whatever reason you can't use rust nightly to build your project, you can still compile your eBPF crate with:
```sh $ cargo rustc --release -- \ -C linker-plugin-lto \ -C linker-flavor=wasm-ld -C linker=bpf-linker \ -C link-arg=--target=bpf Compiling bpf-log-clone v0.1.0 (/home/alessandro/bpf-log-clone) Finished release [optimized] target(s) in 0.86s
$ file target/release/libbpflogclone.so target/release/libbpflogclone.so: ELF 64-bit LSB relocatable, eBPF, version 1 (SYSV), not stripped ```
For a simple example of how to use the linker with clang see this gist. In the example lib.c is compiled as a static library which is then linked by program.c. The Makefile shows how to compile the C code and then link it.
``` bpf-linker
USAGE: bpf-linker [FLAGS] [OPTIONS] --output
FLAGS:
--disable-expand-memcpy-in-order Disable passing --bpf-expand-memcpy-in-order to LLVM
--disable-memory-builtins Disble exporting memcpy, memmove, memset, memcmp and bcmp. Exporting those
is commonly needed when LLVM does not manage to expand memory intrinsics to
a sequence of loads and stores
-h, --help Prints help information
--ignore-inline-never Ignore noinline
/#[inline(never)]
. Useful when targeting kernels that
don't support function calls
--unroll-loops Try hard to unroll loops. Useful when targeting kernels that don't support
loops
-V, --version Prints version information
OPTIONS:
--cpu generic
, probe
, v1
, v2
, v3
[default:
generic]
--cpu-features path
before generating the code
--emit llvm-bc
, asm
, llvm-ir
, obj
[default: obj]
--export --export-symbols
--export-symbols path
. The symbols must be separated by
new lines
-L path
--log-level off
, info
, warn
, debug
, trace
-O
ARGS:
bpf-linker is licensed under either of
at your option.