#btf #ebpf

btf-rs

BPF类型格式(BTF)库

4 个版本 (稳定)

1.1.1 2024年8月8日
1.1.0 2024年2月27日
1.0.0 2023年12月19日
0.1.0 2023年3月9日

#154 in Unix API

Download history 5/week @ 2024-04-28 3/week @ 2024-05-05 10/week @ 2024-05-12 12/week @ 2024-05-19 3/week @ 2024-05-26 55/week @ 2024-06-02 15/week @ 2024-06-09 14/week @ 2024-06-16 33/week @ 2024-06-23 31/week @ 2024-06-30 15/week @ 2024-07-14 7/week @ 2024-07-21 13/week @ 2024-07-28 121/week @ 2024-08-04 32/week @ 2024-08-11

每月下载量 173 次

LGPL-2.1 或更高版本

48KB
1K SLoC

Btf-rs

Rust语言编写的BPF类型格式(BTF)库。BPF类型格式是一种元数据格式,用于编码调试信息,如类型、函数原型、结构布局等,通常用于处理eBPF(扩展伯克利包过滤)程序,但不仅限于此。

此库最初是为内核数据包跟踪工具retis开发的,但作为独立库发布,因为它与该工具没有特定的关联,可以在各种Rust项目中(重新)使用。

[dependencies]
btf-rs = "1.1"

集成测试提供了如何使用此库的好例子。我们建议阅读官方BTF文档,因为此库提供了低级API。

概览

BTF解析

此库提供的主要对象是 struct Btf,它表示解析后的BTF对象。它提供了解析ID(u32)、名称(String)和类型/链式类型(enum Type)的帮助程序。

struct Btf可以使用BTF文件或拆分BTF文件构建。BTF文件包含自包含的信息,而拆分BTF文件基于基本BTF文件并扩展它。例如,在标准Linux环境中,BTF文件和拆分文件可以在 /sys/kernel/btf 下找到,其中 /sys/kernel/btf/vmlinux 是内核的BTF文件,其他匹配 /sys/kernel/btf/<module-name> 的文件是该模块的BTF拆分文件。

let base = Btf::from_file("/sys/kernel/btf/vmlinux").unwrap();

let ovs = Btf::from_split_file("/sys/kernel/btf/openvswitch", &base).unwrap();
let bbr = Btf::from_split_file("/sys/kernel/btf/tcp_bbr", &base).unwrap();

Btf-rs 也支持使用字节切片构建 struct Btf

let base = Btf::from_bytes(&fs::read("/sys/kernel/btf/vmlinux").unwrap()).unwrap();

let ovs = Btf::from_split_bytes(&fs::read("/sys/kernel/btf/openvswitch").unwrap(), &base).unwrap();
let bbr = Btf::from_split_bytes(&fs::read("/sys/kernel/btf/bbr").unwrap(), &base).unwrap();

解析类型

可以使用 struct Btf 对象来解析类型。以下是一个如何检查函数以检索其第一个参数信息的示例。这里,函数 kfree_skb_reasonstruct sk_buff * 作为其第一个参数。

let btf = Btf::from_file("/sys/kernel/btf/vmlinux").unwrap();

let func = match btf.resolve_types_by_name("kfree_skb_reason").unwrap().pop().unwrap() {
	Type::Func(func) => func,
	_ => panic!("Resolved type is not a function"),
};

let proto = match btf.resolve_chained_type(&func).unwrap() {
	Type::FuncProto(proto) => proto,
	_ => panic!("Resolved type is not a function proto"),
};

assert!(proto.parameters.len() > 1);

// The following prints "skb".
println!("{}", btf.resolve_name(&proto.parameters[0]).unwrap());

let ptr = match btf.resolve_chained_type(&proto.parameters[0]).unwrap() {
	Type::Ptr(ptr) => ptr,
	_ => panic!("Resolved type is not a pointer"),
};

let r#struct = match btf.resolve_chained_type(&ptr).unwrap() {
	Type::Struct(r#struct) => r#struct,
	_ => panic!("Resolved type is not a struct"),
};

// The following prints "sk_buff".
println!("{}", btf.resolve_name(&r#struct).unwrap());

还可以检索其他信息,如函数作用域和返回值、结构大小和成员等。有关所有这些信息,请参阅 enum Type 及其相关结构文档。

依赖关系

~245KB