BPF Linker 🔗

bpf-linker aims to simplify building modern BPF programs while still supporting older, more restrictive kernels.

Build

Overview

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).

Installation

The linker requires LLVM 11.

On Debian based distributions you need to install the llvm-11-dev and libclang-11-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 11 you can install the linker running: cargo install --git https://github.com/alessandrod/bpf-linker --rev origin/main

If you don't have cargo you can get it from https://rustup.rs or from your distro's package manager.

Examples

Rust

The ultimate goal is to have rustc --target=bpf[el|eb]-unknown-none invoke bpf-linker directly.

In the meantime you can already compile a crate for BPF by explicitly making rustc use bpf-linker:

``` $ 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 ```

With -C linker-plugin-lto we instruct rustc to pass bitcode to the linker, with -C linker-flavor=wasm-ld -C linker=bpf-linker we make the compiler use bpf-linker, which conveniently implements a command line compatible with wasm-ld so rustc knows how to invoke it.

Clang

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.

Usage

``` bpf-linker

USAGE: bpf-linker [FLAGS] [OPTIONS] --output [--] [inputs]...

FLAGS: -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 Target BPF processor. Can be one of generic, probe, v1, v2, v3 [default: generic] --cpu-features Enable or disable CPU features. The available features are: alu32, dummy, dwarfris. Use +feature to enable a feature, or -feature to disable it. For example --cpu- features=+alu32,-dwarfris [default: ] --dump-module Dump the final IR module to the given path before generating the code --emit Output type. Can be one of llvm-bc, asm, llvm-ir, obj [default: obj] --export ... Comma separated list of symbols to export. See also --export-symbols --export-symbols Export the symbols specified in the file path. The symbols must be separated by new lines -L ... Add a directory to the library search path --llvm-args ... Extra command line arguments to pass to LLVM --log-file Output logs to the given path --log-level Set the log level. Can be one of off, info, warn, debug, trace -O ... Optimization level. 0-3, s, or z [default: 2] -o, --output Write output to --target LLVM target triple. When not provided, the target is inferred from the inputs

ARGS: ... Input files. Can be object files or static libraries ```

License

bpf-linker is licensed under either of

at your option.