treewide: remove redundant IS_ERR() before error code check
[linux/fpc-iii.git] / tools / testing / selftests / bpf / test_btf.c
blob93040ca83e604963044dc685634654af831274c6
1 /* SPDX-License-Identifier: GPL-2.0 */
2 /* Copyright (c) 2018 Facebook */
4 #include <linux/bpf.h>
5 #include <linux/btf.h>
6 #include <linux/err.h>
7 #include <linux/kernel.h>
8 #include <linux/filter.h>
9 #include <linux/unistd.h>
10 #include <bpf/bpf.h>
11 #include <sys/resource.h>
12 #include <libelf.h>
13 #include <gelf.h>
14 #include <string.h>
15 #include <stdlib.h>
16 #include <stdio.h>
17 #include <stdarg.h>
18 #include <unistd.h>
19 #include <fcntl.h>
20 #include <errno.h>
21 #include <assert.h>
22 #include <bpf/libbpf.h>
23 #include <bpf/btf.h>
25 #include "bpf_rlimit.h"
26 #include "bpf_util.h"
27 #include "test_btf.h"
29 #define MAX_INSNS 512
30 #define MAX_SUBPROGS 16
32 static uint32_t pass_cnt;
33 static uint32_t error_cnt;
34 static uint32_t skip_cnt;
36 #define CHECK(condition, format...) ({ \
37 int __ret = !!(condition); \
38 if (__ret) { \
39 fprintf(stderr, "%s:%d:FAIL ", __func__, __LINE__); \
40 fprintf(stderr, format); \
41 } \
42 __ret; \
45 static int count_result(int err)
47 if (err)
48 error_cnt++;
49 else
50 pass_cnt++;
52 fprintf(stderr, "\n");
53 return err;
56 static int __base_pr(enum libbpf_print_level level __attribute__((unused)),
57 const char *format, va_list args)
59 return vfprintf(stderr, format, args);
62 #define BTF_END_RAW 0xdeadbeef
63 #define NAME_TBD 0xdeadb33f
65 #define NAME_NTH(N) (0xffff0000 | N)
66 #define IS_NAME_NTH(X) ((X & 0xffff0000) == 0xffff0000)
67 #define GET_NAME_NTH_IDX(X) (X & 0x0000ffff)
69 #define MAX_NR_RAW_U32 1024
70 #define BTF_LOG_BUF_SIZE 65535
72 static struct args {
73 unsigned int raw_test_num;
74 unsigned int file_test_num;
75 unsigned int get_info_test_num;
76 unsigned int info_raw_test_num;
77 unsigned int dedup_test_num;
78 bool raw_test;
79 bool file_test;
80 bool get_info_test;
81 bool pprint_test;
82 bool always_log;
83 bool info_raw_test;
84 bool dedup_test;
85 } args;
87 static char btf_log_buf[BTF_LOG_BUF_SIZE];
89 static struct btf_header hdr_tmpl = {
90 .magic = BTF_MAGIC,
91 .version = BTF_VERSION,
92 .hdr_len = sizeof(struct btf_header),
95 /* several different mapv kinds(types) supported by pprint */
96 enum pprint_mapv_kind_t {
97 PPRINT_MAPV_KIND_BASIC = 0,
98 PPRINT_MAPV_KIND_INT128,
101 struct btf_raw_test {
102 const char *descr;
103 const char *str_sec;
104 const char *map_name;
105 const char *err_str;
106 __u32 raw_types[MAX_NR_RAW_U32];
107 __u32 str_sec_size;
108 enum bpf_map_type map_type;
109 __u32 key_size;
110 __u32 value_size;
111 __u32 key_type_id;
112 __u32 value_type_id;
113 __u32 max_entries;
114 bool btf_load_err;
115 bool map_create_err;
116 bool ordered_map;
117 bool lossless_map;
118 bool percpu_map;
119 int hdr_len_delta;
120 int type_off_delta;
121 int str_off_delta;
122 int str_len_delta;
123 enum pprint_mapv_kind_t mapv_kind;
126 #define BTF_STR_SEC(str) \
127 .str_sec = str, .str_sec_size = sizeof(str)
129 static struct btf_raw_test raw_tests[] = {
130 /* enum E {
131 * E0,
132 * E1,
133 * };
135 * struct A {
136 * unsigned long long m;
137 * int n;
138 * char o;
139 * [3 bytes hole]
140 * int p[8];
141 * int q[4][8];
142 * enum E r;
143 * };
146 .descr = "struct test #1",
147 .raw_types = {
148 /* int */
149 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
150 /* unsigned long long */
151 BTF_TYPE_INT_ENC(0, 0, 0, 64, 8), /* [2] */
152 /* char */
153 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 8, 1), /* [3] */
154 /* int[8] */
155 BTF_TYPE_ARRAY_ENC(1, 1, 8), /* [4] */
156 /* struct A { */ /* [5] */
157 BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 6), 180),
158 BTF_MEMBER_ENC(NAME_TBD, 2, 0), /* unsigned long long m;*/
159 BTF_MEMBER_ENC(NAME_TBD, 1, 64),/* int n; */
160 BTF_MEMBER_ENC(NAME_TBD, 3, 96),/* char o; */
161 BTF_MEMBER_ENC(NAME_TBD, 4, 128),/* int p[8] */
162 BTF_MEMBER_ENC(NAME_TBD, 6, 384),/* int q[4][8] */
163 BTF_MEMBER_ENC(NAME_TBD, 7, 1408), /* enum E r */
164 /* } */
165 /* int[4][8] */
166 BTF_TYPE_ARRAY_ENC(4, 1, 4), /* [6] */
167 /* enum E */ /* [7] */
168 BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_ENUM, 0, 2), sizeof(int)),
169 BTF_ENUM_ENC(NAME_TBD, 0),
170 BTF_ENUM_ENC(NAME_TBD, 1),
171 BTF_END_RAW,
173 .str_sec = "\0A\0m\0n\0o\0p\0q\0r\0E\0E0\0E1",
174 .str_sec_size = sizeof("\0A\0m\0n\0o\0p\0q\0r\0E\0E0\0E1"),
175 .map_type = BPF_MAP_TYPE_ARRAY,
176 .map_name = "struct_test1_map",
177 .key_size = sizeof(int),
178 .value_size = 180,
179 .key_type_id = 1,
180 .value_type_id = 5,
181 .max_entries = 4,
184 /* typedef struct b Struct_B;
186 * struct A {
187 * int m;
188 * struct b n[4];
189 * const Struct_B o[4];
190 * };
192 * struct B {
193 * int m;
194 * int n;
195 * };
198 .descr = "struct test #2",
199 .raw_types = {
200 /* int */ /* [1] */
201 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
202 /* struct b [4] */ /* [2] */
203 BTF_TYPE_ARRAY_ENC(4, 1, 4),
205 /* struct A { */ /* [3] */
206 BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 3), 68),
207 BTF_MEMBER_ENC(NAME_TBD, 1, 0), /* int m; */
208 BTF_MEMBER_ENC(NAME_TBD, 2, 32),/* struct B n[4] */
209 BTF_MEMBER_ENC(NAME_TBD, 8, 288),/* const Struct_B o[4];*/
210 /* } */
212 /* struct B { */ /* [4] */
213 BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 2), 8),
214 BTF_MEMBER_ENC(NAME_TBD, 1, 0), /* int m; */
215 BTF_MEMBER_ENC(NAME_TBD, 1, 32),/* int n; */
216 /* } */
218 /* const int */ /* [5] */
219 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_CONST, 0, 0), 1),
220 /* typedef struct b Struct_B */ /* [6] */
221 BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_TYPEDEF, 0, 0), 4),
222 /* const Struct_B */ /* [7] */
223 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_CONST, 0, 0), 6),
224 /* const Struct_B [4] */ /* [8] */
225 BTF_TYPE_ARRAY_ENC(7, 1, 4),
226 BTF_END_RAW,
228 .str_sec = "\0A\0m\0n\0o\0B\0m\0n\0Struct_B",
229 .str_sec_size = sizeof("\0A\0m\0n\0o\0B\0m\0n\0Struct_B"),
230 .map_type = BPF_MAP_TYPE_ARRAY,
231 .map_name = "struct_test2_map",
232 .key_size = sizeof(int),
233 .value_size = 68,
234 .key_type_id = 1,
235 .value_type_id = 3,
236 .max_entries = 4,
239 .descr = "struct test #3 Invalid member offset",
240 .raw_types = {
241 /* int */ /* [1] */
242 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
243 /* int64 */ /* [2] */
244 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 64, 8),
246 /* struct A { */ /* [3] */
247 BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 2), 16),
248 BTF_MEMBER_ENC(NAME_TBD, 1, 64), /* int m; */
249 BTF_MEMBER_ENC(NAME_TBD, 2, 0), /* int64 n; */
250 /* } */
251 BTF_END_RAW,
253 .str_sec = "\0A\0m\0n\0",
254 .str_sec_size = sizeof("\0A\0m\0n\0"),
255 .map_type = BPF_MAP_TYPE_ARRAY,
256 .map_name = "struct_test3_map",
257 .key_size = sizeof(int),
258 .value_size = 16,
259 .key_type_id = 1,
260 .value_type_id = 3,
261 .max_entries = 4,
262 .btf_load_err = true,
263 .err_str = "Invalid member bits_offset",
266 * struct A {
267 * unsigned long long m;
268 * int n;
269 * char o;
270 * [3 bytes hole]
271 * int p[8];
272 * };
275 .descr = "global data test #1",
276 .raw_types = {
277 /* int */
278 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
279 /* unsigned long long */
280 BTF_TYPE_INT_ENC(0, 0, 0, 64, 8), /* [2] */
281 /* char */
282 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 8, 1), /* [3] */
283 /* int[8] */
284 BTF_TYPE_ARRAY_ENC(1, 1, 8), /* [4] */
285 /* struct A { */ /* [5] */
286 BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 4), 48),
287 BTF_MEMBER_ENC(NAME_TBD, 2, 0), /* unsigned long long m;*/
288 BTF_MEMBER_ENC(NAME_TBD, 1, 64),/* int n; */
289 BTF_MEMBER_ENC(NAME_TBD, 3, 96),/* char o; */
290 BTF_MEMBER_ENC(NAME_TBD, 4, 128),/* int p[8] */
291 /* } */
292 BTF_END_RAW,
294 .str_sec = "\0A\0m\0n\0o\0p",
295 .str_sec_size = sizeof("\0A\0m\0n\0o\0p"),
296 .map_type = BPF_MAP_TYPE_ARRAY,
297 .map_name = "struct_test1_map",
298 .key_size = sizeof(int),
299 .value_size = 48,
300 .key_type_id = 1,
301 .value_type_id = 5,
302 .max_entries = 4,
305 * struct A {
306 * unsigned long long m;
307 * int n;
308 * char o;
309 * [3 bytes hole]
310 * int p[8];
311 * };
312 * static struct A t; <- in .bss
315 .descr = "global data test #2",
316 .raw_types = {
317 /* int */
318 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
319 /* unsigned long long */
320 BTF_TYPE_INT_ENC(0, 0, 0, 64, 8), /* [2] */
321 /* char */
322 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 8, 1), /* [3] */
323 /* int[8] */
324 BTF_TYPE_ARRAY_ENC(1, 1, 8), /* [4] */
325 /* struct A { */ /* [5] */
326 BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 4), 48),
327 BTF_MEMBER_ENC(NAME_TBD, 2, 0), /* unsigned long long m;*/
328 BTF_MEMBER_ENC(NAME_TBD, 1, 64),/* int n; */
329 BTF_MEMBER_ENC(NAME_TBD, 3, 96),/* char o; */
330 BTF_MEMBER_ENC(NAME_TBD, 4, 128),/* int p[8] */
331 /* } */
332 /* static struct A t */
333 BTF_VAR_ENC(NAME_TBD, 5, 0), /* [6] */
334 /* .bss section */ /* [7] */
335 BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_DATASEC, 0, 1), 48),
336 BTF_VAR_SECINFO_ENC(6, 0, 48),
337 BTF_END_RAW,
339 .str_sec = "\0A\0m\0n\0o\0p\0t\0.bss",
340 .str_sec_size = sizeof("\0A\0m\0n\0o\0p\0t\0.bss"),
341 .map_type = BPF_MAP_TYPE_ARRAY,
342 .map_name = ".bss",
343 .key_size = sizeof(int),
344 .value_size = 48,
345 .key_type_id = 0,
346 .value_type_id = 7,
347 .max_entries = 1,
350 .descr = "global data test #3",
351 .raw_types = {
352 /* int */
353 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
354 /* static int t */
355 BTF_VAR_ENC(NAME_TBD, 1, 0), /* [2] */
356 /* .bss section */ /* [3] */
357 BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_DATASEC, 0, 1), 4),
358 BTF_VAR_SECINFO_ENC(2, 0, 4),
359 BTF_END_RAW,
361 .str_sec = "\0t\0.bss",
362 .str_sec_size = sizeof("\0t\0.bss"),
363 .map_type = BPF_MAP_TYPE_ARRAY,
364 .map_name = ".bss",
365 .key_size = sizeof(int),
366 .value_size = 4,
367 .key_type_id = 0,
368 .value_type_id = 3,
369 .max_entries = 1,
372 .descr = "global data test #4, unsupported linkage",
373 .raw_types = {
374 /* int */
375 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
376 /* static int t */
377 BTF_VAR_ENC(NAME_TBD, 1, 2), /* [2] */
378 /* .bss section */ /* [3] */
379 BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_DATASEC, 0, 1), 4),
380 BTF_VAR_SECINFO_ENC(2, 0, 4),
381 BTF_END_RAW,
383 .str_sec = "\0t\0.bss",
384 .str_sec_size = sizeof("\0t\0.bss"),
385 .map_type = BPF_MAP_TYPE_ARRAY,
386 .map_name = ".bss",
387 .key_size = sizeof(int),
388 .value_size = 4,
389 .key_type_id = 0,
390 .value_type_id = 3,
391 .max_entries = 1,
392 .btf_load_err = true,
393 .err_str = "Linkage not supported",
396 .descr = "global data test #5, invalid var type",
397 .raw_types = {
398 /* static void t */
399 BTF_VAR_ENC(NAME_TBD, 0, 0), /* [1] */
400 /* .bss section */ /* [2] */
401 BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_DATASEC, 0, 1), 4),
402 BTF_VAR_SECINFO_ENC(1, 0, 4),
403 BTF_END_RAW,
405 .str_sec = "\0t\0.bss",
406 .str_sec_size = sizeof("\0t\0.bss"),
407 .map_type = BPF_MAP_TYPE_ARRAY,
408 .map_name = ".bss",
409 .key_size = sizeof(int),
410 .value_size = 4,
411 .key_type_id = 0,
412 .value_type_id = 2,
413 .max_entries = 1,
414 .btf_load_err = true,
415 .err_str = "Invalid type_id",
418 .descr = "global data test #6, invalid var type (fwd type)",
419 .raw_types = {
420 /* union A */
421 BTF_TYPE_ENC(NAME_TBD,
422 BTF_INFO_ENC(BTF_KIND_FWD, 1, 0), 0), /* [1] */
423 /* static union A t */
424 BTF_VAR_ENC(NAME_TBD, 1, 0), /* [2] */
425 /* .bss section */ /* [3] */
426 BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_DATASEC, 0, 1), 4),
427 BTF_VAR_SECINFO_ENC(2, 0, 4),
428 BTF_END_RAW,
430 .str_sec = "\0A\0t\0.bss",
431 .str_sec_size = sizeof("\0A\0t\0.bss"),
432 .map_type = BPF_MAP_TYPE_ARRAY,
433 .map_name = ".bss",
434 .key_size = sizeof(int),
435 .value_size = 4,
436 .key_type_id = 0,
437 .value_type_id = 2,
438 .max_entries = 1,
439 .btf_load_err = true,
440 .err_str = "Invalid type",
443 .descr = "global data test #7, invalid var type (fwd type)",
444 .raw_types = {
445 /* union A */
446 BTF_TYPE_ENC(NAME_TBD,
447 BTF_INFO_ENC(BTF_KIND_FWD, 1, 0), 0), /* [1] */
448 /* static union A t */
449 BTF_VAR_ENC(NAME_TBD, 1, 0), /* [2] */
450 /* .bss section */ /* [3] */
451 BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_DATASEC, 0, 1), 4),
452 BTF_VAR_SECINFO_ENC(1, 0, 4),
453 BTF_END_RAW,
455 .str_sec = "\0A\0t\0.bss",
456 .str_sec_size = sizeof("\0A\0t\0.bss"),
457 .map_type = BPF_MAP_TYPE_ARRAY,
458 .map_name = ".bss",
459 .key_size = sizeof(int),
460 .value_size = 4,
461 .key_type_id = 0,
462 .value_type_id = 2,
463 .max_entries = 1,
464 .btf_load_err = true,
465 .err_str = "Invalid type",
468 .descr = "global data test #8, invalid var size",
469 .raw_types = {
470 /* int */
471 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
472 /* unsigned long long */
473 BTF_TYPE_INT_ENC(0, 0, 0, 64, 8), /* [2] */
474 /* char */
475 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 8, 1), /* [3] */
476 /* int[8] */
477 BTF_TYPE_ARRAY_ENC(1, 1, 8), /* [4] */
478 /* struct A { */ /* [5] */
479 BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 4), 48),
480 BTF_MEMBER_ENC(NAME_TBD, 2, 0), /* unsigned long long m;*/
481 BTF_MEMBER_ENC(NAME_TBD, 1, 64),/* int n; */
482 BTF_MEMBER_ENC(NAME_TBD, 3, 96),/* char o; */
483 BTF_MEMBER_ENC(NAME_TBD, 4, 128),/* int p[8] */
484 /* } */
485 /* static struct A t */
486 BTF_VAR_ENC(NAME_TBD, 5, 0), /* [6] */
487 /* .bss section */ /* [7] */
488 BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_DATASEC, 0, 1), 48),
489 BTF_VAR_SECINFO_ENC(6, 0, 47),
490 BTF_END_RAW,
492 .str_sec = "\0A\0m\0n\0o\0p\0t\0.bss",
493 .str_sec_size = sizeof("\0A\0m\0n\0o\0p\0t\0.bss"),
494 .map_type = BPF_MAP_TYPE_ARRAY,
495 .map_name = ".bss",
496 .key_size = sizeof(int),
497 .value_size = 48,
498 .key_type_id = 0,
499 .value_type_id = 7,
500 .max_entries = 1,
501 .btf_load_err = true,
502 .err_str = "Invalid size",
505 .descr = "global data test #9, invalid var size",
506 .raw_types = {
507 /* int */
508 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
509 /* unsigned long long */
510 BTF_TYPE_INT_ENC(0, 0, 0, 64, 8), /* [2] */
511 /* char */
512 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 8, 1), /* [3] */
513 /* int[8] */
514 BTF_TYPE_ARRAY_ENC(1, 1, 8), /* [4] */
515 /* struct A { */ /* [5] */
516 BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 4), 48),
517 BTF_MEMBER_ENC(NAME_TBD, 2, 0), /* unsigned long long m;*/
518 BTF_MEMBER_ENC(NAME_TBD, 1, 64),/* int n; */
519 BTF_MEMBER_ENC(NAME_TBD, 3, 96),/* char o; */
520 BTF_MEMBER_ENC(NAME_TBD, 4, 128),/* int p[8] */
521 /* } */
522 /* static struct A t */
523 BTF_VAR_ENC(NAME_TBD, 5, 0), /* [6] */
524 /* .bss section */ /* [7] */
525 BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_DATASEC, 0, 1), 46),
526 BTF_VAR_SECINFO_ENC(6, 0, 48),
527 BTF_END_RAW,
529 .str_sec = "\0A\0m\0n\0o\0p\0t\0.bss",
530 .str_sec_size = sizeof("\0A\0m\0n\0o\0p\0t\0.bss"),
531 .map_type = BPF_MAP_TYPE_ARRAY,
532 .map_name = ".bss",
533 .key_size = sizeof(int),
534 .value_size = 48,
535 .key_type_id = 0,
536 .value_type_id = 7,
537 .max_entries = 1,
538 .btf_load_err = true,
539 .err_str = "Invalid size",
542 .descr = "global data test #10, invalid var size",
543 .raw_types = {
544 /* int */
545 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
546 /* unsigned long long */
547 BTF_TYPE_INT_ENC(0, 0, 0, 64, 8), /* [2] */
548 /* char */
549 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 8, 1), /* [3] */
550 /* int[8] */
551 BTF_TYPE_ARRAY_ENC(1, 1, 8), /* [4] */
552 /* struct A { */ /* [5] */
553 BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 4), 48),
554 BTF_MEMBER_ENC(NAME_TBD, 2, 0), /* unsigned long long m;*/
555 BTF_MEMBER_ENC(NAME_TBD, 1, 64),/* int n; */
556 BTF_MEMBER_ENC(NAME_TBD, 3, 96),/* char o; */
557 BTF_MEMBER_ENC(NAME_TBD, 4, 128),/* int p[8] */
558 /* } */
559 /* static struct A t */
560 BTF_VAR_ENC(NAME_TBD, 5, 0), /* [6] */
561 /* .bss section */ /* [7] */
562 BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_DATASEC, 0, 1), 46),
563 BTF_VAR_SECINFO_ENC(6, 0, 46),
564 BTF_END_RAW,
566 .str_sec = "\0A\0m\0n\0o\0p\0t\0.bss",
567 .str_sec_size = sizeof("\0A\0m\0n\0o\0p\0t\0.bss"),
568 .map_type = BPF_MAP_TYPE_ARRAY,
569 .map_name = ".bss",
570 .key_size = sizeof(int),
571 .value_size = 48,
572 .key_type_id = 0,
573 .value_type_id = 7,
574 .max_entries = 1,
575 .btf_load_err = true,
576 .err_str = "Invalid size",
579 .descr = "global data test #11, multiple section members",
580 .raw_types = {
581 /* int */
582 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
583 /* unsigned long long */
584 BTF_TYPE_INT_ENC(0, 0, 0, 64, 8), /* [2] */
585 /* char */
586 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 8, 1), /* [3] */
587 /* int[8] */
588 BTF_TYPE_ARRAY_ENC(1, 1, 8), /* [4] */
589 /* struct A { */ /* [5] */
590 BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 4), 48),
591 BTF_MEMBER_ENC(NAME_TBD, 2, 0), /* unsigned long long m;*/
592 BTF_MEMBER_ENC(NAME_TBD, 1, 64),/* int n; */
593 BTF_MEMBER_ENC(NAME_TBD, 3, 96),/* char o; */
594 BTF_MEMBER_ENC(NAME_TBD, 4, 128),/* int p[8] */
595 /* } */
596 /* static struct A t */
597 BTF_VAR_ENC(NAME_TBD, 5, 0), /* [6] */
598 /* static int u */
599 BTF_VAR_ENC(NAME_TBD, 1, 0), /* [7] */
600 /* .bss section */ /* [8] */
601 BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_DATASEC, 0, 2), 62),
602 BTF_VAR_SECINFO_ENC(6, 10, 48),
603 BTF_VAR_SECINFO_ENC(7, 58, 4),
604 BTF_END_RAW,
606 .str_sec = "\0A\0m\0n\0o\0p\0t\0u\0.bss",
607 .str_sec_size = sizeof("\0A\0m\0n\0o\0p\0t\0u\0.bss"),
608 .map_type = BPF_MAP_TYPE_ARRAY,
609 .map_name = ".bss",
610 .key_size = sizeof(int),
611 .value_size = 62,
612 .key_type_id = 0,
613 .value_type_id = 8,
614 .max_entries = 1,
617 .descr = "global data test #12, invalid offset",
618 .raw_types = {
619 /* int */
620 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
621 /* unsigned long long */
622 BTF_TYPE_INT_ENC(0, 0, 0, 64, 8), /* [2] */
623 /* char */
624 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 8, 1), /* [3] */
625 /* int[8] */
626 BTF_TYPE_ARRAY_ENC(1, 1, 8), /* [4] */
627 /* struct A { */ /* [5] */
628 BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 4), 48),
629 BTF_MEMBER_ENC(NAME_TBD, 2, 0), /* unsigned long long m;*/
630 BTF_MEMBER_ENC(NAME_TBD, 1, 64),/* int n; */
631 BTF_MEMBER_ENC(NAME_TBD, 3, 96),/* char o; */
632 BTF_MEMBER_ENC(NAME_TBD, 4, 128),/* int p[8] */
633 /* } */
634 /* static struct A t */
635 BTF_VAR_ENC(NAME_TBD, 5, 0), /* [6] */
636 /* static int u */
637 BTF_VAR_ENC(NAME_TBD, 1, 0), /* [7] */
638 /* .bss section */ /* [8] */
639 BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_DATASEC, 0, 2), 62),
640 BTF_VAR_SECINFO_ENC(6, 10, 48),
641 BTF_VAR_SECINFO_ENC(7, 60, 4),
642 BTF_END_RAW,
644 .str_sec = "\0A\0m\0n\0o\0p\0t\0u\0.bss",
645 .str_sec_size = sizeof("\0A\0m\0n\0o\0p\0t\0u\0.bss"),
646 .map_type = BPF_MAP_TYPE_ARRAY,
647 .map_name = ".bss",
648 .key_size = sizeof(int),
649 .value_size = 62,
650 .key_type_id = 0,
651 .value_type_id = 8,
652 .max_entries = 1,
653 .btf_load_err = true,
654 .err_str = "Invalid offset+size",
657 .descr = "global data test #13, invalid offset",
658 .raw_types = {
659 /* int */
660 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
661 /* unsigned long long */
662 BTF_TYPE_INT_ENC(0, 0, 0, 64, 8), /* [2] */
663 /* char */
664 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 8, 1), /* [3] */
665 /* int[8] */
666 BTF_TYPE_ARRAY_ENC(1, 1, 8), /* [4] */
667 /* struct A { */ /* [5] */
668 BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 4), 48),
669 BTF_MEMBER_ENC(NAME_TBD, 2, 0), /* unsigned long long m;*/
670 BTF_MEMBER_ENC(NAME_TBD, 1, 64),/* int n; */
671 BTF_MEMBER_ENC(NAME_TBD, 3, 96),/* char o; */
672 BTF_MEMBER_ENC(NAME_TBD, 4, 128),/* int p[8] */
673 /* } */
674 /* static struct A t */
675 BTF_VAR_ENC(NAME_TBD, 5, 0), /* [6] */
676 /* static int u */
677 BTF_VAR_ENC(NAME_TBD, 1, 0), /* [7] */
678 /* .bss section */ /* [8] */
679 BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_DATASEC, 0, 2), 62),
680 BTF_VAR_SECINFO_ENC(6, 10, 48),
681 BTF_VAR_SECINFO_ENC(7, 12, 4),
682 BTF_END_RAW,
684 .str_sec = "\0A\0m\0n\0o\0p\0t\0u\0.bss",
685 .str_sec_size = sizeof("\0A\0m\0n\0o\0p\0t\0u\0.bss"),
686 .map_type = BPF_MAP_TYPE_ARRAY,
687 .map_name = ".bss",
688 .key_size = sizeof(int),
689 .value_size = 62,
690 .key_type_id = 0,
691 .value_type_id = 8,
692 .max_entries = 1,
693 .btf_load_err = true,
694 .err_str = "Invalid offset",
697 .descr = "global data test #14, invalid offset",
698 .raw_types = {
699 /* int */
700 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
701 /* unsigned long long */
702 BTF_TYPE_INT_ENC(0, 0, 0, 64, 8), /* [2] */
703 /* char */
704 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 8, 1), /* [3] */
705 /* int[8] */
706 BTF_TYPE_ARRAY_ENC(1, 1, 8), /* [4] */
707 /* struct A { */ /* [5] */
708 BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 4), 48),
709 BTF_MEMBER_ENC(NAME_TBD, 2, 0), /* unsigned long long m;*/
710 BTF_MEMBER_ENC(NAME_TBD, 1, 64),/* int n; */
711 BTF_MEMBER_ENC(NAME_TBD, 3, 96),/* char o; */
712 BTF_MEMBER_ENC(NAME_TBD, 4, 128),/* int p[8] */
713 /* } */
714 /* static struct A t */
715 BTF_VAR_ENC(NAME_TBD, 5, 0), /* [6] */
716 /* static int u */
717 BTF_VAR_ENC(NAME_TBD, 1, 0), /* [7] */
718 /* .bss section */ /* [8] */
719 BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_DATASEC, 0, 2), 62),
720 BTF_VAR_SECINFO_ENC(7, 58, 4),
721 BTF_VAR_SECINFO_ENC(6, 10, 48),
722 BTF_END_RAW,
724 .str_sec = "\0A\0m\0n\0o\0p\0t\0u\0.bss",
725 .str_sec_size = sizeof("\0A\0m\0n\0o\0p\0t\0u\0.bss"),
726 .map_type = BPF_MAP_TYPE_ARRAY,
727 .map_name = ".bss",
728 .key_size = sizeof(int),
729 .value_size = 62,
730 .key_type_id = 0,
731 .value_type_id = 8,
732 .max_entries = 1,
733 .btf_load_err = true,
734 .err_str = "Invalid offset",
737 .descr = "global data test #15, not var kind",
738 .raw_types = {
739 /* int */
740 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
741 BTF_VAR_ENC(NAME_TBD, 1, 0), /* [2] */
742 /* .bss section */ /* [3] */
743 BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_DATASEC, 0, 1), 4),
744 BTF_VAR_SECINFO_ENC(1, 0, 4),
745 BTF_END_RAW,
747 .str_sec = "\0A\0t\0.bss",
748 .str_sec_size = sizeof("\0A\0t\0.bss"),
749 .map_type = BPF_MAP_TYPE_ARRAY,
750 .map_name = ".bss",
751 .key_size = sizeof(int),
752 .value_size = 4,
753 .key_type_id = 0,
754 .value_type_id = 3,
755 .max_entries = 1,
756 .btf_load_err = true,
757 .err_str = "Not a VAR kind member",
760 .descr = "global data test #16, invalid var referencing sec",
761 .raw_types = {
762 /* int */
763 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
764 BTF_VAR_ENC(NAME_TBD, 5, 0), /* [2] */
765 BTF_VAR_ENC(NAME_TBD, 2, 0), /* [3] */
766 /* a section */ /* [4] */
767 BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_DATASEC, 0, 1), 4),
768 BTF_VAR_SECINFO_ENC(3, 0, 4),
769 /* a section */ /* [5] */
770 BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_DATASEC, 0, 1), 4),
771 BTF_VAR_SECINFO_ENC(6, 0, 4),
772 BTF_VAR_ENC(NAME_TBD, 1, 0), /* [6] */
773 BTF_END_RAW,
775 .str_sec = "\0A\0t\0s\0a\0a",
776 .str_sec_size = sizeof("\0A\0t\0s\0a\0a"),
777 .map_type = BPF_MAP_TYPE_ARRAY,
778 .map_name = ".bss",
779 .key_size = sizeof(int),
780 .value_size = 4,
781 .key_type_id = 0,
782 .value_type_id = 4,
783 .max_entries = 1,
784 .btf_load_err = true,
785 .err_str = "Invalid type_id",
788 .descr = "global data test #17, invalid var referencing var",
789 .raw_types = {
790 /* int */
791 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
792 BTF_VAR_ENC(NAME_TBD, 1, 0), /* [2] */
793 BTF_VAR_ENC(NAME_TBD, 2, 0), /* [3] */
794 /* a section */ /* [4] */
795 BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_DATASEC, 0, 1), 4),
796 BTF_VAR_SECINFO_ENC(3, 0, 4),
797 BTF_END_RAW,
799 .str_sec = "\0A\0t\0s\0a\0a",
800 .str_sec_size = sizeof("\0A\0t\0s\0a\0a"),
801 .map_type = BPF_MAP_TYPE_ARRAY,
802 .map_name = ".bss",
803 .key_size = sizeof(int),
804 .value_size = 4,
805 .key_type_id = 0,
806 .value_type_id = 4,
807 .max_entries = 1,
808 .btf_load_err = true,
809 .err_str = "Invalid type_id",
812 .descr = "global data test #18, invalid var loop",
813 .raw_types = {
814 /* int */
815 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
816 BTF_VAR_ENC(NAME_TBD, 2, 0), /* [2] */
817 /* .bss section */ /* [3] */
818 BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_DATASEC, 0, 1), 4),
819 BTF_VAR_SECINFO_ENC(2, 0, 4),
820 BTF_END_RAW,
822 .str_sec = "\0A\0t\0aaa",
823 .str_sec_size = sizeof("\0A\0t\0aaa"),
824 .map_type = BPF_MAP_TYPE_ARRAY,
825 .map_name = ".bss",
826 .key_size = sizeof(int),
827 .value_size = 4,
828 .key_type_id = 0,
829 .value_type_id = 4,
830 .max_entries = 1,
831 .btf_load_err = true,
832 .err_str = "Invalid type_id",
835 .descr = "global data test #19, invalid var referencing var",
836 .raw_types = {
837 /* int */
838 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
839 BTF_VAR_ENC(NAME_TBD, 3, 0), /* [2] */
840 BTF_VAR_ENC(NAME_TBD, 1, 0), /* [3] */
841 BTF_END_RAW,
843 .str_sec = "\0A\0t\0s\0a\0a",
844 .str_sec_size = sizeof("\0A\0t\0s\0a\0a"),
845 .map_type = BPF_MAP_TYPE_ARRAY,
846 .map_name = ".bss",
847 .key_size = sizeof(int),
848 .value_size = 4,
849 .key_type_id = 0,
850 .value_type_id = 4,
851 .max_entries = 1,
852 .btf_load_err = true,
853 .err_str = "Invalid type_id",
856 .descr = "global data test #20, invalid ptr referencing var",
857 .raw_types = {
858 /* int */
859 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
860 /* PTR type_id=3 */ /* [2] */
861 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_PTR, 0, 0), 3),
862 BTF_VAR_ENC(NAME_TBD, 1, 0), /* [3] */
863 BTF_END_RAW,
865 .str_sec = "\0A\0t\0s\0a\0a",
866 .str_sec_size = sizeof("\0A\0t\0s\0a\0a"),
867 .map_type = BPF_MAP_TYPE_ARRAY,
868 .map_name = ".bss",
869 .key_size = sizeof(int),
870 .value_size = 4,
871 .key_type_id = 0,
872 .value_type_id = 4,
873 .max_entries = 1,
874 .btf_load_err = true,
875 .err_str = "Invalid type_id",
878 .descr = "global data test #21, var included in struct",
879 .raw_types = {
880 /* int */
881 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
882 /* struct A { */ /* [2] */
883 BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 2), sizeof(int) * 2),
884 BTF_MEMBER_ENC(NAME_TBD, 1, 0), /* int m; */
885 BTF_MEMBER_ENC(NAME_TBD, 3, 32),/* VAR type_id=3; */
886 /* } */
887 BTF_VAR_ENC(NAME_TBD, 1, 0), /* [3] */
888 BTF_END_RAW,
890 .str_sec = "\0A\0t\0s\0a\0a",
891 .str_sec_size = sizeof("\0A\0t\0s\0a\0a"),
892 .map_type = BPF_MAP_TYPE_ARRAY,
893 .map_name = ".bss",
894 .key_size = sizeof(int),
895 .value_size = 4,
896 .key_type_id = 0,
897 .value_type_id = 4,
898 .max_entries = 1,
899 .btf_load_err = true,
900 .err_str = "Invalid member",
903 .descr = "global data test #22, array of var",
904 .raw_types = {
905 /* int */
906 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
907 BTF_TYPE_ARRAY_ENC(3, 1, 4), /* [2] */
908 BTF_VAR_ENC(NAME_TBD, 1, 0), /* [3] */
909 BTF_END_RAW,
911 .str_sec = "\0A\0t\0s\0a\0a",
912 .str_sec_size = sizeof("\0A\0t\0s\0a\0a"),
913 .map_type = BPF_MAP_TYPE_ARRAY,
914 .map_name = ".bss",
915 .key_size = sizeof(int),
916 .value_size = 4,
917 .key_type_id = 0,
918 .value_type_id = 4,
919 .max_entries = 1,
920 .btf_load_err = true,
921 .err_str = "Invalid elem",
923 /* Test member exceeds the size of struct.
925 * struct A {
926 * int m;
927 * int n;
928 * };
931 .descr = "size check test #1",
932 .raw_types = {
933 /* int */ /* [1] */
934 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
935 /* struct A { */ /* [2] */
936 BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 2), sizeof(int) * 2 - 1),
937 BTF_MEMBER_ENC(NAME_TBD, 1, 0), /* int m; */
938 BTF_MEMBER_ENC(NAME_TBD, 1, 32),/* int n; */
939 /* } */
940 BTF_END_RAW,
942 .str_sec = "\0A\0m\0n",
943 .str_sec_size = sizeof("\0A\0m\0n"),
944 .map_type = BPF_MAP_TYPE_ARRAY,
945 .map_name = "size_check1_map",
946 .key_size = sizeof(int),
947 .value_size = 1,
948 .key_type_id = 1,
949 .value_type_id = 2,
950 .max_entries = 4,
951 .btf_load_err = true,
952 .err_str = "Member exceeds struct_size",
955 /* Test member exeeds the size of struct
957 * struct A {
958 * int m;
959 * int n[2];
960 * };
963 .descr = "size check test #2",
964 .raw_types = {
965 /* int */ /* [1] */
966 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, sizeof(int)),
967 /* int[2] */ /* [2] */
968 BTF_TYPE_ARRAY_ENC(1, 1, 2),
969 /* struct A { */ /* [3] */
970 BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 2), sizeof(int) * 3 - 1),
971 BTF_MEMBER_ENC(NAME_TBD, 1, 0), /* int m; */
972 BTF_MEMBER_ENC(NAME_TBD, 2, 32),/* int n[2]; */
973 /* } */
974 BTF_END_RAW,
976 .str_sec = "\0A\0m\0n",
977 .str_sec_size = sizeof("\0A\0m\0n"),
978 .map_type = BPF_MAP_TYPE_ARRAY,
979 .map_name = "size_check2_map",
980 .key_size = sizeof(int),
981 .value_size = 1,
982 .key_type_id = 1,
983 .value_type_id = 3,
984 .max_entries = 4,
985 .btf_load_err = true,
986 .err_str = "Member exceeds struct_size",
989 /* Test member exeeds the size of struct
991 * struct A {
992 * int m;
993 * void *n;
994 * };
997 .descr = "size check test #3",
998 .raw_types = {
999 /* int */ /* [1] */
1000 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, sizeof(int)),
1001 /* void* */ /* [2] */
1002 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_PTR, 0, 0), 0),
1003 /* struct A { */ /* [3] */
1004 BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 2), sizeof(int) + sizeof(void *) - 1),
1005 BTF_MEMBER_ENC(NAME_TBD, 1, 0), /* int m; */
1006 BTF_MEMBER_ENC(NAME_TBD, 2, 32),/* void *n; */
1007 /* } */
1008 BTF_END_RAW,
1010 .str_sec = "\0A\0m\0n",
1011 .str_sec_size = sizeof("\0A\0m\0n"),
1012 .map_type = BPF_MAP_TYPE_ARRAY,
1013 .map_name = "size_check3_map",
1014 .key_size = sizeof(int),
1015 .value_size = 1,
1016 .key_type_id = 1,
1017 .value_type_id = 3,
1018 .max_entries = 4,
1019 .btf_load_err = true,
1020 .err_str = "Member exceeds struct_size",
1023 /* Test member exceeds the size of struct
1025 * enum E {
1026 * E0,
1027 * E1,
1028 * };
1030 * struct A {
1031 * int m;
1032 * enum E n;
1033 * };
1036 .descr = "size check test #4",
1037 .raw_types = {
1038 /* int */ /* [1] */
1039 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, sizeof(int)),
1040 /* enum E { */ /* [2] */
1041 BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_ENUM, 0, 2), sizeof(int)),
1042 BTF_ENUM_ENC(NAME_TBD, 0),
1043 BTF_ENUM_ENC(NAME_TBD, 1),
1044 /* } */
1045 /* struct A { */ /* [3] */
1046 BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 2), sizeof(int) * 2 - 1),
1047 BTF_MEMBER_ENC(NAME_TBD, 1, 0), /* int m; */
1048 BTF_MEMBER_ENC(NAME_TBD, 2, 32),/* enum E n; */
1049 /* } */
1050 BTF_END_RAW,
1052 .str_sec = "\0E\0E0\0E1\0A\0m\0n",
1053 .str_sec_size = sizeof("\0E\0E0\0E1\0A\0m\0n"),
1054 .map_type = BPF_MAP_TYPE_ARRAY,
1055 .map_name = "size_check4_map",
1056 .key_size = sizeof(int),
1057 .value_size = 1,
1058 .key_type_id = 1,
1059 .value_type_id = 3,
1060 .max_entries = 4,
1061 .btf_load_err = true,
1062 .err_str = "Member exceeds struct_size",
1065 /* typedef const void * const_void_ptr;
1066 * struct A {
1067 * const_void_ptr m;
1068 * };
1071 .descr = "void test #1",
1072 .raw_types = {
1073 /* int */ /* [1] */
1074 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
1075 /* const void */ /* [2] */
1076 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_CONST, 0, 0), 0),
1077 /* const void* */ /* [3] */
1078 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_PTR, 0, 0), 2),
1079 /* typedef const void * const_void_ptr */
1080 BTF_TYPEDEF_ENC(NAME_TBD, 3), /* [4] */
1081 /* struct A { */ /* [5] */
1082 BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 1), sizeof(void *)),
1083 /* const_void_ptr m; */
1084 BTF_MEMBER_ENC(NAME_TBD, 4, 0),
1085 /* } */
1086 BTF_END_RAW,
1088 .str_sec = "\0const_void_ptr\0A\0m",
1089 .str_sec_size = sizeof("\0const_void_ptr\0A\0m"),
1090 .map_type = BPF_MAP_TYPE_ARRAY,
1091 .map_name = "void_test1_map",
1092 .key_size = sizeof(int),
1093 .value_size = sizeof(void *),
1094 .key_type_id = 1,
1095 .value_type_id = 4,
1096 .max_entries = 4,
1099 /* struct A {
1100 * const void m;
1101 * };
1104 .descr = "void test #2",
1105 .raw_types = {
1106 /* int */ /* [1] */
1107 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
1108 /* const void */ /* [2] */
1109 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_CONST, 0, 0), 0),
1110 /* struct A { */ /* [3] */
1111 BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 1), 8),
1112 /* const void m; */
1113 BTF_MEMBER_ENC(NAME_TBD, 2, 0),
1114 /* } */
1115 BTF_END_RAW,
1117 .str_sec = "\0A\0m",
1118 .str_sec_size = sizeof("\0A\0m"),
1119 .map_type = BPF_MAP_TYPE_ARRAY,
1120 .map_name = "void_test2_map",
1121 .key_size = sizeof(int),
1122 .value_size = sizeof(void *),
1123 .key_type_id = 1,
1124 .value_type_id = 3,
1125 .max_entries = 4,
1126 .btf_load_err = true,
1127 .err_str = "Invalid member",
1130 /* typedef const void * const_void_ptr;
1131 * const_void_ptr[4]
1134 .descr = "void test #3",
1135 .raw_types = {
1136 /* int */ /* [1] */
1137 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
1138 /* const void */ /* [2] */
1139 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_CONST, 0, 0), 0),
1140 /* const void* */ /* [3] */
1141 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_PTR, 0, 0), 2),
1142 /* typedef const void * const_void_ptr */
1143 BTF_TYPEDEF_ENC(NAME_TBD, 3), /* [4] */
1144 /* const_void_ptr[4] */
1145 BTF_TYPE_ARRAY_ENC(4, 1, 4), /* [5] */
1146 BTF_END_RAW,
1148 .str_sec = "\0const_void_ptr",
1149 .str_sec_size = sizeof("\0const_void_ptr"),
1150 .map_type = BPF_MAP_TYPE_ARRAY,
1151 .map_name = "void_test3_map",
1152 .key_size = sizeof(int),
1153 .value_size = sizeof(void *) * 4,
1154 .key_type_id = 1,
1155 .value_type_id = 5,
1156 .max_entries = 4,
1159 /* const void[4] */
1161 .descr = "void test #4",
1162 .raw_types = {
1163 /* int */ /* [1] */
1164 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
1165 /* const void */ /* [2] */
1166 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_CONST, 0, 0), 0),
1167 /* const void[4] */ /* [3] */
1168 BTF_TYPE_ARRAY_ENC(2, 1, 4),
1169 BTF_END_RAW,
1171 .str_sec = "\0A\0m",
1172 .str_sec_size = sizeof("\0A\0m"),
1173 .map_type = BPF_MAP_TYPE_ARRAY,
1174 .map_name = "void_test4_map",
1175 .key_size = sizeof(int),
1176 .value_size = sizeof(void *) * 4,
1177 .key_type_id = 1,
1178 .value_type_id = 3,
1179 .max_entries = 4,
1180 .btf_load_err = true,
1181 .err_str = "Invalid elem",
1184 /* Array_A <------------------+
1185 * elem_type == Array_B |
1186 * | |
1187 * | |
1188 * Array_B <-------- + |
1189 * elem_type == Array A --+
1192 .descr = "loop test #1",
1193 .raw_types = {
1194 /* int */ /* [1] */
1195 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
1196 /* Array_A */ /* [2] */
1197 BTF_TYPE_ARRAY_ENC(3, 1, 8),
1198 /* Array_B */ /* [3] */
1199 BTF_TYPE_ARRAY_ENC(2, 1, 8),
1200 BTF_END_RAW,
1202 .str_sec = "",
1203 .str_sec_size = sizeof(""),
1204 .map_type = BPF_MAP_TYPE_ARRAY,
1205 .map_name = "loop_test1_map",
1206 .key_size = sizeof(int),
1207 .value_size = sizeof(sizeof(int) * 8),
1208 .key_type_id = 1,
1209 .value_type_id = 2,
1210 .max_entries = 4,
1211 .btf_load_err = true,
1212 .err_str = "Loop detected",
1215 /* typedef is _before_ the BTF type of Array_A and Array_B
1217 * typedef Array_B int_array;
1219 * Array_A <------------------+
1220 * elem_type == int_array |
1221 * | |
1222 * | |
1223 * Array_B <-------- + |
1224 * elem_type == Array_A --+
1227 .descr = "loop test #2",
1228 .raw_types = {
1229 /* int */
1230 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
1231 /* typedef Array_B int_array */
1232 BTF_TYPEDEF_ENC(1, 4), /* [2] */
1233 /* Array_A */
1234 BTF_TYPE_ARRAY_ENC(2, 1, 8), /* [3] */
1235 /* Array_B */
1236 BTF_TYPE_ARRAY_ENC(3, 1, 8), /* [4] */
1237 BTF_END_RAW,
1239 .str_sec = "\0int_array\0",
1240 .str_sec_size = sizeof("\0int_array"),
1241 .map_type = BPF_MAP_TYPE_ARRAY,
1242 .map_name = "loop_test2_map",
1243 .key_size = sizeof(int),
1244 .value_size = sizeof(sizeof(int) * 8),
1245 .key_type_id = 1,
1246 .value_type_id = 2,
1247 .max_entries = 4,
1248 .btf_load_err = true,
1249 .err_str = "Loop detected",
1252 /* Array_A <------------------+
1253 * elem_type == Array_B |
1254 * | |
1255 * | |
1256 * Array_B <-------- + |
1257 * elem_type == Array_A --+
1260 .descr = "loop test #3",
1261 .raw_types = {
1262 /* int */ /* [1] */
1263 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
1264 /* Array_A */ /* [2] */
1265 BTF_TYPE_ARRAY_ENC(3, 1, 8),
1266 /* Array_B */ /* [3] */
1267 BTF_TYPE_ARRAY_ENC(2, 1, 8),
1268 BTF_END_RAW,
1270 .str_sec = "",
1271 .str_sec_size = sizeof(""),
1272 .map_type = BPF_MAP_TYPE_ARRAY,
1273 .map_name = "loop_test3_map",
1274 .key_size = sizeof(int),
1275 .value_size = sizeof(sizeof(int) * 8),
1276 .key_type_id = 1,
1277 .value_type_id = 2,
1278 .max_entries = 4,
1279 .btf_load_err = true,
1280 .err_str = "Loop detected",
1283 /* typedef is _between_ the BTF type of Array_A and Array_B
1285 * typedef Array_B int_array;
1287 * Array_A <------------------+
1288 * elem_type == int_array |
1289 * | |
1290 * | |
1291 * Array_B <-------- + |
1292 * elem_type == Array_A --+
1295 .descr = "loop test #4",
1296 .raw_types = {
1297 /* int */ /* [1] */
1298 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
1299 /* Array_A */ /* [2] */
1300 BTF_TYPE_ARRAY_ENC(3, 1, 8),
1301 /* typedef Array_B int_array */ /* [3] */
1302 BTF_TYPEDEF_ENC(NAME_TBD, 4),
1303 /* Array_B */ /* [4] */
1304 BTF_TYPE_ARRAY_ENC(2, 1, 8),
1305 BTF_END_RAW,
1307 .str_sec = "\0int_array\0",
1308 .str_sec_size = sizeof("\0int_array"),
1309 .map_type = BPF_MAP_TYPE_ARRAY,
1310 .map_name = "loop_test4_map",
1311 .key_size = sizeof(int),
1312 .value_size = sizeof(sizeof(int) * 8),
1313 .key_type_id = 1,
1314 .value_type_id = 2,
1315 .max_entries = 4,
1316 .btf_load_err = true,
1317 .err_str = "Loop detected",
1320 /* typedef struct B Struct_B
1322 * struct A {
1323 * int x;
1324 * Struct_B y;
1325 * };
1327 * struct B {
1328 * int x;
1329 * struct A y;
1330 * };
1333 .descr = "loop test #5",
1334 .raw_types = {
1335 /* int */
1336 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
1337 /* struct A */ /* [2] */
1338 BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 2), 8),
1339 BTF_MEMBER_ENC(NAME_TBD, 1, 0), /* int x; */
1340 BTF_MEMBER_ENC(NAME_TBD, 3, 32),/* Struct_B y; */
1341 /* typedef struct B Struct_B */
1342 BTF_TYPEDEF_ENC(NAME_TBD, 4), /* [3] */
1343 /* struct B */ /* [4] */
1344 BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 2), 8),
1345 BTF_MEMBER_ENC(NAME_TBD, 1, 0), /* int x; */
1346 BTF_MEMBER_ENC(NAME_TBD, 2, 32),/* struct A y; */
1347 BTF_END_RAW,
1349 .str_sec = "\0A\0x\0y\0Struct_B\0B\0x\0y",
1350 .str_sec_size = sizeof("\0A\0x\0y\0Struct_B\0B\0x\0y"),
1351 .map_type = BPF_MAP_TYPE_ARRAY,
1352 .map_name = "loop_test5_map",
1353 .key_size = sizeof(int),
1354 .value_size = 8,
1355 .key_type_id = 1,
1356 .value_type_id = 2,
1357 .max_entries = 4,
1358 .btf_load_err = true,
1359 .err_str = "Loop detected",
1362 /* struct A {
1363 * int x;
1364 * struct A array_a[4];
1365 * };
1368 .descr = "loop test #6",
1369 .raw_types = {
1370 /* int */
1371 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
1372 BTF_TYPE_ARRAY_ENC(3, 1, 4), /* [2] */
1373 /* struct A */ /* [3] */
1374 BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 2), 8),
1375 BTF_MEMBER_ENC(NAME_TBD, 1, 0), /* int x; */
1376 BTF_MEMBER_ENC(NAME_TBD, 2, 32),/* struct A array_a[4]; */
1377 BTF_END_RAW,
1379 .str_sec = "\0A\0x\0y",
1380 .str_sec_size = sizeof("\0A\0x\0y"),
1381 .map_type = BPF_MAP_TYPE_ARRAY,
1382 .map_name = "loop_test6_map",
1383 .key_size = sizeof(int),
1384 .value_size = 8,
1385 .key_type_id = 1,
1386 .value_type_id = 2,
1387 .max_entries = 4,
1388 .btf_load_err = true,
1389 .err_str = "Loop detected",
1393 .descr = "loop test #7",
1394 .raw_types = {
1395 /* int */ /* [1] */
1396 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
1397 /* struct A { */ /* [2] */
1398 BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 1), sizeof(void *)),
1399 /* const void *m; */
1400 BTF_MEMBER_ENC(NAME_TBD, 3, 0),
1401 /* CONST type_id=3 */ /* [3] */
1402 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_CONST, 0, 0), 4),
1403 /* PTR type_id=2 */ /* [4] */
1404 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_PTR, 0, 0), 3),
1405 BTF_END_RAW,
1407 .str_sec = "\0A\0m",
1408 .str_sec_size = sizeof("\0A\0m"),
1409 .map_type = BPF_MAP_TYPE_ARRAY,
1410 .map_name = "loop_test7_map",
1411 .key_size = sizeof(int),
1412 .value_size = sizeof(void *),
1413 .key_type_id = 1,
1414 .value_type_id = 2,
1415 .max_entries = 4,
1416 .btf_load_err = true,
1417 .err_str = "Loop detected",
1421 .descr = "loop test #8",
1422 .raw_types = {
1423 /* int */ /* [1] */
1424 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
1425 /* struct A { */ /* [2] */
1426 BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 1), sizeof(void *)),
1427 /* const void *m; */
1428 BTF_MEMBER_ENC(NAME_TBD, 4, 0),
1429 /* struct B { */ /* [3] */
1430 BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 1), sizeof(void *)),
1431 /* const void *n; */
1432 BTF_MEMBER_ENC(NAME_TBD, 6, 0),
1433 /* CONST type_id=5 */ /* [4] */
1434 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_CONST, 0, 0), 5),
1435 /* PTR type_id=6 */ /* [5] */
1436 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_PTR, 0, 0), 6),
1437 /* CONST type_id=7 */ /* [6] */
1438 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_CONST, 0, 0), 7),
1439 /* PTR type_id=4 */ /* [7] */
1440 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_PTR, 0, 0), 4),
1441 BTF_END_RAW,
1443 .str_sec = "\0A\0m\0B\0n",
1444 .str_sec_size = sizeof("\0A\0m\0B\0n"),
1445 .map_type = BPF_MAP_TYPE_ARRAY,
1446 .map_name = "loop_test8_map",
1447 .key_size = sizeof(int),
1448 .value_size = sizeof(void *),
1449 .key_type_id = 1,
1450 .value_type_id = 2,
1451 .max_entries = 4,
1452 .btf_load_err = true,
1453 .err_str = "Loop detected",
1457 .descr = "string section does not end with null",
1458 .raw_types = {
1459 /* int */ /* [1] */
1460 BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),
1461 BTF_END_RAW,
1463 .str_sec = "\0int",
1464 .str_sec_size = sizeof("\0int") - 1,
1465 .map_type = BPF_MAP_TYPE_ARRAY,
1466 .map_name = "hdr_test_map",
1467 .key_size = sizeof(int),
1468 .value_size = sizeof(int),
1469 .key_type_id = 1,
1470 .value_type_id = 1,
1471 .max_entries = 4,
1472 .btf_load_err = true,
1473 .err_str = "Invalid string section",
1477 .descr = "empty string section",
1478 .raw_types = {
1479 /* int */ /* [1] */
1480 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
1481 BTF_END_RAW,
1483 .str_sec = "",
1484 .str_sec_size = 0,
1485 .map_type = BPF_MAP_TYPE_ARRAY,
1486 .map_name = "hdr_test_map",
1487 .key_size = sizeof(int),
1488 .value_size = sizeof(int),
1489 .key_type_id = 1,
1490 .value_type_id = 1,
1491 .max_entries = 4,
1492 .btf_load_err = true,
1493 .err_str = "Invalid string section",
1497 .descr = "empty type section",
1498 .raw_types = {
1499 BTF_END_RAW,
1501 .str_sec = "\0int",
1502 .str_sec_size = sizeof("\0int"),
1503 .map_type = BPF_MAP_TYPE_ARRAY,
1504 .map_name = "hdr_test_map",
1505 .key_size = sizeof(int),
1506 .value_size = sizeof(int),
1507 .key_type_id = 1,
1508 .value_type_id = 1,
1509 .max_entries = 4,
1510 .btf_load_err = true,
1511 .err_str = "No type found",
1515 .descr = "btf_header test. Longer hdr_len",
1516 .raw_types = {
1517 /* int */ /* [1] */
1518 BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),
1519 BTF_END_RAW,
1521 .str_sec = "\0int",
1522 .str_sec_size = sizeof("\0int"),
1523 .map_type = BPF_MAP_TYPE_ARRAY,
1524 .map_name = "hdr_test_map",
1525 .key_size = sizeof(int),
1526 .value_size = sizeof(int),
1527 .key_type_id = 1,
1528 .value_type_id = 1,
1529 .max_entries = 4,
1530 .btf_load_err = true,
1531 .hdr_len_delta = 4,
1532 .err_str = "Unsupported btf_header",
1536 .descr = "btf_header test. Gap between hdr and type",
1537 .raw_types = {
1538 /* int */ /* [1] */
1539 BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),
1540 BTF_END_RAW,
1542 .str_sec = "\0int",
1543 .str_sec_size = sizeof("\0int"),
1544 .map_type = BPF_MAP_TYPE_ARRAY,
1545 .map_name = "hdr_test_map",
1546 .key_size = sizeof(int),
1547 .value_size = sizeof(int),
1548 .key_type_id = 1,
1549 .value_type_id = 1,
1550 .max_entries = 4,
1551 .btf_load_err = true,
1552 .type_off_delta = 4,
1553 .err_str = "Unsupported section found",
1557 .descr = "btf_header test. Gap between type and str",
1558 .raw_types = {
1559 /* int */ /* [1] */
1560 BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),
1561 BTF_END_RAW,
1563 .str_sec = "\0int",
1564 .str_sec_size = sizeof("\0int"),
1565 .map_type = BPF_MAP_TYPE_ARRAY,
1566 .map_name = "hdr_test_map",
1567 .key_size = sizeof(int),
1568 .value_size = sizeof(int),
1569 .key_type_id = 1,
1570 .value_type_id = 1,
1571 .max_entries = 4,
1572 .btf_load_err = true,
1573 .str_off_delta = 4,
1574 .err_str = "Unsupported section found",
1578 .descr = "btf_header test. Overlap between type and str",
1579 .raw_types = {
1580 /* int */ /* [1] */
1581 BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),
1582 BTF_END_RAW,
1584 .str_sec = "\0int",
1585 .str_sec_size = sizeof("\0int"),
1586 .map_type = BPF_MAP_TYPE_ARRAY,
1587 .map_name = "hdr_test_map",
1588 .key_size = sizeof(int),
1589 .value_size = sizeof(int),
1590 .key_type_id = 1,
1591 .value_type_id = 1,
1592 .max_entries = 4,
1593 .btf_load_err = true,
1594 .str_off_delta = -4,
1595 .err_str = "Section overlap found",
1599 .descr = "btf_header test. Larger BTF size",
1600 .raw_types = {
1601 /* int */ /* [1] */
1602 BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),
1603 BTF_END_RAW,
1605 .str_sec = "\0int",
1606 .str_sec_size = sizeof("\0int"),
1607 .map_type = BPF_MAP_TYPE_ARRAY,
1608 .map_name = "hdr_test_map",
1609 .key_size = sizeof(int),
1610 .value_size = sizeof(int),
1611 .key_type_id = 1,
1612 .value_type_id = 1,
1613 .max_entries = 4,
1614 .btf_load_err = true,
1615 .str_len_delta = -4,
1616 .err_str = "Unsupported section found",
1620 .descr = "btf_header test. Smaller BTF size",
1621 .raw_types = {
1622 /* int */ /* [1] */
1623 BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),
1624 BTF_END_RAW,
1626 .str_sec = "\0int",
1627 .str_sec_size = sizeof("\0int"),
1628 .map_type = BPF_MAP_TYPE_ARRAY,
1629 .map_name = "hdr_test_map",
1630 .key_size = sizeof(int),
1631 .value_size = sizeof(int),
1632 .key_type_id = 1,
1633 .value_type_id = 1,
1634 .max_entries = 4,
1635 .btf_load_err = true,
1636 .str_len_delta = 4,
1637 .err_str = "Total section length too long",
1641 .descr = "array test. index_type/elem_type \"int\"",
1642 .raw_types = {
1643 /* int */ /* [1] */
1644 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
1645 /* int[16] */ /* [2] */
1646 BTF_TYPE_ARRAY_ENC(1, 1, 16),
1647 BTF_END_RAW,
1649 .str_sec = "",
1650 .str_sec_size = sizeof(""),
1651 .map_type = BPF_MAP_TYPE_ARRAY,
1652 .map_name = "array_test_map",
1653 .key_size = sizeof(int),
1654 .value_size = sizeof(int),
1655 .key_type_id = 1,
1656 .value_type_id = 1,
1657 .max_entries = 4,
1661 .descr = "array test. index_type/elem_type \"const int\"",
1662 .raw_types = {
1663 /* int */ /* [1] */
1664 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
1665 /* int[16] */ /* [2] */
1666 BTF_TYPE_ARRAY_ENC(3, 3, 16),
1667 /* CONST type_id=1 */ /* [3] */
1668 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_CONST, 0, 0), 1),
1669 BTF_END_RAW,
1671 .str_sec = "",
1672 .str_sec_size = sizeof(""),
1673 .map_type = BPF_MAP_TYPE_ARRAY,
1674 .map_name = "array_test_map",
1675 .key_size = sizeof(int),
1676 .value_size = sizeof(int),
1677 .key_type_id = 1,
1678 .value_type_id = 1,
1679 .max_entries = 4,
1683 .descr = "array test. index_type \"const int:31\"",
1684 .raw_types = {
1685 /* int */ /* [1] */
1686 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
1687 /* int:31 */ /* [2] */
1688 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 31, 4),
1689 /* int[16] */ /* [3] */
1690 BTF_TYPE_ARRAY_ENC(1, 4, 16),
1691 /* CONST type_id=2 */ /* [4] */
1692 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_CONST, 0, 0), 2),
1693 BTF_END_RAW,
1695 .str_sec = "",
1696 .str_sec_size = sizeof(""),
1697 .map_type = BPF_MAP_TYPE_ARRAY,
1698 .map_name = "array_test_map",
1699 .key_size = sizeof(int),
1700 .value_size = sizeof(int),
1701 .key_type_id = 1,
1702 .value_type_id = 1,
1703 .max_entries = 4,
1704 .btf_load_err = true,
1705 .err_str = "Invalid index",
1709 .descr = "array test. elem_type \"const int:31\"",
1710 .raw_types = {
1711 /* int */ /* [1] */
1712 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
1713 /* int:31 */ /* [2] */
1714 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 31, 4),
1715 /* int[16] */ /* [3] */
1716 BTF_TYPE_ARRAY_ENC(4, 1, 16),
1717 /* CONST type_id=2 */ /* [4] */
1718 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_CONST, 0, 0), 2),
1719 BTF_END_RAW,
1721 .str_sec = "",
1722 .str_sec_size = sizeof(""),
1723 .map_type = BPF_MAP_TYPE_ARRAY,
1724 .map_name = "array_test_map",
1725 .key_size = sizeof(int),
1726 .value_size = sizeof(int),
1727 .key_type_id = 1,
1728 .value_type_id = 1,
1729 .max_entries = 4,
1730 .btf_load_err = true,
1731 .err_str = "Invalid array of int",
1735 .descr = "array test. index_type \"void\"",
1736 .raw_types = {
1737 /* int */ /* [1] */
1738 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
1739 /* int[16] */ /* [2] */
1740 BTF_TYPE_ARRAY_ENC(1, 0, 16),
1741 BTF_END_RAW,
1743 .str_sec = "",
1744 .str_sec_size = sizeof(""),
1745 .map_type = BPF_MAP_TYPE_ARRAY,
1746 .map_name = "array_test_map",
1747 .key_size = sizeof(int),
1748 .value_size = sizeof(int),
1749 .key_type_id = 1,
1750 .value_type_id = 1,
1751 .max_entries = 4,
1752 .btf_load_err = true,
1753 .err_str = "Invalid index",
1757 .descr = "array test. index_type \"const void\"",
1758 .raw_types = {
1759 /* int */ /* [1] */
1760 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
1761 /* int[16] */ /* [2] */
1762 BTF_TYPE_ARRAY_ENC(1, 3, 16),
1763 /* CONST type_id=0 (void) */ /* [3] */
1764 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_CONST, 0, 0), 0),
1765 BTF_END_RAW,
1767 .str_sec = "",
1768 .str_sec_size = sizeof(""),
1769 .map_type = BPF_MAP_TYPE_ARRAY,
1770 .map_name = "array_test_map",
1771 .key_size = sizeof(int),
1772 .value_size = sizeof(int),
1773 .key_type_id = 1,
1774 .value_type_id = 1,
1775 .max_entries = 4,
1776 .btf_load_err = true,
1777 .err_str = "Invalid index",
1781 .descr = "array test. elem_type \"const void\"",
1782 .raw_types = {
1783 /* int */ /* [1] */
1784 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
1785 /* int[16] */ /* [2] */
1786 BTF_TYPE_ARRAY_ENC(3, 1, 16),
1787 /* CONST type_id=0 (void) */ /* [3] */
1788 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_CONST, 0, 0), 0),
1789 BTF_END_RAW,
1791 .str_sec = "",
1792 .str_sec_size = sizeof(""),
1793 .map_type = BPF_MAP_TYPE_ARRAY,
1794 .map_name = "array_test_map",
1795 .key_size = sizeof(int),
1796 .value_size = sizeof(int),
1797 .key_type_id = 1,
1798 .value_type_id = 1,
1799 .max_entries = 4,
1800 .btf_load_err = true,
1801 .err_str = "Invalid elem",
1805 .descr = "array test. elem_type \"const void *\"",
1806 .raw_types = {
1807 /* int */ /* [1] */
1808 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
1809 /* const void *[16] */ /* [2] */
1810 BTF_TYPE_ARRAY_ENC(3, 1, 16),
1811 /* CONST type_id=4 */ /* [3] */
1812 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_CONST, 0, 0), 4),
1813 /* void* */ /* [4] */
1814 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_PTR, 0, 0), 0),
1815 BTF_END_RAW,
1817 .str_sec = "",
1818 .str_sec_size = sizeof(""),
1819 .map_type = BPF_MAP_TYPE_ARRAY,
1820 .map_name = "array_test_map",
1821 .key_size = sizeof(int),
1822 .value_size = sizeof(int),
1823 .key_type_id = 1,
1824 .value_type_id = 1,
1825 .max_entries = 4,
1829 .descr = "array test. index_type \"const void *\"",
1830 .raw_types = {
1831 /* int */ /* [1] */
1832 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
1833 /* const void *[16] */ /* [2] */
1834 BTF_TYPE_ARRAY_ENC(3, 3, 16),
1835 /* CONST type_id=4 */ /* [3] */
1836 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_CONST, 0, 0), 4),
1837 /* void* */ /* [4] */
1838 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_PTR, 0, 0), 0),
1839 BTF_END_RAW,
1841 .str_sec = "",
1842 .str_sec_size = sizeof(""),
1843 .map_type = BPF_MAP_TYPE_ARRAY,
1844 .map_name = "array_test_map",
1845 .key_size = sizeof(int),
1846 .value_size = sizeof(int),
1847 .key_type_id = 1,
1848 .value_type_id = 1,
1849 .max_entries = 4,
1850 .btf_load_err = true,
1851 .err_str = "Invalid index",
1855 .descr = "array test. t->size != 0\"",
1856 .raw_types = {
1857 /* int */ /* [1] */
1858 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
1859 /* int[16] */ /* [2] */
1860 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_ARRAY, 0, 0), 1),
1861 BTF_ARRAY_ENC(1, 1, 16),
1862 BTF_END_RAW,
1864 .str_sec = "",
1865 .str_sec_size = sizeof(""),
1866 .map_type = BPF_MAP_TYPE_ARRAY,
1867 .map_name = "array_test_map",
1868 .key_size = sizeof(int),
1869 .value_size = sizeof(int),
1870 .key_type_id = 1,
1871 .value_type_id = 1,
1872 .max_entries = 4,
1873 .btf_load_err = true,
1874 .err_str = "size != 0",
1878 .descr = "int test. invalid int_data",
1879 .raw_types = {
1880 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_INT, 0, 0), 4),
1881 0x10000000,
1882 BTF_END_RAW,
1884 .str_sec = "",
1885 .str_sec_size = sizeof(""),
1886 .map_type = BPF_MAP_TYPE_ARRAY,
1887 .map_name = "array_test_map",
1888 .key_size = sizeof(int),
1889 .value_size = sizeof(int),
1890 .key_type_id = 1,
1891 .value_type_id = 1,
1892 .max_entries = 4,
1893 .btf_load_err = true,
1894 .err_str = "Invalid int_data",
1898 .descr = "invalid BTF_INFO",
1899 .raw_types = {
1900 /* int */ /* [1] */
1901 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
1902 BTF_TYPE_ENC(0, 0x10000000, 4),
1903 BTF_END_RAW,
1905 .str_sec = "",
1906 .str_sec_size = sizeof(""),
1907 .map_type = BPF_MAP_TYPE_ARRAY,
1908 .map_name = "array_test_map",
1909 .key_size = sizeof(int),
1910 .value_size = sizeof(int),
1911 .key_type_id = 1,
1912 .value_type_id = 1,
1913 .max_entries = 4,
1914 .btf_load_err = true,
1915 .err_str = "Invalid btf_info",
1919 .descr = "fwd test. t->type != 0\"",
1920 .raw_types = {
1921 /* int */ /* [1] */
1922 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
1923 /* fwd type */ /* [2] */
1924 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_FWD, 0, 0), 1),
1925 BTF_END_RAW,
1927 .str_sec = "",
1928 .str_sec_size = sizeof(""),
1929 .map_type = BPF_MAP_TYPE_ARRAY,
1930 .map_name = "fwd_test_map",
1931 .key_size = sizeof(int),
1932 .value_size = sizeof(int),
1933 .key_type_id = 1,
1934 .value_type_id = 1,
1935 .max_entries = 4,
1936 .btf_load_err = true,
1937 .err_str = "type != 0",
1941 .descr = "typedef (invalid name, name_off = 0)",
1942 .raw_types = {
1943 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
1944 BTF_TYPEDEF_ENC(0, 1), /* [2] */
1945 BTF_END_RAW,
1947 .str_sec = "\0__int",
1948 .str_sec_size = sizeof("\0__int"),
1949 .map_type = BPF_MAP_TYPE_ARRAY,
1950 .map_name = "typedef_check_btf",
1951 .key_size = sizeof(int),
1952 .value_size = sizeof(int),
1953 .key_type_id = 1,
1954 .value_type_id = 1,
1955 .max_entries = 4,
1956 .btf_load_err = true,
1957 .err_str = "Invalid name",
1961 .descr = "typedef (invalid name, invalid identifier)",
1962 .raw_types = {
1963 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
1964 BTF_TYPEDEF_ENC(NAME_TBD, 1), /* [2] */
1965 BTF_END_RAW,
1967 .str_sec = "\0__!int",
1968 .str_sec_size = sizeof("\0__!int"),
1969 .map_type = BPF_MAP_TYPE_ARRAY,
1970 .map_name = "typedef_check_btf",
1971 .key_size = sizeof(int),
1972 .value_size = sizeof(int),
1973 .key_type_id = 1,
1974 .value_type_id = 1,
1975 .max_entries = 4,
1976 .btf_load_err = true,
1977 .err_str = "Invalid name",
1981 .descr = "ptr type (invalid name, name_off <> 0)",
1982 .raw_types = {
1983 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
1984 BTF_TYPE_ENC(NAME_TBD,
1985 BTF_INFO_ENC(BTF_KIND_PTR, 0, 0), 1), /* [2] */
1986 BTF_END_RAW,
1988 .str_sec = "\0__int",
1989 .str_sec_size = sizeof("\0__int"),
1990 .map_type = BPF_MAP_TYPE_ARRAY,
1991 .map_name = "ptr_type_check_btf",
1992 .key_size = sizeof(int),
1993 .value_size = sizeof(int),
1994 .key_type_id = 1,
1995 .value_type_id = 1,
1996 .max_entries = 4,
1997 .btf_load_err = true,
1998 .err_str = "Invalid name",
2002 .descr = "volatile type (invalid name, name_off <> 0)",
2003 .raw_types = {
2004 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
2005 BTF_TYPE_ENC(NAME_TBD,
2006 BTF_INFO_ENC(BTF_KIND_VOLATILE, 0, 0), 1), /* [2] */
2007 BTF_END_RAW,
2009 .str_sec = "\0__int",
2010 .str_sec_size = sizeof("\0__int"),
2011 .map_type = BPF_MAP_TYPE_ARRAY,
2012 .map_name = "volatile_type_check_btf",
2013 .key_size = sizeof(int),
2014 .value_size = sizeof(int),
2015 .key_type_id = 1,
2016 .value_type_id = 1,
2017 .max_entries = 4,
2018 .btf_load_err = true,
2019 .err_str = "Invalid name",
2023 .descr = "const type (invalid name, name_off <> 0)",
2024 .raw_types = {
2025 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
2026 BTF_TYPE_ENC(NAME_TBD,
2027 BTF_INFO_ENC(BTF_KIND_CONST, 0, 0), 1), /* [2] */
2028 BTF_END_RAW,
2030 .str_sec = "\0__int",
2031 .str_sec_size = sizeof("\0__int"),
2032 .map_type = BPF_MAP_TYPE_ARRAY,
2033 .map_name = "const_type_check_btf",
2034 .key_size = sizeof(int),
2035 .value_size = sizeof(int),
2036 .key_type_id = 1,
2037 .value_type_id = 1,
2038 .max_entries = 4,
2039 .btf_load_err = true,
2040 .err_str = "Invalid name",
2044 .descr = "restrict type (invalid name, name_off <> 0)",
2045 .raw_types = {
2046 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
2047 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_PTR, 0, 0), 1), /* [2] */
2048 BTF_TYPE_ENC(NAME_TBD,
2049 BTF_INFO_ENC(BTF_KIND_RESTRICT, 0, 0), 2), /* [3] */
2050 BTF_END_RAW,
2052 .str_sec = "\0__int",
2053 .str_sec_size = sizeof("\0__int"),
2054 .map_type = BPF_MAP_TYPE_ARRAY,
2055 .map_name = "restrict_type_check_btf",
2056 .key_size = sizeof(int),
2057 .value_size = sizeof(int),
2058 .key_type_id = 1,
2059 .value_type_id = 1,
2060 .max_entries = 4,
2061 .btf_load_err = true,
2062 .err_str = "Invalid name",
2066 .descr = "fwd type (invalid name, name_off = 0)",
2067 .raw_types = {
2068 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
2069 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_FWD, 0, 0), 0), /* [2] */
2070 BTF_END_RAW,
2072 .str_sec = "\0__skb",
2073 .str_sec_size = sizeof("\0__skb"),
2074 .map_type = BPF_MAP_TYPE_ARRAY,
2075 .map_name = "fwd_type_check_btf",
2076 .key_size = sizeof(int),
2077 .value_size = sizeof(int),
2078 .key_type_id = 1,
2079 .value_type_id = 1,
2080 .max_entries = 4,
2081 .btf_load_err = true,
2082 .err_str = "Invalid name",
2086 .descr = "fwd type (invalid name, invalid identifier)",
2087 .raw_types = {
2088 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
2089 BTF_TYPE_ENC(NAME_TBD,
2090 BTF_INFO_ENC(BTF_KIND_FWD, 0, 0), 0), /* [2] */
2091 BTF_END_RAW,
2093 .str_sec = "\0__!skb",
2094 .str_sec_size = sizeof("\0__!skb"),
2095 .map_type = BPF_MAP_TYPE_ARRAY,
2096 .map_name = "fwd_type_check_btf",
2097 .key_size = sizeof(int),
2098 .value_size = sizeof(int),
2099 .key_type_id = 1,
2100 .value_type_id = 1,
2101 .max_entries = 4,
2102 .btf_load_err = true,
2103 .err_str = "Invalid name",
2107 .descr = "array type (invalid name, name_off <> 0)",
2108 .raw_types = {
2109 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
2110 BTF_TYPE_ENC(NAME_TBD,
2111 BTF_INFO_ENC(BTF_KIND_ARRAY, 0, 0), 0), /* [2] */
2112 BTF_ARRAY_ENC(1, 1, 4),
2113 BTF_END_RAW,
2115 .str_sec = "\0__skb",
2116 .str_sec_size = sizeof("\0__skb"),
2117 .map_type = BPF_MAP_TYPE_ARRAY,
2118 .map_name = "array_type_check_btf",
2119 .key_size = sizeof(int),
2120 .value_size = sizeof(int),
2121 .key_type_id = 1,
2122 .value_type_id = 1,
2123 .max_entries = 4,
2124 .btf_load_err = true,
2125 .err_str = "Invalid name",
2129 .descr = "struct type (name_off = 0)",
2130 .raw_types = {
2131 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
2132 BTF_TYPE_ENC(0,
2133 BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 1), 4), /* [2] */
2134 BTF_MEMBER_ENC(NAME_TBD, 1, 0),
2135 BTF_END_RAW,
2137 .str_sec = "\0A",
2138 .str_sec_size = sizeof("\0A"),
2139 .map_type = BPF_MAP_TYPE_ARRAY,
2140 .map_name = "struct_type_check_btf",
2141 .key_size = sizeof(int),
2142 .value_size = sizeof(int),
2143 .key_type_id = 1,
2144 .value_type_id = 1,
2145 .max_entries = 4,
2149 .descr = "struct type (invalid name, invalid identifier)",
2150 .raw_types = {
2151 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
2152 BTF_TYPE_ENC(NAME_TBD,
2153 BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 1), 4), /* [2] */
2154 BTF_MEMBER_ENC(NAME_TBD, 1, 0),
2155 BTF_END_RAW,
2157 .str_sec = "\0A!\0B",
2158 .str_sec_size = sizeof("\0A!\0B"),
2159 .map_type = BPF_MAP_TYPE_ARRAY,
2160 .map_name = "struct_type_check_btf",
2161 .key_size = sizeof(int),
2162 .value_size = sizeof(int),
2163 .key_type_id = 1,
2164 .value_type_id = 1,
2165 .max_entries = 4,
2166 .btf_load_err = true,
2167 .err_str = "Invalid name",
2171 .descr = "struct member (name_off = 0)",
2172 .raw_types = {
2173 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
2174 BTF_TYPE_ENC(0,
2175 BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 1), 4), /* [2] */
2176 BTF_MEMBER_ENC(NAME_TBD, 1, 0),
2177 BTF_END_RAW,
2179 .str_sec = "\0A",
2180 .str_sec_size = sizeof("\0A"),
2181 .map_type = BPF_MAP_TYPE_ARRAY,
2182 .map_name = "struct_type_check_btf",
2183 .key_size = sizeof(int),
2184 .value_size = sizeof(int),
2185 .key_type_id = 1,
2186 .value_type_id = 1,
2187 .max_entries = 4,
2191 .descr = "struct member (invalid name, invalid identifier)",
2192 .raw_types = {
2193 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
2194 BTF_TYPE_ENC(NAME_TBD,
2195 BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 1), 4), /* [2] */
2196 BTF_MEMBER_ENC(NAME_TBD, 1, 0),
2197 BTF_END_RAW,
2199 .str_sec = "\0A\0B*",
2200 .str_sec_size = sizeof("\0A\0B*"),
2201 .map_type = BPF_MAP_TYPE_ARRAY,
2202 .map_name = "struct_type_check_btf",
2203 .key_size = sizeof(int),
2204 .value_size = sizeof(int),
2205 .key_type_id = 1,
2206 .value_type_id = 1,
2207 .max_entries = 4,
2208 .btf_load_err = true,
2209 .err_str = "Invalid name",
2213 .descr = "enum type (name_off = 0)",
2214 .raw_types = {
2215 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
2216 BTF_TYPE_ENC(0,
2217 BTF_INFO_ENC(BTF_KIND_ENUM, 0, 1),
2218 sizeof(int)), /* [2] */
2219 BTF_ENUM_ENC(NAME_TBD, 0),
2220 BTF_END_RAW,
2222 .str_sec = "\0A\0B",
2223 .str_sec_size = sizeof("\0A\0B"),
2224 .map_type = BPF_MAP_TYPE_ARRAY,
2225 .map_name = "enum_type_check_btf",
2226 .key_size = sizeof(int),
2227 .value_size = sizeof(int),
2228 .key_type_id = 1,
2229 .value_type_id = 1,
2230 .max_entries = 4,
2234 .descr = "enum type (invalid name, invalid identifier)",
2235 .raw_types = {
2236 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
2237 BTF_TYPE_ENC(NAME_TBD,
2238 BTF_INFO_ENC(BTF_KIND_ENUM, 0, 1),
2239 sizeof(int)), /* [2] */
2240 BTF_ENUM_ENC(NAME_TBD, 0),
2241 BTF_END_RAW,
2243 .str_sec = "\0A!\0B",
2244 .str_sec_size = sizeof("\0A!\0B"),
2245 .map_type = BPF_MAP_TYPE_ARRAY,
2246 .map_name = "enum_type_check_btf",
2247 .key_size = sizeof(int),
2248 .value_size = sizeof(int),
2249 .key_type_id = 1,
2250 .value_type_id = 1,
2251 .max_entries = 4,
2252 .btf_load_err = true,
2253 .err_str = "Invalid name",
2257 .descr = "enum member (invalid name, name_off = 0)",
2258 .raw_types = {
2259 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
2260 BTF_TYPE_ENC(0,
2261 BTF_INFO_ENC(BTF_KIND_ENUM, 0, 1),
2262 sizeof(int)), /* [2] */
2263 BTF_ENUM_ENC(0, 0),
2264 BTF_END_RAW,
2266 .str_sec = "",
2267 .str_sec_size = sizeof(""),
2268 .map_type = BPF_MAP_TYPE_ARRAY,
2269 .map_name = "enum_type_check_btf",
2270 .key_size = sizeof(int),
2271 .value_size = sizeof(int),
2272 .key_type_id = 1,
2273 .value_type_id = 1,
2274 .max_entries = 4,
2275 .btf_load_err = true,
2276 .err_str = "Invalid name",
2280 .descr = "enum member (invalid name, invalid identifier)",
2281 .raw_types = {
2282 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
2283 BTF_TYPE_ENC(0,
2284 BTF_INFO_ENC(BTF_KIND_ENUM, 0, 1),
2285 sizeof(int)), /* [2] */
2286 BTF_ENUM_ENC(NAME_TBD, 0),
2287 BTF_END_RAW,
2289 .str_sec = "\0A!",
2290 .str_sec_size = sizeof("\0A!"),
2291 .map_type = BPF_MAP_TYPE_ARRAY,
2292 .map_name = "enum_type_check_btf",
2293 .key_size = sizeof(int),
2294 .value_size = sizeof(int),
2295 .key_type_id = 1,
2296 .value_type_id = 1,
2297 .max_entries = 4,
2298 .btf_load_err = true,
2299 .err_str = "Invalid name",
2302 .descr = "arraymap invalid btf key (a bit field)",
2303 .raw_types = {
2304 /* int */ /* [1] */
2305 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
2306 /* 32 bit int with 32 bit offset */ /* [2] */
2307 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 32, 32, 8),
2308 BTF_END_RAW,
2310 .str_sec = "",
2311 .str_sec_size = sizeof(""),
2312 .map_type = BPF_MAP_TYPE_ARRAY,
2313 .map_name = "array_map_check_btf",
2314 .key_size = sizeof(int),
2315 .value_size = sizeof(int),
2316 .key_type_id = 2,
2317 .value_type_id = 1,
2318 .max_entries = 4,
2319 .map_create_err = true,
2323 .descr = "arraymap invalid btf key (!= 32 bits)",
2324 .raw_types = {
2325 /* int */ /* [1] */
2326 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
2327 /* 16 bit int with 0 bit offset */ /* [2] */
2328 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 16, 2),
2329 BTF_END_RAW,
2331 .str_sec = "",
2332 .str_sec_size = sizeof(""),
2333 .map_type = BPF_MAP_TYPE_ARRAY,
2334 .map_name = "array_map_check_btf",
2335 .key_size = sizeof(int),
2336 .value_size = sizeof(int),
2337 .key_type_id = 2,
2338 .value_type_id = 1,
2339 .max_entries = 4,
2340 .map_create_err = true,
2344 .descr = "arraymap invalid btf value (too small)",
2345 .raw_types = {
2346 /* int */ /* [1] */
2347 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
2348 BTF_END_RAW,
2350 .str_sec = "",
2351 .str_sec_size = sizeof(""),
2352 .map_type = BPF_MAP_TYPE_ARRAY,
2353 .map_name = "array_map_check_btf",
2354 .key_size = sizeof(int),
2355 /* btf_value_size < map->value_size */
2356 .value_size = sizeof(__u64),
2357 .key_type_id = 1,
2358 .value_type_id = 1,
2359 .max_entries = 4,
2360 .map_create_err = true,
2364 .descr = "arraymap invalid btf value (too big)",
2365 .raw_types = {
2366 /* int */ /* [1] */
2367 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
2368 BTF_END_RAW,
2370 .str_sec = "",
2371 .str_sec_size = sizeof(""),
2372 .map_type = BPF_MAP_TYPE_ARRAY,
2373 .map_name = "array_map_check_btf",
2374 .key_size = sizeof(int),
2375 /* btf_value_size > map->value_size */
2376 .value_size = sizeof(__u16),
2377 .key_type_id = 1,
2378 .value_type_id = 1,
2379 .max_entries = 4,
2380 .map_create_err = true,
2384 .descr = "func proto (int (*)(int, unsigned int))",
2385 .raw_types = {
2386 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
2387 BTF_TYPE_INT_ENC(0, 0, 0, 32, 4), /* [2] */
2388 /* int (*)(int, unsigned int) */
2389 BTF_FUNC_PROTO_ENC(1, 2), /* [3] */
2390 BTF_FUNC_PROTO_ARG_ENC(0, 1),
2391 BTF_FUNC_PROTO_ARG_ENC(0, 2),
2392 BTF_END_RAW,
2394 .str_sec = "",
2395 .str_sec_size = sizeof(""),
2396 .map_type = BPF_MAP_TYPE_ARRAY,
2397 .map_name = "func_proto_type_check_btf",
2398 .key_size = sizeof(int),
2399 .value_size = sizeof(int),
2400 .key_type_id = 1,
2401 .value_type_id = 1,
2402 .max_entries = 4,
2406 .descr = "func proto (vararg)",
2407 .raw_types = {
2408 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
2409 BTF_TYPE_INT_ENC(0, 0, 0, 32, 4), /* [2] */
2410 /* void (*)(int, unsigned int, ...) */
2411 BTF_FUNC_PROTO_ENC(0, 3), /* [3] */
2412 BTF_FUNC_PROTO_ARG_ENC(0, 1),
2413 BTF_FUNC_PROTO_ARG_ENC(0, 2),
2414 BTF_FUNC_PROTO_ARG_ENC(0, 0),
2415 BTF_END_RAW,
2417 .str_sec = "",
2418 .str_sec_size = sizeof(""),
2419 .map_type = BPF_MAP_TYPE_ARRAY,
2420 .map_name = "func_proto_type_check_btf",
2421 .key_size = sizeof(int),
2422 .value_size = sizeof(int),
2423 .key_type_id = 1,
2424 .value_type_id = 1,
2425 .max_entries = 4,
2429 .descr = "func proto (vararg with name)",
2430 .raw_types = {
2431 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
2432 BTF_TYPE_INT_ENC(0, 0, 0, 32, 4), /* [2] */
2433 /* void (*)(int a, unsigned int b, ... c) */
2434 BTF_FUNC_PROTO_ENC(0, 3), /* [3] */
2435 BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
2436 BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 2),
2437 BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 0),
2438 BTF_END_RAW,
2440 .str_sec = "\0a\0b\0c",
2441 .str_sec_size = sizeof("\0a\0b\0c"),
2442 .map_type = BPF_MAP_TYPE_ARRAY,
2443 .map_name = "func_proto_type_check_btf",
2444 .key_size = sizeof(int),
2445 .value_size = sizeof(int),
2446 .key_type_id = 1,
2447 .value_type_id = 1,
2448 .max_entries = 4,
2449 .btf_load_err = true,
2450 .err_str = "Invalid arg#3",
2454 .descr = "func proto (arg after vararg)",
2455 .raw_types = {
2456 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
2457 BTF_TYPE_INT_ENC(0, 0, 0, 32, 4), /* [2] */
2458 /* void (*)(int a, ..., unsigned int b) */
2459 BTF_FUNC_PROTO_ENC(0, 3), /* [3] */
2460 BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
2461 BTF_FUNC_PROTO_ARG_ENC(0, 0),
2462 BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 2),
2463 BTF_END_RAW,
2465 .str_sec = "\0a\0b",
2466 .str_sec_size = sizeof("\0a\0b"),
2467 .map_type = BPF_MAP_TYPE_ARRAY,
2468 .map_name = "func_proto_type_check_btf",
2469 .key_size = sizeof(int),
2470 .value_size = sizeof(int),
2471 .key_type_id = 1,
2472 .value_type_id = 1,
2473 .max_entries = 4,
2474 .btf_load_err = true,
2475 .err_str = "Invalid arg#2",
2479 .descr = "func proto (CONST=>TYPEDEF=>PTR=>FUNC_PROTO)",
2480 .raw_types = {
2481 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
2482 BTF_TYPE_INT_ENC(0, 0, 0, 32, 4), /* [2] */
2483 /* typedef void (*func_ptr)(int, unsigned int) */
2484 BTF_TYPEDEF_ENC(NAME_TBD, 5), /* [3] */
2485 /* const func_ptr */
2486 BTF_CONST_ENC(3), /* [4] */
2487 BTF_PTR_ENC(6), /* [5] */
2488 BTF_FUNC_PROTO_ENC(0, 2), /* [6] */
2489 BTF_FUNC_PROTO_ARG_ENC(0, 1),
2490 BTF_FUNC_PROTO_ARG_ENC(0, 2),
2491 BTF_END_RAW,
2493 .str_sec = "\0func_ptr",
2494 .str_sec_size = sizeof("\0func_ptr"),
2495 .map_type = BPF_MAP_TYPE_ARRAY,
2496 .map_name = "func_proto_type_check_btf",
2497 .key_size = sizeof(int),
2498 .value_size = sizeof(int),
2499 .key_type_id = 1,
2500 .value_type_id = 1,
2501 .max_entries = 4,
2505 .descr = "func proto (TYPEDEF=>FUNC_PROTO)",
2506 .raw_types = {
2507 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
2508 BTF_TYPE_INT_ENC(0, 0, 0, 32, 4), /* [2] */
2509 BTF_TYPEDEF_ENC(NAME_TBD, 4), /* [3] */
2510 BTF_FUNC_PROTO_ENC(0, 2), /* [4] */
2511 BTF_FUNC_PROTO_ARG_ENC(0, 1),
2512 BTF_FUNC_PROTO_ARG_ENC(0, 2),
2513 BTF_END_RAW,
2515 .str_sec = "\0func_typedef",
2516 .str_sec_size = sizeof("\0func_typedef"),
2517 .map_type = BPF_MAP_TYPE_ARRAY,
2518 .map_name = "func_proto_type_check_btf",
2519 .key_size = sizeof(int),
2520 .value_size = sizeof(int),
2521 .key_type_id = 1,
2522 .value_type_id = 1,
2523 .max_entries = 4,
2527 .descr = "func proto (btf_resolve(arg))",
2528 .raw_types = {
2529 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
2530 /* void (*)(const void *) */
2531 BTF_FUNC_PROTO_ENC(0, 1), /* [2] */
2532 BTF_FUNC_PROTO_ARG_ENC(0, 3),
2533 BTF_CONST_ENC(4), /* [3] */
2534 BTF_PTR_ENC(0), /* [4] */
2535 BTF_END_RAW,
2537 .str_sec = "",
2538 .str_sec_size = sizeof(""),
2539 .map_type = BPF_MAP_TYPE_ARRAY,
2540 .map_name = "func_proto_type_check_btf",
2541 .key_size = sizeof(int),
2542 .value_size = sizeof(int),
2543 .key_type_id = 1,
2544 .value_type_id = 1,
2545 .max_entries = 4,
2549 .descr = "func proto (Not all arg has name)",
2550 .raw_types = {
2551 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
2552 BTF_TYPE_INT_ENC(0, 0, 0, 32, 4), /* [2] */
2553 /* void (*)(int, unsigned int b) */
2554 BTF_FUNC_PROTO_ENC(0, 2), /* [3] */
2555 BTF_FUNC_PROTO_ARG_ENC(0, 1),
2556 BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 2),
2557 BTF_END_RAW,
2559 .str_sec = "\0b",
2560 .str_sec_size = sizeof("\0b"),
2561 .map_type = BPF_MAP_TYPE_ARRAY,
2562 .map_name = "func_proto_type_check_btf",
2563 .key_size = sizeof(int),
2564 .value_size = sizeof(int),
2565 .key_type_id = 1,
2566 .value_type_id = 1,
2567 .max_entries = 4,
2571 .descr = "func proto (Bad arg name_off)",
2572 .raw_types = {
2573 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
2574 BTF_TYPE_INT_ENC(0, 0, 0, 32, 4), /* [2] */
2575 /* void (*)(int a, unsigned int <bad_name_off>) */
2576 BTF_FUNC_PROTO_ENC(0, 2), /* [3] */
2577 BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
2578 BTF_FUNC_PROTO_ARG_ENC(0x0fffffff, 2),
2579 BTF_END_RAW,
2581 .str_sec = "\0a",
2582 .str_sec_size = sizeof("\0a"),
2583 .map_type = BPF_MAP_TYPE_ARRAY,
2584 .map_name = "func_proto_type_check_btf",
2585 .key_size = sizeof(int),
2586 .value_size = sizeof(int),
2587 .key_type_id = 1,
2588 .value_type_id = 1,
2589 .max_entries = 4,
2590 .btf_load_err = true,
2591 .err_str = "Invalid arg#2",
2595 .descr = "func proto (Bad arg name)",
2596 .raw_types = {
2597 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
2598 BTF_TYPE_INT_ENC(0, 0, 0, 32, 4), /* [2] */
2599 /* void (*)(int a, unsigned int !!!) */
2600 BTF_FUNC_PROTO_ENC(0, 2), /* [3] */
2601 BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
2602 BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 2),
2603 BTF_END_RAW,
2605 .str_sec = "\0a\0!!!",
2606 .str_sec_size = sizeof("\0a\0!!!"),
2607 .map_type = BPF_MAP_TYPE_ARRAY,
2608 .map_name = "func_proto_type_check_btf",
2609 .key_size = sizeof(int),
2610 .value_size = sizeof(int),
2611 .key_type_id = 1,
2612 .value_type_id = 1,
2613 .max_entries = 4,
2614 .btf_load_err = true,
2615 .err_str = "Invalid arg#2",
2619 .descr = "func proto (Invalid return type)",
2620 .raw_types = {
2621 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
2622 BTF_TYPE_INT_ENC(0, 0, 0, 32, 4), /* [2] */
2623 /* <bad_ret_type> (*)(int, unsigned int) */
2624 BTF_FUNC_PROTO_ENC(100, 2), /* [3] */
2625 BTF_FUNC_PROTO_ARG_ENC(0, 1),
2626 BTF_FUNC_PROTO_ARG_ENC(0, 2),
2627 BTF_END_RAW,
2629 .str_sec = "",
2630 .str_sec_size = sizeof(""),
2631 .map_type = BPF_MAP_TYPE_ARRAY,
2632 .map_name = "func_proto_type_check_btf",
2633 .key_size = sizeof(int),
2634 .value_size = sizeof(int),
2635 .key_type_id = 1,
2636 .value_type_id = 1,
2637 .max_entries = 4,
2638 .btf_load_err = true,
2639 .err_str = "Invalid return type",
2643 .descr = "func proto (with func name)",
2644 .raw_types = {
2645 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
2646 BTF_TYPE_INT_ENC(0, 0, 0, 32, 4), /* [2] */
2647 /* void func_proto(int, unsigned int) */
2648 BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_FUNC_PROTO, 0, 2), 0), /* [3] */
2649 BTF_FUNC_PROTO_ARG_ENC(0, 1),
2650 BTF_FUNC_PROTO_ARG_ENC(0, 2),
2651 BTF_END_RAW,
2653 .str_sec = "\0func_proto",
2654 .str_sec_size = sizeof("\0func_proto"),
2655 .map_type = BPF_MAP_TYPE_ARRAY,
2656 .map_name = "func_proto_type_check_btf",
2657 .key_size = sizeof(int),
2658 .value_size = sizeof(int),
2659 .key_type_id = 1,
2660 .value_type_id = 1,
2661 .max_entries = 4,
2662 .btf_load_err = true,
2663 .err_str = "Invalid name",
2667 .descr = "func proto (const void arg)",
2668 .raw_types = {
2669 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
2670 BTF_TYPE_INT_ENC(0, 0, 0, 32, 4), /* [2] */
2671 /* void (*)(const void) */
2672 BTF_FUNC_PROTO_ENC(0, 1), /* [3] */
2673 BTF_FUNC_PROTO_ARG_ENC(0, 4),
2674 BTF_CONST_ENC(0), /* [4] */
2675 BTF_END_RAW,
2677 .str_sec = "",
2678 .str_sec_size = sizeof(""),
2679 .map_type = BPF_MAP_TYPE_ARRAY,
2680 .map_name = "func_proto_type_check_btf",
2681 .key_size = sizeof(int),
2682 .value_size = sizeof(int),
2683 .key_type_id = 1,
2684 .value_type_id = 1,
2685 .max_entries = 4,
2686 .btf_load_err = true,
2687 .err_str = "Invalid arg#1",
2691 .descr = "func (void func(int a, unsigned int b))",
2692 .raw_types = {
2693 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
2694 BTF_TYPE_INT_ENC(0, 0, 0, 32, 4), /* [2] */
2695 /* void (*)(int a, unsigned int b) */
2696 BTF_FUNC_PROTO_ENC(0, 2), /* [3] */
2697 BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
2698 BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 2),
2699 /* void func(int a, unsigned int b) */
2700 BTF_FUNC_ENC(NAME_TBD, 3), /* [4] */
2701 BTF_END_RAW,
2703 .str_sec = "\0a\0b\0func",
2704 .str_sec_size = sizeof("\0a\0b\0func"),
2705 .map_type = BPF_MAP_TYPE_ARRAY,
2706 .map_name = "func_type_check_btf",
2707 .key_size = sizeof(int),
2708 .value_size = sizeof(int),
2709 .key_type_id = 1,
2710 .value_type_id = 1,
2711 .max_entries = 4,
2715 .descr = "func (No func name)",
2716 .raw_types = {
2717 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
2718 BTF_TYPE_INT_ENC(0, 0, 0, 32, 4), /* [2] */
2719 /* void (*)(int a, unsigned int b) */
2720 BTF_FUNC_PROTO_ENC(0, 2), /* [3] */
2721 BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
2722 BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 2),
2723 /* void <no_name>(int a, unsigned int b) */
2724 BTF_FUNC_ENC(0, 3), /* [4] */
2725 BTF_END_RAW,
2727 .str_sec = "\0a\0b",
2728 .str_sec_size = sizeof("\0a\0b"),
2729 .map_type = BPF_MAP_TYPE_ARRAY,
2730 .map_name = "func_type_check_btf",
2731 .key_size = sizeof(int),
2732 .value_size = sizeof(int),
2733 .key_type_id = 1,
2734 .value_type_id = 1,
2735 .max_entries = 4,
2736 .btf_load_err = true,
2737 .err_str = "Invalid name",
2741 .descr = "func (Invalid func name)",
2742 .raw_types = {
2743 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
2744 BTF_TYPE_INT_ENC(0, 0, 0, 32, 4), /* [2] */
2745 /* void (*)(int a, unsigned int b) */
2746 BTF_FUNC_PROTO_ENC(0, 2), /* [3] */
2747 BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
2748 BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 2),
2749 /* void !!!(int a, unsigned int b) */
2750 BTF_FUNC_ENC(NAME_TBD, 3), /* [4] */
2751 BTF_END_RAW,
2753 .str_sec = "\0a\0b\0!!!",
2754 .str_sec_size = sizeof("\0a\0b\0!!!"),
2755 .map_type = BPF_MAP_TYPE_ARRAY,
2756 .map_name = "func_type_check_btf",
2757 .key_size = sizeof(int),
2758 .value_size = sizeof(int),
2759 .key_type_id = 1,
2760 .value_type_id = 1,
2761 .max_entries = 4,
2762 .btf_load_err = true,
2763 .err_str = "Invalid name",
2767 .descr = "func (Some arg has no name)",
2768 .raw_types = {
2769 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
2770 BTF_TYPE_INT_ENC(0, 0, 0, 32, 4), /* [2] */
2771 /* void (*)(int a, unsigned int) */
2772 BTF_FUNC_PROTO_ENC(0, 2), /* [3] */
2773 BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
2774 BTF_FUNC_PROTO_ARG_ENC(0, 2),
2775 /* void func(int a, unsigned int) */
2776 BTF_FUNC_ENC(NAME_TBD, 3), /* [4] */
2777 BTF_END_RAW,
2779 .str_sec = "\0a\0func",
2780 .str_sec_size = sizeof("\0a\0func"),
2781 .map_type = BPF_MAP_TYPE_ARRAY,
2782 .map_name = "func_type_check_btf",
2783 .key_size = sizeof(int),
2784 .value_size = sizeof(int),
2785 .key_type_id = 1,
2786 .value_type_id = 1,
2787 .max_entries = 4,
2788 .btf_load_err = true,
2789 .err_str = "Invalid arg#2",
2793 .descr = "func (Non zero vlen)",
2794 .raw_types = {
2795 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
2796 BTF_TYPE_INT_ENC(0, 0, 0, 32, 4), /* [2] */
2797 /* void (*)(int a, unsigned int b) */
2798 BTF_FUNC_PROTO_ENC(0, 2), /* [3] */
2799 BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
2800 BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 2),
2801 /* void func(int a, unsigned int b) */
2802 BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_FUNC, 0, 2), 3), /* [4] */
2803 BTF_END_RAW,
2805 .str_sec = "\0a\0b\0func",
2806 .str_sec_size = sizeof("\0a\0b\0func"),
2807 .map_type = BPF_MAP_TYPE_ARRAY,
2808 .map_name = "func_type_check_btf",
2809 .key_size = sizeof(int),
2810 .value_size = sizeof(int),
2811 .key_type_id = 1,
2812 .value_type_id = 1,
2813 .max_entries = 4,
2814 .btf_load_err = true,
2815 .err_str = "vlen != 0",
2819 .descr = "func (Not referring to FUNC_PROTO)",
2820 .raw_types = {
2821 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
2822 BTF_FUNC_ENC(NAME_TBD, 1), /* [2] */
2823 BTF_END_RAW,
2825 .str_sec = "\0func",
2826 .str_sec_size = sizeof("\0func"),
2827 .map_type = BPF_MAP_TYPE_ARRAY,
2828 .map_name = "func_type_check_btf",
2829 .key_size = sizeof(int),
2830 .value_size = sizeof(int),
2831 .key_type_id = 1,
2832 .value_type_id = 1,
2833 .max_entries = 4,
2834 .btf_load_err = true,
2835 .err_str = "Invalid type_id",
2839 .descr = "invalid int kind_flag",
2840 .raw_types = {
2841 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
2842 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_INT, 1, 0), 4), /* [2] */
2843 BTF_INT_ENC(0, 0, 32),
2844 BTF_END_RAW,
2846 BTF_STR_SEC(""),
2847 .map_type = BPF_MAP_TYPE_ARRAY,
2848 .map_name = "int_type_check_btf",
2849 .key_size = sizeof(int),
2850 .value_size = sizeof(int),
2851 .key_type_id = 1,
2852 .value_type_id = 1,
2853 .max_entries = 4,
2854 .btf_load_err = true,
2855 .err_str = "Invalid btf_info kind_flag",
2859 .descr = "invalid ptr kind_flag",
2860 .raw_types = {
2861 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
2862 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_PTR, 1, 0), 1), /* [2] */
2863 BTF_END_RAW,
2865 BTF_STR_SEC(""),
2866 .map_type = BPF_MAP_TYPE_ARRAY,
2867 .map_name = "ptr_type_check_btf",
2868 .key_size = sizeof(int),
2869 .value_size = sizeof(int),
2870 .key_type_id = 1,
2871 .value_type_id = 1,
2872 .max_entries = 4,
2873 .btf_load_err = true,
2874 .err_str = "Invalid btf_info kind_flag",
2878 .descr = "invalid array kind_flag",
2879 .raw_types = {
2880 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
2881 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_ARRAY, 1, 0), 0), /* [2] */
2882 BTF_ARRAY_ENC(1, 1, 1),
2883 BTF_END_RAW,
2885 BTF_STR_SEC(""),
2886 .map_type = BPF_MAP_TYPE_ARRAY,
2887 .map_name = "array_type_check_btf",
2888 .key_size = sizeof(int),
2889 .value_size = sizeof(int),
2890 .key_type_id = 1,
2891 .value_type_id = 1,
2892 .max_entries = 4,
2893 .btf_load_err = true,
2894 .err_str = "Invalid btf_info kind_flag",
2898 .descr = "invalid enum kind_flag",
2899 .raw_types = {
2900 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
2901 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_ENUM, 1, 1), 4), /* [2] */
2902 BTF_ENUM_ENC(NAME_TBD, 0),
2903 BTF_END_RAW,
2905 BTF_STR_SEC("\0A"),
2906 .map_type = BPF_MAP_TYPE_ARRAY,
2907 .map_name = "enum_type_check_btf",
2908 .key_size = sizeof(int),
2909 .value_size = sizeof(int),
2910 .key_type_id = 1,
2911 .value_type_id = 1,
2912 .max_entries = 4,
2913 .btf_load_err = true,
2914 .err_str = "Invalid btf_info kind_flag",
2918 .descr = "valid fwd kind_flag",
2919 .raw_types = {
2920 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
2921 BTF_TYPE_ENC(NAME_TBD,
2922 BTF_INFO_ENC(BTF_KIND_FWD, 1, 0), 0), /* [2] */
2923 BTF_END_RAW,
2925 BTF_STR_SEC("\0A"),
2926 .map_type = BPF_MAP_TYPE_ARRAY,
2927 .map_name = "fwd_type_check_btf",
2928 .key_size = sizeof(int),
2929 .value_size = sizeof(int),
2930 .key_type_id = 1,
2931 .value_type_id = 1,
2932 .max_entries = 4,
2936 .descr = "invalid typedef kind_flag",
2937 .raw_types = {
2938 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
2939 BTF_TYPE_ENC(NAME_TBD,
2940 BTF_INFO_ENC(BTF_KIND_TYPEDEF, 1, 0), 1), /* [2] */
2941 BTF_END_RAW,
2943 BTF_STR_SEC("\0A"),
2944 .map_type = BPF_MAP_TYPE_ARRAY,
2945 .map_name = "typedef_type_check_btf",
2946 .key_size = sizeof(int),
2947 .value_size = sizeof(int),
2948 .key_type_id = 1,
2949 .value_type_id = 1,
2950 .max_entries = 4,
2951 .btf_load_err = true,
2952 .err_str = "Invalid btf_info kind_flag",
2956 .descr = "invalid volatile kind_flag",
2957 .raw_types = {
2958 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
2959 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_VOLATILE, 1, 0), 1), /* [2] */
2960 BTF_END_RAW,
2962 BTF_STR_SEC(""),
2963 .map_type = BPF_MAP_TYPE_ARRAY,
2964 .map_name = "volatile_type_check_btf",
2965 .key_size = sizeof(int),
2966 .value_size = sizeof(int),
2967 .key_type_id = 1,
2968 .value_type_id = 1,
2969 .max_entries = 4,
2970 .btf_load_err = true,
2971 .err_str = "Invalid btf_info kind_flag",
2975 .descr = "invalid const kind_flag",
2976 .raw_types = {
2977 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
2978 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_CONST, 1, 0), 1), /* [2] */
2979 BTF_END_RAW,
2981 BTF_STR_SEC(""),
2982 .map_type = BPF_MAP_TYPE_ARRAY,
2983 .map_name = "const_type_check_btf",
2984 .key_size = sizeof(int),
2985 .value_size = sizeof(int),
2986 .key_type_id = 1,
2987 .value_type_id = 1,
2988 .max_entries = 4,
2989 .btf_load_err = true,
2990 .err_str = "Invalid btf_info kind_flag",
2994 .descr = "invalid restrict kind_flag",
2995 .raw_types = {
2996 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
2997 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_RESTRICT, 1, 0), 1), /* [2] */
2998 BTF_END_RAW,
3000 BTF_STR_SEC(""),
3001 .map_type = BPF_MAP_TYPE_ARRAY,
3002 .map_name = "restrict_type_check_btf",
3003 .key_size = sizeof(int),
3004 .value_size = sizeof(int),
3005 .key_type_id = 1,
3006 .value_type_id = 1,
3007 .max_entries = 4,
3008 .btf_load_err = true,
3009 .err_str = "Invalid btf_info kind_flag",
3013 .descr = "invalid func kind_flag",
3014 .raw_types = {
3015 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
3016 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_FUNC_PROTO, 0, 0), 0), /* [2] */
3017 BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_FUNC, 1, 0), 2), /* [3] */
3018 BTF_END_RAW,
3020 BTF_STR_SEC("\0A"),
3021 .map_type = BPF_MAP_TYPE_ARRAY,
3022 .map_name = "func_type_check_btf",
3023 .key_size = sizeof(int),
3024 .value_size = sizeof(int),
3025 .key_type_id = 1,
3026 .value_type_id = 1,
3027 .max_entries = 4,
3028 .btf_load_err = true,
3029 .err_str = "Invalid btf_info kind_flag",
3033 .descr = "invalid func_proto kind_flag",
3034 .raw_types = {
3035 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
3036 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_FUNC_PROTO, 1, 0), 0), /* [2] */
3037 BTF_END_RAW,
3039 BTF_STR_SEC(""),
3040 .map_type = BPF_MAP_TYPE_ARRAY,
3041 .map_name = "func_proto_type_check_btf",
3042 .key_size = sizeof(int),
3043 .value_size = sizeof(int),
3044 .key_type_id = 1,
3045 .value_type_id = 1,
3046 .max_entries = 4,
3047 .btf_load_err = true,
3048 .err_str = "Invalid btf_info kind_flag",
3052 .descr = "valid struct, kind_flag, bitfield_size = 0",
3053 .raw_types = {
3054 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
3055 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_STRUCT, 1, 2), 8), /* [2] */
3056 BTF_MEMBER_ENC(NAME_TBD, 1, BTF_MEMBER_OFFSET(0, 0)),
3057 BTF_MEMBER_ENC(NAME_TBD, 1, BTF_MEMBER_OFFSET(0, 32)),
3058 BTF_END_RAW,
3060 BTF_STR_SEC("\0A\0B"),
3061 .map_type = BPF_MAP_TYPE_ARRAY,
3062 .map_name = "struct_type_check_btf",
3063 .key_size = sizeof(int),
3064 .value_size = sizeof(int),
3065 .key_type_id = 1,
3066 .value_type_id = 1,
3067 .max_entries = 4,
3071 .descr = "valid struct, kind_flag, int member, bitfield_size != 0",
3072 .raw_types = {
3073 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
3074 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_STRUCT, 1, 2), 4), /* [2] */
3075 BTF_MEMBER_ENC(NAME_TBD, 1, BTF_MEMBER_OFFSET(4, 0)),
3076 BTF_MEMBER_ENC(NAME_TBD, 1, BTF_MEMBER_OFFSET(4, 4)),
3077 BTF_END_RAW,
3079 BTF_STR_SEC("\0A\0B"),
3080 .map_type = BPF_MAP_TYPE_ARRAY,
3081 .map_name = "struct_type_check_btf",
3082 .key_size = sizeof(int),
3083 .value_size = sizeof(int),
3084 .key_type_id = 1,
3085 .value_type_id = 1,
3086 .max_entries = 4,
3090 .descr = "valid union, kind_flag, int member, bitfield_size != 0",
3091 .raw_types = {
3092 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
3093 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_UNION, 1, 2), 4), /* [2] */
3094 BTF_MEMBER_ENC(NAME_TBD, 1, BTF_MEMBER_OFFSET(4, 0)),
3095 BTF_MEMBER_ENC(NAME_TBD, 1, BTF_MEMBER_OFFSET(4, 0)),
3096 BTF_END_RAW,
3098 BTF_STR_SEC("\0A\0B"),
3099 .map_type = BPF_MAP_TYPE_ARRAY,
3100 .map_name = "union_type_check_btf",
3101 .key_size = sizeof(int),
3102 .value_size = sizeof(int),
3103 .key_type_id = 1,
3104 .value_type_id = 1,
3105 .max_entries = 4,
3109 .descr = "valid struct, kind_flag, enum member, bitfield_size != 0",
3110 .raw_types = {
3111 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
3112 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_ENUM, 0, 1), 4), /* [2] */
3113 BTF_ENUM_ENC(NAME_TBD, 0),
3114 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_STRUCT, 1, 2), 4),/* [3] */
3115 BTF_MEMBER_ENC(NAME_TBD, 2, BTF_MEMBER_OFFSET(4, 0)),
3116 BTF_MEMBER_ENC(NAME_TBD, 2, BTF_MEMBER_OFFSET(4, 4)),
3117 BTF_END_RAW,
3119 BTF_STR_SEC("\0A\0B\0C"),
3120 .map_type = BPF_MAP_TYPE_ARRAY,
3121 .map_name = "struct_type_check_btf",
3122 .key_size = sizeof(int),
3123 .value_size = sizeof(int),
3124 .key_type_id = 1,
3125 .value_type_id = 1,
3126 .max_entries = 4,
3130 .descr = "valid union, kind_flag, enum member, bitfield_size != 0",
3131 .raw_types = {
3132 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
3133 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_ENUM, 0, 1), 4), /* [2] */
3134 BTF_ENUM_ENC(NAME_TBD, 0),
3135 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_UNION, 1, 2), 4), /* [3] */
3136 BTF_MEMBER_ENC(NAME_TBD, 2, BTF_MEMBER_OFFSET(4, 0)),
3137 BTF_MEMBER_ENC(NAME_TBD, 2, BTF_MEMBER_OFFSET(4, 0)),
3138 BTF_END_RAW,
3140 BTF_STR_SEC("\0A\0B\0C"),
3141 .map_type = BPF_MAP_TYPE_ARRAY,
3142 .map_name = "union_type_check_btf",
3143 .key_size = sizeof(int),
3144 .value_size = sizeof(int),
3145 .key_type_id = 1,
3146 .value_type_id = 1,
3147 .max_entries = 4,
3151 .descr = "valid struct, kind_flag, typedef member, bitfield_size != 0",
3152 .raw_types = {
3153 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
3154 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_ENUM, 0, 1), 4), /* [2] */
3155 BTF_ENUM_ENC(NAME_TBD, 0),
3156 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_STRUCT, 1, 2), 4),/* [3] */
3157 BTF_MEMBER_ENC(NAME_TBD, 4, BTF_MEMBER_OFFSET(4, 0)),
3158 BTF_MEMBER_ENC(NAME_TBD, 5, BTF_MEMBER_OFFSET(4, 4)),
3159 BTF_TYPEDEF_ENC(NAME_TBD, 1), /* [4] */
3160 BTF_TYPEDEF_ENC(NAME_TBD, 2), /* [5] */
3161 BTF_END_RAW,
3163 BTF_STR_SEC("\0A\0B\0C\0D\0E"),
3164 .map_type = BPF_MAP_TYPE_ARRAY,
3165 .map_name = "struct_type_check_btf",
3166 .key_size = sizeof(int),
3167 .value_size = sizeof(int),
3168 .key_type_id = 1,
3169 .value_type_id = 1,
3170 .max_entries = 4,
3174 .descr = "valid union, kind_flag, typedef member, bitfield_size != 0",
3175 .raw_types = {
3176 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
3177 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_ENUM, 0, 1), 4), /* [2] */
3178 BTF_ENUM_ENC(NAME_TBD, 0),
3179 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_UNION, 1, 2), 4), /* [3] */
3180 BTF_MEMBER_ENC(NAME_TBD, 4, BTF_MEMBER_OFFSET(4, 0)),
3181 BTF_MEMBER_ENC(NAME_TBD, 5, BTF_MEMBER_OFFSET(4, 0)),
3182 BTF_TYPEDEF_ENC(NAME_TBD, 1), /* [4] */
3183 BTF_TYPEDEF_ENC(NAME_TBD, 2), /* [5] */
3184 BTF_END_RAW,
3186 BTF_STR_SEC("\0A\0B\0C\0D\0E"),
3187 .map_type = BPF_MAP_TYPE_ARRAY,
3188 .map_name = "union_type_check_btf",
3189 .key_size = sizeof(int),
3190 .value_size = sizeof(int),
3191 .key_type_id = 1,
3192 .value_type_id = 1,
3193 .max_entries = 4,
3197 .descr = "invalid struct, kind_flag, bitfield_size greater than struct size",
3198 .raw_types = {
3199 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
3200 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_STRUCT, 1, 2), 4), /* [2] */
3201 BTF_MEMBER_ENC(NAME_TBD, 1, BTF_MEMBER_OFFSET(20, 0)),
3202 BTF_MEMBER_ENC(NAME_TBD, 1, BTF_MEMBER_OFFSET(20, 20)),
3203 BTF_END_RAW,
3205 BTF_STR_SEC("\0A\0B"),
3206 .map_type = BPF_MAP_TYPE_ARRAY,
3207 .map_name = "struct_type_check_btf",
3208 .key_size = sizeof(int),
3209 .value_size = sizeof(int),
3210 .key_type_id = 1,
3211 .value_type_id = 1,
3212 .max_entries = 4,
3213 .btf_load_err = true,
3214 .err_str = "Member exceeds struct_size",
3218 .descr = "invalid struct, kind_flag, bitfield base_type int not regular",
3219 .raw_types = {
3220 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
3221 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 20, 4), /* [2] */
3222 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_STRUCT, 1, 2), 4), /* [3] */
3223 BTF_MEMBER_ENC(NAME_TBD, 2, BTF_MEMBER_OFFSET(20, 0)),
3224 BTF_MEMBER_ENC(NAME_TBD, 2, BTF_MEMBER_OFFSET(20, 20)),
3225 BTF_END_RAW,
3227 BTF_STR_SEC("\0A\0B"),
3228 .map_type = BPF_MAP_TYPE_ARRAY,
3229 .map_name = "struct_type_check_btf",
3230 .key_size = sizeof(int),
3231 .value_size = sizeof(int),
3232 .key_type_id = 1,
3233 .value_type_id = 1,
3234 .max_entries = 4,
3235 .btf_load_err = true,
3236 .err_str = "Invalid member base type",
3240 .descr = "invalid struct, kind_flag, base_type int not regular",
3241 .raw_types = {
3242 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
3243 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 12, 4), /* [2] */
3244 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_STRUCT, 1, 2), 4), /* [3] */
3245 BTF_MEMBER_ENC(NAME_TBD, 2, BTF_MEMBER_OFFSET(8, 0)),
3246 BTF_MEMBER_ENC(NAME_TBD, 2, BTF_MEMBER_OFFSET(8, 8)),
3247 BTF_END_RAW,
3249 BTF_STR_SEC("\0A\0B"),
3250 .map_type = BPF_MAP_TYPE_ARRAY,
3251 .map_name = "struct_type_check_btf",
3252 .key_size = sizeof(int),
3253 .value_size = sizeof(int),
3254 .key_type_id = 1,
3255 .value_type_id = 1,
3256 .max_entries = 4,
3257 .btf_load_err = true,
3258 .err_str = "Invalid member base type",
3262 .descr = "invalid union, kind_flag, bitfield_size greater than struct size",
3263 .raw_types = {
3264 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
3265 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_UNION, 1, 2), 2), /* [2] */
3266 BTF_MEMBER_ENC(NAME_TBD, 1, BTF_MEMBER_OFFSET(8, 0)),
3267 BTF_MEMBER_ENC(NAME_TBD, 1, BTF_MEMBER_OFFSET(20, 0)),
3268 BTF_END_RAW,
3270 BTF_STR_SEC("\0A\0B"),
3271 .map_type = BPF_MAP_TYPE_ARRAY,
3272 .map_name = "union_type_check_btf",
3273 .key_size = sizeof(int),
3274 .value_size = sizeof(int),
3275 .key_type_id = 1,
3276 .value_type_id = 1,
3277 .max_entries = 4,
3278 .btf_load_err = true,
3279 .err_str = "Member exceeds struct_size",
3283 .descr = "invalid struct, kind_flag, int member, bitfield_size = 0, wrong byte alignment",
3284 .raw_types = {
3285 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
3286 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [2] */
3287 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_STRUCT, 1, 2), 12), /* [3] */
3288 BTF_MEMBER_ENC(NAME_TBD, 2, BTF_MEMBER_OFFSET(0, 0)),
3289 BTF_MEMBER_ENC(NAME_TBD, 2, BTF_MEMBER_OFFSET(0, 36)),
3290 BTF_END_RAW,
3292 BTF_STR_SEC("\0A\0B"),
3293 .map_type = BPF_MAP_TYPE_ARRAY,
3294 .map_name = "struct_type_check_btf",
3295 .key_size = sizeof(int),
3296 .value_size = sizeof(int),
3297 .key_type_id = 1,
3298 .value_type_id = 1,
3299 .max_entries = 4,
3300 .btf_load_err = true,
3301 .err_str = "Invalid member offset",
3305 .descr = "invalid struct, kind_flag, enum member, bitfield_size = 0, wrong byte alignment",
3306 .raw_types = {
3307 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
3308 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [2] */
3309 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_ENUM, 0, 1), 4), /* [2] */
3310 BTF_ENUM_ENC(NAME_TBD, 0),
3311 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_STRUCT, 1, 2), 12), /* [3] */
3312 BTF_MEMBER_ENC(NAME_TBD, 2, BTF_MEMBER_OFFSET(0, 0)),
3313 BTF_MEMBER_ENC(NAME_TBD, 2, BTF_MEMBER_OFFSET(0, 36)),
3314 BTF_END_RAW,
3316 BTF_STR_SEC("\0A\0B\0C"),
3317 .map_type = BPF_MAP_TYPE_ARRAY,
3318 .map_name = "struct_type_check_btf",
3319 .key_size = sizeof(int),
3320 .value_size = sizeof(int),
3321 .key_type_id = 1,
3322 .value_type_id = 1,
3323 .max_entries = 4,
3324 .btf_load_err = true,
3325 .err_str = "Invalid member offset",
3329 .descr = "128-bit int",
3330 .raw_types = {
3331 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
3332 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 128, 16), /* [2] */
3333 BTF_END_RAW,
3335 BTF_STR_SEC("\0A"),
3336 .map_type = BPF_MAP_TYPE_ARRAY,
3337 .map_name = "int_type_check_btf",
3338 .key_size = sizeof(int),
3339 .value_size = sizeof(int),
3340 .key_type_id = 1,
3341 .value_type_id = 1,
3342 .max_entries = 4,
3346 .descr = "struct, 128-bit int member",
3347 .raw_types = {
3348 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
3349 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 128, 16), /* [2] */
3350 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 1), 16), /* [3] */
3351 BTF_MEMBER_ENC(NAME_TBD, 2, 0),
3352 BTF_END_RAW,
3354 BTF_STR_SEC("\0A"),
3355 .map_type = BPF_MAP_TYPE_ARRAY,
3356 .map_name = "struct_type_check_btf",
3357 .key_size = sizeof(int),
3358 .value_size = sizeof(int),
3359 .key_type_id = 1,
3360 .value_type_id = 1,
3361 .max_entries = 4,
3365 .descr = "struct, 120-bit int member bitfield",
3366 .raw_types = {
3367 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
3368 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 120, 16), /* [2] */
3369 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 1), 16), /* [3] */
3370 BTF_MEMBER_ENC(NAME_TBD, 2, 0),
3371 BTF_END_RAW,
3373 BTF_STR_SEC("\0A"),
3374 .map_type = BPF_MAP_TYPE_ARRAY,
3375 .map_name = "struct_type_check_btf",
3376 .key_size = sizeof(int),
3377 .value_size = sizeof(int),
3378 .key_type_id = 1,
3379 .value_type_id = 1,
3380 .max_entries = 4,
3384 .descr = "struct, kind_flag, 128-bit int member",
3385 .raw_types = {
3386 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
3387 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 128, 16), /* [2] */
3388 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_STRUCT, 1, 1), 16), /* [3] */
3389 BTF_MEMBER_ENC(NAME_TBD, 2, BTF_MEMBER_OFFSET(0, 0)),
3390 BTF_END_RAW,
3392 BTF_STR_SEC("\0A"),
3393 .map_type = BPF_MAP_TYPE_ARRAY,
3394 .map_name = "struct_type_check_btf",
3395 .key_size = sizeof(int),
3396 .value_size = sizeof(int),
3397 .key_type_id = 1,
3398 .value_type_id = 1,
3399 .max_entries = 4,
3403 .descr = "struct, kind_flag, 120-bit int member bitfield",
3404 .raw_types = {
3405 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
3406 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 128, 16), /* [2] */
3407 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_STRUCT, 1, 1), 16), /* [3] */
3408 BTF_MEMBER_ENC(NAME_TBD, 2, BTF_MEMBER_OFFSET(120, 0)),
3409 BTF_END_RAW,
3411 BTF_STR_SEC("\0A"),
3412 .map_type = BPF_MAP_TYPE_ARRAY,
3413 .map_name = "struct_type_check_btf",
3414 .key_size = sizeof(int),
3415 .value_size = sizeof(int),
3416 .key_type_id = 1,
3417 .value_type_id = 1,
3418 .max_entries = 4,
3421 * typedef int arr_t[16];
3422 * struct s {
3423 * arr_t *a;
3424 * };
3427 .descr = "struct->ptr->typedef->array->int size resolution",
3428 .raw_types = {
3429 BTF_STRUCT_ENC(NAME_TBD, 1, 8), /* [1] */
3430 BTF_MEMBER_ENC(NAME_TBD, 2, 0),
3431 BTF_PTR_ENC(3), /* [2] */
3432 BTF_TYPEDEF_ENC(NAME_TBD, 4), /* [3] */
3433 BTF_TYPE_ARRAY_ENC(5, 5, 16), /* [4] */
3434 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [5] */
3435 BTF_END_RAW,
3437 BTF_STR_SEC("\0s\0a\0arr_t"),
3438 .map_type = BPF_MAP_TYPE_ARRAY,
3439 .map_name = "ptr_mod_chain_size_resolve_map",
3440 .key_size = sizeof(int),
3441 .value_size = sizeof(int) * 16,
3442 .key_type_id = 5 /* int */,
3443 .value_type_id = 3 /* arr_t */,
3444 .max_entries = 4,
3447 * typedef int arr_t[16][8][4];
3448 * struct s {
3449 * arr_t *a;
3450 * };
3453 .descr = "struct->ptr->typedef->multi-array->int size resolution",
3454 .raw_types = {
3455 BTF_STRUCT_ENC(NAME_TBD, 1, 8), /* [1] */
3456 BTF_MEMBER_ENC(NAME_TBD, 2, 0),
3457 BTF_PTR_ENC(3), /* [2] */
3458 BTF_TYPEDEF_ENC(NAME_TBD, 4), /* [3] */
3459 BTF_TYPE_ARRAY_ENC(5, 7, 16), /* [4] */
3460 BTF_TYPE_ARRAY_ENC(6, 7, 8), /* [5] */
3461 BTF_TYPE_ARRAY_ENC(7, 7, 4), /* [6] */
3462 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [7] */
3463 BTF_END_RAW,
3465 BTF_STR_SEC("\0s\0a\0arr_t"),
3466 .map_type = BPF_MAP_TYPE_ARRAY,
3467 .map_name = "multi_arr_size_resolve_map",
3468 .key_size = sizeof(int),
3469 .value_size = sizeof(int) * 16 * 8 * 4,
3470 .key_type_id = 7 /* int */,
3471 .value_type_id = 3 /* arr_t */,
3472 .max_entries = 4,
3475 * typedef int int_t;
3476 * typedef int_t arr3_t[4];
3477 * typedef arr3_t arr2_t[8];
3478 * typedef arr2_t arr1_t[16];
3479 * struct s {
3480 * arr1_t *a;
3481 * };
3484 .descr = "typedef/multi-arr mix size resolution",
3485 .raw_types = {
3486 BTF_STRUCT_ENC(NAME_TBD, 1, 8), /* [1] */
3487 BTF_MEMBER_ENC(NAME_TBD, 2, 0),
3488 BTF_PTR_ENC(3), /* [2] */
3489 BTF_TYPEDEF_ENC(NAME_TBD, 4), /* [3] */
3490 BTF_TYPE_ARRAY_ENC(5, 10, 16), /* [4] */
3491 BTF_TYPEDEF_ENC(NAME_TBD, 6), /* [5] */
3492 BTF_TYPE_ARRAY_ENC(7, 10, 8), /* [6] */
3493 BTF_TYPEDEF_ENC(NAME_TBD, 8), /* [7] */
3494 BTF_TYPE_ARRAY_ENC(9, 10, 4), /* [8] */
3495 BTF_TYPEDEF_ENC(NAME_TBD, 10), /* [9] */
3496 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [10] */
3497 BTF_END_RAW,
3499 BTF_STR_SEC("\0s\0a\0arr1_t\0arr2_t\0arr3_t\0int_t"),
3500 .map_type = BPF_MAP_TYPE_ARRAY,
3501 .map_name = "typedef_arra_mix_size_resolve_map",
3502 .key_size = sizeof(int),
3503 .value_size = sizeof(int) * 16 * 8 * 4,
3504 .key_type_id = 10 /* int */,
3505 .value_type_id = 3 /* arr_t */,
3506 .max_entries = 4,
3509 }; /* struct btf_raw_test raw_tests[] */
3511 static const char *get_next_str(const char *start, const char *end)
3513 return start < end - 1 ? start + 1 : NULL;
3516 static int get_raw_sec_size(const __u32 *raw_types)
3518 int i;
3520 for (i = MAX_NR_RAW_U32 - 1;
3521 i >= 0 && raw_types[i] != BTF_END_RAW;
3522 i--)
3525 return i < 0 ? i : i * sizeof(raw_types[0]);
3528 static void *btf_raw_create(const struct btf_header *hdr,
3529 const __u32 *raw_types,
3530 const char *str,
3531 unsigned int str_sec_size,
3532 unsigned int *btf_size,
3533 const char **ret_next_str)
3535 const char *next_str = str, *end_str = str + str_sec_size;
3536 const char **strs_idx = NULL, **tmp_strs_idx;
3537 int strs_cap = 0, strs_cnt = 0, next_str_idx = 0;
3538 unsigned int size_needed, offset;
3539 struct btf_header *ret_hdr;
3540 int i, type_sec_size, err = 0;
3541 uint32_t *ret_types;
3542 void *raw_btf = NULL;
3544 type_sec_size = get_raw_sec_size(raw_types);
3545 if (CHECK(type_sec_size < 0, "Cannot get nr_raw_types"))
3546 return NULL;
3548 size_needed = sizeof(*hdr) + type_sec_size + str_sec_size;
3549 raw_btf = malloc(size_needed);
3550 if (CHECK(!raw_btf, "Cannot allocate memory for raw_btf"))
3551 return NULL;
3553 /* Copy header */
3554 memcpy(raw_btf, hdr, sizeof(*hdr));
3555 offset = sizeof(*hdr);
3557 /* Index strings */
3558 while ((next_str = get_next_str(next_str, end_str))) {
3559 if (strs_cnt == strs_cap) {
3560 strs_cap += max(16, strs_cap / 2);
3561 tmp_strs_idx = realloc(strs_idx,
3562 sizeof(*strs_idx) * strs_cap);
3563 if (CHECK(!tmp_strs_idx,
3564 "Cannot allocate memory for strs_idx")) {
3565 err = -1;
3566 goto done;
3568 strs_idx = tmp_strs_idx;
3570 strs_idx[strs_cnt++] = next_str;
3571 next_str += strlen(next_str);
3574 /* Copy type section */
3575 ret_types = raw_btf + offset;
3576 for (i = 0; i < type_sec_size / sizeof(raw_types[0]); i++) {
3577 if (raw_types[i] == NAME_TBD) {
3578 if (CHECK(next_str_idx == strs_cnt,
3579 "Error in getting next_str #%d",
3580 next_str_idx)) {
3581 err = -1;
3582 goto done;
3584 ret_types[i] = strs_idx[next_str_idx++] - str;
3585 } else if (IS_NAME_NTH(raw_types[i])) {
3586 int idx = GET_NAME_NTH_IDX(raw_types[i]);
3588 if (CHECK(idx <= 0 || idx > strs_cnt,
3589 "Error getting string #%d, strs_cnt:%d",
3590 idx, strs_cnt)) {
3591 err = -1;
3592 goto done;
3594 ret_types[i] = strs_idx[idx-1] - str;
3595 } else {
3596 ret_types[i] = raw_types[i];
3599 offset += type_sec_size;
3601 /* Copy string section */
3602 memcpy(raw_btf + offset, str, str_sec_size);
3604 ret_hdr = (struct btf_header *)raw_btf;
3605 ret_hdr->type_len = type_sec_size;
3606 ret_hdr->str_off = type_sec_size;
3607 ret_hdr->str_len = str_sec_size;
3609 *btf_size = size_needed;
3610 if (ret_next_str)
3611 *ret_next_str =
3612 next_str_idx < strs_cnt ? strs_idx[next_str_idx] : NULL;
3614 done:
3615 if (err) {
3616 if (raw_btf)
3617 free(raw_btf);
3618 if (strs_idx)
3619 free(strs_idx);
3620 return NULL;
3622 return raw_btf;
3625 static int do_test_raw(unsigned int test_num)
3627 struct btf_raw_test *test = &raw_tests[test_num - 1];
3628 struct bpf_create_map_attr create_attr = {};
3629 int map_fd = -1, btf_fd = -1;
3630 unsigned int raw_btf_size;
3631 struct btf_header *hdr;
3632 void *raw_btf;
3633 int err;
3635 fprintf(stderr, "BTF raw test[%u] (%s): ", test_num, test->descr);
3636 raw_btf = btf_raw_create(&hdr_tmpl,
3637 test->raw_types,
3638 test->str_sec,
3639 test->str_sec_size,
3640 &raw_btf_size, NULL);
3642 if (!raw_btf)
3643 return -1;
3645 hdr = raw_btf;
3647 hdr->hdr_len = (int)hdr->hdr_len + test->hdr_len_delta;
3648 hdr->type_off = (int)hdr->type_off + test->type_off_delta;
3649 hdr->str_off = (int)hdr->str_off + test->str_off_delta;
3650 hdr->str_len = (int)hdr->str_len + test->str_len_delta;
3652 *btf_log_buf = '\0';
3653 btf_fd = bpf_load_btf(raw_btf, raw_btf_size,
3654 btf_log_buf, BTF_LOG_BUF_SIZE,
3655 args.always_log);
3656 free(raw_btf);
3658 err = ((btf_fd == -1) != test->btf_load_err);
3659 if (CHECK(err, "btf_fd:%d test->btf_load_err:%u",
3660 btf_fd, test->btf_load_err) ||
3661 CHECK(test->err_str && !strstr(btf_log_buf, test->err_str),
3662 "expected err_str:%s", test->err_str)) {
3663 err = -1;
3664 goto done;
3667 if (err || btf_fd == -1)
3668 goto done;
3670 create_attr.name = test->map_name;
3671 create_attr.map_type = test->map_type;
3672 create_attr.key_size = test->key_size;
3673 create_attr.value_size = test->value_size;
3674 create_attr.max_entries = test->max_entries;
3675 create_attr.btf_fd = btf_fd;
3676 create_attr.btf_key_type_id = test->key_type_id;
3677 create_attr.btf_value_type_id = test->value_type_id;
3679 map_fd = bpf_create_map_xattr(&create_attr);
3681 err = ((map_fd == -1) != test->map_create_err);
3682 CHECK(err, "map_fd:%d test->map_create_err:%u",
3683 map_fd, test->map_create_err);
3685 done:
3686 if (!err)
3687 fprintf(stderr, "OK");
3689 if (*btf_log_buf && (err || args.always_log))
3690 fprintf(stderr, "\n%s", btf_log_buf);
3692 if (btf_fd != -1)
3693 close(btf_fd);
3694 if (map_fd != -1)
3695 close(map_fd);
3697 return err;
3700 static int test_raw(void)
3702 unsigned int i;
3703 int err = 0;
3705 if (args.raw_test_num)
3706 return count_result(do_test_raw(args.raw_test_num));
3708 for (i = 1; i <= ARRAY_SIZE(raw_tests); i++)
3709 err |= count_result(do_test_raw(i));
3711 return err;
3714 struct btf_get_info_test {
3715 const char *descr;
3716 const char *str_sec;
3717 __u32 raw_types[MAX_NR_RAW_U32];
3718 __u32 str_sec_size;
3719 int btf_size_delta;
3720 int (*special_test)(unsigned int test_num);
3723 static int test_big_btf_info(unsigned int test_num);
3724 static int test_btf_id(unsigned int test_num);
3726 const struct btf_get_info_test get_info_tests[] = {
3728 .descr = "== raw_btf_size+1",
3729 .raw_types = {
3730 /* int */ /* [1] */
3731 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
3732 BTF_END_RAW,
3734 .str_sec = "",
3735 .str_sec_size = sizeof(""),
3736 .btf_size_delta = 1,
3739 .descr = "== raw_btf_size-3",
3740 .raw_types = {
3741 /* int */ /* [1] */
3742 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
3743 BTF_END_RAW,
3745 .str_sec = "",
3746 .str_sec_size = sizeof(""),
3747 .btf_size_delta = -3,
3750 .descr = "Large bpf_btf_info",
3751 .raw_types = {
3752 /* int */ /* [1] */
3753 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
3754 BTF_END_RAW,
3756 .str_sec = "",
3757 .str_sec_size = sizeof(""),
3758 .special_test = test_big_btf_info,
3761 .descr = "BTF ID",
3762 .raw_types = {
3763 /* int */ /* [1] */
3764 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
3765 /* unsigned int */ /* [2] */
3766 BTF_TYPE_INT_ENC(0, 0, 0, 32, 4),
3767 BTF_END_RAW,
3769 .str_sec = "",
3770 .str_sec_size = sizeof(""),
3771 .special_test = test_btf_id,
3775 static inline __u64 ptr_to_u64(const void *ptr)
3777 return (__u64)(unsigned long)ptr;
3780 static int test_big_btf_info(unsigned int test_num)
3782 const struct btf_get_info_test *test = &get_info_tests[test_num - 1];
3783 uint8_t *raw_btf = NULL, *user_btf = NULL;
3784 unsigned int raw_btf_size;
3785 struct {
3786 struct bpf_btf_info info;
3787 uint64_t garbage;
3788 } info_garbage;
3789 struct bpf_btf_info *info;
3790 int btf_fd = -1, err;
3791 uint32_t info_len;
3793 raw_btf = btf_raw_create(&hdr_tmpl,
3794 test->raw_types,
3795 test->str_sec,
3796 test->str_sec_size,
3797 &raw_btf_size, NULL);
3799 if (!raw_btf)
3800 return -1;
3802 *btf_log_buf = '\0';
3804 user_btf = malloc(raw_btf_size);
3805 if (CHECK(!user_btf, "!user_btf")) {
3806 err = -1;
3807 goto done;
3810 btf_fd = bpf_load_btf(raw_btf, raw_btf_size,
3811 btf_log_buf, BTF_LOG_BUF_SIZE,
3812 args.always_log);
3813 if (CHECK(btf_fd == -1, "errno:%d", errno)) {
3814 err = -1;
3815 goto done;
3819 * GET_INFO should error out if the userspace info
3820 * has non zero tailing bytes.
3822 info = &info_garbage.info;
3823 memset(info, 0, sizeof(*info));
3824 info_garbage.garbage = 0xdeadbeef;
3825 info_len = sizeof(info_garbage);
3826 info->btf = ptr_to_u64(user_btf);
3827 info->btf_size = raw_btf_size;
3829 err = bpf_obj_get_info_by_fd(btf_fd, info, &info_len);
3830 if (CHECK(!err, "!err")) {
3831 err = -1;
3832 goto done;
3836 * GET_INFO should succeed even info_len is larger than
3837 * the kernel supported as long as tailing bytes are zero.
3838 * The kernel supported info len should also be returned
3839 * to userspace.
3841 info_garbage.garbage = 0;
3842 err = bpf_obj_get_info_by_fd(btf_fd, info, &info_len);
3843 if (CHECK(err || info_len != sizeof(*info),
3844 "err:%d errno:%d info_len:%u sizeof(*info):%lu",
3845 err, errno, info_len, sizeof(*info))) {
3846 err = -1;
3847 goto done;
3850 fprintf(stderr, "OK");
3852 done:
3853 if (*btf_log_buf && (err || args.always_log))
3854 fprintf(stderr, "\n%s", btf_log_buf);
3856 free(raw_btf);
3857 free(user_btf);
3859 if (btf_fd != -1)
3860 close(btf_fd);
3862 return err;
3865 static int test_btf_id(unsigned int test_num)
3867 const struct btf_get_info_test *test = &get_info_tests[test_num - 1];
3868 struct bpf_create_map_attr create_attr = {};
3869 uint8_t *raw_btf = NULL, *user_btf[2] = {};
3870 int btf_fd[2] = {-1, -1}, map_fd = -1;
3871 struct bpf_map_info map_info = {};
3872 struct bpf_btf_info info[2] = {};
3873 unsigned int raw_btf_size;
3874 uint32_t info_len;
3875 int err, i, ret;
3877 raw_btf = btf_raw_create(&hdr_tmpl,
3878 test->raw_types,
3879 test->str_sec,
3880 test->str_sec_size,
3881 &raw_btf_size, NULL);
3883 if (!raw_btf)
3884 return -1;
3886 *btf_log_buf = '\0';
3888 for (i = 0; i < 2; i++) {
3889 user_btf[i] = malloc(raw_btf_size);
3890 if (CHECK(!user_btf[i], "!user_btf[%d]", i)) {
3891 err = -1;
3892 goto done;
3894 info[i].btf = ptr_to_u64(user_btf[i]);
3895 info[i].btf_size = raw_btf_size;
3898 btf_fd[0] = bpf_load_btf(raw_btf, raw_btf_size,
3899 btf_log_buf, BTF_LOG_BUF_SIZE,
3900 args.always_log);
3901 if (CHECK(btf_fd[0] == -1, "errno:%d", errno)) {
3902 err = -1;
3903 goto done;
3906 /* Test BPF_OBJ_GET_INFO_BY_ID on btf_id */
3907 info_len = sizeof(info[0]);
3908 err = bpf_obj_get_info_by_fd(btf_fd[0], &info[0], &info_len);
3909 if (CHECK(err, "errno:%d", errno)) {
3910 err = -1;
3911 goto done;
3914 btf_fd[1] = bpf_btf_get_fd_by_id(info[0].id);
3915 if (CHECK(btf_fd[1] == -1, "errno:%d", errno)) {
3916 err = -1;
3917 goto done;
3920 ret = 0;
3921 err = bpf_obj_get_info_by_fd(btf_fd[1], &info[1], &info_len);
3922 if (CHECK(err || info[0].id != info[1].id ||
3923 info[0].btf_size != info[1].btf_size ||
3924 (ret = memcmp(user_btf[0], user_btf[1], info[0].btf_size)),
3925 "err:%d errno:%d id0:%u id1:%u btf_size0:%u btf_size1:%u memcmp:%d",
3926 err, errno, info[0].id, info[1].id,
3927 info[0].btf_size, info[1].btf_size, ret)) {
3928 err = -1;
3929 goto done;
3932 /* Test btf members in struct bpf_map_info */
3933 create_attr.name = "test_btf_id";
3934 create_attr.map_type = BPF_MAP_TYPE_ARRAY;
3935 create_attr.key_size = sizeof(int);
3936 create_attr.value_size = sizeof(unsigned int);
3937 create_attr.max_entries = 4;
3938 create_attr.btf_fd = btf_fd[0];
3939 create_attr.btf_key_type_id = 1;
3940 create_attr.btf_value_type_id = 2;
3942 map_fd = bpf_create_map_xattr(&create_attr);
3943 if (CHECK(map_fd == -1, "errno:%d", errno)) {
3944 err = -1;
3945 goto done;
3948 info_len = sizeof(map_info);
3949 err = bpf_obj_get_info_by_fd(map_fd, &map_info, &info_len);
3950 if (CHECK(err || map_info.btf_id != info[0].id ||
3951 map_info.btf_key_type_id != 1 || map_info.btf_value_type_id != 2,
3952 "err:%d errno:%d info.id:%u btf_id:%u btf_key_type_id:%u btf_value_type_id:%u",
3953 err, errno, info[0].id, map_info.btf_id, map_info.btf_key_type_id,
3954 map_info.btf_value_type_id)) {
3955 err = -1;
3956 goto done;
3959 for (i = 0; i < 2; i++) {
3960 close(btf_fd[i]);
3961 btf_fd[i] = -1;
3964 /* Test BTF ID is removed from the kernel */
3965 btf_fd[0] = bpf_btf_get_fd_by_id(map_info.btf_id);
3966 if (CHECK(btf_fd[0] == -1, "errno:%d", errno)) {
3967 err = -1;
3968 goto done;
3970 close(btf_fd[0]);
3971 btf_fd[0] = -1;
3973 /* The map holds the last ref to BTF and its btf_id */
3974 close(map_fd);
3975 map_fd = -1;
3976 btf_fd[0] = bpf_btf_get_fd_by_id(map_info.btf_id);
3977 if (CHECK(btf_fd[0] != -1, "BTF lingers")) {
3978 err = -1;
3979 goto done;
3982 fprintf(stderr, "OK");
3984 done:
3985 if (*btf_log_buf && (err || args.always_log))
3986 fprintf(stderr, "\n%s", btf_log_buf);
3988 free(raw_btf);
3989 if (map_fd != -1)
3990 close(map_fd);
3991 for (i = 0; i < 2; i++) {
3992 free(user_btf[i]);
3993 if (btf_fd[i] != -1)
3994 close(btf_fd[i]);
3997 return err;
4000 static int do_test_get_info(unsigned int test_num)
4002 const struct btf_get_info_test *test = &get_info_tests[test_num - 1];
4003 unsigned int raw_btf_size, user_btf_size, expected_nbytes;
4004 uint8_t *raw_btf = NULL, *user_btf = NULL;
4005 struct bpf_btf_info info = {};
4006 int btf_fd = -1, err, ret;
4007 uint32_t info_len;
4009 fprintf(stderr, "BTF GET_INFO test[%u] (%s): ",
4010 test_num, test->descr);
4012 if (test->special_test)
4013 return test->special_test(test_num);
4015 raw_btf = btf_raw_create(&hdr_tmpl,
4016 test->raw_types,
4017 test->str_sec,
4018 test->str_sec_size,
4019 &raw_btf_size, NULL);
4021 if (!raw_btf)
4022 return -1;
4024 *btf_log_buf = '\0';
4026 user_btf = malloc(raw_btf_size);
4027 if (CHECK(!user_btf, "!user_btf")) {
4028 err = -1;
4029 goto done;
4032 btf_fd = bpf_load_btf(raw_btf, raw_btf_size,
4033 btf_log_buf, BTF_LOG_BUF_SIZE,
4034 args.always_log);
4035 if (CHECK(btf_fd == -1, "errno:%d", errno)) {
4036 err = -1;
4037 goto done;
4040 user_btf_size = (int)raw_btf_size + test->btf_size_delta;
4041 expected_nbytes = min(raw_btf_size, user_btf_size);
4042 if (raw_btf_size > expected_nbytes)
4043 memset(user_btf + expected_nbytes, 0xff,
4044 raw_btf_size - expected_nbytes);
4046 info_len = sizeof(info);
4047 info.btf = ptr_to_u64(user_btf);
4048 info.btf_size = user_btf_size;
4050 ret = 0;
4051 err = bpf_obj_get_info_by_fd(btf_fd, &info, &info_len);
4052 if (CHECK(err || !info.id || info_len != sizeof(info) ||
4053 info.btf_size != raw_btf_size ||
4054 (ret = memcmp(raw_btf, user_btf, expected_nbytes)),
4055 "err:%d errno:%d info.id:%u info_len:%u sizeof(info):%lu raw_btf_size:%u info.btf_size:%u expected_nbytes:%u memcmp:%d",
4056 err, errno, info.id, info_len, sizeof(info),
4057 raw_btf_size, info.btf_size, expected_nbytes, ret)) {
4058 err = -1;
4059 goto done;
4062 while (expected_nbytes < raw_btf_size) {
4063 fprintf(stderr, "%u...", expected_nbytes);
4064 if (CHECK(user_btf[expected_nbytes++] != 0xff,
4065 "user_btf[%u]:%x != 0xff", expected_nbytes - 1,
4066 user_btf[expected_nbytes - 1])) {
4067 err = -1;
4068 goto done;
4072 fprintf(stderr, "OK");
4074 done:
4075 if (*btf_log_buf && (err || args.always_log))
4076 fprintf(stderr, "\n%s", btf_log_buf);
4078 free(raw_btf);
4079 free(user_btf);
4081 if (btf_fd != -1)
4082 close(btf_fd);
4084 return err;
4087 static int test_get_info(void)
4089 unsigned int i;
4090 int err = 0;
4092 if (args.get_info_test_num)
4093 return count_result(do_test_get_info(args.get_info_test_num));
4095 for (i = 1; i <= ARRAY_SIZE(get_info_tests); i++)
4096 err |= count_result(do_test_get_info(i));
4098 return err;
4101 struct btf_file_test {
4102 const char *file;
4103 bool btf_kv_notfound;
4106 static struct btf_file_test file_tests[] = {
4107 { .file = "test_btf_haskv.o", },
4108 { .file = "test_btf_newkv.o", },
4109 { .file = "test_btf_nokv.o", .btf_kv_notfound = true, },
4112 static int do_test_file(unsigned int test_num)
4114 const struct btf_file_test *test = &file_tests[test_num - 1];
4115 const char *expected_fnames[] = {"_dummy_tracepoint",
4116 "test_long_fname_1",
4117 "test_long_fname_2"};
4118 struct btf_ext *btf_ext = NULL;
4119 struct bpf_prog_info info = {};
4120 struct bpf_object *obj = NULL;
4121 struct bpf_func_info *finfo;
4122 struct bpf_program *prog;
4123 __u32 info_len, rec_size;
4124 bool has_btf_ext = false;
4125 struct btf *btf = NULL;
4126 void *func_info = NULL;
4127 struct bpf_map *map;
4128 int i, err, prog_fd;
4130 fprintf(stderr, "BTF libbpf test[%u] (%s): ", test_num,
4131 test->file);
4133 btf = btf__parse_elf(test->file, &btf_ext);
4134 if (IS_ERR(btf)) {
4135 if (PTR_ERR(btf) == -ENOENT) {
4136 fprintf(stderr, "SKIP. No ELF %s found", BTF_ELF_SEC);
4137 skip_cnt++;
4138 return 0;
4140 return PTR_ERR(btf);
4142 btf__free(btf);
4144 has_btf_ext = btf_ext != NULL;
4145 btf_ext__free(btf_ext);
4147 obj = bpf_object__open(test->file);
4148 if (CHECK(IS_ERR(obj), "obj: %ld", PTR_ERR(obj)))
4149 return PTR_ERR(obj);
4151 prog = bpf_program__next(NULL, obj);
4152 if (CHECK(!prog, "Cannot find bpf_prog")) {
4153 err = -1;
4154 goto done;
4157 bpf_program__set_type(prog, BPF_PROG_TYPE_TRACEPOINT);
4158 err = bpf_object__load(obj);
4159 if (CHECK(err < 0, "bpf_object__load: %d", err))
4160 goto done;
4161 prog_fd = bpf_program__fd(prog);
4163 map = bpf_object__find_map_by_name(obj, "btf_map");
4164 if (CHECK(!map, "btf_map not found")) {
4165 err = -1;
4166 goto done;
4169 err = (bpf_map__btf_key_type_id(map) == 0 || bpf_map__btf_value_type_id(map) == 0)
4170 != test->btf_kv_notfound;
4171 if (CHECK(err, "btf_key_type_id:%u btf_value_type_id:%u test->btf_kv_notfound:%u",
4172 bpf_map__btf_key_type_id(map), bpf_map__btf_value_type_id(map),
4173 test->btf_kv_notfound))
4174 goto done;
4176 if (!has_btf_ext)
4177 goto skip;
4179 /* get necessary program info */
4180 info_len = sizeof(struct bpf_prog_info);
4181 err = bpf_obj_get_info_by_fd(prog_fd, &info, &info_len);
4183 if (CHECK(err == -1, "invalid get info (1st) errno:%d", errno)) {
4184 fprintf(stderr, "%s\n", btf_log_buf);
4185 err = -1;
4186 goto done;
4188 if (CHECK(info.nr_func_info != 3,
4189 "incorrect info.nr_func_info (1st) %d",
4190 info.nr_func_info)) {
4191 err = -1;
4192 goto done;
4194 rec_size = info.func_info_rec_size;
4195 if (CHECK(rec_size != sizeof(struct bpf_func_info),
4196 "incorrect info.func_info_rec_size (1st) %d\n", rec_size)) {
4197 err = -1;
4198 goto done;
4201 func_info = malloc(info.nr_func_info * rec_size);
4202 if (CHECK(!func_info, "out of memory")) {
4203 err = -1;
4204 goto done;
4207 /* reset info to only retrieve func_info related data */
4208 memset(&info, 0, sizeof(info));
4209 info.nr_func_info = 3;
4210 info.func_info_rec_size = rec_size;
4211 info.func_info = ptr_to_u64(func_info);
4213 err = bpf_obj_get_info_by_fd(prog_fd, &info, &info_len);
4215 if (CHECK(err == -1, "invalid get info (2nd) errno:%d", errno)) {
4216 fprintf(stderr, "%s\n", btf_log_buf);
4217 err = -1;
4218 goto done;
4220 if (CHECK(info.nr_func_info != 3,
4221 "incorrect info.nr_func_info (2nd) %d",
4222 info.nr_func_info)) {
4223 err = -1;
4224 goto done;
4226 if (CHECK(info.func_info_rec_size != rec_size,
4227 "incorrect info.func_info_rec_size (2nd) %d",
4228 info.func_info_rec_size)) {
4229 err = -1;
4230 goto done;
4233 err = btf__get_from_id(info.btf_id, &btf);
4234 if (CHECK(err, "cannot get btf from kernel, err: %d", err))
4235 goto done;
4237 /* check three functions */
4238 finfo = func_info;
4239 for (i = 0; i < 3; i++) {
4240 const struct btf_type *t;
4241 const char *fname;
4243 t = btf__type_by_id(btf, finfo->type_id);
4244 if (CHECK(!t, "btf__type_by_id failure: id %u",
4245 finfo->type_id)) {
4246 err = -1;
4247 goto done;
4250 fname = btf__name_by_offset(btf, t->name_off);
4251 err = strcmp(fname, expected_fnames[i]);
4252 /* for the second and third functions in .text section,
4253 * the compiler may order them either way.
4255 if (i && err)
4256 err = strcmp(fname, expected_fnames[3 - i]);
4257 if (CHECK(err, "incorrect fname %s", fname ? : "")) {
4258 err = -1;
4259 goto done;
4262 finfo = (void *)finfo + rec_size;
4265 skip:
4266 fprintf(stderr, "OK");
4268 done:
4269 free(func_info);
4270 bpf_object__close(obj);
4271 return err;
4274 static int test_file(void)
4276 unsigned int i;
4277 int err = 0;
4279 if (args.file_test_num)
4280 return count_result(do_test_file(args.file_test_num));
4282 for (i = 1; i <= ARRAY_SIZE(file_tests); i++)
4283 err |= count_result(do_test_file(i));
4285 return err;
4288 const char *pprint_enum_str[] = {
4289 "ENUM_ZERO",
4290 "ENUM_ONE",
4291 "ENUM_TWO",
4292 "ENUM_THREE",
4295 struct pprint_mapv {
4296 uint32_t ui32;
4297 uint16_t ui16;
4298 /* 2 bytes hole */
4299 int32_t si32;
4300 uint32_t unused_bits2a:2,
4301 bits28:28,
4302 unused_bits2b:2;
4303 union {
4304 uint64_t ui64;
4305 uint8_t ui8a[8];
4307 enum {
4308 ENUM_ZERO,
4309 ENUM_ONE,
4310 ENUM_TWO,
4311 ENUM_THREE,
4312 } aenum;
4313 uint32_t ui32b;
4314 uint32_t bits2c:2;
4315 uint8_t si8_4[2][2];
4318 #ifdef __SIZEOF_INT128__
4319 struct pprint_mapv_int128 {
4320 __int128 si128a;
4321 __int128 si128b;
4322 unsigned __int128 bits3:3;
4323 unsigned __int128 bits80:80;
4324 unsigned __int128 ui128;
4326 #endif
4328 static struct btf_raw_test pprint_test_template[] = {
4330 .raw_types = {
4331 /* unsighed char */ /* [1] */
4332 BTF_TYPE_INT_ENC(NAME_TBD, 0, 0, 8, 1),
4333 /* unsigned short */ /* [2] */
4334 BTF_TYPE_INT_ENC(NAME_TBD, 0, 0, 16, 2),
4335 /* unsigned int */ /* [3] */
4336 BTF_TYPE_INT_ENC(NAME_TBD, 0, 0, 32, 4),
4337 /* int */ /* [4] */
4338 BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),
4339 /* unsigned long long */ /* [5] */
4340 BTF_TYPE_INT_ENC(NAME_TBD, 0, 0, 64, 8),
4341 /* 2 bits */ /* [6] */
4342 BTF_TYPE_INT_ENC(0, 0, 0, 2, 2),
4343 /* 28 bits */ /* [7] */
4344 BTF_TYPE_INT_ENC(0, 0, 0, 28, 4),
4345 /* uint8_t[8] */ /* [8] */
4346 BTF_TYPE_ARRAY_ENC(9, 1, 8),
4347 /* typedef unsigned char uint8_t */ /* [9] */
4348 BTF_TYPEDEF_ENC(NAME_TBD, 1),
4349 /* typedef unsigned short uint16_t */ /* [10] */
4350 BTF_TYPEDEF_ENC(NAME_TBD, 2),
4351 /* typedef unsigned int uint32_t */ /* [11] */
4352 BTF_TYPEDEF_ENC(NAME_TBD, 3),
4353 /* typedef int int32_t */ /* [12] */
4354 BTF_TYPEDEF_ENC(NAME_TBD, 4),
4355 /* typedef unsigned long long uint64_t *//* [13] */
4356 BTF_TYPEDEF_ENC(NAME_TBD, 5),
4357 /* union (anon) */ /* [14] */
4358 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_UNION, 0, 2), 8),
4359 BTF_MEMBER_ENC(NAME_TBD, 13, 0),/* uint64_t ui64; */
4360 BTF_MEMBER_ENC(NAME_TBD, 8, 0), /* uint8_t ui8a[8]; */
4361 /* enum (anon) */ /* [15] */
4362 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_ENUM, 0, 4), 4),
4363 BTF_ENUM_ENC(NAME_TBD, 0),
4364 BTF_ENUM_ENC(NAME_TBD, 1),
4365 BTF_ENUM_ENC(NAME_TBD, 2),
4366 BTF_ENUM_ENC(NAME_TBD, 3),
4367 /* struct pprint_mapv */ /* [16] */
4368 BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 11), 40),
4369 BTF_MEMBER_ENC(NAME_TBD, 11, 0), /* uint32_t ui32 */
4370 BTF_MEMBER_ENC(NAME_TBD, 10, 32), /* uint16_t ui16 */
4371 BTF_MEMBER_ENC(NAME_TBD, 12, 64), /* int32_t si32 */
4372 BTF_MEMBER_ENC(NAME_TBD, 6, 96), /* unused_bits2a */
4373 BTF_MEMBER_ENC(NAME_TBD, 7, 98), /* bits28 */
4374 BTF_MEMBER_ENC(NAME_TBD, 6, 126), /* unused_bits2b */
4375 BTF_MEMBER_ENC(0, 14, 128), /* union (anon) */
4376 BTF_MEMBER_ENC(NAME_TBD, 15, 192), /* aenum */
4377 BTF_MEMBER_ENC(NAME_TBD, 11, 224), /* uint32_t ui32b */
4378 BTF_MEMBER_ENC(NAME_TBD, 6, 256), /* bits2c */
4379 BTF_MEMBER_ENC(NAME_TBD, 17, 264), /* si8_4 */
4380 BTF_TYPE_ARRAY_ENC(18, 1, 2), /* [17] */
4381 BTF_TYPE_ARRAY_ENC(1, 1, 2), /* [18] */
4382 BTF_END_RAW,
4384 BTF_STR_SEC("\0unsigned char\0unsigned short\0unsigned int\0int\0unsigned long long\0uint8_t\0uint16_t\0uint32_t\0int32_t\0uint64_t\0ui64\0ui8a\0ENUM_ZERO\0ENUM_ONE\0ENUM_TWO\0ENUM_THREE\0pprint_mapv\0ui32\0ui16\0si32\0unused_bits2a\0bits28\0unused_bits2b\0aenum\0ui32b\0bits2c\0si8_4"),
4385 .key_size = sizeof(unsigned int),
4386 .value_size = sizeof(struct pprint_mapv),
4387 .key_type_id = 3, /* unsigned int */
4388 .value_type_id = 16, /* struct pprint_mapv */
4389 .max_entries = 128 * 1024,
4393 /* this type will have the same type as the
4394 * first .raw_types definition, but struct type will
4395 * be encoded with kind_flag set.
4397 .raw_types = {
4398 /* unsighed char */ /* [1] */
4399 BTF_TYPE_INT_ENC(NAME_TBD, 0, 0, 8, 1),
4400 /* unsigned short */ /* [2] */
4401 BTF_TYPE_INT_ENC(NAME_TBD, 0, 0, 16, 2),
4402 /* unsigned int */ /* [3] */
4403 BTF_TYPE_INT_ENC(NAME_TBD, 0, 0, 32, 4),
4404 /* int */ /* [4] */
4405 BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),
4406 /* unsigned long long */ /* [5] */
4407 BTF_TYPE_INT_ENC(NAME_TBD, 0, 0, 64, 8),
4408 BTF_TYPE_INT_ENC(0, 0, 0, 32, 4), /* [6] */
4409 BTF_TYPE_INT_ENC(0, 0, 0, 32, 4), /* [7] */
4410 /* uint8_t[8] */ /* [8] */
4411 BTF_TYPE_ARRAY_ENC(9, 1, 8),
4412 /* typedef unsigned char uint8_t */ /* [9] */
4413 BTF_TYPEDEF_ENC(NAME_TBD, 1),
4414 /* typedef unsigned short uint16_t */ /* [10] */
4415 BTF_TYPEDEF_ENC(NAME_TBD, 2),
4416 /* typedef unsigned int uint32_t */ /* [11] */
4417 BTF_TYPEDEF_ENC(NAME_TBD, 3),
4418 /* typedef int int32_t */ /* [12] */
4419 BTF_TYPEDEF_ENC(NAME_TBD, 4),
4420 /* typedef unsigned long long uint64_t *//* [13] */
4421 BTF_TYPEDEF_ENC(NAME_TBD, 5),
4422 /* union (anon) */ /* [14] */
4423 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_UNION, 0, 2), 8),
4424 BTF_MEMBER_ENC(NAME_TBD, 13, 0),/* uint64_t ui64; */
4425 BTF_MEMBER_ENC(NAME_TBD, 8, 0), /* uint8_t ui8a[8]; */
4426 /* enum (anon) */ /* [15] */
4427 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_ENUM, 0, 4), 4),
4428 BTF_ENUM_ENC(NAME_TBD, 0),
4429 BTF_ENUM_ENC(NAME_TBD, 1),
4430 BTF_ENUM_ENC(NAME_TBD, 2),
4431 BTF_ENUM_ENC(NAME_TBD, 3),
4432 /* struct pprint_mapv */ /* [16] */
4433 BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 1, 11), 40),
4434 BTF_MEMBER_ENC(NAME_TBD, 11, BTF_MEMBER_OFFSET(0, 0)), /* uint32_t ui32 */
4435 BTF_MEMBER_ENC(NAME_TBD, 10, BTF_MEMBER_OFFSET(0, 32)), /* uint16_t ui16 */
4436 BTF_MEMBER_ENC(NAME_TBD, 12, BTF_MEMBER_OFFSET(0, 64)), /* int32_t si32 */
4437 BTF_MEMBER_ENC(NAME_TBD, 6, BTF_MEMBER_OFFSET(2, 96)), /* unused_bits2a */
4438 BTF_MEMBER_ENC(NAME_TBD, 7, BTF_MEMBER_OFFSET(28, 98)), /* bits28 */
4439 BTF_MEMBER_ENC(NAME_TBD, 6, BTF_MEMBER_OFFSET(2, 126)), /* unused_bits2b */
4440 BTF_MEMBER_ENC(0, 14, BTF_MEMBER_OFFSET(0, 128)), /* union (anon) */
4441 BTF_MEMBER_ENC(NAME_TBD, 15, BTF_MEMBER_OFFSET(0, 192)), /* aenum */
4442 BTF_MEMBER_ENC(NAME_TBD, 11, BTF_MEMBER_OFFSET(0, 224)), /* uint32_t ui32b */
4443 BTF_MEMBER_ENC(NAME_TBD, 6, BTF_MEMBER_OFFSET(2, 256)), /* bits2c */
4444 BTF_MEMBER_ENC(NAME_TBD, 17, 264), /* si8_4 */
4445 BTF_TYPE_ARRAY_ENC(18, 1, 2), /* [17] */
4446 BTF_TYPE_ARRAY_ENC(1, 1, 2), /* [18] */
4447 BTF_END_RAW,
4449 BTF_STR_SEC("\0unsigned char\0unsigned short\0unsigned int\0int\0unsigned long long\0uint8_t\0uint16_t\0uint32_t\0int32_t\0uint64_t\0ui64\0ui8a\0ENUM_ZERO\0ENUM_ONE\0ENUM_TWO\0ENUM_THREE\0pprint_mapv\0ui32\0ui16\0si32\0unused_bits2a\0bits28\0unused_bits2b\0aenum\0ui32b\0bits2c\0si8_4"),
4450 .key_size = sizeof(unsigned int),
4451 .value_size = sizeof(struct pprint_mapv),
4452 .key_type_id = 3, /* unsigned int */
4453 .value_type_id = 16, /* struct pprint_mapv */
4454 .max_entries = 128 * 1024,
4458 /* this type will have the same layout as the
4459 * first .raw_types definition. The struct type will
4460 * be encoded with kind_flag set, bitfield members
4461 * are added typedef/const/volatile, and bitfield members
4462 * will have both int and enum types.
4464 .raw_types = {
4465 /* unsighed char */ /* [1] */
4466 BTF_TYPE_INT_ENC(NAME_TBD, 0, 0, 8, 1),
4467 /* unsigned short */ /* [2] */
4468 BTF_TYPE_INT_ENC(NAME_TBD, 0, 0, 16, 2),
4469 /* unsigned int */ /* [3] */
4470 BTF_TYPE_INT_ENC(NAME_TBD, 0, 0, 32, 4),
4471 /* int */ /* [4] */
4472 BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),
4473 /* unsigned long long */ /* [5] */
4474 BTF_TYPE_INT_ENC(NAME_TBD, 0, 0, 64, 8),
4475 BTF_TYPE_INT_ENC(0, 0, 0, 32, 4), /* [6] */
4476 BTF_TYPE_INT_ENC(0, 0, 0, 32, 4), /* [7] */
4477 /* uint8_t[8] */ /* [8] */
4478 BTF_TYPE_ARRAY_ENC(9, 1, 8),
4479 /* typedef unsigned char uint8_t */ /* [9] */
4480 BTF_TYPEDEF_ENC(NAME_TBD, 1),
4481 /* typedef unsigned short uint16_t */ /* [10] */
4482 BTF_TYPEDEF_ENC(NAME_TBD, 2),
4483 /* typedef unsigned int uint32_t */ /* [11] */
4484 BTF_TYPEDEF_ENC(NAME_TBD, 3),
4485 /* typedef int int32_t */ /* [12] */
4486 BTF_TYPEDEF_ENC(NAME_TBD, 4),
4487 /* typedef unsigned long long uint64_t *//* [13] */
4488 BTF_TYPEDEF_ENC(NAME_TBD, 5),
4489 /* union (anon) */ /* [14] */
4490 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_UNION, 0, 2), 8),
4491 BTF_MEMBER_ENC(NAME_TBD, 13, 0),/* uint64_t ui64; */
4492 BTF_MEMBER_ENC(NAME_TBD, 8, 0), /* uint8_t ui8a[8]; */
4493 /* enum (anon) */ /* [15] */
4494 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_ENUM, 0, 4), 4),
4495 BTF_ENUM_ENC(NAME_TBD, 0),
4496 BTF_ENUM_ENC(NAME_TBD, 1),
4497 BTF_ENUM_ENC(NAME_TBD, 2),
4498 BTF_ENUM_ENC(NAME_TBD, 3),
4499 /* struct pprint_mapv */ /* [16] */
4500 BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 1, 11), 40),
4501 BTF_MEMBER_ENC(NAME_TBD, 11, BTF_MEMBER_OFFSET(0, 0)), /* uint32_t ui32 */
4502 BTF_MEMBER_ENC(NAME_TBD, 10, BTF_MEMBER_OFFSET(0, 32)), /* uint16_t ui16 */
4503 BTF_MEMBER_ENC(NAME_TBD, 12, BTF_MEMBER_OFFSET(0, 64)), /* int32_t si32 */
4504 BTF_MEMBER_ENC(NAME_TBD, 17, BTF_MEMBER_OFFSET(2, 96)), /* unused_bits2a */
4505 BTF_MEMBER_ENC(NAME_TBD, 7, BTF_MEMBER_OFFSET(28, 98)), /* bits28 */
4506 BTF_MEMBER_ENC(NAME_TBD, 19, BTF_MEMBER_OFFSET(2, 126)),/* unused_bits2b */
4507 BTF_MEMBER_ENC(0, 14, BTF_MEMBER_OFFSET(0, 128)), /* union (anon) */
4508 BTF_MEMBER_ENC(NAME_TBD, 15, BTF_MEMBER_OFFSET(0, 192)), /* aenum */
4509 BTF_MEMBER_ENC(NAME_TBD, 11, BTF_MEMBER_OFFSET(0, 224)), /* uint32_t ui32b */
4510 BTF_MEMBER_ENC(NAME_TBD, 17, BTF_MEMBER_OFFSET(2, 256)), /* bits2c */
4511 BTF_MEMBER_ENC(NAME_TBD, 20, BTF_MEMBER_OFFSET(0, 264)), /* si8_4 */
4512 /* typedef unsigned int ___int */ /* [17] */
4513 BTF_TYPEDEF_ENC(NAME_TBD, 18),
4514 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_VOLATILE, 0, 0), 6), /* [18] */
4515 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_CONST, 0, 0), 15), /* [19] */
4516 BTF_TYPE_ARRAY_ENC(21, 1, 2), /* [20] */
4517 BTF_TYPE_ARRAY_ENC(1, 1, 2), /* [21] */
4518 BTF_END_RAW,
4520 BTF_STR_SEC("\0unsigned char\0unsigned short\0unsigned int\0int\0unsigned long long\0uint8_t\0uint16_t\0uint32_t\0int32_t\0uint64_t\0ui64\0ui8a\0ENUM_ZERO\0ENUM_ONE\0ENUM_TWO\0ENUM_THREE\0pprint_mapv\0ui32\0ui16\0si32\0unused_bits2a\0bits28\0unused_bits2b\0aenum\0ui32b\0bits2c\0___int\0si8_4"),
4521 .key_size = sizeof(unsigned int),
4522 .value_size = sizeof(struct pprint_mapv),
4523 .key_type_id = 3, /* unsigned int */
4524 .value_type_id = 16, /* struct pprint_mapv */
4525 .max_entries = 128 * 1024,
4528 #ifdef __SIZEOF_INT128__
4530 /* test int128 */
4531 .raw_types = {
4532 /* unsigned int */ /* [1] */
4533 BTF_TYPE_INT_ENC(NAME_TBD, 0, 0, 32, 4),
4534 /* __int128 */ /* [2] */
4535 BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 128, 16),
4536 /* unsigned __int128 */ /* [3] */
4537 BTF_TYPE_INT_ENC(NAME_TBD, 0, 0, 128, 16),
4538 /* struct pprint_mapv_int128 */ /* [4] */
4539 BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 1, 5), 64),
4540 BTF_MEMBER_ENC(NAME_TBD, 2, BTF_MEMBER_OFFSET(0, 0)), /* si128a */
4541 BTF_MEMBER_ENC(NAME_TBD, 2, BTF_MEMBER_OFFSET(0, 128)), /* si128b */
4542 BTF_MEMBER_ENC(NAME_TBD, 3, BTF_MEMBER_OFFSET(3, 256)), /* bits3 */
4543 BTF_MEMBER_ENC(NAME_TBD, 3, BTF_MEMBER_OFFSET(80, 259)), /* bits80 */
4544 BTF_MEMBER_ENC(NAME_TBD, 3, BTF_MEMBER_OFFSET(0, 384)), /* ui128 */
4545 BTF_END_RAW,
4547 BTF_STR_SEC("\0unsigned int\0__int128\0unsigned __int128\0pprint_mapv_int128\0si128a\0si128b\0bits3\0bits80\0ui128"),
4548 .key_size = sizeof(unsigned int),
4549 .value_size = sizeof(struct pprint_mapv_int128),
4550 .key_type_id = 1,
4551 .value_type_id = 4,
4552 .max_entries = 128 * 1024,
4553 .mapv_kind = PPRINT_MAPV_KIND_INT128,
4555 #endif
4559 static struct btf_pprint_test_meta {
4560 const char *descr;
4561 enum bpf_map_type map_type;
4562 const char *map_name;
4563 bool ordered_map;
4564 bool lossless_map;
4565 bool percpu_map;
4566 } pprint_tests_meta[] = {
4568 .descr = "BTF pretty print array",
4569 .map_type = BPF_MAP_TYPE_ARRAY,
4570 .map_name = "pprint_test_array",
4571 .ordered_map = true,
4572 .lossless_map = true,
4573 .percpu_map = false,
4577 .descr = "BTF pretty print hash",
4578 .map_type = BPF_MAP_TYPE_HASH,
4579 .map_name = "pprint_test_hash",
4580 .ordered_map = false,
4581 .lossless_map = true,
4582 .percpu_map = false,
4586 .descr = "BTF pretty print lru hash",
4587 .map_type = BPF_MAP_TYPE_LRU_HASH,
4588 .map_name = "pprint_test_lru_hash",
4589 .ordered_map = false,
4590 .lossless_map = false,
4591 .percpu_map = false,
4595 .descr = "BTF pretty print percpu array",
4596 .map_type = BPF_MAP_TYPE_PERCPU_ARRAY,
4597 .map_name = "pprint_test_percpu_array",
4598 .ordered_map = true,
4599 .lossless_map = true,
4600 .percpu_map = true,
4604 .descr = "BTF pretty print percpu hash",
4605 .map_type = BPF_MAP_TYPE_PERCPU_HASH,
4606 .map_name = "pprint_test_percpu_hash",
4607 .ordered_map = false,
4608 .lossless_map = true,
4609 .percpu_map = true,
4613 .descr = "BTF pretty print lru percpu hash",
4614 .map_type = BPF_MAP_TYPE_LRU_PERCPU_HASH,
4615 .map_name = "pprint_test_lru_percpu_hash",
4616 .ordered_map = false,
4617 .lossless_map = false,
4618 .percpu_map = true,
4623 static size_t get_pprint_mapv_size(enum pprint_mapv_kind_t mapv_kind)
4625 if (mapv_kind == PPRINT_MAPV_KIND_BASIC)
4626 return sizeof(struct pprint_mapv);
4628 #ifdef __SIZEOF_INT128__
4629 if (mapv_kind == PPRINT_MAPV_KIND_INT128)
4630 return sizeof(struct pprint_mapv_int128);
4631 #endif
4633 assert(0);
4636 static void set_pprint_mapv(enum pprint_mapv_kind_t mapv_kind,
4637 void *mapv, uint32_t i,
4638 int num_cpus, int rounded_value_size)
4640 int cpu;
4642 if (mapv_kind == PPRINT_MAPV_KIND_BASIC) {
4643 struct pprint_mapv *v = mapv;
4645 for (cpu = 0; cpu < num_cpus; cpu++) {
4646 v->ui32 = i + cpu;
4647 v->si32 = -i;
4648 v->unused_bits2a = 3;
4649 v->bits28 = i;
4650 v->unused_bits2b = 3;
4651 v->ui64 = i;
4652 v->aenum = i & 0x03;
4653 v->ui32b = 4;
4654 v->bits2c = 1;
4655 v->si8_4[0][0] = (cpu + i) & 0xff;
4656 v->si8_4[0][1] = (cpu + i + 1) & 0xff;
4657 v->si8_4[1][0] = (cpu + i + 2) & 0xff;
4658 v->si8_4[1][1] = (cpu + i + 3) & 0xff;
4659 v = (void *)v + rounded_value_size;
4663 #ifdef __SIZEOF_INT128__
4664 if (mapv_kind == PPRINT_MAPV_KIND_INT128) {
4665 struct pprint_mapv_int128 *v = mapv;
4667 for (cpu = 0; cpu < num_cpus; cpu++) {
4668 v->si128a = i;
4669 v->si128b = -i;
4670 v->bits3 = i & 0x07;
4671 v->bits80 = (((unsigned __int128)1) << 64) + i;
4672 v->ui128 = (((unsigned __int128)2) << 64) + i;
4673 v = (void *)v + rounded_value_size;
4676 #endif
4679 ssize_t get_pprint_expected_line(enum pprint_mapv_kind_t mapv_kind,
4680 char *expected_line, ssize_t line_size,
4681 bool percpu_map, unsigned int next_key,
4682 int cpu, void *mapv)
4684 ssize_t nexpected_line = -1;
4686 if (mapv_kind == PPRINT_MAPV_KIND_BASIC) {
4687 struct pprint_mapv *v = mapv;
4689 nexpected_line = snprintf(expected_line, line_size,
4690 "%s%u: {%u,0,%d,0x%x,0x%x,0x%x,"
4691 "{%lu|[%u,%u,%u,%u,%u,%u,%u,%u]},%s,"
4692 "%u,0x%x,[[%d,%d],[%d,%d]]}\n",
4693 percpu_map ? "\tcpu" : "",
4694 percpu_map ? cpu : next_key,
4695 v->ui32, v->si32,
4696 v->unused_bits2a,
4697 v->bits28,
4698 v->unused_bits2b,
4699 v->ui64,
4700 v->ui8a[0], v->ui8a[1],
4701 v->ui8a[2], v->ui8a[3],
4702 v->ui8a[4], v->ui8a[5],
4703 v->ui8a[6], v->ui8a[7],
4704 pprint_enum_str[v->aenum],
4705 v->ui32b,
4706 v->bits2c,
4707 v->si8_4[0][0], v->si8_4[0][1],
4708 v->si8_4[1][0], v->si8_4[1][1]);
4711 #ifdef __SIZEOF_INT128__
4712 if (mapv_kind == PPRINT_MAPV_KIND_INT128) {
4713 struct pprint_mapv_int128 *v = mapv;
4715 nexpected_line = snprintf(expected_line, line_size,
4716 "%s%u: {0x%lx,0x%lx,0x%lx,"
4717 "0x%lx%016lx,0x%lx%016lx}\n",
4718 percpu_map ? "\tcpu" : "",
4719 percpu_map ? cpu : next_key,
4720 (uint64_t)v->si128a,
4721 (uint64_t)v->si128b,
4722 (uint64_t)v->bits3,
4723 (uint64_t)(v->bits80 >> 64),
4724 (uint64_t)v->bits80,
4725 (uint64_t)(v->ui128 >> 64),
4726 (uint64_t)v->ui128);
4728 #endif
4730 return nexpected_line;
4733 static int check_line(const char *expected_line, int nexpected_line,
4734 int expected_line_len, const char *line)
4736 if (CHECK(nexpected_line == expected_line_len,
4737 "expected_line is too long"))
4738 return -1;
4740 if (strcmp(expected_line, line)) {
4741 fprintf(stderr, "unexpected pprint output\n");
4742 fprintf(stderr, "expected: %s", expected_line);
4743 fprintf(stderr, " read: %s", line);
4744 return -1;
4747 return 0;
4751 static int do_test_pprint(int test_num)
4753 const struct btf_raw_test *test = &pprint_test_template[test_num];
4754 enum pprint_mapv_kind_t mapv_kind = test->mapv_kind;
4755 struct bpf_create_map_attr create_attr = {};
4756 bool ordered_map, lossless_map, percpu_map;
4757 int err, ret, num_cpus, rounded_value_size;
4758 unsigned int key, nr_read_elems;
4759 int map_fd = -1, btf_fd = -1;
4760 unsigned int raw_btf_size;
4761 char expected_line[255];
4762 FILE *pin_file = NULL;
4763 char pin_path[255];
4764 size_t line_len = 0;
4765 char *line = NULL;
4766 void *mapv = NULL;
4767 uint8_t *raw_btf;
4768 ssize_t nread;
4770 fprintf(stderr, "%s(#%d)......", test->descr, test_num);
4771 raw_btf = btf_raw_create(&hdr_tmpl, test->raw_types,
4772 test->str_sec, test->str_sec_size,
4773 &raw_btf_size, NULL);
4775 if (!raw_btf)
4776 return -1;
4778 *btf_log_buf = '\0';
4779 btf_fd = bpf_load_btf(raw_btf, raw_btf_size,
4780 btf_log_buf, BTF_LOG_BUF_SIZE,
4781 args.always_log);
4782 free(raw_btf);
4784 if (CHECK(btf_fd == -1, "errno:%d", errno)) {
4785 err = -1;
4786 goto done;
4789 create_attr.name = test->map_name;
4790 create_attr.map_type = test->map_type;
4791 create_attr.key_size = test->key_size;
4792 create_attr.value_size = test->value_size;
4793 create_attr.max_entries = test->max_entries;
4794 create_attr.btf_fd = btf_fd;
4795 create_attr.btf_key_type_id = test->key_type_id;
4796 create_attr.btf_value_type_id = test->value_type_id;
4798 map_fd = bpf_create_map_xattr(&create_attr);
4799 if (CHECK(map_fd == -1, "errno:%d", errno)) {
4800 err = -1;
4801 goto done;
4804 ret = snprintf(pin_path, sizeof(pin_path), "%s/%s",
4805 "/sys/fs/bpf", test->map_name);
4807 if (CHECK(ret == sizeof(pin_path), "pin_path %s/%s is too long",
4808 "/sys/fs/bpf", test->map_name)) {
4809 err = -1;
4810 goto done;
4813 err = bpf_obj_pin(map_fd, pin_path);
4814 if (CHECK(err, "bpf_obj_pin(%s): errno:%d.", pin_path, errno))
4815 goto done;
4817 percpu_map = test->percpu_map;
4818 num_cpus = percpu_map ? bpf_num_possible_cpus() : 1;
4819 rounded_value_size = round_up(get_pprint_mapv_size(mapv_kind), 8);
4820 mapv = calloc(num_cpus, rounded_value_size);
4821 if (CHECK(!mapv, "mapv allocation failure")) {
4822 err = -1;
4823 goto done;
4826 for (key = 0; key < test->max_entries; key++) {
4827 set_pprint_mapv(mapv_kind, mapv, key, num_cpus, rounded_value_size);
4828 bpf_map_update_elem(map_fd, &key, mapv, 0);
4831 pin_file = fopen(pin_path, "r");
4832 if (CHECK(!pin_file, "fopen(%s): errno:%d", pin_path, errno)) {
4833 err = -1;
4834 goto done;
4837 /* Skip lines start with '#' */
4838 while ((nread = getline(&line, &line_len, pin_file)) > 0 &&
4839 *line == '#')
4842 if (CHECK(nread <= 0, "Unexpected EOF")) {
4843 err = -1;
4844 goto done;
4847 nr_read_elems = 0;
4848 ordered_map = test->ordered_map;
4849 lossless_map = test->lossless_map;
4850 do {
4851 ssize_t nexpected_line;
4852 unsigned int next_key;
4853 void *cmapv;
4854 int cpu;
4856 next_key = ordered_map ? nr_read_elems : atoi(line);
4857 set_pprint_mapv(mapv_kind, mapv, next_key, num_cpus, rounded_value_size);
4858 cmapv = mapv;
4860 for (cpu = 0; cpu < num_cpus; cpu++) {
4861 if (percpu_map) {
4862 /* for percpu map, the format looks like:
4863 * <key>: {
4864 * cpu0: <value_on_cpu0>
4865 * cpu1: <value_on_cpu1>
4866 * ...
4867 * cpun: <value_on_cpun>
4870 * let us verify the line containing the key here.
4872 if (cpu == 0) {
4873 nexpected_line = snprintf(expected_line,
4874 sizeof(expected_line),
4875 "%u: {\n",
4876 next_key);
4878 err = check_line(expected_line, nexpected_line,
4879 sizeof(expected_line), line);
4880 if (err == -1)
4881 goto done;
4884 /* read value@cpu */
4885 nread = getline(&line, &line_len, pin_file);
4886 if (nread < 0)
4887 break;
4890 nexpected_line = get_pprint_expected_line(mapv_kind, expected_line,
4891 sizeof(expected_line),
4892 percpu_map, next_key,
4893 cpu, cmapv);
4894 err = check_line(expected_line, nexpected_line,
4895 sizeof(expected_line), line);
4896 if (err == -1)
4897 goto done;
4899 cmapv = cmapv + rounded_value_size;
4902 if (percpu_map) {
4903 /* skip the last bracket for the percpu map */
4904 nread = getline(&line, &line_len, pin_file);
4905 if (nread < 0)
4906 break;
4909 nread = getline(&line, &line_len, pin_file);
4910 } while (++nr_read_elems < test->max_entries && nread > 0);
4912 if (lossless_map &&
4913 CHECK(nr_read_elems < test->max_entries,
4914 "Unexpected EOF. nr_read_elems:%u test->max_entries:%u",
4915 nr_read_elems, test->max_entries)) {
4916 err = -1;
4917 goto done;
4920 if (CHECK(nread > 0, "Unexpected extra pprint output: %s", line)) {
4921 err = -1;
4922 goto done;
4925 err = 0;
4927 done:
4928 if (mapv)
4929 free(mapv);
4930 if (!err)
4931 fprintf(stderr, "OK");
4932 if (*btf_log_buf && (err || args.always_log))
4933 fprintf(stderr, "\n%s", btf_log_buf);
4934 if (btf_fd != -1)
4935 close(btf_fd);
4936 if (map_fd != -1)
4937 close(map_fd);
4938 if (pin_file)
4939 fclose(pin_file);
4940 unlink(pin_path);
4941 free(line);
4943 return err;
4946 static int test_pprint(void)
4948 unsigned int i;
4949 int err = 0;
4951 /* test various maps with the first test template */
4952 for (i = 0; i < ARRAY_SIZE(pprint_tests_meta); i++) {
4953 pprint_test_template[0].descr = pprint_tests_meta[i].descr;
4954 pprint_test_template[0].map_type = pprint_tests_meta[i].map_type;
4955 pprint_test_template[0].map_name = pprint_tests_meta[i].map_name;
4956 pprint_test_template[0].ordered_map = pprint_tests_meta[i].ordered_map;
4957 pprint_test_template[0].lossless_map = pprint_tests_meta[i].lossless_map;
4958 pprint_test_template[0].percpu_map = pprint_tests_meta[i].percpu_map;
4960 err |= count_result(do_test_pprint(0));
4963 /* test rest test templates with the first map */
4964 for (i = 1; i < ARRAY_SIZE(pprint_test_template); i++) {
4965 pprint_test_template[i].descr = pprint_tests_meta[0].descr;
4966 pprint_test_template[i].map_type = pprint_tests_meta[0].map_type;
4967 pprint_test_template[i].map_name = pprint_tests_meta[0].map_name;
4968 pprint_test_template[i].ordered_map = pprint_tests_meta[0].ordered_map;
4969 pprint_test_template[i].lossless_map = pprint_tests_meta[0].lossless_map;
4970 pprint_test_template[i].percpu_map = pprint_tests_meta[0].percpu_map;
4971 err |= count_result(do_test_pprint(i));
4974 return err;
4977 #define BPF_LINE_INFO_ENC(insn_off, file_off, line_off, line_num, line_col) \
4978 (insn_off), (file_off), (line_off), ((line_num) << 10 | ((line_col) & 0x3ff))
4980 static struct prog_info_raw_test {
4981 const char *descr;
4982 const char *str_sec;
4983 const char *err_str;
4984 __u32 raw_types[MAX_NR_RAW_U32];
4985 __u32 str_sec_size;
4986 struct bpf_insn insns[MAX_INSNS];
4987 __u32 prog_type;
4988 __u32 func_info[MAX_SUBPROGS][2];
4989 __u32 func_info_rec_size;
4990 __u32 func_info_cnt;
4991 __u32 line_info[MAX_NR_RAW_U32];
4992 __u32 line_info_rec_size;
4993 __u32 nr_jited_ksyms;
4994 bool expected_prog_load_failure;
4995 __u32 dead_code_cnt;
4996 __u32 dead_code_mask;
4997 __u32 dead_func_cnt;
4998 __u32 dead_func_mask;
4999 } info_raw_tests[] = {
5001 .descr = "func_type (main func + one sub)",
5002 .raw_types = {
5003 BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
5004 BTF_TYPE_INT_ENC(NAME_TBD, 0, 0, 32, 4), /* [2] */
5005 BTF_FUNC_PROTO_ENC(1, 2), /* [3] */
5006 BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
5007 BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 2),
5008 BTF_FUNC_PROTO_ENC(1, 2), /* [4] */
5009 BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 2),
5010 BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
5011 BTF_FUNC_ENC(NAME_TBD, 3), /* [5] */
5012 BTF_FUNC_ENC(NAME_TBD, 4), /* [6] */
5013 BTF_END_RAW,
5015 .str_sec = "\0int\0unsigned int\0a\0b\0c\0d\0funcA\0funcB",
5016 .str_sec_size = sizeof("\0int\0unsigned int\0a\0b\0c\0d\0funcA\0funcB"),
5017 .insns = {
5018 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2),
5019 BPF_MOV64_IMM(BPF_REG_0, 1),
5020 BPF_EXIT_INSN(),
5021 BPF_MOV64_IMM(BPF_REG_0, 2),
5022 BPF_EXIT_INSN(),
5024 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5025 .func_info = { {0, 5}, {3, 6} },
5026 .func_info_rec_size = 8,
5027 .func_info_cnt = 2,
5028 .line_info = { BTF_END_RAW },
5032 .descr = "func_type (Incorrect func_info_rec_size)",
5033 .raw_types = {
5034 BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
5035 BTF_TYPE_INT_ENC(NAME_TBD, 0, 0, 32, 4), /* [2] */
5036 BTF_FUNC_PROTO_ENC(1, 2), /* [3] */
5037 BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
5038 BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 2),
5039 BTF_FUNC_PROTO_ENC(1, 2), /* [4] */
5040 BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 2),
5041 BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
5042 BTF_FUNC_ENC(NAME_TBD, 3), /* [5] */
5043 BTF_FUNC_ENC(NAME_TBD, 4), /* [6] */
5044 BTF_END_RAW,
5046 .str_sec = "\0int\0unsigned int\0a\0b\0c\0d\0funcA\0funcB",
5047 .str_sec_size = sizeof("\0int\0unsigned int\0a\0b\0c\0d\0funcA\0funcB"),
5048 .insns = {
5049 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2),
5050 BPF_MOV64_IMM(BPF_REG_0, 1),
5051 BPF_EXIT_INSN(),
5052 BPF_MOV64_IMM(BPF_REG_0, 2),
5053 BPF_EXIT_INSN(),
5055 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5056 .func_info = { {0, 5}, {3, 6} },
5057 .func_info_rec_size = 4,
5058 .func_info_cnt = 2,
5059 .line_info = { BTF_END_RAW },
5060 .expected_prog_load_failure = true,
5064 .descr = "func_type (Incorrect func_info_cnt)",
5065 .raw_types = {
5066 BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
5067 BTF_TYPE_INT_ENC(NAME_TBD, 0, 0, 32, 4), /* [2] */
5068 BTF_FUNC_PROTO_ENC(1, 2), /* [3] */
5069 BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
5070 BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 2),
5071 BTF_FUNC_PROTO_ENC(1, 2), /* [4] */
5072 BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 2),
5073 BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
5074 BTF_FUNC_ENC(NAME_TBD, 3), /* [5] */
5075 BTF_FUNC_ENC(NAME_TBD, 4), /* [6] */
5076 BTF_END_RAW,
5078 .str_sec = "\0int\0unsigned int\0a\0b\0c\0d\0funcA\0funcB",
5079 .str_sec_size = sizeof("\0int\0unsigned int\0a\0b\0c\0d\0funcA\0funcB"),
5080 .insns = {
5081 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2),
5082 BPF_MOV64_IMM(BPF_REG_0, 1),
5083 BPF_EXIT_INSN(),
5084 BPF_MOV64_IMM(BPF_REG_0, 2),
5085 BPF_EXIT_INSN(),
5087 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5088 .func_info = { {0, 5}, {3, 6} },
5089 .func_info_rec_size = 8,
5090 .func_info_cnt = 1,
5091 .line_info = { BTF_END_RAW },
5092 .expected_prog_load_failure = true,
5096 .descr = "func_type (Incorrect bpf_func_info.insn_off)",
5097 .raw_types = {
5098 BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
5099 BTF_TYPE_INT_ENC(NAME_TBD, 0, 0, 32, 4), /* [2] */
5100 BTF_FUNC_PROTO_ENC(1, 2), /* [3] */
5101 BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
5102 BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 2),
5103 BTF_FUNC_PROTO_ENC(1, 2), /* [4] */
5104 BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 2),
5105 BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
5106 BTF_FUNC_ENC(NAME_TBD, 3), /* [5] */
5107 BTF_FUNC_ENC(NAME_TBD, 4), /* [6] */
5108 BTF_END_RAW,
5110 .str_sec = "\0int\0unsigned int\0a\0b\0c\0d\0funcA\0funcB",
5111 .str_sec_size = sizeof("\0int\0unsigned int\0a\0b\0c\0d\0funcA\0funcB"),
5112 .insns = {
5113 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2),
5114 BPF_MOV64_IMM(BPF_REG_0, 1),
5115 BPF_EXIT_INSN(),
5116 BPF_MOV64_IMM(BPF_REG_0, 2),
5117 BPF_EXIT_INSN(),
5119 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5120 .func_info = { {0, 5}, {2, 6} },
5121 .func_info_rec_size = 8,
5122 .func_info_cnt = 2,
5123 .line_info = { BTF_END_RAW },
5124 .expected_prog_load_failure = true,
5128 .descr = "line_info (No subprog)",
5129 .raw_types = {
5130 BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
5131 BTF_END_RAW,
5133 BTF_STR_SEC("\0int\0int a=1;\0int b=2;\0return a + b;\0return a + b;"),
5134 .insns = {
5135 BPF_MOV64_IMM(BPF_REG_0, 1),
5136 BPF_MOV64_IMM(BPF_REG_1, 2),
5137 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
5138 BPF_EXIT_INSN(),
5140 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5141 .func_info_cnt = 0,
5142 .line_info = {
5143 BPF_LINE_INFO_ENC(0, 0, NAME_TBD, 1, 10),
5144 BPF_LINE_INFO_ENC(1, 0, NAME_TBD, 2, 9),
5145 BPF_LINE_INFO_ENC(2, 0, NAME_TBD, 3, 8),
5146 BPF_LINE_INFO_ENC(3, 0, NAME_TBD, 4, 7),
5147 BTF_END_RAW,
5149 .line_info_rec_size = sizeof(struct bpf_line_info),
5150 .nr_jited_ksyms = 1,
5154 .descr = "line_info (No subprog. insn_off >= prog->len)",
5155 .raw_types = {
5156 BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
5157 BTF_END_RAW,
5159 BTF_STR_SEC("\0int\0int a=1;\0int b=2;\0return a + b;\0return a + b;"),
5160 .insns = {
5161 BPF_MOV64_IMM(BPF_REG_0, 1),
5162 BPF_MOV64_IMM(BPF_REG_1, 2),
5163 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
5164 BPF_EXIT_INSN(),
5166 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5167 .func_info_cnt = 0,
5168 .line_info = {
5169 BPF_LINE_INFO_ENC(0, 0, NAME_TBD, 1, 10),
5170 BPF_LINE_INFO_ENC(1, 0, NAME_TBD, 2, 9),
5171 BPF_LINE_INFO_ENC(2, 0, NAME_TBD, 3, 8),
5172 BPF_LINE_INFO_ENC(3, 0, NAME_TBD, 4, 7),
5173 BPF_LINE_INFO_ENC(4, 0, 0, 5, 6),
5174 BTF_END_RAW,
5176 .line_info_rec_size = sizeof(struct bpf_line_info),
5177 .nr_jited_ksyms = 1,
5178 .err_str = "line_info[4].insn_off",
5179 .expected_prog_load_failure = true,
5183 .descr = "line_info (Zero bpf insn code)",
5184 .raw_types = {
5185 BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
5186 BTF_TYPE_INT_ENC(NAME_TBD, 0, 0, 64, 8), /* [2] */
5187 BTF_TYPEDEF_ENC(NAME_TBD, 2), /* [3] */
5188 BTF_END_RAW,
5190 BTF_STR_SEC("\0int\0unsigned long\0u64\0u64 a=1;\0return a;"),
5191 .insns = {
5192 BPF_LD_IMM64(BPF_REG_0, 1),
5193 BPF_EXIT_INSN(),
5195 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5196 .func_info_cnt = 0,
5197 .line_info = {
5198 BPF_LINE_INFO_ENC(0, 0, NAME_TBD, 1, 10),
5199 BPF_LINE_INFO_ENC(1, 0, 0, 2, 9),
5200 BPF_LINE_INFO_ENC(2, 0, NAME_TBD, 3, 8),
5201 BTF_END_RAW,
5203 .line_info_rec_size = sizeof(struct bpf_line_info),
5204 .nr_jited_ksyms = 1,
5205 .err_str = "Invalid insn code at line_info[1]",
5206 .expected_prog_load_failure = true,
5210 .descr = "line_info (No subprog. zero tailing line_info",
5211 .raw_types = {
5212 BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
5213 BTF_END_RAW,
5215 BTF_STR_SEC("\0int\0int a=1;\0int b=2;\0return a + b;\0return a + b;"),
5216 .insns = {
5217 BPF_MOV64_IMM(BPF_REG_0, 1),
5218 BPF_MOV64_IMM(BPF_REG_1, 2),
5219 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
5220 BPF_EXIT_INSN(),
5222 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5223 .func_info_cnt = 0,
5224 .line_info = {
5225 BPF_LINE_INFO_ENC(0, 0, NAME_TBD, 1, 10), 0,
5226 BPF_LINE_INFO_ENC(1, 0, NAME_TBD, 2, 9), 0,
5227 BPF_LINE_INFO_ENC(2, 0, NAME_TBD, 3, 8), 0,
5228 BPF_LINE_INFO_ENC(3, 0, NAME_TBD, 4, 7), 0,
5229 BTF_END_RAW,
5231 .line_info_rec_size = sizeof(struct bpf_line_info) + sizeof(__u32),
5232 .nr_jited_ksyms = 1,
5236 .descr = "line_info (No subprog. nonzero tailing line_info)",
5237 .raw_types = {
5238 BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
5239 BTF_END_RAW,
5241 BTF_STR_SEC("\0int\0int a=1;\0int b=2;\0return a + b;\0return a + b;"),
5242 .insns = {
5243 BPF_MOV64_IMM(BPF_REG_0, 1),
5244 BPF_MOV64_IMM(BPF_REG_1, 2),
5245 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
5246 BPF_EXIT_INSN(),
5248 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5249 .func_info_cnt = 0,
5250 .line_info = {
5251 BPF_LINE_INFO_ENC(0, 0, NAME_TBD, 1, 10), 0,
5252 BPF_LINE_INFO_ENC(1, 0, NAME_TBD, 2, 9), 0,
5253 BPF_LINE_INFO_ENC(2, 0, NAME_TBD, 3, 8), 0,
5254 BPF_LINE_INFO_ENC(3, 0, NAME_TBD, 4, 7), 1,
5255 BTF_END_RAW,
5257 .line_info_rec_size = sizeof(struct bpf_line_info) + sizeof(__u32),
5258 .nr_jited_ksyms = 1,
5259 .err_str = "nonzero tailing record in line_info",
5260 .expected_prog_load_failure = true,
5264 .descr = "line_info (subprog)",
5265 .raw_types = {
5266 BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
5267 BTF_END_RAW,
5269 BTF_STR_SEC("\0int\0int a=1+1;\0return func(a);\0b+=1;\0return b;"),
5270 .insns = {
5271 BPF_MOV64_IMM(BPF_REG_2, 1),
5272 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, 1),
5273 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
5274 BPF_CALL_REL(1),
5275 BPF_EXIT_INSN(),
5276 BPF_MOV64_REG(BPF_REG_0, BPF_REG_1),
5277 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 1),
5278 BPF_EXIT_INSN(),
5280 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5281 .func_info_cnt = 0,
5282 .line_info = {
5283 BPF_LINE_INFO_ENC(0, 0, NAME_TBD, 1, 10),
5284 BPF_LINE_INFO_ENC(2, 0, NAME_TBD, 2, 9),
5285 BPF_LINE_INFO_ENC(5, 0, NAME_TBD, 3, 8),
5286 BPF_LINE_INFO_ENC(7, 0, NAME_TBD, 4, 7),
5287 BTF_END_RAW,
5289 .line_info_rec_size = sizeof(struct bpf_line_info),
5290 .nr_jited_ksyms = 2,
5294 .descr = "line_info (subprog + func_info)",
5295 .raw_types = {
5296 BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
5297 BTF_FUNC_PROTO_ENC(1, 1), /* [2] */
5298 BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
5299 BTF_FUNC_ENC(NAME_TBD, 2), /* [3] */
5300 BTF_FUNC_ENC(NAME_TBD, 2), /* [4] */
5301 BTF_END_RAW,
5303 BTF_STR_SEC("\0int\0x\0sub\0main\0int a=1+1;\0return func(a);\0b+=1;\0return b;"),
5304 .insns = {
5305 BPF_MOV64_IMM(BPF_REG_2, 1),
5306 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, 1),
5307 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
5308 BPF_CALL_REL(1),
5309 BPF_EXIT_INSN(),
5310 BPF_MOV64_REG(BPF_REG_0, BPF_REG_1),
5311 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 1),
5312 BPF_EXIT_INSN(),
5314 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5315 .func_info_cnt = 2,
5316 .func_info_rec_size = 8,
5317 .func_info = { {0, 4}, {5, 3} },
5318 .line_info = {
5319 BPF_LINE_INFO_ENC(0, 0, NAME_TBD, 1, 10),
5320 BPF_LINE_INFO_ENC(2, 0, NAME_TBD, 2, 9),
5321 BPF_LINE_INFO_ENC(5, 0, NAME_TBD, 3, 8),
5322 BPF_LINE_INFO_ENC(7, 0, NAME_TBD, 4, 7),
5323 BTF_END_RAW,
5325 .line_info_rec_size = sizeof(struct bpf_line_info),
5326 .nr_jited_ksyms = 2,
5330 .descr = "line_info (subprog. missing 1st func line info)",
5331 .raw_types = {
5332 BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
5333 BTF_END_RAW,
5335 BTF_STR_SEC("\0int\0int a=1+1;\0return func(a);\0b+=1;\0return b;"),
5336 .insns = {
5337 BPF_MOV64_IMM(BPF_REG_2, 1),
5338 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, 1),
5339 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
5340 BPF_CALL_REL(1),
5341 BPF_EXIT_INSN(),
5342 BPF_MOV64_REG(BPF_REG_0, BPF_REG_1),
5343 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 1),
5344 BPF_EXIT_INSN(),
5346 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5347 .func_info_cnt = 0,
5348 .line_info = {
5349 BPF_LINE_INFO_ENC(1, 0, NAME_TBD, 1, 10),
5350 BPF_LINE_INFO_ENC(2, 0, NAME_TBD, 2, 9),
5351 BPF_LINE_INFO_ENC(5, 0, NAME_TBD, 3, 8),
5352 BPF_LINE_INFO_ENC(7, 0, NAME_TBD, 4, 7),
5353 BTF_END_RAW,
5355 .line_info_rec_size = sizeof(struct bpf_line_info),
5356 .nr_jited_ksyms = 2,
5357 .err_str = "missing bpf_line_info for func#0",
5358 .expected_prog_load_failure = true,
5362 .descr = "line_info (subprog. missing 2nd func line info)",
5363 .raw_types = {
5364 BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
5365 BTF_END_RAW,
5367 BTF_STR_SEC("\0int\0int a=1+1;\0return func(a);\0b+=1;\0return b;"),
5368 .insns = {
5369 BPF_MOV64_IMM(BPF_REG_2, 1),
5370 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, 1),
5371 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
5372 BPF_CALL_REL(1),
5373 BPF_EXIT_INSN(),
5374 BPF_MOV64_REG(BPF_REG_0, BPF_REG_1),
5375 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 1),
5376 BPF_EXIT_INSN(),
5378 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5379 .func_info_cnt = 0,
5380 .line_info = {
5381 BPF_LINE_INFO_ENC(0, 0, NAME_TBD, 1, 10),
5382 BPF_LINE_INFO_ENC(2, 0, NAME_TBD, 2, 9),
5383 BPF_LINE_INFO_ENC(6, 0, NAME_TBD, 3, 8),
5384 BPF_LINE_INFO_ENC(7, 0, NAME_TBD, 4, 7),
5385 BTF_END_RAW,
5387 .line_info_rec_size = sizeof(struct bpf_line_info),
5388 .nr_jited_ksyms = 2,
5389 .err_str = "missing bpf_line_info for func#1",
5390 .expected_prog_load_failure = true,
5394 .descr = "line_info (subprog. unordered insn offset)",
5395 .raw_types = {
5396 BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
5397 BTF_END_RAW,
5399 BTF_STR_SEC("\0int\0int a=1+1;\0return func(a);\0b+=1;\0return b;"),
5400 .insns = {
5401 BPF_MOV64_IMM(BPF_REG_2, 1),
5402 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, 1),
5403 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
5404 BPF_CALL_REL(1),
5405 BPF_EXIT_INSN(),
5406 BPF_MOV64_REG(BPF_REG_0, BPF_REG_1),
5407 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 1),
5408 BPF_EXIT_INSN(),
5410 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5411 .func_info_cnt = 0,
5412 .line_info = {
5413 BPF_LINE_INFO_ENC(0, 0, NAME_TBD, 1, 10),
5414 BPF_LINE_INFO_ENC(5, 0, NAME_TBD, 2, 9),
5415 BPF_LINE_INFO_ENC(2, 0, NAME_TBD, 3, 8),
5416 BPF_LINE_INFO_ENC(7, 0, NAME_TBD, 4, 7),
5417 BTF_END_RAW,
5419 .line_info_rec_size = sizeof(struct bpf_line_info),
5420 .nr_jited_ksyms = 2,
5421 .err_str = "Invalid line_info[2].insn_off",
5422 .expected_prog_load_failure = true,
5426 .descr = "line_info (dead start)",
5427 .raw_types = {
5428 BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
5429 BTF_END_RAW,
5431 BTF_STR_SEC("\0int\0/* dead jmp */\0int a=1;\0int b=2;\0return a + b;\0return a + b;"),
5432 .insns = {
5433 BPF_JMP_IMM(BPF_JA, 0, 0, 0),
5434 BPF_MOV64_IMM(BPF_REG_0, 1),
5435 BPF_MOV64_IMM(BPF_REG_1, 2),
5436 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
5437 BPF_EXIT_INSN(),
5439 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5440 .func_info_cnt = 0,
5441 .line_info = {
5442 BPF_LINE_INFO_ENC(0, 0, NAME_TBD, 1, 10),
5443 BPF_LINE_INFO_ENC(1, 0, NAME_TBD, 2, 9),
5444 BPF_LINE_INFO_ENC(2, 0, NAME_TBD, 3, 8),
5445 BPF_LINE_INFO_ENC(3, 0, NAME_TBD, 4, 7),
5446 BPF_LINE_INFO_ENC(4, 0, NAME_TBD, 5, 6),
5447 BTF_END_RAW,
5449 .line_info_rec_size = sizeof(struct bpf_line_info),
5450 .nr_jited_ksyms = 1,
5451 .dead_code_cnt = 1,
5452 .dead_code_mask = 0x01,
5456 .descr = "line_info (dead end)",
5457 .raw_types = {
5458 BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
5459 BTF_END_RAW,
5461 BTF_STR_SEC("\0int\0int a=1;\0int b=2;\0return a + b;\0/* dead jmp */\0return a + b;\0/* dead exit */"),
5462 .insns = {
5463 BPF_MOV64_IMM(BPF_REG_0, 1),
5464 BPF_MOV64_IMM(BPF_REG_1, 2),
5465 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
5466 BPF_JMP_IMM(BPF_JGE, BPF_REG_0, 10, 1),
5467 BPF_EXIT_INSN(),
5468 BPF_EXIT_INSN(),
5470 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5471 .func_info_cnt = 0,
5472 .line_info = {
5473 BPF_LINE_INFO_ENC(0, 0, NAME_TBD, 1, 12),
5474 BPF_LINE_INFO_ENC(1, 0, NAME_TBD, 2, 11),
5475 BPF_LINE_INFO_ENC(2, 0, NAME_TBD, 3, 10),
5476 BPF_LINE_INFO_ENC(3, 0, NAME_TBD, 4, 9),
5477 BPF_LINE_INFO_ENC(4, 0, NAME_TBD, 5, 8),
5478 BPF_LINE_INFO_ENC(5, 0, NAME_TBD, 6, 7),
5479 BTF_END_RAW,
5481 .line_info_rec_size = sizeof(struct bpf_line_info),
5482 .nr_jited_ksyms = 1,
5483 .dead_code_cnt = 2,
5484 .dead_code_mask = 0x28,
5488 .descr = "line_info (dead code + subprog + func_info)",
5489 .raw_types = {
5490 BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
5491 BTF_FUNC_PROTO_ENC(1, 1), /* [2] */
5492 BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
5493 BTF_FUNC_ENC(NAME_TBD, 2), /* [3] */
5494 BTF_FUNC_ENC(NAME_TBD, 2), /* [4] */
5495 BTF_END_RAW,
5497 BTF_STR_SEC("\0int\0x\0sub\0main\0int a=1+1;\0/* dead jmp */"
5498 "\0/* dead */\0/* dead */\0/* dead */\0/* dead */"
5499 "\0/* dead */\0/* dead */\0/* dead */\0/* dead */"
5500 "\0return func(a);\0b+=1;\0return b;"),
5501 .insns = {
5502 BPF_MOV64_IMM(BPF_REG_2, 1),
5503 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, 1),
5504 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
5505 BPF_JMP_IMM(BPF_JGE, BPF_REG_2, 0, 8),
5506 BPF_MOV64_IMM(BPF_REG_2, 1),
5507 BPF_MOV64_IMM(BPF_REG_2, 1),
5508 BPF_MOV64_IMM(BPF_REG_2, 1),
5509 BPF_MOV64_IMM(BPF_REG_2, 1),
5510 BPF_MOV64_IMM(BPF_REG_2, 1),
5511 BPF_MOV64_IMM(BPF_REG_2, 1),
5512 BPF_MOV64_IMM(BPF_REG_2, 1),
5513 BPF_MOV64_IMM(BPF_REG_2, 1),
5514 BPF_CALL_REL(1),
5515 BPF_EXIT_INSN(),
5516 BPF_MOV64_REG(BPF_REG_0, BPF_REG_1),
5517 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 1),
5518 BPF_EXIT_INSN(),
5520 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5521 .func_info_cnt = 2,
5522 .func_info_rec_size = 8,
5523 .func_info = { {0, 4}, {14, 3} },
5524 .line_info = {
5525 BPF_LINE_INFO_ENC(0, 0, NAME_TBD, 1, 10),
5526 BPF_LINE_INFO_ENC(3, 0, NAME_TBD, 1, 10),
5527 BPF_LINE_INFO_ENC(4, 0, NAME_TBD, 1, 10),
5528 BPF_LINE_INFO_ENC(5, 0, NAME_TBD, 1, 10),
5529 BPF_LINE_INFO_ENC(6, 0, NAME_TBD, 1, 10),
5530 BPF_LINE_INFO_ENC(7, 0, NAME_TBD, 1, 10),
5531 BPF_LINE_INFO_ENC(8, 0, NAME_TBD, 1, 10),
5532 BPF_LINE_INFO_ENC(9, 0, NAME_TBD, 1, 10),
5533 BPF_LINE_INFO_ENC(10, 0, NAME_TBD, 1, 10),
5534 BPF_LINE_INFO_ENC(11, 0, NAME_TBD, 2, 9),
5535 BPF_LINE_INFO_ENC(12, 0, NAME_TBD, 2, 9),
5536 BPF_LINE_INFO_ENC(14, 0, NAME_TBD, 3, 8),
5537 BPF_LINE_INFO_ENC(16, 0, NAME_TBD, 4, 7),
5538 BTF_END_RAW,
5540 .line_info_rec_size = sizeof(struct bpf_line_info),
5541 .nr_jited_ksyms = 2,
5542 .dead_code_cnt = 9,
5543 .dead_code_mask = 0x3fe,
5547 .descr = "line_info (dead subprog)",
5548 .raw_types = {
5549 BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
5550 BTF_FUNC_PROTO_ENC(1, 1), /* [2] */
5551 BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
5552 BTF_FUNC_ENC(NAME_TBD, 2), /* [3] */
5553 BTF_FUNC_ENC(NAME_TBD, 2), /* [4] */
5554 BTF_FUNC_ENC(NAME_TBD, 2), /* [5] */
5555 BTF_END_RAW,
5557 BTF_STR_SEC("\0int\0x\0dead\0main\0func\0int a=1+1;\0/* live call */"
5558 "\0return 0;\0return 0;\0/* dead */\0/* dead */"
5559 "\0/* dead */\0return bla + 1;\0return bla + 1;"
5560 "\0return bla + 1;\0return func(a);\0b+=1;\0return b;"),
5561 .insns = {
5562 BPF_MOV64_IMM(BPF_REG_2, 1),
5563 BPF_JMP_IMM(BPF_JGE, BPF_REG_2, 0, 1),
5564 BPF_CALL_REL(3),
5565 BPF_CALL_REL(5),
5566 BPF_MOV64_IMM(BPF_REG_0, 0),
5567 BPF_EXIT_INSN(),
5568 BPF_MOV64_IMM(BPF_REG_0, 0),
5569 BPF_CALL_REL(1),
5570 BPF_EXIT_INSN(),
5571 BPF_MOV64_REG(BPF_REG_0, 2),
5572 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 1),
5573 BPF_EXIT_INSN(),
5575 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5576 .func_info_cnt = 3,
5577 .func_info_rec_size = 8,
5578 .func_info = { {0, 4}, {6, 3}, {9, 5} },
5579 .line_info = {
5580 BPF_LINE_INFO_ENC(0, 0, NAME_TBD, 1, 10),
5581 BPF_LINE_INFO_ENC(3, 0, NAME_TBD, 1, 10),
5582 BPF_LINE_INFO_ENC(4, 0, NAME_TBD, 1, 10),
5583 BPF_LINE_INFO_ENC(5, 0, NAME_TBD, 1, 10),
5584 BPF_LINE_INFO_ENC(6, 0, NAME_TBD, 1, 10),
5585 BPF_LINE_INFO_ENC(7, 0, NAME_TBD, 1, 10),
5586 BPF_LINE_INFO_ENC(8, 0, NAME_TBD, 1, 10),
5587 BPF_LINE_INFO_ENC(9, 0, NAME_TBD, 1, 10),
5588 BPF_LINE_INFO_ENC(10, 0, NAME_TBD, 1, 10),
5589 BPF_LINE_INFO_ENC(11, 0, NAME_TBD, 2, 9),
5590 BTF_END_RAW,
5592 .line_info_rec_size = sizeof(struct bpf_line_info),
5593 .nr_jited_ksyms = 2,
5594 .dead_code_cnt = 3,
5595 .dead_code_mask = 0x70,
5596 .dead_func_cnt = 1,
5597 .dead_func_mask = 0x2,
5601 .descr = "line_info (dead last subprog)",
5602 .raw_types = {
5603 BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
5604 BTF_FUNC_PROTO_ENC(1, 1), /* [2] */
5605 BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
5606 BTF_FUNC_ENC(NAME_TBD, 2), /* [3] */
5607 BTF_FUNC_ENC(NAME_TBD, 2), /* [5] */
5608 BTF_END_RAW,
5610 BTF_STR_SEC("\0int\0x\0dead\0main\0int a=1+1;\0/* live call */"
5611 "\0return 0;\0/* dead */\0/* dead */"),
5612 .insns = {
5613 BPF_MOV64_IMM(BPF_REG_2, 1),
5614 BPF_JMP_IMM(BPF_JGE, BPF_REG_2, 0, 1),
5615 BPF_CALL_REL(2),
5616 BPF_MOV64_IMM(BPF_REG_0, 0),
5617 BPF_EXIT_INSN(),
5618 BPF_MOV64_IMM(BPF_REG_0, 0),
5619 BPF_EXIT_INSN(),
5621 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5622 .func_info_cnt = 2,
5623 .func_info_rec_size = 8,
5624 .func_info = { {0, 4}, {5, 3} },
5625 .line_info = {
5626 BPF_LINE_INFO_ENC(0, 0, NAME_TBD, 1, 10),
5627 BPF_LINE_INFO_ENC(3, 0, NAME_TBD, 1, 10),
5628 BPF_LINE_INFO_ENC(4, 0, NAME_TBD, 1, 10),
5629 BPF_LINE_INFO_ENC(5, 0, NAME_TBD, 1, 10),
5630 BPF_LINE_INFO_ENC(6, 0, NAME_TBD, 1, 10),
5631 BTF_END_RAW,
5633 .line_info_rec_size = sizeof(struct bpf_line_info),
5634 .nr_jited_ksyms = 1,
5635 .dead_code_cnt = 2,
5636 .dead_code_mask = 0x18,
5637 .dead_func_cnt = 1,
5638 .dead_func_mask = 0x2,
5642 .descr = "line_info (dead subprog + dead start)",
5643 .raw_types = {
5644 BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
5645 BTF_FUNC_PROTO_ENC(1, 1), /* [2] */
5646 BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
5647 BTF_FUNC_ENC(NAME_TBD, 2), /* [3] */
5648 BTF_FUNC_ENC(NAME_TBD, 2), /* [4] */
5649 BTF_FUNC_ENC(NAME_TBD, 2), /* [5] */
5650 BTF_END_RAW,
5652 BTF_STR_SEC("\0int\0x\0dead\0main\0func\0int a=1+1;\0/* dead */"
5653 "\0return 0;\0return 0;\0return 0;"
5654 "\0/* dead */\0/* dead */\0/* dead */\0/* dead */"
5655 "\0return b + 1;\0return b + 1;\0return b + 1;"),
5656 .insns = {
5657 BPF_JMP_IMM(BPF_JA, 0, 0, 0),
5658 BPF_MOV64_IMM(BPF_REG_2, 1),
5659 BPF_JMP_IMM(BPF_JGE, BPF_REG_2, 0, 1),
5660 BPF_CALL_REL(3),
5661 BPF_CALL_REL(5),
5662 BPF_MOV64_IMM(BPF_REG_0, 0),
5663 BPF_EXIT_INSN(),
5664 BPF_MOV64_IMM(BPF_REG_0, 0),
5665 BPF_CALL_REL(1),
5666 BPF_EXIT_INSN(),
5667 BPF_JMP_IMM(BPF_JA, 0, 0, 0),
5668 BPF_MOV64_REG(BPF_REG_0, 2),
5669 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 1),
5670 BPF_EXIT_INSN(),
5672 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5673 .func_info_cnt = 3,
5674 .func_info_rec_size = 8,
5675 .func_info = { {0, 4}, {7, 3}, {10, 5} },
5676 .line_info = {
5677 BPF_LINE_INFO_ENC(0, 0, NAME_TBD, 1, 10),
5678 BPF_LINE_INFO_ENC(3, 0, NAME_TBD, 1, 10),
5679 BPF_LINE_INFO_ENC(4, 0, NAME_TBD, 1, 10),
5680 BPF_LINE_INFO_ENC(5, 0, NAME_TBD, 1, 10),
5681 BPF_LINE_INFO_ENC(6, 0, NAME_TBD, 1, 10),
5682 BPF_LINE_INFO_ENC(7, 0, NAME_TBD, 1, 10),
5683 BPF_LINE_INFO_ENC(8, 0, NAME_TBD, 1, 10),
5684 BPF_LINE_INFO_ENC(9, 0, NAME_TBD, 1, 10),
5685 BPF_LINE_INFO_ENC(10, 0, NAME_TBD, 1, 10),
5686 BPF_LINE_INFO_ENC(11, 0, NAME_TBD, 2, 9),
5687 BPF_LINE_INFO_ENC(12, 0, NAME_TBD, 2, 9),
5688 BPF_LINE_INFO_ENC(13, 0, NAME_TBD, 2, 9),
5689 BTF_END_RAW,
5691 .line_info_rec_size = sizeof(struct bpf_line_info),
5692 .nr_jited_ksyms = 2,
5693 .dead_code_cnt = 5,
5694 .dead_code_mask = 0x1e2,
5695 .dead_func_cnt = 1,
5696 .dead_func_mask = 0x2,
5700 .descr = "line_info (dead subprog + dead start w/ move)",
5701 .raw_types = {
5702 BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
5703 BTF_FUNC_PROTO_ENC(1, 1), /* [2] */
5704 BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
5705 BTF_FUNC_ENC(NAME_TBD, 2), /* [3] */
5706 BTF_FUNC_ENC(NAME_TBD, 2), /* [4] */
5707 BTF_FUNC_ENC(NAME_TBD, 2), /* [5] */
5708 BTF_END_RAW,
5710 BTF_STR_SEC("\0int\0x\0dead\0main\0func\0int a=1+1;\0/* live call */"
5711 "\0return 0;\0return 0;\0/* dead */\0/* dead */"
5712 "\0/* dead */\0return bla + 1;\0return bla + 1;"
5713 "\0return bla + 1;\0return func(a);\0b+=1;\0return b;"),
5714 .insns = {
5715 BPF_MOV64_IMM(BPF_REG_2, 1),
5716 BPF_JMP_IMM(BPF_JGE, BPF_REG_2, 0, 1),
5717 BPF_CALL_REL(3),
5718 BPF_CALL_REL(5),
5719 BPF_MOV64_IMM(BPF_REG_0, 0),
5720 BPF_EXIT_INSN(),
5721 BPF_MOV64_IMM(BPF_REG_0, 0),
5722 BPF_CALL_REL(1),
5723 BPF_EXIT_INSN(),
5724 BPF_JMP_IMM(BPF_JA, 0, 0, 0),
5725 BPF_MOV64_REG(BPF_REG_0, 2),
5726 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 1),
5727 BPF_EXIT_INSN(),
5729 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5730 .func_info_cnt = 3,
5731 .func_info_rec_size = 8,
5732 .func_info = { {0, 4}, {6, 3}, {9, 5} },
5733 .line_info = {
5734 BPF_LINE_INFO_ENC(0, 0, NAME_TBD, 1, 10),
5735 BPF_LINE_INFO_ENC(3, 0, NAME_TBD, 1, 10),
5736 BPF_LINE_INFO_ENC(4, 0, NAME_TBD, 1, 10),
5737 BPF_LINE_INFO_ENC(5, 0, NAME_TBD, 1, 10),
5738 BPF_LINE_INFO_ENC(6, 0, NAME_TBD, 1, 10),
5739 BPF_LINE_INFO_ENC(7, 0, NAME_TBD, 1, 10),
5740 BPF_LINE_INFO_ENC(8, 0, NAME_TBD, 1, 10),
5741 BPF_LINE_INFO_ENC(9, 0, NAME_TBD, 1, 10),
5742 BPF_LINE_INFO_ENC(11, 0, NAME_TBD, 1, 10),
5743 BPF_LINE_INFO_ENC(12, 0, NAME_TBD, 2, 9),
5744 BTF_END_RAW,
5746 .line_info_rec_size = sizeof(struct bpf_line_info),
5747 .nr_jited_ksyms = 2,
5748 .dead_code_cnt = 3,
5749 .dead_code_mask = 0x70,
5750 .dead_func_cnt = 1,
5751 .dead_func_mask = 0x2,
5755 .descr = "line_info (dead end + subprog start w/ no linfo)",
5756 .raw_types = {
5757 BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
5758 BTF_FUNC_PROTO_ENC(1, 1), /* [2] */
5759 BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
5760 BTF_FUNC_ENC(NAME_TBD, 2), /* [3] */
5761 BTF_FUNC_ENC(NAME_TBD, 2), /* [4] */
5762 BTF_END_RAW,
5764 BTF_STR_SEC("\0int\0x\0main\0func\0/* main linfo */\0/* func linfo */"),
5765 .insns = {
5766 BPF_MOV64_IMM(BPF_REG_0, 0),
5767 BPF_JMP_IMM(BPF_JGE, BPF_REG_0, 1, 3),
5768 BPF_CALL_REL(3),
5769 BPF_MOV64_IMM(BPF_REG_0, 0),
5770 BPF_EXIT_INSN(),
5771 BPF_EXIT_INSN(),
5772 BPF_JMP_IMM(BPF_JA, 0, 0, 0),
5773 BPF_EXIT_INSN(),
5775 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5776 .func_info_cnt = 2,
5777 .func_info_rec_size = 8,
5778 .func_info = { {0, 3}, {6, 4}, },
5779 .line_info = {
5780 BPF_LINE_INFO_ENC(0, 0, NAME_TBD, 1, 10),
5781 BPF_LINE_INFO_ENC(6, 0, NAME_TBD, 1, 10),
5782 BTF_END_RAW,
5784 .line_info_rec_size = sizeof(struct bpf_line_info),
5785 .nr_jited_ksyms = 2,
5790 static size_t probe_prog_length(const struct bpf_insn *fp)
5792 size_t len;
5794 for (len = MAX_INSNS - 1; len > 0; --len)
5795 if (fp[len].code != 0 || fp[len].imm != 0)
5796 break;
5797 return len + 1;
5800 static __u32 *patch_name_tbd(const __u32 *raw_u32,
5801 const char *str, __u32 str_off,
5802 unsigned int str_sec_size,
5803 unsigned int *ret_size)
5805 int i, raw_u32_size = get_raw_sec_size(raw_u32);
5806 const char *end_str = str + str_sec_size;
5807 const char *next_str = str + str_off;
5808 __u32 *new_u32 = NULL;
5810 if (raw_u32_size == -1)
5811 return ERR_PTR(-EINVAL);
5813 if (!raw_u32_size) {
5814 *ret_size = 0;
5815 return NULL;
5818 new_u32 = malloc(raw_u32_size);
5819 if (!new_u32)
5820 return ERR_PTR(-ENOMEM);
5822 for (i = 0; i < raw_u32_size / sizeof(raw_u32[0]); i++) {
5823 if (raw_u32[i] == NAME_TBD) {
5824 next_str = get_next_str(next_str, end_str);
5825 if (CHECK(!next_str, "Error in getting next_str\n")) {
5826 free(new_u32);
5827 return ERR_PTR(-EINVAL);
5829 new_u32[i] = next_str - str;
5830 next_str += strlen(next_str);
5831 } else {
5832 new_u32[i] = raw_u32[i];
5836 *ret_size = raw_u32_size;
5837 return new_u32;
5840 static int test_get_finfo(const struct prog_info_raw_test *test,
5841 int prog_fd)
5843 struct bpf_prog_info info = {};
5844 struct bpf_func_info *finfo;
5845 __u32 info_len, rec_size, i;
5846 void *func_info = NULL;
5847 __u32 nr_func_info;
5848 int err;
5850 /* get necessary lens */
5851 info_len = sizeof(struct bpf_prog_info);
5852 err = bpf_obj_get_info_by_fd(prog_fd, &info, &info_len);
5853 if (CHECK(err == -1, "invalid get info (1st) errno:%d", errno)) {
5854 fprintf(stderr, "%s\n", btf_log_buf);
5855 return -1;
5857 nr_func_info = test->func_info_cnt - test->dead_func_cnt;
5858 if (CHECK(info.nr_func_info != nr_func_info,
5859 "incorrect info.nr_func_info (1st) %d",
5860 info.nr_func_info)) {
5861 return -1;
5864 rec_size = info.func_info_rec_size;
5865 if (CHECK(rec_size != sizeof(struct bpf_func_info),
5866 "incorrect info.func_info_rec_size (1st) %d", rec_size)) {
5867 return -1;
5870 if (!info.nr_func_info)
5871 return 0;
5873 func_info = malloc(info.nr_func_info * rec_size);
5874 if (CHECK(!func_info, "out of memory"))
5875 return -1;
5877 /* reset info to only retrieve func_info related data */
5878 memset(&info, 0, sizeof(info));
5879 info.nr_func_info = nr_func_info;
5880 info.func_info_rec_size = rec_size;
5881 info.func_info = ptr_to_u64(func_info);
5882 err = bpf_obj_get_info_by_fd(prog_fd, &info, &info_len);
5883 if (CHECK(err == -1, "invalid get info (2nd) errno:%d", errno)) {
5884 fprintf(stderr, "%s\n", btf_log_buf);
5885 err = -1;
5886 goto done;
5888 if (CHECK(info.nr_func_info != nr_func_info,
5889 "incorrect info.nr_func_info (2nd) %d",
5890 info.nr_func_info)) {
5891 err = -1;
5892 goto done;
5894 if (CHECK(info.func_info_rec_size != rec_size,
5895 "incorrect info.func_info_rec_size (2nd) %d",
5896 info.func_info_rec_size)) {
5897 err = -1;
5898 goto done;
5901 finfo = func_info;
5902 for (i = 0; i < nr_func_info; i++) {
5903 if (test->dead_func_mask & (1 << i))
5904 continue;
5905 if (CHECK(finfo->type_id != test->func_info[i][1],
5906 "incorrect func_type %u expected %u",
5907 finfo->type_id, test->func_info[i][1])) {
5908 err = -1;
5909 goto done;
5911 finfo = (void *)finfo + rec_size;
5914 err = 0;
5916 done:
5917 free(func_info);
5918 return err;
5921 static int test_get_linfo(const struct prog_info_raw_test *test,
5922 const void *patched_linfo,
5923 __u32 cnt, int prog_fd)
5925 __u32 i, info_len, nr_jited_ksyms, nr_jited_func_lens;
5926 __u64 *jited_linfo = NULL, *jited_ksyms = NULL;
5927 __u32 rec_size, jited_rec_size, jited_cnt;
5928 struct bpf_line_info *linfo = NULL;
5929 __u32 cur_func_len, ksyms_found;
5930 struct bpf_prog_info info = {};
5931 __u32 *jited_func_lens = NULL;
5932 __u64 cur_func_ksyms;
5933 __u32 dead_insns;
5934 int err;
5936 jited_cnt = cnt;
5937 rec_size = sizeof(*linfo);
5938 jited_rec_size = sizeof(*jited_linfo);
5939 if (test->nr_jited_ksyms)
5940 nr_jited_ksyms = test->nr_jited_ksyms;
5941 else
5942 nr_jited_ksyms = test->func_info_cnt - test->dead_func_cnt;
5943 nr_jited_func_lens = nr_jited_ksyms;
5945 info_len = sizeof(struct bpf_prog_info);
5946 err = bpf_obj_get_info_by_fd(prog_fd, &info, &info_len);
5947 if (CHECK(err == -1, "err:%d errno:%d", err, errno)) {
5948 err = -1;
5949 goto done;
5952 if (!info.jited_prog_len) {
5953 /* prog is not jited */
5954 jited_cnt = 0;
5955 nr_jited_ksyms = 1;
5956 nr_jited_func_lens = 1;
5959 if (CHECK(info.nr_line_info != cnt ||
5960 info.nr_jited_line_info != jited_cnt ||
5961 info.nr_jited_ksyms != nr_jited_ksyms ||
5962 info.nr_jited_func_lens != nr_jited_func_lens ||
5963 (!info.nr_line_info && info.nr_jited_line_info),
5964 "info: nr_line_info:%u(expected:%u) nr_jited_line_info:%u(expected:%u) nr_jited_ksyms:%u(expected:%u) nr_jited_func_lens:%u(expected:%u)",
5965 info.nr_line_info, cnt,
5966 info.nr_jited_line_info, jited_cnt,
5967 info.nr_jited_ksyms, nr_jited_ksyms,
5968 info.nr_jited_func_lens, nr_jited_func_lens)) {
5969 err = -1;
5970 goto done;
5973 if (CHECK(info.line_info_rec_size != sizeof(struct bpf_line_info) ||
5974 info.jited_line_info_rec_size != sizeof(__u64),
5975 "info: line_info_rec_size:%u(userspace expected:%u) jited_line_info_rec_size:%u(userspace expected:%u)",
5976 info.line_info_rec_size, rec_size,
5977 info.jited_line_info_rec_size, jited_rec_size)) {
5978 err = -1;
5979 goto done;
5982 if (!cnt)
5983 return 0;
5985 rec_size = info.line_info_rec_size;
5986 jited_rec_size = info.jited_line_info_rec_size;
5988 memset(&info, 0, sizeof(info));
5990 linfo = calloc(cnt, rec_size);
5991 if (CHECK(!linfo, "!linfo")) {
5992 err = -1;
5993 goto done;
5995 info.nr_line_info = cnt;
5996 info.line_info_rec_size = rec_size;
5997 info.line_info = ptr_to_u64(linfo);
5999 if (jited_cnt) {
6000 jited_linfo = calloc(jited_cnt, jited_rec_size);
6001 jited_ksyms = calloc(nr_jited_ksyms, sizeof(*jited_ksyms));
6002 jited_func_lens = calloc(nr_jited_func_lens,
6003 sizeof(*jited_func_lens));
6004 if (CHECK(!jited_linfo || !jited_ksyms || !jited_func_lens,
6005 "jited_linfo:%p jited_ksyms:%p jited_func_lens:%p",
6006 jited_linfo, jited_ksyms, jited_func_lens)) {
6007 err = -1;
6008 goto done;
6011 info.nr_jited_line_info = jited_cnt;
6012 info.jited_line_info_rec_size = jited_rec_size;
6013 info.jited_line_info = ptr_to_u64(jited_linfo);
6014 info.nr_jited_ksyms = nr_jited_ksyms;
6015 info.jited_ksyms = ptr_to_u64(jited_ksyms);
6016 info.nr_jited_func_lens = nr_jited_func_lens;
6017 info.jited_func_lens = ptr_to_u64(jited_func_lens);
6020 err = bpf_obj_get_info_by_fd(prog_fd, &info, &info_len);
6023 * Only recheck the info.*line_info* fields.
6024 * Other fields are not the concern of this test.
6026 if (CHECK(err == -1 ||
6027 info.nr_line_info != cnt ||
6028 (jited_cnt && !info.jited_line_info) ||
6029 info.nr_jited_line_info != jited_cnt ||
6030 info.line_info_rec_size != rec_size ||
6031 info.jited_line_info_rec_size != jited_rec_size,
6032 "err:%d errno:%d info: nr_line_info:%u(expected:%u) nr_jited_line_info:%u(expected:%u) line_info_rec_size:%u(expected:%u) jited_linfo_rec_size:%u(expected:%u) line_info:%p jited_line_info:%p",
6033 err, errno,
6034 info.nr_line_info, cnt,
6035 info.nr_jited_line_info, jited_cnt,
6036 info.line_info_rec_size, rec_size,
6037 info.jited_line_info_rec_size, jited_rec_size,
6038 (void *)(long)info.line_info,
6039 (void *)(long)info.jited_line_info)) {
6040 err = -1;
6041 goto done;
6044 dead_insns = 0;
6045 while (test->dead_code_mask & (1 << dead_insns))
6046 dead_insns++;
6048 CHECK(linfo[0].insn_off, "linfo[0].insn_off:%u",
6049 linfo[0].insn_off);
6050 for (i = 1; i < cnt; i++) {
6051 const struct bpf_line_info *expected_linfo;
6053 while (test->dead_code_mask & (1 << (i + dead_insns)))
6054 dead_insns++;
6056 expected_linfo = patched_linfo +
6057 ((i + dead_insns) * test->line_info_rec_size);
6058 if (CHECK(linfo[i].insn_off <= linfo[i - 1].insn_off,
6059 "linfo[%u].insn_off:%u <= linfo[%u].insn_off:%u",
6060 i, linfo[i].insn_off,
6061 i - 1, linfo[i - 1].insn_off)) {
6062 err = -1;
6063 goto done;
6065 if (CHECK(linfo[i].file_name_off != expected_linfo->file_name_off ||
6066 linfo[i].line_off != expected_linfo->line_off ||
6067 linfo[i].line_col != expected_linfo->line_col,
6068 "linfo[%u] (%u, %u, %u) != (%u, %u, %u)", i,
6069 linfo[i].file_name_off,
6070 linfo[i].line_off,
6071 linfo[i].line_col,
6072 expected_linfo->file_name_off,
6073 expected_linfo->line_off,
6074 expected_linfo->line_col)) {
6075 err = -1;
6076 goto done;
6080 if (!jited_cnt) {
6081 fprintf(stderr, "not jited. skipping jited_line_info check. ");
6082 err = 0;
6083 goto done;
6086 if (CHECK(jited_linfo[0] != jited_ksyms[0],
6087 "jited_linfo[0]:%lx != jited_ksyms[0]:%lx",
6088 (long)(jited_linfo[0]), (long)(jited_ksyms[0]))) {
6089 err = -1;
6090 goto done;
6093 ksyms_found = 1;
6094 cur_func_len = jited_func_lens[0];
6095 cur_func_ksyms = jited_ksyms[0];
6096 for (i = 1; i < jited_cnt; i++) {
6097 if (ksyms_found < nr_jited_ksyms &&
6098 jited_linfo[i] == jited_ksyms[ksyms_found]) {
6099 cur_func_ksyms = jited_ksyms[ksyms_found];
6100 cur_func_len = jited_ksyms[ksyms_found];
6101 ksyms_found++;
6102 continue;
6105 if (CHECK(jited_linfo[i] <= jited_linfo[i - 1],
6106 "jited_linfo[%u]:%lx <= jited_linfo[%u]:%lx",
6107 i, (long)jited_linfo[i],
6108 i - 1, (long)(jited_linfo[i - 1]))) {
6109 err = -1;
6110 goto done;
6113 if (CHECK(jited_linfo[i] - cur_func_ksyms > cur_func_len,
6114 "jited_linfo[%u]:%lx - %lx > %u",
6115 i, (long)jited_linfo[i], (long)cur_func_ksyms,
6116 cur_func_len)) {
6117 err = -1;
6118 goto done;
6122 if (CHECK(ksyms_found != nr_jited_ksyms,
6123 "ksyms_found:%u != nr_jited_ksyms:%u",
6124 ksyms_found, nr_jited_ksyms)) {
6125 err = -1;
6126 goto done;
6129 err = 0;
6131 done:
6132 free(linfo);
6133 free(jited_linfo);
6134 free(jited_ksyms);
6135 free(jited_func_lens);
6136 return err;
6139 static int do_test_info_raw(unsigned int test_num)
6141 const struct prog_info_raw_test *test = &info_raw_tests[test_num - 1];
6142 unsigned int raw_btf_size, linfo_str_off, linfo_size;
6143 int btf_fd = -1, prog_fd = -1, err = 0;
6144 void *raw_btf, *patched_linfo = NULL;
6145 const char *ret_next_str;
6146 union bpf_attr attr = {};
6148 fprintf(stderr, "BTF prog info raw test[%u] (%s): ", test_num, test->descr);
6149 raw_btf = btf_raw_create(&hdr_tmpl, test->raw_types,
6150 test->str_sec, test->str_sec_size,
6151 &raw_btf_size, &ret_next_str);
6153 if (!raw_btf)
6154 return -1;
6156 *btf_log_buf = '\0';
6157 btf_fd = bpf_load_btf(raw_btf, raw_btf_size,
6158 btf_log_buf, BTF_LOG_BUF_SIZE,
6159 args.always_log);
6160 free(raw_btf);
6162 if (CHECK(btf_fd == -1, "invalid btf_fd errno:%d", errno)) {
6163 err = -1;
6164 goto done;
6167 if (*btf_log_buf && args.always_log)
6168 fprintf(stderr, "\n%s", btf_log_buf);
6169 *btf_log_buf = '\0';
6171 linfo_str_off = ret_next_str - test->str_sec;
6172 patched_linfo = patch_name_tbd(test->line_info,
6173 test->str_sec, linfo_str_off,
6174 test->str_sec_size, &linfo_size);
6175 if (IS_ERR(patched_linfo)) {
6176 fprintf(stderr, "error in creating raw bpf_line_info");
6177 err = -1;
6178 goto done;
6181 attr.prog_type = test->prog_type;
6182 attr.insns = ptr_to_u64(test->insns);
6183 attr.insn_cnt = probe_prog_length(test->insns);
6184 attr.license = ptr_to_u64("GPL");
6185 attr.prog_btf_fd = btf_fd;
6186 attr.func_info_rec_size = test->func_info_rec_size;
6187 attr.func_info_cnt = test->func_info_cnt;
6188 attr.func_info = ptr_to_u64(test->func_info);
6189 attr.log_buf = ptr_to_u64(btf_log_buf);
6190 attr.log_size = BTF_LOG_BUF_SIZE;
6191 attr.log_level = 1;
6192 if (linfo_size) {
6193 attr.line_info_rec_size = test->line_info_rec_size;
6194 attr.line_info = ptr_to_u64(patched_linfo);
6195 attr.line_info_cnt = linfo_size / attr.line_info_rec_size;
6198 prog_fd = syscall(__NR_bpf, BPF_PROG_LOAD, &attr, sizeof(attr));
6199 err = ((prog_fd == -1) != test->expected_prog_load_failure);
6200 if (CHECK(err, "prog_fd:%d expected_prog_load_failure:%u errno:%d",
6201 prog_fd, test->expected_prog_load_failure, errno) ||
6202 CHECK(test->err_str && !strstr(btf_log_buf, test->err_str),
6203 "expected err_str:%s", test->err_str)) {
6204 err = -1;
6205 goto done;
6208 if (prog_fd == -1)
6209 goto done;
6211 err = test_get_finfo(test, prog_fd);
6212 if (err)
6213 goto done;
6215 err = test_get_linfo(test, patched_linfo,
6216 attr.line_info_cnt - test->dead_code_cnt,
6217 prog_fd);
6218 if (err)
6219 goto done;
6221 done:
6222 if (!err)
6223 fprintf(stderr, "OK");
6225 if (*btf_log_buf && (err || args.always_log))
6226 fprintf(stderr, "\n%s", btf_log_buf);
6228 if (btf_fd != -1)
6229 close(btf_fd);
6230 if (prog_fd != -1)
6231 close(prog_fd);
6233 if (!IS_ERR(patched_linfo))
6234 free(patched_linfo);
6236 return err;
6239 static int test_info_raw(void)
6241 unsigned int i;
6242 int err = 0;
6244 if (args.info_raw_test_num)
6245 return count_result(do_test_info_raw(args.info_raw_test_num));
6247 for (i = 1; i <= ARRAY_SIZE(info_raw_tests); i++)
6248 err |= count_result(do_test_info_raw(i));
6250 return err;
6253 struct btf_raw_data {
6254 __u32 raw_types[MAX_NR_RAW_U32];
6255 const char *str_sec;
6256 __u32 str_sec_size;
6259 struct btf_dedup_test {
6260 const char *descr;
6261 struct btf_raw_data input;
6262 struct btf_raw_data expect;
6263 struct btf_dedup_opts opts;
6266 const struct btf_dedup_test dedup_tests[] = {
6269 .descr = "dedup: unused strings filtering",
6270 .input = {
6271 .raw_types = {
6272 BTF_TYPE_INT_ENC(NAME_NTH(2), BTF_INT_SIGNED, 0, 32, 4),
6273 BTF_TYPE_INT_ENC(NAME_NTH(5), BTF_INT_SIGNED, 0, 64, 8),
6274 BTF_END_RAW,
6276 BTF_STR_SEC("\0unused\0int\0foo\0bar\0long"),
6278 .expect = {
6279 .raw_types = {
6280 BTF_TYPE_INT_ENC(NAME_NTH(1), BTF_INT_SIGNED, 0, 32, 4),
6281 BTF_TYPE_INT_ENC(NAME_NTH(2), BTF_INT_SIGNED, 0, 64, 8),
6282 BTF_END_RAW,
6284 BTF_STR_SEC("\0int\0long"),
6286 .opts = {
6287 .dont_resolve_fwds = false,
6291 .descr = "dedup: strings deduplication",
6292 .input = {
6293 .raw_types = {
6294 BTF_TYPE_INT_ENC(NAME_NTH(1), BTF_INT_SIGNED, 0, 32, 4),
6295 BTF_TYPE_INT_ENC(NAME_NTH(2), BTF_INT_SIGNED, 0, 64, 8),
6296 BTF_TYPE_INT_ENC(NAME_NTH(3), BTF_INT_SIGNED, 0, 32, 4),
6297 BTF_TYPE_INT_ENC(NAME_NTH(4), BTF_INT_SIGNED, 0, 64, 8),
6298 BTF_TYPE_INT_ENC(NAME_NTH(5), BTF_INT_SIGNED, 0, 32, 4),
6299 BTF_END_RAW,
6301 BTF_STR_SEC("\0int\0long int\0int\0long int\0int"),
6303 .expect = {
6304 .raw_types = {
6305 BTF_TYPE_INT_ENC(NAME_NTH(1), BTF_INT_SIGNED, 0, 32, 4),
6306 BTF_TYPE_INT_ENC(NAME_NTH(2), BTF_INT_SIGNED, 0, 64, 8),
6307 BTF_END_RAW,
6309 BTF_STR_SEC("\0int\0long int"),
6311 .opts = {
6312 .dont_resolve_fwds = false,
6316 .descr = "dedup: struct example #1",
6318 * struct s {
6319 * struct s *next;
6320 * const int *a;
6321 * int b[16];
6322 * int c;
6325 .input = {
6326 .raw_types = {
6327 /* int */
6328 BTF_TYPE_INT_ENC(NAME_NTH(1), BTF_INT_SIGNED, 0, 32, 4), /* [1] */
6329 /* int[16] */
6330 BTF_TYPE_ARRAY_ENC(1, 1, 16), /* [2] */
6331 /* struct s { */
6332 BTF_STRUCT_ENC(NAME_NTH(2), 4, 84), /* [3] */
6333 BTF_MEMBER_ENC(NAME_NTH(3), 4, 0), /* struct s *next; */
6334 BTF_MEMBER_ENC(NAME_NTH(4), 5, 64), /* const int *a; */
6335 BTF_MEMBER_ENC(NAME_NTH(5), 2, 128), /* int b[16]; */
6336 BTF_MEMBER_ENC(NAME_NTH(6), 1, 640), /* int c; */
6337 /* ptr -> [3] struct s */
6338 BTF_PTR_ENC(3), /* [4] */
6339 /* ptr -> [6] const int */
6340 BTF_PTR_ENC(6), /* [5] */
6341 /* const -> [1] int */
6342 BTF_CONST_ENC(1), /* [6] */
6344 /* full copy of the above */
6345 BTF_TYPE_INT_ENC(NAME_NTH(1), BTF_INT_SIGNED, 0, 32, 4), /* [7] */
6346 BTF_TYPE_ARRAY_ENC(7, 7, 16), /* [8] */
6347 BTF_STRUCT_ENC(NAME_NTH(2), 4, 84), /* [9] */
6348 BTF_MEMBER_ENC(NAME_NTH(3), 10, 0),
6349 BTF_MEMBER_ENC(NAME_NTH(4), 11, 64),
6350 BTF_MEMBER_ENC(NAME_NTH(5), 8, 128),
6351 BTF_MEMBER_ENC(NAME_NTH(6), 7, 640),
6352 BTF_PTR_ENC(9), /* [10] */
6353 BTF_PTR_ENC(12), /* [11] */
6354 BTF_CONST_ENC(7), /* [12] */
6355 BTF_END_RAW,
6357 BTF_STR_SEC("\0int\0s\0next\0a\0b\0c\0"),
6359 .expect = {
6360 .raw_types = {
6361 /* int */
6362 BTF_TYPE_INT_ENC(NAME_NTH(4), BTF_INT_SIGNED, 0, 32, 4), /* [1] */
6363 /* int[16] */
6364 BTF_TYPE_ARRAY_ENC(1, 1, 16), /* [2] */
6365 /* struct s { */
6366 BTF_STRUCT_ENC(NAME_NTH(6), 4, 84), /* [3] */
6367 BTF_MEMBER_ENC(NAME_NTH(5), 4, 0), /* struct s *next; */
6368 BTF_MEMBER_ENC(NAME_NTH(1), 5, 64), /* const int *a; */
6369 BTF_MEMBER_ENC(NAME_NTH(2), 2, 128), /* int b[16]; */
6370 BTF_MEMBER_ENC(NAME_NTH(3), 1, 640), /* int c; */
6371 /* ptr -> [3] struct s */
6372 BTF_PTR_ENC(3), /* [4] */
6373 /* ptr -> [6] const int */
6374 BTF_PTR_ENC(6), /* [5] */
6375 /* const -> [1] int */
6376 BTF_CONST_ENC(1), /* [6] */
6377 BTF_END_RAW,
6379 BTF_STR_SEC("\0a\0b\0c\0int\0next\0s"),
6381 .opts = {
6382 .dont_resolve_fwds = false,
6386 .descr = "dedup: struct <-> fwd resolution w/ hash collision",
6388 * // CU 1:
6389 * struct x;
6390 * struct s {
6391 * struct x *x;
6392 * };
6393 * // CU 2:
6394 * struct x {};
6395 * struct s {
6396 * struct x *x;
6397 * };
6399 .input = {
6400 .raw_types = {
6401 /* CU 1 */
6402 BTF_FWD_ENC(NAME_TBD, 0 /* struct fwd */), /* [1] fwd x */
6403 BTF_PTR_ENC(1), /* [2] ptr -> [1] */
6404 BTF_STRUCT_ENC(NAME_TBD, 1, 8), /* [3] struct s */
6405 BTF_MEMBER_ENC(NAME_TBD, 2, 0),
6406 /* CU 2 */
6407 BTF_STRUCT_ENC(NAME_TBD, 0, 0), /* [4] struct x */
6408 BTF_PTR_ENC(4), /* [5] ptr -> [4] */
6409 BTF_STRUCT_ENC(NAME_TBD, 1, 8), /* [6] struct s */
6410 BTF_MEMBER_ENC(NAME_TBD, 5, 0),
6411 BTF_END_RAW,
6413 BTF_STR_SEC("\0x\0s\0x\0x\0s\0x\0"),
6415 .expect = {
6416 .raw_types = {
6417 BTF_PTR_ENC(3), /* [1] ptr -> [3] */
6418 BTF_STRUCT_ENC(NAME_TBD, 1, 8), /* [2] struct s */
6419 BTF_MEMBER_ENC(NAME_TBD, 1, 0),
6420 BTF_STRUCT_ENC(NAME_NTH(2), 0, 0), /* [3] struct x */
6421 BTF_END_RAW,
6423 BTF_STR_SEC("\0s\0x"),
6425 .opts = {
6426 .dont_resolve_fwds = false,
6427 .dedup_table_size = 1, /* force hash collisions */
6431 .descr = "dedup: void equiv check",
6433 * // CU 1:
6434 * struct s {
6435 * struct {} *x;
6436 * };
6437 * // CU 2:
6438 * struct s {
6439 * int *x;
6440 * };
6442 .input = {
6443 .raw_types = {
6444 /* CU 1 */
6445 BTF_STRUCT_ENC(0, 0, 1), /* [1] struct {} */
6446 BTF_PTR_ENC(1), /* [2] ptr -> [1] */
6447 BTF_STRUCT_ENC(NAME_NTH(1), 1, 8), /* [3] struct s */
6448 BTF_MEMBER_ENC(NAME_NTH(2), 2, 0),
6449 /* CU 2 */
6450 BTF_PTR_ENC(0), /* [4] ptr -> void */
6451 BTF_STRUCT_ENC(NAME_NTH(1), 1, 8), /* [5] struct s */
6452 BTF_MEMBER_ENC(NAME_NTH(2), 4, 0),
6453 BTF_END_RAW,
6455 BTF_STR_SEC("\0s\0x"),
6457 .expect = {
6458 .raw_types = {
6459 /* CU 1 */
6460 BTF_STRUCT_ENC(0, 0, 1), /* [1] struct {} */
6461 BTF_PTR_ENC(1), /* [2] ptr -> [1] */
6462 BTF_STRUCT_ENC(NAME_NTH(1), 1, 8), /* [3] struct s */
6463 BTF_MEMBER_ENC(NAME_NTH(2), 2, 0),
6464 /* CU 2 */
6465 BTF_PTR_ENC(0), /* [4] ptr -> void */
6466 BTF_STRUCT_ENC(NAME_NTH(1), 1, 8), /* [5] struct s */
6467 BTF_MEMBER_ENC(NAME_NTH(2), 4, 0),
6468 BTF_END_RAW,
6470 BTF_STR_SEC("\0s\0x"),
6472 .opts = {
6473 .dont_resolve_fwds = false,
6474 .dedup_table_size = 1, /* force hash collisions */
6478 .descr = "dedup: all possible kinds (no duplicates)",
6479 .input = {
6480 .raw_types = {
6481 BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 8), /* [1] int */
6482 BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_ENUM, 0, 2), 4), /* [2] enum */
6483 BTF_ENUM_ENC(NAME_TBD, 0),
6484 BTF_ENUM_ENC(NAME_TBD, 1),
6485 BTF_FWD_ENC(NAME_TBD, 1 /* union kind_flag */), /* [3] fwd */
6486 BTF_TYPE_ARRAY_ENC(2, 1, 7), /* [4] array */
6487 BTF_STRUCT_ENC(NAME_TBD, 1, 4), /* [5] struct */
6488 BTF_MEMBER_ENC(NAME_TBD, 1, 0),
6489 BTF_UNION_ENC(NAME_TBD, 1, 4), /* [6] union */
6490 BTF_MEMBER_ENC(NAME_TBD, 1, 0),
6491 BTF_TYPEDEF_ENC(NAME_TBD, 1), /* [7] typedef */
6492 BTF_PTR_ENC(0), /* [8] ptr */
6493 BTF_CONST_ENC(8), /* [9] const */
6494 BTF_VOLATILE_ENC(8), /* [10] volatile */
6495 BTF_RESTRICT_ENC(8), /* [11] restrict */
6496 BTF_FUNC_PROTO_ENC(1, 2), /* [12] func_proto */
6497 BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
6498 BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 8),
6499 BTF_FUNC_ENC(NAME_TBD, 12), /* [13] func */
6500 BTF_END_RAW,
6502 BTF_STR_SEC("\0A\0B\0C\0D\0E\0F\0G\0H\0I\0J\0K\0L\0M"),
6504 .expect = {
6505 .raw_types = {
6506 BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 8), /* [1] int */
6507 BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_ENUM, 0, 2), 4), /* [2] enum */
6508 BTF_ENUM_ENC(NAME_TBD, 0),
6509 BTF_ENUM_ENC(NAME_TBD, 1),
6510 BTF_FWD_ENC(NAME_TBD, 1 /* union kind_flag */), /* [3] fwd */
6511 BTF_TYPE_ARRAY_ENC(2, 1, 7), /* [4] array */
6512 BTF_STRUCT_ENC(NAME_TBD, 1, 4), /* [5] struct */
6513 BTF_MEMBER_ENC(NAME_TBD, 1, 0),
6514 BTF_UNION_ENC(NAME_TBD, 1, 4), /* [6] union */
6515 BTF_MEMBER_ENC(NAME_TBD, 1, 0),
6516 BTF_TYPEDEF_ENC(NAME_TBD, 1), /* [7] typedef */
6517 BTF_PTR_ENC(0), /* [8] ptr */
6518 BTF_CONST_ENC(8), /* [9] const */
6519 BTF_VOLATILE_ENC(8), /* [10] volatile */
6520 BTF_RESTRICT_ENC(8), /* [11] restrict */
6521 BTF_FUNC_PROTO_ENC(1, 2), /* [12] func_proto */
6522 BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
6523 BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 8),
6524 BTF_FUNC_ENC(NAME_TBD, 12), /* [13] func */
6525 BTF_END_RAW,
6527 BTF_STR_SEC("\0A\0B\0C\0D\0E\0F\0G\0H\0I\0J\0K\0L\0M"),
6529 .opts = {
6530 .dont_resolve_fwds = false,
6534 .descr = "dedup: no int duplicates",
6535 .input = {
6536 .raw_types = {
6537 BTF_TYPE_INT_ENC(NAME_NTH(1), BTF_INT_SIGNED, 0, 32, 8),
6538 /* different name */
6539 BTF_TYPE_INT_ENC(NAME_NTH(2), BTF_INT_SIGNED, 0, 32, 8),
6540 /* different encoding */
6541 BTF_TYPE_INT_ENC(NAME_NTH(1), BTF_INT_CHAR, 0, 32, 8),
6542 BTF_TYPE_INT_ENC(NAME_NTH(1), BTF_INT_BOOL, 0, 32, 8),
6543 /* different bit offset */
6544 BTF_TYPE_INT_ENC(NAME_NTH(1), BTF_INT_SIGNED, 8, 32, 8),
6545 /* different bit size */
6546 BTF_TYPE_INT_ENC(NAME_NTH(1), BTF_INT_SIGNED, 0, 27, 8),
6547 /* different byte size */
6548 BTF_TYPE_INT_ENC(NAME_NTH(1), BTF_INT_SIGNED, 0, 32, 4),
6549 BTF_END_RAW,
6551 BTF_STR_SEC("\0int\0some other int"),
6553 .expect = {
6554 .raw_types = {
6555 BTF_TYPE_INT_ENC(NAME_NTH(1), BTF_INT_SIGNED, 0, 32, 8),
6556 /* different name */
6557 BTF_TYPE_INT_ENC(NAME_NTH(2), BTF_INT_SIGNED, 0, 32, 8),
6558 /* different encoding */
6559 BTF_TYPE_INT_ENC(NAME_NTH(1), BTF_INT_CHAR, 0, 32, 8),
6560 BTF_TYPE_INT_ENC(NAME_NTH(1), BTF_INT_BOOL, 0, 32, 8),
6561 /* different bit offset */
6562 BTF_TYPE_INT_ENC(NAME_NTH(1), BTF_INT_SIGNED, 8, 32, 8),
6563 /* different bit size */
6564 BTF_TYPE_INT_ENC(NAME_NTH(1), BTF_INT_SIGNED, 0, 27, 8),
6565 /* different byte size */
6566 BTF_TYPE_INT_ENC(NAME_NTH(1), BTF_INT_SIGNED, 0, 32, 4),
6567 BTF_END_RAW,
6569 BTF_STR_SEC("\0int\0some other int"),
6571 .opts = {
6572 .dont_resolve_fwds = false,
6576 .descr = "dedup: enum fwd resolution",
6577 .input = {
6578 .raw_types = {
6579 /* [1] fwd enum 'e1' before full enum */
6580 BTF_TYPE_ENC(NAME_NTH(1), BTF_INFO_ENC(BTF_KIND_ENUM, 0, 0), 4),
6581 /* [2] full enum 'e1' after fwd */
6582 BTF_TYPE_ENC(NAME_NTH(1), BTF_INFO_ENC(BTF_KIND_ENUM, 0, 1), 4),
6583 BTF_ENUM_ENC(NAME_NTH(2), 123),
6584 /* [3] full enum 'e2' before fwd */
6585 BTF_TYPE_ENC(NAME_NTH(3), BTF_INFO_ENC(BTF_KIND_ENUM, 0, 1), 4),
6586 BTF_ENUM_ENC(NAME_NTH(4), 456),
6587 /* [4] fwd enum 'e2' after full enum */
6588 BTF_TYPE_ENC(NAME_NTH(3), BTF_INFO_ENC(BTF_KIND_ENUM, 0, 0), 4),
6589 /* [5] incompatible fwd enum with different size */
6590 BTF_TYPE_ENC(NAME_NTH(1), BTF_INFO_ENC(BTF_KIND_ENUM, 0, 0), 1),
6591 /* [6] incompatible full enum with different value */
6592 BTF_TYPE_ENC(NAME_NTH(1), BTF_INFO_ENC(BTF_KIND_ENUM, 0, 1), 4),
6593 BTF_ENUM_ENC(NAME_NTH(2), 321),
6594 BTF_END_RAW,
6596 BTF_STR_SEC("\0e1\0e1_val\0e2\0e2_val"),
6598 .expect = {
6599 .raw_types = {
6600 /* [1] full enum 'e1' */
6601 BTF_TYPE_ENC(NAME_NTH(1), BTF_INFO_ENC(BTF_KIND_ENUM, 0, 1), 4),
6602 BTF_ENUM_ENC(NAME_NTH(2), 123),
6603 /* [2] full enum 'e2' */
6604 BTF_TYPE_ENC(NAME_NTH(3), BTF_INFO_ENC(BTF_KIND_ENUM, 0, 1), 4),
6605 BTF_ENUM_ENC(NAME_NTH(4), 456),
6606 /* [3] incompatible fwd enum with different size */
6607 BTF_TYPE_ENC(NAME_NTH(1), BTF_INFO_ENC(BTF_KIND_ENUM, 0, 0), 1),
6608 /* [4] incompatible full enum with different value */
6609 BTF_TYPE_ENC(NAME_NTH(1), BTF_INFO_ENC(BTF_KIND_ENUM, 0, 1), 4),
6610 BTF_ENUM_ENC(NAME_NTH(2), 321),
6611 BTF_END_RAW,
6613 BTF_STR_SEC("\0e1\0e1_val\0e2\0e2_val"),
6615 .opts = {
6616 .dont_resolve_fwds = false,
6620 .descr = "dedup: datasec and vars pass-through",
6621 .input = {
6622 .raw_types = {
6623 /* int */
6624 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
6625 /* static int t */
6626 BTF_VAR_ENC(NAME_NTH(2), 1, 0), /* [2] */
6627 /* .bss section */ /* [3] */
6628 BTF_TYPE_ENC(NAME_NTH(1), BTF_INFO_ENC(BTF_KIND_DATASEC, 0, 1), 4),
6629 BTF_VAR_SECINFO_ENC(2, 0, 4),
6630 /* int, referenced from [5] */
6631 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [4] */
6632 /* another static int t */
6633 BTF_VAR_ENC(NAME_NTH(2), 4, 0), /* [5] */
6634 /* another .bss section */ /* [6] */
6635 BTF_TYPE_ENC(NAME_NTH(1), BTF_INFO_ENC(BTF_KIND_DATASEC, 0, 1), 4),
6636 BTF_VAR_SECINFO_ENC(5, 0, 4),
6637 BTF_END_RAW,
6639 BTF_STR_SEC("\0.bss\0t"),
6641 .expect = {
6642 .raw_types = {
6643 /* int */
6644 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
6645 /* static int t */
6646 BTF_VAR_ENC(NAME_NTH(2), 1, 0), /* [2] */
6647 /* .bss section */ /* [3] */
6648 BTF_TYPE_ENC(NAME_NTH(1), BTF_INFO_ENC(BTF_KIND_DATASEC, 0, 1), 4),
6649 BTF_VAR_SECINFO_ENC(2, 0, 4),
6650 /* another static int t */
6651 BTF_VAR_ENC(NAME_NTH(2), 1, 0), /* [4] */
6652 /* another .bss section */ /* [5] */
6653 BTF_TYPE_ENC(NAME_NTH(1), BTF_INFO_ENC(BTF_KIND_DATASEC, 0, 1), 4),
6654 BTF_VAR_SECINFO_ENC(4, 0, 4),
6655 BTF_END_RAW,
6657 BTF_STR_SEC("\0.bss\0t"),
6659 .opts = {
6660 .dont_resolve_fwds = false,
6661 .dedup_table_size = 1
6667 static int btf_type_size(const struct btf_type *t)
6669 int base_size = sizeof(struct btf_type);
6670 __u16 vlen = BTF_INFO_VLEN(t->info);
6671 __u16 kind = BTF_INFO_KIND(t->info);
6673 switch (kind) {
6674 case BTF_KIND_FWD:
6675 case BTF_KIND_CONST:
6676 case BTF_KIND_VOLATILE:
6677 case BTF_KIND_RESTRICT:
6678 case BTF_KIND_PTR:
6679 case BTF_KIND_TYPEDEF:
6680 case BTF_KIND_FUNC:
6681 return base_size;
6682 case BTF_KIND_INT:
6683 return base_size + sizeof(__u32);
6684 case BTF_KIND_ENUM:
6685 return base_size + vlen * sizeof(struct btf_enum);
6686 case BTF_KIND_ARRAY:
6687 return base_size + sizeof(struct btf_array);
6688 case BTF_KIND_STRUCT:
6689 case BTF_KIND_UNION:
6690 return base_size + vlen * sizeof(struct btf_member);
6691 case BTF_KIND_FUNC_PROTO:
6692 return base_size + vlen * sizeof(struct btf_param);
6693 case BTF_KIND_VAR:
6694 return base_size + sizeof(struct btf_var);
6695 case BTF_KIND_DATASEC:
6696 return base_size + vlen * sizeof(struct btf_var_secinfo);
6697 default:
6698 fprintf(stderr, "Unsupported BTF_KIND:%u\n", kind);
6699 return -EINVAL;
6703 static void dump_btf_strings(const char *strs, __u32 len)
6705 const char *cur = strs;
6706 int i = 0;
6708 while (cur < strs + len) {
6709 fprintf(stderr, "string #%d: '%s'\n", i, cur);
6710 cur += strlen(cur) + 1;
6711 i++;
6715 static int do_test_dedup(unsigned int test_num)
6717 const struct btf_dedup_test *test = &dedup_tests[test_num - 1];
6718 __u32 test_nr_types, expect_nr_types, test_btf_size, expect_btf_size;
6719 const struct btf_header *test_hdr, *expect_hdr;
6720 struct btf *test_btf = NULL, *expect_btf = NULL;
6721 const void *test_btf_data, *expect_btf_data;
6722 const char *ret_test_next_str, *ret_expect_next_str;
6723 const char *test_strs, *expect_strs;
6724 const char *test_str_cur, *test_str_end;
6725 const char *expect_str_cur, *expect_str_end;
6726 unsigned int raw_btf_size;
6727 void *raw_btf;
6728 int err = 0, i;
6730 fprintf(stderr, "BTF dedup test[%u] (%s):", test_num, test->descr);
6732 raw_btf = btf_raw_create(&hdr_tmpl, test->input.raw_types,
6733 test->input.str_sec, test->input.str_sec_size,
6734 &raw_btf_size, &ret_test_next_str);
6735 if (!raw_btf)
6736 return -1;
6737 test_btf = btf__new((__u8 *)raw_btf, raw_btf_size);
6738 free(raw_btf);
6739 if (CHECK(IS_ERR(test_btf), "invalid test_btf errno:%ld",
6740 PTR_ERR(test_btf))) {
6741 err = -1;
6742 goto done;
6745 raw_btf = btf_raw_create(&hdr_tmpl, test->expect.raw_types,
6746 test->expect.str_sec,
6747 test->expect.str_sec_size,
6748 &raw_btf_size, &ret_expect_next_str);
6749 if (!raw_btf)
6750 return -1;
6751 expect_btf = btf__new((__u8 *)raw_btf, raw_btf_size);
6752 free(raw_btf);
6753 if (CHECK(IS_ERR(expect_btf), "invalid expect_btf errno:%ld",
6754 PTR_ERR(expect_btf))) {
6755 err = -1;
6756 goto done;
6759 err = btf__dedup(test_btf, NULL, &test->opts);
6760 if (CHECK(err, "btf_dedup failed errno:%d", err)) {
6761 err = -1;
6762 goto done;
6765 test_btf_data = btf__get_raw_data(test_btf, &test_btf_size);
6766 expect_btf_data = btf__get_raw_data(expect_btf, &expect_btf_size);
6767 if (CHECK(test_btf_size != expect_btf_size,
6768 "test_btf_size:%u != expect_btf_size:%u",
6769 test_btf_size, expect_btf_size)) {
6770 err = -1;
6771 goto done;
6774 test_hdr = test_btf_data;
6775 test_strs = test_btf_data + sizeof(*test_hdr) + test_hdr->str_off;
6776 expect_hdr = expect_btf_data;
6777 expect_strs = expect_btf_data + sizeof(*test_hdr) + expect_hdr->str_off;
6778 if (CHECK(test_hdr->str_len != expect_hdr->str_len,
6779 "test_hdr->str_len:%u != expect_hdr->str_len:%u",
6780 test_hdr->str_len, expect_hdr->str_len)) {
6781 fprintf(stderr, "\ntest strings:\n");
6782 dump_btf_strings(test_strs, test_hdr->str_len);
6783 fprintf(stderr, "\nexpected strings:\n");
6784 dump_btf_strings(expect_strs, expect_hdr->str_len);
6785 err = -1;
6786 goto done;
6789 test_str_cur = test_strs;
6790 test_str_end = test_strs + test_hdr->str_len;
6791 expect_str_cur = expect_strs;
6792 expect_str_end = expect_strs + expect_hdr->str_len;
6793 while (test_str_cur < test_str_end && expect_str_cur < expect_str_end) {
6794 size_t test_len, expect_len;
6796 test_len = strlen(test_str_cur);
6797 expect_len = strlen(expect_str_cur);
6798 if (CHECK(test_len != expect_len,
6799 "test_len:%zu != expect_len:%zu "
6800 "(test_str:%s, expect_str:%s)",
6801 test_len, expect_len, test_str_cur, expect_str_cur)) {
6802 err = -1;
6803 goto done;
6805 if (CHECK(strcmp(test_str_cur, expect_str_cur),
6806 "test_str:%s != expect_str:%s",
6807 test_str_cur, expect_str_cur)) {
6808 err = -1;
6809 goto done;
6811 test_str_cur += test_len + 1;
6812 expect_str_cur += expect_len + 1;
6814 if (CHECK(test_str_cur != test_str_end,
6815 "test_str_cur:%p != test_str_end:%p",
6816 test_str_cur, test_str_end)) {
6817 err = -1;
6818 goto done;
6821 test_nr_types = btf__get_nr_types(test_btf);
6822 expect_nr_types = btf__get_nr_types(expect_btf);
6823 if (CHECK(test_nr_types != expect_nr_types,
6824 "test_nr_types:%u != expect_nr_types:%u",
6825 test_nr_types, expect_nr_types)) {
6826 err = -1;
6827 goto done;
6830 for (i = 1; i <= test_nr_types; i++) {
6831 const struct btf_type *test_type, *expect_type;
6832 int test_size, expect_size;
6834 test_type = btf__type_by_id(test_btf, i);
6835 expect_type = btf__type_by_id(expect_btf, i);
6836 test_size = btf_type_size(test_type);
6837 expect_size = btf_type_size(expect_type);
6839 if (CHECK(test_size != expect_size,
6840 "type #%d: test_size:%d != expect_size:%u",
6841 i, test_size, expect_size)) {
6842 err = -1;
6843 goto done;
6845 if (CHECK(memcmp((void *)test_type,
6846 (void *)expect_type,
6847 test_size),
6848 "type #%d: contents differ", i)) {
6849 err = -1;
6850 goto done;
6854 done:
6855 if (!err)
6856 fprintf(stderr, "OK");
6857 if (!IS_ERR(test_btf))
6858 btf__free(test_btf);
6859 if (!IS_ERR(expect_btf))
6860 btf__free(expect_btf);
6862 return err;
6865 static int test_dedup(void)
6867 unsigned int i;
6868 int err = 0;
6870 if (args.dedup_test_num)
6871 return count_result(do_test_dedup(args.dedup_test_num));
6873 for (i = 1; i <= ARRAY_SIZE(dedup_tests); i++)
6874 err |= count_result(do_test_dedup(i));
6876 return err;
6879 static void usage(const char *cmd)
6881 fprintf(stderr, "Usage: %s [-l] [[-r btf_raw_test_num (1 - %zu)] |\n"
6882 "\t[-g btf_get_info_test_num (1 - %zu)] |\n"
6883 "\t[-f btf_file_test_num (1 - %zu)] |\n"
6884 "\t[-k btf_prog_info_raw_test_num (1 - %zu)] |\n"
6885 "\t[-p (pretty print test)] |\n"
6886 "\t[-d btf_dedup_test_num (1 - %zu)]]\n",
6887 cmd, ARRAY_SIZE(raw_tests), ARRAY_SIZE(get_info_tests),
6888 ARRAY_SIZE(file_tests), ARRAY_SIZE(info_raw_tests),
6889 ARRAY_SIZE(dedup_tests));
6892 static int parse_args(int argc, char **argv)
6894 const char *optstr = "hlpk:f:r:g:d:";
6895 int opt;
6897 while ((opt = getopt(argc, argv, optstr)) != -1) {
6898 switch (opt) {
6899 case 'l':
6900 args.always_log = true;
6901 break;
6902 case 'f':
6903 args.file_test_num = atoi(optarg);
6904 args.file_test = true;
6905 break;
6906 case 'r':
6907 args.raw_test_num = atoi(optarg);
6908 args.raw_test = true;
6909 break;
6910 case 'g':
6911 args.get_info_test_num = atoi(optarg);
6912 args.get_info_test = true;
6913 break;
6914 case 'p':
6915 args.pprint_test = true;
6916 break;
6917 case 'k':
6918 args.info_raw_test_num = atoi(optarg);
6919 args.info_raw_test = true;
6920 break;
6921 case 'd':
6922 args.dedup_test_num = atoi(optarg);
6923 args.dedup_test = true;
6924 break;
6925 case 'h':
6926 usage(argv[0]);
6927 exit(0);
6928 default:
6929 usage(argv[0]);
6930 return -1;
6934 if (args.raw_test_num &&
6935 (args.raw_test_num < 1 ||
6936 args.raw_test_num > ARRAY_SIZE(raw_tests))) {
6937 fprintf(stderr, "BTF raw test number must be [1 - %zu]\n",
6938 ARRAY_SIZE(raw_tests));
6939 return -1;
6942 if (args.file_test_num &&
6943 (args.file_test_num < 1 ||
6944 args.file_test_num > ARRAY_SIZE(file_tests))) {
6945 fprintf(stderr, "BTF file test number must be [1 - %zu]\n",
6946 ARRAY_SIZE(file_tests));
6947 return -1;
6950 if (args.get_info_test_num &&
6951 (args.get_info_test_num < 1 ||
6952 args.get_info_test_num > ARRAY_SIZE(get_info_tests))) {
6953 fprintf(stderr, "BTF get info test number must be [1 - %zu]\n",
6954 ARRAY_SIZE(get_info_tests));
6955 return -1;
6958 if (args.info_raw_test_num &&
6959 (args.info_raw_test_num < 1 ||
6960 args.info_raw_test_num > ARRAY_SIZE(info_raw_tests))) {
6961 fprintf(stderr, "BTF prog info raw test number must be [1 - %zu]\n",
6962 ARRAY_SIZE(info_raw_tests));
6963 return -1;
6966 if (args.dedup_test_num &&
6967 (args.dedup_test_num < 1 ||
6968 args.dedup_test_num > ARRAY_SIZE(dedup_tests))) {
6969 fprintf(stderr, "BTF dedup test number must be [1 - %zu]\n",
6970 ARRAY_SIZE(dedup_tests));
6971 return -1;
6974 return 0;
6977 static void print_summary(void)
6979 fprintf(stderr, "PASS:%u SKIP:%u FAIL:%u\n",
6980 pass_cnt - skip_cnt, skip_cnt, error_cnt);
6983 int main(int argc, char **argv)
6985 int err = 0;
6987 err = parse_args(argc, argv);
6988 if (err)
6989 return err;
6991 if (args.always_log)
6992 libbpf_set_print(__base_pr);
6994 if (args.raw_test)
6995 err |= test_raw();
6997 if (args.get_info_test)
6998 err |= test_get_info();
7000 if (args.file_test)
7001 err |= test_file();
7003 if (args.pprint_test)
7004 err |= test_pprint();
7006 if (args.info_raw_test)
7007 err |= test_info_raw();
7009 if (args.dedup_test)
7010 err |= test_dedup();
7012 if (args.raw_test || args.get_info_test || args.file_test ||
7013 args.pprint_test || args.info_raw_test || args.dedup_test)
7014 goto done;
7016 err |= test_raw();
7017 err |= test_get_info();
7018 err |= test_file();
7019 err |= test_info_raw();
7020 err |= test_dedup();
7022 done:
7023 print_summary();
7024 return err;