1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
//! BTF offsets for `BPF_MAP_TYPE_STRUCT_OPS` value rendering.
//!
//! `bpf_struct_ops_map` (`kernel/bpf/bpf_struct_ops.c::bpf_struct_ops_map`)
//! embeds a `struct bpf_struct_ops_value kvalue` directly — the registered
//! kernel struct's bytes (e.g. `sched_ext_ops` for ktstr's scx-ktstr
//! fixture) live inline at `kvalue.data`, prefixed by an
//! 8-byte `bpf_struct_ops_common_value` (refcnt + state) header.
//!
//! `map->btf_value_type_id` (set by libbpf to the user program's
//! interpretation of the registered struct — `tools/lib/bpf/libbpf.c`
//! around `map->btf_value_type_id = type_id` in `bpf_object__init_struct_ops`)
//! describes the `data` payload only; it does NOT cover the common
//! header. To render through the existing BTF path with that type_id,
//! the dump renderer reads from `kvalue + value_data` (the data start)
//! for `value_size - value_data` bytes.
//!
//! Verified against `kernel/bpf/bpf_struct_ops.c::bpf_struct_ops_map_alloc`:
//! `if (attr->value_size != vt->size) return -EINVAL` (line ~1090) —
//! `value_size` is the wrapper size (common + data). `st_map_size =
//! sizeof(*st_map) + (vt->size - sizeof(struct bpf_struct_ops_value))`
//! extends the trailing flex array so `kvalue.data` has exactly the
//! registered struct's worth of room.
use ;
use Btf;
use ;
/// Byte offsets needed to read `BPF_MAP_TYPE_STRUCT_OPS` value bytes
/// from guest memory.
///
/// Resolution is optional — `resolve_struct_ops_offsets()` returns
/// `Err` when `bpf_struct_ops_map` or `bpf_struct_ops_value` is
/// missing from BTF (kernels built without struct_ops support).
/// Resolve `StructOpsOffsets` from a parsed BTF object.
pub