| Crates.io | ksym |
| lib.rs | ksym |
| version | 0.3.0 |
| created_at | 2025-10-10 10:55:21.063283+00 |
| updated_at | 2025-10-27 08:27:19.278627+00 |
| description | A Rust crate for generating kernel symbol tables (ksyms) from kernel binaries. |
| homepage | https://github.com/Godones/ext_ebpf |
| repository | https://github.com/Godones/ext_ebpf |
| max_upload_size | |
| id | 1876788 |
| size | 46,223 |
本目录提供从标准输入读取的 kallsyms 风格符号列表(例如 /proc/kallsyms)生成压缩二进制 blob 的工具,以及对应的零拷贝读取格式约定。
本文档描述:
KallsymsBlob 是构建期的数据容器,用于收集符号并压缩、序列化。关键字段:
kallsyms_names 中的起始偏移(按字节),与地址序下的符号一一对应。关系示意:
kallsyms_addresses[i]kallsyms_offsets[i],每条名称均以类型和前缀长度字段开头,长度为 TY_LEN=1、LENGTH_BYTES=2(小端,低字节在前),即PREFIX_LEN = TY_LEN + LENGTH_BYTES,
实际片段范围 = kallsyms_names[kallsyms_offsets[i] + PREFIX_LEN .. kallsyms_offsets[i] + PREFIX_LEN + entry_len],其中 entry_len 来自该条目前置的 2 字节小端长度。kallsyms_seqs_of_names 上二分比较(通过展开名称),命中 mid 后得到地址序索引 seq = kallsyms_seqs_of_names[mid]。0xFF <id> 0xFF(1 字节 id)或 0xFF <id_hi> <id_lo> 0xFF(2 字节 id)开头,随后跟随名称剩余原始字节;TOKEN_MARKER = 0xFF。备注:读取输入时仅保留文本符号类型 T/t,并进行 Rust demangle。编码阶段会把符号类型字符(T/t)作为前缀放在压缩名称的最前面。
kallsyms_addresses 与 kallsyms_offsets 按地址升序排列;kallsyms_seqs_of_names 用于名字二分。kallsyms_addresses 上二分得到 i;为处理“同址符号别名(alias)”,会向前回溯到该地址的第一个符号,然后向后搜索下一个“地址不同”的符号以确定大小;若找不到则以文本段结束地址作为上界。名称解码基于 kallsyms_offsets[i] 与记录内的长度前缀来截取片段再展开。kallsyms_seqs_of_names[mid] 取回地址序索引,再用长度前缀解码对应名称进行比较;命中后返回对应地址。所有数值均为小端序列化。为满足零拷贝读取时的对齐要求(u64 按 8 字节对齐,u32 按 4 字节对齐),在写入各段之前会插入适当的 padding。内核加载该 bin 时会将其映射到 4K 对齐的页起始地址;在此前提下,下面的对齐能保证 from_raw_parts 的对齐安全。
布局顺序(括号中为对齐要求):
[type: u8] [len: u16(le)] [payload: u8[len]]说明:
Vec<u8> 进行 padding 实现。kallsyms_offsets 使用 u32 存储,要求 kallsyms_names.len() < 4GiB。from_blob(&blob, stext, etext) 直接把上述各段解释为切片,同时记住文本段边界用于地址查找:
&[u64] 对应 addresses,&[u32] 对应 offsets、seqs、token_index,&[u8] 对应 names、token_table。from_raw_parts 的对齐要求满足,避免拷贝。kallsyms_offsets 为 u32,限制 kallsyms_names 总长度 < 4GiB。nm -n -C {ELF} | grep ' [Tt] ' | grep -v '\.L' | grep -v '$x' | cargo run -p ksym-bin --bin gen_ksym --features demangle > kallsyms.bin使用 ksym_bin::KallsymsMapped::from_blob(&blob, stext, etext) 零拷贝解析;
可调用 lookup_address、lookup_name、或 dump_all_symbols() 获取数据(dump 输出形如:<addr_hex> <type_char> <name>)。
cargo test --bin gen_ksym --features="demangle"
示例(简化三条符号):
kallsyms_names 中三段压缩名称的起始位置;以上即当前实现对应的元数据关系与二进制布局说明。