btf_rs/lib.rs
1//! Library for the [BPF Type Format (BTF)](https://www.kernel.org/doc/html/latest/bpf/btf.html).
2//! The BPF Type Format is a metadata format encoding debugging information such
3//! as types, function prototypes, structure layouts, etc. and is often used,
4//! but not limited, to deal with [eBPF](https://ebpf.io) programs.
5//!
6//! The [integration tests](https://github.com/retis-org/btf-rs/blob/main/tests/integration_test.rs)
7//! give good examples on how to use this library. We recommend reading the
8//! [official BTF documentation](https://www.kernel.org/doc/html/latest/bpf/btf.html)
9//! as this library is offering a low-level API.
10//!
11//! ### Parsing BTF
12//!
13//! The main object this library offers is [`Btf`], which represents a parsed
14//! BTF object. It offers helpers to resolve ids ([`u32`]), names ([`String`])
15//! and types / chained types ([`Type`]).
16//!
17//! [`Btf`] can be constructed using a BTF file or a split BTF one. BTF files
18//! hold self-contained information, while split BTF files are built upon a base
19//! BTF file and extend it. For example, in a standard Linux environment BTF
20//! files and split files can be found under `/sys/kernel/btf`,
21//! `/sys/kernel/btf/vmlinux` being the BTF file for the kernel and other files
22//! matching `/sys/kernel/btf/<module-name>` being BTF split files for its
23//! modules.
24//!
25//! ```no_run
26//! use btf_rs::Btf;
27//!
28//! let base = Btf::from_file("/sys/kernel/btf/vmlinux").unwrap();
29//!
30//! let ovs = Btf::from_split_file("/sys/kernel/btf/openvswitch", &base).unwrap();
31//! let bbr = Btf::from_split_file("/sys/kernel/btf/tcp_bbr", &base).unwrap();
32//! ```
33//!
34//! *Btf-rs* also supports constructing [`Btf`] using byte slices.
35//!
36//! ```no_run
37//! use std::fs;
38//! use btf_rs::Btf;
39//!
40//! let base = Btf::from_bytes(&fs::read("/sys/kernel/btf/vmlinux").unwrap()).unwrap();
41//!
42//! let ovs = Btf::from_split_bytes(&fs::read("/sys/kernel/btf/openvswitch").unwrap(), &base)
43//! .unwrap();
44//! let bbr = Btf::from_split_bytes(&fs::read("/sys/kernel/btf/bbr").unwrap(), &base).unwrap();
45//! ```
46//!
47//! ### Resolving types
48//!
49//! Types can be resolved using a [`Btf`] object. The following is an
50//! example of how a function can be inspected to retrieve information about its
51//! first parameter. Here the function `kfree_skb_reason` is taking a `struct
52//! sk_buff *` as its first argument.
53//!
54//! ```no_run
55//! use btf_rs::*;
56//!
57//! let btf = Btf::from_file("/sys/kernel/btf/vmlinux").unwrap();
58//!
59//! let func = match btf.resolve_types_by_name("kfree_skb_reason").unwrap().pop().unwrap() {
60//! Type::Func(func) => func,
61//! _ => panic!("Resolved type is not a function"),
62//! };
63//!
64//! let proto = match btf.resolve_chained_type(&func).unwrap() {
65//! Type::FuncProto(proto) => proto,
66//! _ => panic!("Resolved type is not a function proto"),
67//! };
68//!
69//! assert!(proto.parameters.len() > 1);
70//!
71//! // The following prints "skb".
72//! println!("{}", btf.resolve_name(&proto.parameters[0]).unwrap());
73//!
74//! let ptr = match btf.resolve_chained_type(&proto.parameters[0]).unwrap() {
75//! Type::Ptr(ptr) => ptr,
76//! _ => panic!("Resolved type is not a pointer"),
77//! };
78//!
79//! let r#struct = match btf.resolve_chained_type(&ptr).unwrap() {
80//! Type::Struct(r#struct) => r#struct,
81//! _ => panic!("Resolved type is not a struct"),
82//! };
83//!
84//! // The following prints "sk_buff".
85//! println!("{}", btf.resolve_name(&r#struct).unwrap());
86//! ```
87//!
88//! Other information such as function scope and return value, structure size
89//! and members, etc. can be retrieved. For all those see the [`Type`] and its
90//! associated structures documentation.
91//!
92//! Feature flags:
93//! - test_runtime: Use the system's runtime BTF files to perform extra
94//! integration tests.
95
96pub mod btf;
97
98mod cbtf;
99mod obj;
100
101#[doc(inline)]
102pub use crate::btf::*;