Whistler: Live eBPF Programming from the Common Lisp REPL
3 days ago
- #Common Lisp
- #System Programming
- #eBPF
- Whistler is a Common Lisp-based DSL for eBPF that allows writing shorter, less ceremonial code compared to eBPF C.
- It generates highly-optimized eBPF output directly, bypassing the clang+llvm toolchain.
- Whistler enables inlining eBPF code in Common Lisp programs, compiling/loading/unloading them via the REPL without creating object files on disk.
- Example provided: a kprobe counting execve calls, showcasing Whistler's ability to compile to eBPF bytecode during macroexpansion.
- A real-world example demonstrates tracing ffi_call invocations in libffi, counting calls by program name and function signature.
- Whistler's compiler runs during macroexpansion, embedding eBPF bytecode as a literal in the expansion, facilitating compile-time errors with context.
- It supports defining structures (defstruct) that generate accessors for both BPF and Common Lisp, ensuring consistency between kernel and userspace.
- Whistler can import definitions directly from the running kernel, eliminating the need for kernel headers.
- Includes a pure Common Lisp BPF userspace loader with zero C dependencies, supporting ELF parsing, map operations, and program loading.
- Supports polyglot userspace development, allowing generation of matching struct definitions for Go, C, Rust, or Python from the same defstruct declarations.
- Operates without root privileges by granting specific capabilities to SBCL, enhancing security and usability.
- Whistler simplifies the eBPF workflow by integrating the compiler, loader, and application in a single process, enabling rapid development via the REPL.