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#include <errno.h>
15#include <linux/err.h>
16#include <fcntl.h>
17#include <unistd.h>
18#include "libbpf_legacy.h"
19#include "relo_core.h"
20
21
22#pragma GCC poison u8 u16 u32 u64 s8 s16 s32 s64
23
24
25#pragma GCC poison reallocarray
26
27#include "libbpf.h"
28#include "btf.h"
29
30#ifndef EM_BPF
31#define EM_BPF 247
32#endif
33
34#ifndef R_BPF_64_64
35#define R_BPF_64_64 1
36#endif
37#ifndef R_BPF_64_ABS64
38#define R_BPF_64_ABS64 2
39#endif
40#ifndef R_BPF_64_ABS32
41#define R_BPF_64_ABS32 3
42#endif
43#ifndef R_BPF_64_32
44#define R_BPF_64_32 10
45#endif
46
47#ifndef SHT_LLVM_ADDRSIG
48#define SHT_LLVM_ADDRSIG 0x6FFF4C03
49#endif
50
51
52#ifndef ELF_C_READ_MMAP
53#define ELF_C_READ_MMAP ELF_C_READ
54#endif
55
56
57#ifndef ELF64_ST_VISIBILITY
58#define ELF64_ST_VISIBILITY(o) ((o) & 0x03)
59#endif
60
61#define BTF_INFO_ENC(kind, kind_flag, vlen) \
62 ((!!(kind_flag) << 31) | ((kind) << 24) | ((vlen) & BTF_MAX_VLEN))
63#define BTF_TYPE_ENC(name, info, size_or_type) (name), (info), (size_or_type)
64#define BTF_INT_ENC(encoding, bits_offset, nr_bits) \
65 ((encoding) << 24 | (bits_offset) << 16 | (nr_bits))
66#define BTF_TYPE_INT_ENC(name, encoding, bits_offset, bits, sz) \
67 BTF_TYPE_ENC(name, BTF_INFO_ENC(BTF_KIND_INT, 0, 0), sz), \
68 BTF_INT_ENC(encoding, bits_offset, bits)
69#define BTF_MEMBER_ENC(name, type, bits_offset) (name), (type), (bits_offset)
70#define BTF_PARAM_ENC(name, type) (name), (type)
71#define BTF_VAR_SECINFO_ENC(type, offset, size) (type), (offset), (size)
72#define BTF_TYPE_FLOAT_ENC(name, sz) \
73 BTF_TYPE_ENC(name, BTF_INFO_ENC(BTF_KIND_FLOAT, 0, 0), sz)
74#define BTF_TYPE_DECL_TAG_ENC(value, type, component_idx) \
75 BTF_TYPE_ENC(value, BTF_INFO_ENC(BTF_KIND_DECL_TAG, 0, 0), type), (component_idx)
76
77#ifndef likely
78#define likely(x) __builtin_expect(!!(x), 1)
79#endif
80#ifndef unlikely
81#define unlikely(x) __builtin_expect(!!(x), 0)
82#endif
83#ifndef min
84# define min(x, y) ((x) < (y) ? (x) : (y))
85#endif
86#ifndef max
87# define max(x, y) ((x) < (y) ? (y) : (x))
88#endif
89#ifndef offsetofend
90# define offsetofend(TYPE, FIELD) \
91 (offsetof(TYPE, FIELD) + sizeof(((TYPE *)0)->FIELD))
92#endif
93
94
95
96
97
98#define str_has_pfx(str, pfx) \
99 (strncmp(str, pfx, __builtin_constant_p(pfx) ? sizeof(pfx) - 1 : strlen(pfx)) == 0)
100
101
102
103
104
105
106
107#if defined(SHARED) && defined(__GNUC__) && __GNUC__ >= 10
108
109#define DEFAULT_VERSION(internal_name, api_name, version) \
110 __attribute__((symver(#api_name "@@" #version)))
111#define COMPAT_VERSION(internal_name, api_name, version) \
112 __attribute__((symver(#api_name "@" #version)))
113
114#elif defined(SHARED)
115
116#define COMPAT_VERSION(internal_name, api_name, version) \
117 asm(".symver " #internal_name "," #api_name "@" #version);
118#define DEFAULT_VERSION(internal_name, api_name, version) \
119 asm(".symver " #internal_name "," #api_name "@@" #version);
120
121#else
122
123#define COMPAT_VERSION(internal_name, api_name, version)
124#define DEFAULT_VERSION(internal_name, api_name, version) \
125 extern typeof(internal_name) api_name \
126 __attribute__((alias(#internal_name)));
127
128#endif
129
130extern void libbpf_print(enum libbpf_print_level level,
131 const char *format, ...)
132 __attribute__((format(printf, 2, 3)));
133
134#define __pr(level, fmt, ...) \
135do { \
136 libbpf_print(level, "libbpf: " fmt, ##__VA_ARGS__); \
137} while (0)
138
139#define pr_warn(fmt, ...) __pr(LIBBPF_WARN, fmt, ##__VA_ARGS__)
140#define pr_info(fmt, ...) __pr(LIBBPF_INFO, fmt, ##__VA_ARGS__)
141#define pr_debug(fmt, ...) __pr(LIBBPF_DEBUG, fmt, ##__VA_ARGS__)
142
143#ifndef __has_builtin
144#define __has_builtin(x) 0
145#endif
146
147
148
149
150
151
152
153
154
155static inline void *libbpf_reallocarray(void *ptr, size_t nmemb, size_t size)
156{
157 size_t total;
158
159#if __has_builtin(__builtin_mul_overflow)
160 if (unlikely(__builtin_mul_overflow(nmemb, size, &total)))
161 return NULL;
162#else
163 if (size == 0 || nmemb > ULONG_MAX / size)
164 return NULL;
165 total = nmemb * size;
166#endif
167 return realloc(ptr, total);
168}
169
170struct btf;
171struct btf_type;
172
173struct btf_type *btf_type_by_id(struct btf *btf, __u32 type_id);
174const char *btf_kind_str(const struct btf_type *t);
175const struct btf_type *skip_mods_and_typedefs(const struct btf *btf, __u32 id, __u32 *res_id);
176
177static inline enum btf_func_linkage btf_func_linkage(const struct btf_type *t)
178{
179 return (enum btf_func_linkage)(int)btf_vlen(t);
180}
181
182static inline __u32 btf_type_info(int kind, int vlen, int kflag)
183{
184 return (kflag << 31) | (kind << 24) | vlen;
185}
186
187enum map_def_parts {
188 MAP_DEF_MAP_TYPE = 0x001,
189 MAP_DEF_KEY_TYPE = 0x002,
190 MAP_DEF_KEY_SIZE = 0x004,
191 MAP_DEF_VALUE_TYPE = 0x008,
192 MAP_DEF_VALUE_SIZE = 0x010,
193 MAP_DEF_MAX_ENTRIES = 0x020,
194 MAP_DEF_MAP_FLAGS = 0x040,
195 MAP_DEF_NUMA_NODE = 0x080,
196 MAP_DEF_PINNING = 0x100,
197 MAP_DEF_INNER_MAP = 0x200,
198 MAP_DEF_MAP_EXTRA = 0x400,
199
200 MAP_DEF_ALL = 0x7ff,
201};
202
203struct btf_map_def {
204 enum map_def_parts parts;
205 __u32 map_type;
206 __u32 key_type_id;
207 __u32 key_size;
208 __u32 value_type_id;
209 __u32 value_size;
210 __u32 max_entries;
211 __u32 map_flags;
212 __u32 numa_node;
213 __u32 pinning;
214 __u64 map_extra;
215};
216
217int parse_btf_map_def(const char *map_name, struct btf *btf,
218 const struct btf_type *def_t, bool strict,
219 struct btf_map_def *map_def, struct btf_map_def *inner_def);
220
221void *libbpf_add_mem(void **data, size_t *cap_cnt, size_t elem_sz,
222 size_t cur_cnt, size_t max_cnt, size_t add_cnt);
223int libbpf_ensure_mem(void **data, size_t *cap_cnt, size_t elem_sz, size_t need_cnt);
224
225static inline bool libbpf_is_mem_zeroed(const char *p, ssize_t len)
226{
227 while (len > 0) {
228 if (*p)
229 return false;
230 p++;
231 len--;
232 }
233 return true;
234}
235
236static inline bool libbpf_validate_opts(const char *opts,
237 size_t opts_sz, size_t user_sz,
238 const char *type_name)
239{
240 if (user_sz < sizeof(size_t)) {
241 pr_warn("%s size (%zu) is too small\n", type_name, user_sz);
242 return false;
243 }
244 if (!libbpf_is_mem_zeroed(opts + opts_sz, (ssize_t)user_sz - opts_sz)) {
245 pr_warn("%s has non-zero extra bytes\n", type_name);
246 return false;
247 }
248 return true;
249}
250
251#define OPTS_VALID(opts, type) \
252 (!(opts) || libbpf_validate_opts((const char *)opts, \
253 offsetofend(struct type, \
254 type##__last_field), \
255 (opts)->sz, #type))
256#define OPTS_HAS(opts, field) \
257 ((opts) && opts->sz >= offsetofend(typeof(*(opts)), field))
258#define OPTS_GET(opts, field, fallback_value) \
259 (OPTS_HAS(opts, field) ? (opts)->field : fallback_value)
260#define OPTS_SET(opts, field, value) \
261 do { \
262 if (OPTS_HAS(opts, field)) \
263 (opts)->field = value; \
264 } while (0)
265
266#define OPTS_ZEROED(opts, last_nonzero_field) \
267({ \
268 ssize_t __off = offsetofend(typeof(*(opts)), last_nonzero_field); \
269 !(opts) || libbpf_is_mem_zeroed((const void *)opts + __off, \
270 (opts)->sz - __off); \
271})
272
273
274int parse_cpu_mask_str(const char *s, bool **mask, int *mask_sz);
275int parse_cpu_mask_file(const char *fcpu, bool **mask, int *mask_sz);
276int libbpf__load_raw_btf(const char *raw_types, size_t types_len,
277 const char *str_sec, size_t str_len);
278
279struct bpf_prog_load_params {
280 enum bpf_prog_type prog_type;
281 enum bpf_attach_type expected_attach_type;
282 const char *name;
283 const struct bpf_insn *insns;
284 size_t insn_cnt;
285 const char *license;
286 __u32 kern_version;
287 __u32 attach_prog_fd;
288 __u32 attach_btf_obj_fd;
289 __u32 attach_btf_id;
290 __u32 prog_ifindex;
291 __u32 prog_btf_fd;
292 __u32 prog_flags;
293
294 __u32 func_info_rec_size;
295 const void *func_info;
296 __u32 func_info_cnt;
297
298 __u32 line_info_rec_size;
299 const void *line_info;
300 __u32 line_info_cnt;
301
302 __u32 log_level;
303 char *log_buf;
304 size_t log_buf_sz;
305 int *fd_array;
306};
307
308int libbpf__bpf_prog_load(const struct bpf_prog_load_params *load_attr);
309
310struct bpf_create_map_params {
311 const char *name;
312 enum bpf_map_type map_type;
313 __u32 map_flags;
314 __u32 key_size;
315 __u32 value_size;
316 __u32 max_entries;
317 __u32 numa_node;
318 __u32 btf_fd;
319 __u32 btf_key_type_id;
320 __u32 btf_value_type_id;
321 __u32 map_ifindex;
322 union {
323 __u32 inner_map_fd;
324 __u32 btf_vmlinux_value_type_id;
325 };
326 __u64 map_extra;
327};
328
329int libbpf__bpf_create_map_xattr(const struct bpf_create_map_params *create_attr);
330
331struct btf *btf_get_from_fd(int btf_fd, struct btf *base_btf);
332void btf_get_kernel_prefix_kind(enum bpf_attach_type attach_type,
333 const char **prefix, int *kind);
334
335struct btf_ext_info {
336
337
338
339
340 void *info;
341 __u32 rec_size;
342 __u32 len;
343};
344
345#define for_each_btf_ext_sec(seg, sec) \
346 for (sec = (seg)->info; \
347 (void *)sec < (seg)->info + (seg)->len; \
348 sec = (void *)sec + sizeof(struct btf_ext_info_sec) + \
349 (seg)->rec_size * sec->num_info)
350
351#define for_each_btf_ext_rec(seg, sec, i, rec) \
352 for (i = 0, rec = (void *)&(sec)->data; \
353 i < (sec)->num_info; \
354 i++, rec = (void *)rec + (seg)->rec_size)
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377struct btf_ext_header {
378 __u16 magic;
379 __u8 version;
380 __u8 flags;
381 __u32 hdr_len;
382
383
384 __u32 func_info_off;
385 __u32 func_info_len;
386 __u32 line_info_off;
387 __u32 line_info_len;
388
389
390 __u32 core_relo_off;
391 __u32 core_relo_len;
392};
393
394struct btf_ext {
395 union {
396 struct btf_ext_header *hdr;
397 void *data;
398 };
399 struct btf_ext_info func_info;
400 struct btf_ext_info line_info;
401 struct btf_ext_info core_relo_info;
402 __u32 data_size;
403};
404
405struct btf_ext_info_sec {
406 __u32 sec_name_off;
407 __u32 num_info;
408
409 __u8 data[];
410};
411
412
413struct bpf_func_info_min {
414 __u32 insn_off;
415 __u32 type_id;
416};
417
418
419struct bpf_line_info_min {
420 __u32 insn_off;
421 __u32 file_name_off;
422 __u32 line_off;
423 __u32 line_col;
424};
425
426
427typedef int (*type_id_visit_fn)(__u32 *type_id, void *ctx);
428typedef int (*str_off_visit_fn)(__u32 *str_off, void *ctx);
429int btf_type_visit_type_ids(struct btf_type *t, type_id_visit_fn visit, void *ctx);
430int btf_type_visit_str_offs(struct btf_type *t, str_off_visit_fn visit, void *ctx);
431int btf_ext_visit_type_ids(struct btf_ext *btf_ext, type_id_visit_fn visit, void *ctx);
432int btf_ext_visit_str_offs(struct btf_ext *btf_ext, str_off_visit_fn visit, void *ctx);
433__s32 btf__find_by_name_kind_own(const struct btf *btf, const char *type_name,
434 __u32 kind);
435
436extern enum libbpf_strict_mode libbpf_mode;
437
438
439static inline int libbpf_err(int ret)
440{
441 if (ret < 0)
442 errno = -ret;
443 return ret;
444}
445
446
447
448
449static inline int libbpf_err_errno(int ret)
450{
451 if (libbpf_mode & LIBBPF_STRICT_DIRECT_ERRS)
452
453 return ret < 0 ? -errno : ret;
454
455
456 return ret;
457}
458
459
460static inline void *libbpf_err_ptr(int err)
461{
462
463 errno = -err;
464
465 if (libbpf_mode & LIBBPF_STRICT_CLEAN_PTRS)
466 return NULL;
467
468
469 return ERR_PTR(err);
470}
471
472
473static inline void *libbpf_ptr(void *ret)
474{
475
476 if (IS_ERR(ret))
477 errno = -PTR_ERR(ret);
478
479 if (libbpf_mode & LIBBPF_STRICT_CLEAN_PTRS)
480 return IS_ERR(ret) ? NULL : ret;
481
482
483 return ret;
484}
485
486static inline bool str_is_empty(const char *s)
487{
488 return !s || !s[0];
489}
490
491static inline bool is_ldimm64_insn(struct bpf_insn *insn)
492{
493 return insn->code == (BPF_LD | BPF_IMM | BPF_DW);
494}
495
496
497
498
499
500static inline int ensure_good_fd(int fd)
501{
502 int old_fd = fd, saved_errno;
503
504 if (fd < 0)
505 return fd;
506 if (fd < 3) {
507 fd = fcntl(fd, F_DUPFD_CLOEXEC, 3);
508 saved_errno = errno;
509 close(old_fd);
510 if (fd < 0) {
511 pr_warn("failed to dup FD %d to FD > 2: %d\n", old_fd, -saved_errno);
512 errno = saved_errno;
513 }
514 }
515 return fd;
516}
517
518#endif
519