This project measures the conformance of a BPF runtime to the ISA. To measure conformance the BPF runtime under test is built into a plugin process that does:
- Accept both BPF byte code an initial memory.
- Execute the byte code.
- Return the value in %r0 at the end of the execution.
- Linux Kernel via libbpf
- uBPF
- eBPF for Windows / bpf2c
- rbpf
- Prevail Verifier
- bpftime / llvmbpf, The result is here
Note: Linux Kernel is treated as the authorative eBPF implementation.
sudo apt-get install -y libboost-dev libboost-filesystem-dev libboost-program-options-dev libelf-dev lcov libbpf-dev
brew install cmake ninja ccache boost
Run cmake -S . -B build
to configure the project, then run cmake --build build
to build the project.
Options:
--help Print help messages
--test_file_path arg Path to test file
--test_file_directory arg Path to test file directory
--plugin_path arg Path to plugin
--plugin_options arg Options to pass to plugin
--list_instructions arg List instructions used and not used in tests
--list_used_instructions arg List instructions used in tests
--list_unused_instructions arg List instructions not used in tests
--debug (true|false) Print debug information
--xdp_prolog (true|false) XDP prolog
--elf (true|false) ELF format
--cpu_version arg CPU version
--include_regex arg Include regex
--exclude_regex arg Exclude regex
--xdp_prolog true
should only be used with the libbpf_plugin
.
Select the desired version from bpf_conformance
Assume the package is named: "ghcr.io/alan-jowett/bpf_conformance:main"
docker run --privileged -it --rm ghcr.io/alan-jowett/bpf_conformance:main src/bpf_conformance_runner --test_file_directory tests --plugin_path libbpf_plugin/libbpf_plugin --cpu_version v3
Linux (test require Linux kernel BPF support):
cmake --build build --target test --
Note: The libbpf_plugin requires root or BPF permissions.
The BPF Conformance tests can also be used as a static library as part of another tests.
- Include include/bpf_conformance.h
- Link against libbpf_conformance.a and boost_filesystem (depending on platform).
- Invoke bpf_conformance, passing it a list of test files.
On completion of the test the bpf_conformance tools prints the list of tests that passes/failed and a summary count.
sudo build/src/bpf_conformance --test_file_directory tests --plugin_path build/libbpf_plugin/libbpf_plugin
Test results:
PASS: "tests/add.data"
PASS: "tests/add64.data"
PASS: "tests/alu-arith.data"
PASS: "tests/alu-bit.data"
PASS: "tests/alu64-arith.data"
PASS: "tests/alu64-bit.data"
PASS: "tests/arsh-reg.data"
PASS: "tests/arsh.data"
PASS: "tests/arsh32-high-shift.data"
PASS: "tests/arsh64.data"
PASS: "tests/be16-high.data"
PASS: "tests/be16.data"
PASS: "tests/be32-high.data"
PASS: "tests/be32.data"
PASS: "tests/be64.data"
PASS: "tests/call_unwind_fail.data"
PASS: "tests/div-by-zero-reg.data"
PASS: "tests/div32-high-divisor.data"
PASS: "tests/div32-imm.data"
PASS: "tests/div32-reg.data"
PASS: "tests/div64-by-zero-reg.data"
PASS: "tests/div64-imm.data"
PASS: "tests/div64-reg.data"
PASS: "tests/exit-not-last.data"
PASS: "tests/exit.data"
PASS: "tests/jeq-imm.data"
PASS: "tests/jeq-reg.data"
PASS: "tests/jge-imm.data"
PASS: "tests/jgt-imm.data"
PASS: "tests/jgt-reg.data"
PASS: "tests/jit-bounce.data"
PASS: "tests/jle-imm.data"
PASS: "tests/jle-reg.data"
PASS: "tests/jlt-imm.data"
PASS: "tests/jlt-reg.data"
PASS: "tests/jne-reg.data"
PASS: "tests/jset-imm.data"
PASS: "tests/jset-reg.data"
PASS: "tests/jsge-imm.data"
PASS: "tests/jsge-reg.data"
PASS: "tests/jsgt-imm.data"
PASS: "tests/jsgt-reg.data"
PASS: "tests/jsle-imm.data"
PASS: "tests/jsle-reg.data"
PASS: "tests/jslt-imm.data"
PASS: "tests/jslt-reg.data"
PASS: "tests/lddw.data"
PASS: "tests/lddw2.data"
PASS: "tests/ldxb-all.data"
PASS: "tests/ldxb.data"
PASS: "tests/ldxdw.data"
PASS: "tests/ldxh-all.data"
PASS: "tests/ldxh-all2.data"
PASS: "tests/ldxh-same-reg.data"
PASS: "tests/ldxh.data"
PASS: "tests/ldxw-all.data"
PASS: "tests/ldxw.data"
PASS: "tests/le16.data"
PASS: "tests/le32.data"
PASS: "tests/le64.data"
PASS: "tests/lsh-reg.data"
PASS: "tests/mem-len.data"
PASS: "tests/mod-by-zero-reg.data"
PASS: "tests/mod.data"
PASS: "tests/mod32.data"
PASS: "tests/mod64-by-zero-reg.data"
PASS: "tests/mod64.data"
PASS: "tests/mov.data"
PASS: "tests/mul32-imm.data"
PASS: "tests/mul32-reg-overflow.data"
PASS: "tests/mul32-reg.data"
PASS: "tests/mul64-imm.data"
PASS: "tests/mul64-reg.data"
PASS: "tests/neg.data"
PASS: "tests/neg64.data"
PASS: "tests/prime.data"
PASS: "tests/rsh-reg.data"
PASS: "tests/rsh32.data"
PASS: "tests/stack.data"
PASS: "tests/stb.data"
PASS: "tests/stdw.data"
PASS: "tests/sth.data"
PASS: "tests/stw.data"
PASS: "tests/stxb-all.data"
PASS: "tests/stxb-all2.data"
PASS: "tests/stxb-chain.data"
PASS: "tests/stxb.data"
PASS: "tests/stxdw.data"
PASS: "tests/stxh.data"
PASS: "tests/stxw.data"
PASS: "tests/subnet.data"
Passed 91 out of 91 tests.
bpf_conformance_runner invokes plugins using command-line execution, and uses stdin, stdout, and stderr to exchange additional information as follows:
<plugin name> [<base16 memory bytes>] [<plugin options>] [--elf]
where:
<plugin name>
: the plugin executable name<base16 memory bytes>
: if present, the contents of themem
section of a test data file<plugin options>
: any additional options to pass to the plugin--elf
: if present, indicates that the data passed to stdin will be in ELF format
The program is then passed to the plugin via stdin, either as raw bytecode or (if --elf
is specified) in ELF format.
The plugin must then either:
- compute a successful result and output the final contents of
r0
in hex (either with or without a leading "0x") to stdout and exit with a status of 0, OR - output an error message to stderr and exit with a non-zero status.
Additional plugins can be created based on the above specification.