ePass is an SSA-based compiler framework for eBPF programs. It lifts eBPF bytecode into an LLVM-like IR, runs configurable IR passes, and lowers IR back to eBPF bytecode for kernel verifier/JIT consumption.
The actively developed core is the Rust userspace library under core-rs/. The
old C implementation under deprecated/core/ remains as historical reference.
eBPF bytecode
-> lift
-> ePass SSA IR
-> pass manager
-> register allocation + codegen
-> eBPF bytecode
-> kernel verifier
Key components:
core-rs/epass-ir: pure userspace Rust library. No kernel headers and no libbpf dependency.core-rs/epasstool: CLI for dump-format and ELF-object workflows. ELF support uses libbpf only in the CLI.third-party/ePass-libbpf: patched libbpf that can call the Rust C ABI (epass_run) before loading programs.third-party/ePass-bpftool: bpftool built against the patched libbpf for verifier testing.
- SSA IR with arena allocation and typed handles (
InsnId,BbId). - eBPF bytecode lifter with CFG discovery and SSA construction.
- Pass manager with default-enabled and optional passes, pass-specific options, pass-owned ordering, and post-pass validation.
- Built-in passes:
const_prop,phi,optimize_ir, optionaldump_ir. - Register allocation and codegen back to eBPF bytecode.
- Parseable
.epirIR text dump/load format for debugging. IrBuilderand CFG editing utilities for pass authors.- C ABI for patched libbpf integration.
Rust core and CLI:
cd core-rs
cargo build --release
cargo test --releasePatched libbpf and bpftool for verifier testing:
cd third-party/ePass-libbpf/src
make -j
cd ../../ePass-bpftool/src
make -jcd core-rs
# Rewrite an ELF object's selected BPF program and emit dump-format output.
./target/release/epasstool read -s prog -F log -o out.txt ../test/output/progs_simple1.o
# Process dump-format input: one packed u64 per line.
./target/release/epasstool read -F log -o out.txt prog.txt
# Print without rewriting.
./target/release/epasstool print --gopt print_dump ../test/output/progs_simple1.o
# Dump lifted IR before normal passes.
./target/release/epasstool read -P --popt 'dump_ir(/tmp/prog.epir)' -s prog ../test/output/progs_simple1.o
# Load IR directly instead of lifting bytecode, then run passes and codegen.
./target/release/epasstool read --gopt load_ir=/tmp/prog.epir -F log -o out.txt dummy.txtThe patched libbpf runs ePass when enabled by environment variable:
sudo LIBBPF_ENABLE_EPASS=1 \
LIBBPF_EPASS_GOPT='verbose=1' \
third-party/ePass-bpftool/src/bpftool prog load test.o /sys/fs/bpf/testThe rewritten bytecode is submitted to the kernel verifier. Use bpftool prog show pinned ... to compare xlated byte sizes and confirm the modified program
was loaded.
- Rust core architecture
- Pass manager and pass options
- Writing passes
- IR text format
- IR builder and instruction construction
- Userspace / libbpf testing
- Testing
- Core lifter, IR, pass framework, codegen, IR text load/dump, and verifier
testing path are active in
core-rs. - Several old C demo/instrumentation passes (MSan, insn counter, masking, helper validation, etc.) are not yet fully ported.
- bpf-to-bpf calls and atomic memory ops remain unsupported/limited.
Feel free to open an issue or email xiangyiming2002@gmail.com.