aboutsummaryrefslogtreecommitdiff
path: root/lib/std/os/linux/bpf/btf.zig
blob: 3988fce349c90028606678e14a7eab9e273f2f34 (plain)
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
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
const std = @import("../../../std.zig");

pub const magic = 0xeb9f;
pub const version = 1;

pub const ext = @import("btf_ext.zig");

/// All offsets are in bytes relative to the end of this header
pub const Header = extern struct {
    magic: u16,
    version: u8,
    flags: u8,
    hdr_len: u32,

    /// offset of type section
    type_off: u32,

    /// length of type section
    type_len: u32,

    /// offset of string section
    str_off: u32,

    /// length of string section
    str_len: u32,
};

/// Max number of type identifiers
pub const max_type = 0xfffff;

/// Max offset into string section
pub const max_name_offset = 0xffffff;

/// Max number of struct/union/enum member of func args
pub const max_vlen = 0xffff;

pub const Type = extern struct {
    name_off: u32,
    info: packed struct(u32) {
        /// number of struct's members
        vlen: u16,

        unused_1: u8,
        kind: Kind,
        unused_2: u2,

        /// used by Struct, Union, and Fwd
        kind_flag: bool,
    },

    /// size is used by Int, Enum, Struct, Union, and DataSec, it tells the size
    /// of the type it is describing
    ///
    /// type is used by Ptr, Typedef, Volatile, Const, Restrict, Func,
    /// FuncProto, and Var. It is a type_id referring to another type
    size_type: extern union { size: u32, typ: u32 },
};

/// For some kinds, Type is immediately followed by extra data
pub const Kind = enum(u5) {
    unknown,
    int,
    ptr,
    array,
    @"struct",
    @"union",
    @"enum",
    fwd,
    typedef,
    @"volatile",
    @"const",
    restrict,
    func,
    func_proto,
    @"var",
    datasec,
    float,
    decl_tag,
    type_tag,
    enum64,
};

/// int kind is followed by this struct
pub const IntInfo = packed struct(u32) {
    bits: u8,
    reserved_1: u8,
    offset: u8,
    encoding: enum(u4) {
        signed = 1 << 0,
        char = 1 << 1,
        boolean = 1 << 2,
    },
    reserved_2: u4,
};

test "IntInfo is 32 bits" {
    try std.testing.expectEqual(@bitSizeOf(IntInfo), 32);
}

/// enum kind is followed by this struct
pub const Enum = extern struct {
    name_off: u32,
    val: i32,
};

/// enum64 kind is followed by this struct
pub const Enum64 = extern struct {
    name_off: u32,
    val_lo32: i32,
    val_hi32: i32,
};

/// array kind is followed by this struct
pub const Array = extern struct {
    typ: u32,
    index_type: u32,
    nelems: u32,
};

/// struct and union kinds are followed by multiple Member structs. The exact
/// number is stored in vlen
pub const Member = extern struct {
    name_off: u32,
    typ: u32,

    /// if the kind_flag is set, offset contains both member bitfield size and
    /// bit offset, the bitfield size is set for bitfield members. If the type
    /// info kind_flag is not set, the offset contains only bit offset
    offset: packed struct(u32) {
        bit: u24,
        bitfield_size: u8,
    },
};

/// func_proto is followed by multiple Params, the exact number is stored in vlen
pub const Param = extern struct {
    name_off: u32,
    typ: u32,
};

pub const VarLinkage = enum {
    static,
    global_allocated,
    global_extern,
};

pub const FuncLinkage = enum {
    static,
    global,
    external,
};

/// var kind is followed by a single Var struct to describe additional
/// information related to the variable such as its linkage
pub const Var = extern struct {
    linkage: u32,
};

/// datasec kind is followed by multiple VarSecInfo to describe all Var kind
/// types it contains along with it's in-section offset as well as size.
pub const VarSecInfo = extern struct {
    typ: u32,
    offset: u32,
    size: u32,
};

// decl_tag kind is followed by a single DeclTag struct to describe
// additional information related to the tag applied location.
// If component_idx == -1, the tag is applied to a struct, union,
// variable or function. Otherwise, it is applied to a struct/union
// member or a func argument, and component_idx indicates which member
// or argument (0 ... vlen-1).
pub const DeclTag = extern struct {
    component_idx: u32,
};