1
2
3
4
5
6
7
8
9#ifndef __LIBBPF_LIBBPF_INTERNAL_H
10#define __LIBBPF_LIBBPF_INTERNAL_H
11
12#include <stdlib.h>
13#include <limits.h>
14
15
16#pragma GCC poison u8 u16 u32 u64 s8 s16 s32 s64
17
18
19#pragma GCC poison reallocarray
20
21#include "libbpf.h"
22
23#define BTF_INFO_ENC(kind, kind_flag, vlen) \
24 ((!!(kind_flag) << 31) | ((kind) << 24) | ((vlen) & BTF_MAX_VLEN))
25#define BTF_TYPE_ENC(name, info, size_or_type) (name), (info), (size_or_type)
26#define BTF_INT_ENC(encoding, bits_offset, nr_bits) \
27 ((encoding) << 24 | (bits_offset) << 16 | (nr_bits))
28#define BTF_TYPE_INT_ENC(name, encoding, bits_offset, bits, sz) \
29 BTF_TYPE_ENC(name, BTF_INFO_ENC(BTF_KIND_INT, 0, 0), sz), \
30 BTF_INT_ENC(encoding, bits_offset, bits)
31#define BTF_MEMBER_ENC(name, type, bits_offset) (name), (type), (bits_offset)
32#define BTF_PARAM_ENC(name, type) (name), (type)
33#define BTF_VAR_SECINFO_ENC(type, offset, size) (type), (offset), (size)
34
35#ifndef likely
36#define likely(x) __builtin_expect(!!(x), 1)
37#endif
38#ifndef unlikely
39#define unlikely(x) __builtin_expect(!!(x), 0)
40#endif
41#ifndef min
42# define min(x, y) ((x) < (y) ? (x) : (y))
43#endif
44#ifndef max
45# define max(x, y) ((x) < (y) ? (y) : (x))
46#endif
47#ifndef offsetofend
48# define offsetofend(TYPE, FIELD) \
49 (offsetof(TYPE, FIELD) + sizeof(((TYPE *)0)->FIELD))
50#endif
51
52
53
54
55
56#ifdef SHARED
57# define COMPAT_VERSION(internal_name, api_name, version) \
58 asm(".symver " #internal_name "," #api_name "@" #version);
59# define DEFAULT_VERSION(internal_name, api_name, version) \
60 asm(".symver " #internal_name "," #api_name "@@" #version);
61#else
62# define COMPAT_VERSION(internal_name, api_name, version)
63# define DEFAULT_VERSION(internal_name, api_name, version) \
64 extern typeof(internal_name) api_name \
65 __attribute__((alias(#internal_name)));
66#endif
67
68extern void libbpf_print(enum libbpf_print_level level,
69 const char *format, ...)
70 __attribute__((format(printf, 2, 3)));
71
72#define __pr(level, fmt, ...) \
73do { \
74 libbpf_print(level, "libbpf: " fmt, ##__VA_ARGS__); \
75} while (0)
76
77#define pr_warn(fmt, ...) __pr(LIBBPF_WARN, fmt, ##__VA_ARGS__)
78#define pr_info(fmt, ...) __pr(LIBBPF_INFO, fmt, ##__VA_ARGS__)
79#define pr_debug(fmt, ...) __pr(LIBBPF_DEBUG, fmt, ##__VA_ARGS__)
80
81#ifndef __has_builtin
82#define __has_builtin(x) 0
83#endif
84
85
86
87
88
89
90
91
92
93static inline void *libbpf_reallocarray(void *ptr, size_t nmemb, size_t size)
94{
95 size_t total;
96
97#if __has_builtin(__builtin_mul_overflow)
98 if (unlikely(__builtin_mul_overflow(nmemb, size, &total)))
99 return NULL;
100#else
101 if (size == 0 || nmemb > ULONG_MAX / size)
102 return NULL;
103 total = nmemb * size;
104#endif
105 return realloc(ptr, total);
106}
107
108void *btf_add_mem(void **data, size_t *cap_cnt, size_t elem_sz,
109 size_t cur_cnt, size_t max_cnt, size_t add_cnt);
110int btf_ensure_mem(void **data, size_t *cap_cnt, size_t elem_sz, size_t need_cnt);
111
112static inline bool libbpf_validate_opts(const char *opts,
113 size_t opts_sz, size_t user_sz,
114 const char *type_name)
115{
116 if (user_sz < sizeof(size_t)) {
117 pr_warn("%s size (%zu) is too small\n", type_name, user_sz);
118 return false;
119 }
120 if (user_sz > opts_sz) {
121 size_t i;
122
123 for (i = opts_sz; i < user_sz; i++) {
124 if (opts[i]) {
125 pr_warn("%s has non-zero extra bytes\n",
126 type_name);
127 return false;
128 }
129 }
130 }
131 return true;
132}
133
134#define OPTS_VALID(opts, type) \
135 (!(opts) || libbpf_validate_opts((const char *)opts, \
136 offsetofend(struct type, \
137 type##__last_field), \
138 (opts)->sz, #type))
139#define OPTS_HAS(opts, field) \
140 ((opts) && opts->sz >= offsetofend(typeof(*(opts)), field))
141#define OPTS_GET(opts, field, fallback_value) \
142 (OPTS_HAS(opts, field) ? (opts)->field : fallback_value)
143#define OPTS_SET(opts, field, value) \
144 do { \
145 if (OPTS_HAS(opts, field)) \
146 (opts)->field = value; \
147 } while (0)
148
149int parse_cpu_mask_str(const char *s, bool **mask, int *mask_sz);
150int parse_cpu_mask_file(const char *fcpu, bool **mask, int *mask_sz);
151int libbpf__load_raw_btf(const char *raw_types, size_t types_len,
152 const char *str_sec, size_t str_len);
153
154struct bpf_prog_load_params {
155 enum bpf_prog_type prog_type;
156 enum bpf_attach_type expected_attach_type;
157 const char *name;
158 const struct bpf_insn *insns;
159 size_t insn_cnt;
160 const char *license;
161 __u32 kern_version;
162 __u32 attach_prog_fd;
163 __u32 attach_btf_obj_fd;
164 __u32 attach_btf_id;
165 __u32 prog_ifindex;
166 __u32 prog_btf_fd;
167 __u32 prog_flags;
168
169 __u32 func_info_rec_size;
170 const void *func_info;
171 __u32 func_info_cnt;
172
173 __u32 line_info_rec_size;
174 const void *line_info;
175 __u32 line_info_cnt;
176
177 __u32 log_level;
178 char *log_buf;
179 size_t log_buf_sz;
180};
181
182int libbpf__bpf_prog_load(const struct bpf_prog_load_params *load_attr);
183
184int bpf_object__section_size(const struct bpf_object *obj, const char *name,
185 __u32 *size);
186int bpf_object__variable_offset(const struct bpf_object *obj, const char *name,
187 __u32 *off);
188struct btf *btf_get_from_fd(int btf_fd, struct btf *base_btf);
189
190struct btf_ext_info {
191
192
193
194
195 void *info;
196 __u32 rec_size;
197 __u32 len;
198};
199
200#define for_each_btf_ext_sec(seg, sec) \
201 for (sec = (seg)->info; \
202 (void *)sec < (seg)->info + (seg)->len; \
203 sec = (void *)sec + sizeof(struct btf_ext_info_sec) + \
204 (seg)->rec_size * sec->num_info)
205
206#define for_each_btf_ext_rec(seg, sec, i, rec) \
207 for (i = 0, rec = (void *)&(sec)->data; \
208 i < (sec)->num_info; \
209 i++, rec = (void *)rec + (seg)->rec_size)
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232struct btf_ext_header {
233 __u16 magic;
234 __u8 version;
235 __u8 flags;
236 __u32 hdr_len;
237
238
239 __u32 func_info_off;
240 __u32 func_info_len;
241 __u32 line_info_off;
242 __u32 line_info_len;
243
244
245 __u32 core_relo_off;
246 __u32 core_relo_len;
247};
248
249struct btf_ext {
250 union {
251 struct btf_ext_header *hdr;
252 void *data;
253 };
254 struct btf_ext_info func_info;
255 struct btf_ext_info line_info;
256 struct btf_ext_info core_relo_info;
257 __u32 data_size;
258};
259
260struct btf_ext_info_sec {
261 __u32 sec_name_off;
262 __u32 num_info;
263
264 __u8 data[];
265};
266
267
268struct bpf_func_info_min {
269 __u32 insn_off;
270 __u32 type_id;
271};
272
273
274struct bpf_line_info_min {
275 __u32 insn_off;
276 __u32 file_name_off;
277 __u32 line_off;
278 __u32 line_col;
279};
280
281
282
283
284enum bpf_core_relo_kind {
285 BPF_FIELD_BYTE_OFFSET = 0,
286 BPF_FIELD_BYTE_SIZE = 1,
287 BPF_FIELD_EXISTS = 2,
288 BPF_FIELD_SIGNED = 3,
289 BPF_FIELD_LSHIFT_U64 = 4,
290 BPF_FIELD_RSHIFT_U64 = 5,
291 BPF_TYPE_ID_LOCAL = 6,
292 BPF_TYPE_ID_TARGET = 7,
293 BPF_TYPE_EXISTS = 8,
294 BPF_TYPE_SIZE = 9,
295 BPF_ENUMVAL_EXISTS = 10,
296 BPF_ENUMVAL_VALUE = 11,
297};
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345struct bpf_core_relo {
346 __u32 insn_off;
347 __u32 type_id;
348 __u32 access_str_off;
349 enum bpf_core_relo_kind kind;
350};
351
352#endif
353