29
29
#ifndef max
30
30
# define max (x , y ) ((x) < (y) ? (y) : (x))
31
31
#endif
32
+ #ifndef offsetofend
33
+ # define offsetofend (TYPE , FIELD ) \
34
+ (offsetof(TYPE, FIELD) + sizeof(((TYPE *)0)->FIELD))
35
+ #endif
32
36
33
37
extern void libbpf_print (enum libbpf_print_level level ,
34
38
const char * format , ...)
@@ -46,4 +50,105 @@ do { \
46
50
int libbpf__load_raw_btf (const char * raw_types , size_t types_len ,
47
51
const char * str_sec , size_t str_len );
48
52
53
+ struct btf_ext_info {
54
+ /*
55
+ * info points to the individual info section (e.g. func_info and
56
+ * line_info) from the .BTF.ext. It does not include the __u32 rec_size.
57
+ */
58
+ void * info ;
59
+ __u32 rec_size ;
60
+ __u32 len ;
61
+ };
62
+
63
+ #define for_each_btf_ext_sec (seg , sec ) \
64
+ for (sec = (seg)->info; \
65
+ (void *)sec < (seg)->info + (seg)->len; \
66
+ sec = (void *)sec + sizeof(struct btf_ext_info_sec) + \
67
+ (seg)->rec_size * sec->num_info)
68
+
69
+ #define for_each_btf_ext_rec (seg , sec , i , rec ) \
70
+ for (i = 0, rec = (void *)&(sec)->data; \
71
+ i < (sec)->num_info; \
72
+ i++, rec = (void *)rec + (seg)->rec_size)
73
+
74
+ struct btf_ext {
75
+ union {
76
+ struct btf_ext_header * hdr ;
77
+ void * data ;
78
+ };
79
+ struct btf_ext_info func_info ;
80
+ struct btf_ext_info line_info ;
81
+ struct btf_ext_info offset_reloc_info ;
82
+ __u32 data_size ;
83
+ };
84
+
85
+ struct btf_ext_info_sec {
86
+ __u32 sec_name_off ;
87
+ __u32 num_info ;
88
+ /* Followed by num_info * record_size number of bytes */
89
+ __u8 data [0 ];
90
+ };
91
+
92
+ /* The minimum bpf_func_info checked by the loader */
93
+ struct bpf_func_info_min {
94
+ __u32 insn_off ;
95
+ __u32 type_id ;
96
+ };
97
+
98
+ /* The minimum bpf_line_info checked by the loader */
99
+ struct bpf_line_info_min {
100
+ __u32 insn_off ;
101
+ __u32 file_name_off ;
102
+ __u32 line_off ;
103
+ __u32 line_col ;
104
+ };
105
+
106
+ /* The minimum bpf_offset_reloc checked by the loader
107
+ *
108
+ * Offset relocation captures the following data:
109
+ * - insn_off - instruction offset (in bytes) within a BPF program that needs
110
+ * its insn->imm field to be relocated with actual offset;
111
+ * - type_id - BTF type ID of the "root" (containing) entity of a relocatable
112
+ * offset;
113
+ * - access_str_off - offset into corresponding .BTF string section. String
114
+ * itself encodes an accessed field using a sequence of field and array
115
+ * indicies, separated by colon (:). It's conceptually very close to LLVM's
116
+ * getelementptr ([0]) instruction's arguments for identifying offset to
117
+ * a field.
118
+ *
119
+ * Example to provide a better feel.
120
+ *
121
+ * struct sample {
122
+ * int a;
123
+ * struct {
124
+ * int b[10];
125
+ * };
126
+ * };
127
+ *
128
+ * struct sample *s = ...;
129
+ * int x = &s->a; // encoded as "0:0" (a is field #0)
130
+ * int y = &s->b[5]; // encoded as "0:1:0:5" (anon struct is field #1,
131
+ * // b is field #0 inside anon struct, accessing elem #5)
132
+ * int z = &s[10]->b; // encoded as "10:1" (ptr is used as an array)
133
+ *
134
+ * type_id for all relocs in this example will capture BTF type id of
135
+ * `struct sample`.
136
+ *
137
+ * Such relocation is emitted when using __builtin_preserve_access_index()
138
+ * Clang built-in, passing expression that captures field address, e.g.:
139
+ *
140
+ * bpf_probe_read(&dst, sizeof(dst),
141
+ * __builtin_preserve_access_index(&src->a.b.c));
142
+ *
143
+ * In this case Clang will emit offset relocation recording necessary data to
144
+ * be able to find offset of embedded `a.b.c` field within `src` struct.
145
+ *
146
+ * [0] https://llvm.org/docs/LangRef.html#getelementptr-instruction
147
+ */
148
+ struct bpf_offset_reloc {
149
+ __u32 insn_off ;
150
+ __u32 type_id ;
151
+ __u32 access_str_off ;
152
+ };
153
+
49
154
#endif /* __LIBBPF_LIBBPF_INTERNAL_H */
0 commit comments