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
154int bpf_object__section_size(const struct bpf_object *obj, const char *name,
155 __u32 *size);
156int bpf_object__variable_offset(const struct bpf_object *obj, const char *name,
157 __u32 *off);
158
159struct btf_ext_info {
160
161
162
163
164 void *info;
165 __u32 rec_size;
166 __u32 len;
167};
168
169#define for_each_btf_ext_sec(seg, sec) \
170 for (sec = (seg)->info; \
171 (void *)sec < (seg)->info + (seg)->len; \
172 sec = (void *)sec + sizeof(struct btf_ext_info_sec) + \
173 (seg)->rec_size * sec->num_info)
174
175#define for_each_btf_ext_rec(seg, sec, i, rec) \
176 for (i = 0, rec = (void *)&(sec)->data; \
177 i < (sec)->num_info; \
178 i++, rec = (void *)rec + (seg)->rec_size)
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201struct btf_ext_header {
202 __u16 magic;
203 __u8 version;
204 __u8 flags;
205 __u32 hdr_len;
206
207
208 __u32 func_info_off;
209 __u32 func_info_len;
210 __u32 line_info_off;
211 __u32 line_info_len;
212
213
214 __u32 core_relo_off;
215 __u32 core_relo_len;
216};
217
218struct btf_ext {
219 union {
220 struct btf_ext_header *hdr;
221 void *data;
222 };
223 struct btf_ext_info func_info;
224 struct btf_ext_info line_info;
225 struct btf_ext_info core_relo_info;
226 __u32 data_size;
227};
228
229struct btf_ext_info_sec {
230 __u32 sec_name_off;
231 __u32 num_info;
232
233 __u8 data[];
234};
235
236
237struct bpf_func_info_min {
238 __u32 insn_off;
239 __u32 type_id;
240};
241
242
243struct bpf_line_info_min {
244 __u32 insn_off;
245 __u32 file_name_off;
246 __u32 line_off;
247 __u32 line_col;
248};
249
250
251
252
253enum bpf_core_relo_kind {
254 BPF_FIELD_BYTE_OFFSET = 0,
255 BPF_FIELD_BYTE_SIZE = 1,
256 BPF_FIELD_EXISTS = 2,
257 BPF_FIELD_SIGNED = 3,
258 BPF_FIELD_LSHIFT_U64 = 4,
259 BPF_FIELD_RSHIFT_U64 = 5,
260 BPF_TYPE_ID_LOCAL = 6,
261 BPF_TYPE_ID_TARGET = 7,
262 BPF_TYPE_EXISTS = 8,
263 BPF_TYPE_SIZE = 9,
264 BPF_ENUMVAL_EXISTS = 10,
265 BPF_ENUMVAL_VALUE = 11,
266};
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314struct bpf_core_relo {
315 __u32 insn_off;
316 __u32 type_id;
317 __u32 access_str_off;
318 enum bpf_core_relo_kind kind;
319};
320
321#endif
322