1 /* SPDX-License-Identifier: GPL-2.0 */
2 /* Copyright (c) 2018 Facebook */
7 #include <linux/kernel.h>
8 #include <linux/filter.h>
9 #include <linux/unistd.h>
11 #include <sys/resource.h>
21 #include <bpf/libbpf.h>
24 #include "bpf_rlimit.h"
28 #define MAX_SUBPROGS 16
30 static uint32_t pass_cnt;
31 static uint32_t error_cnt;
32 static uint32_t skip_cnt;
34 #define CHECK(condition, format...) ({ \
35 int __ret = !!(condition); \
37 fprintf(stderr, "%s:%d:FAIL ", __func__, __LINE__); \
38 fprintf(stderr, format); \
43 static int count_result(int err)
50 fprintf(stderr, "\n");
54 #define __printf(a, b) __attribute__((format(printf, a, b)))
57 static int __base_pr(const char *format, ...)
62 va_start(args, format);
63 err = vfprintf(stderr, format, args);
68 #define BTF_INFO_ENC(kind, kind_flag, vlen) \
69 ((!!(kind_flag) << 31) | ((kind) << 24) | ((vlen) & BTF_MAX_VLEN))
71 #define BTF_TYPE_ENC(name, info, size_or_type) \
72 (name), (info), (size_or_type)
74 #define BTF_INT_ENC(encoding, bits_offset, nr_bits) \
75 ((encoding) << 24 | (bits_offset) << 16 | (nr_bits))
76 #define BTF_TYPE_INT_ENC(name, encoding, bits_offset, bits, sz) \
77 BTF_TYPE_ENC(name, BTF_INFO_ENC(BTF_KIND_INT, 0, 0), sz), \
78 BTF_INT_ENC(encoding, bits_offset, bits)
80 #define BTF_ARRAY_ENC(type, index_type, nr_elems) \
81 (type), (index_type), (nr_elems)
82 #define BTF_TYPE_ARRAY_ENC(type, index_type, nr_elems) \
83 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_ARRAY, 0, 0), 0), \
84 BTF_ARRAY_ENC(type, index_type, nr_elems)
86 #define BTF_MEMBER_ENC(name, type, bits_offset) \
87 (name), (type), (bits_offset)
88 #define BTF_ENUM_ENC(name, val) (name), (val)
89 #define BTF_MEMBER_OFFSET(bitfield_size, bits_offset) \
90 ((bitfield_size) << 24 | (bits_offset))
92 #define BTF_TYPEDEF_ENC(name, type) \
93 BTF_TYPE_ENC(name, BTF_INFO_ENC(BTF_KIND_TYPEDEF, 0, 0), type)
95 #define BTF_PTR_ENC(type) \
96 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_PTR, 0, 0), type)
98 #define BTF_CONST_ENC(type) \
99 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_CONST, 0, 0), type)
101 #define BTF_FUNC_PROTO_ENC(ret_type, nargs) \
102 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_FUNC_PROTO, 0, nargs), ret_type)
104 #define BTF_FUNC_PROTO_ARG_ENC(name, type) \
107 #define BTF_FUNC_ENC(name, func_proto) \
108 BTF_TYPE_ENC(name, BTF_INFO_ENC(BTF_KIND_FUNC, 0, 0), func_proto)
110 #define BTF_END_RAW 0xdeadbeef
111 #define NAME_TBD 0xdeadb33f
113 #define MAX_NR_RAW_U32 1024
114 #define BTF_LOG_BUF_SIZE 65535
117 unsigned int raw_test_num;
118 unsigned int file_test_num;
119 unsigned int get_info_test_num;
120 unsigned int info_raw_test_num;
129 static char btf_log_buf[BTF_LOG_BUF_SIZE];
131 static struct btf_header hdr_tmpl = {
133 .version = BTF_VERSION,
134 .hdr_len = sizeof(struct btf_header),
137 struct btf_raw_test {
140 const char *map_name;
142 __u32 raw_types[MAX_NR_RAW_U32];
144 enum bpf_map_type map_type;
161 #define BTF_STR_SEC(str) \
162 .str_sec = str, .str_sec_size = sizeof(str)
164 static struct btf_raw_test raw_tests[] = {
171 * unsigned long long m;
181 .descr = "struct test #1",
184 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
185 /* unsigned long long */
186 BTF_TYPE_INT_ENC(0, 0, 0, 64, 8), /* [2] */
188 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 8, 1), /* [3] */
190 BTF_TYPE_ARRAY_ENC(1, 1, 8), /* [4] */
191 /* struct A { */ /* [5] */
192 BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 6), 180),
193 BTF_MEMBER_ENC(NAME_TBD, 2, 0), /* unsigned long long m;*/
194 BTF_MEMBER_ENC(NAME_TBD, 1, 64),/* int n; */
195 BTF_MEMBER_ENC(NAME_TBD, 3, 96),/* char o; */
196 BTF_MEMBER_ENC(NAME_TBD, 4, 128),/* int p[8] */
197 BTF_MEMBER_ENC(NAME_TBD, 6, 384),/* int q[4][8] */
198 BTF_MEMBER_ENC(NAME_TBD, 7, 1408), /* enum E r */
201 BTF_TYPE_ARRAY_ENC(4, 1, 4), /* [6] */
202 /* enum E */ /* [7] */
203 BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_ENUM, 0, 2), sizeof(int)),
204 BTF_ENUM_ENC(NAME_TBD, 0),
205 BTF_ENUM_ENC(NAME_TBD, 1),
208 .str_sec = "\0A\0m\0n\0o\0p\0q\0r\0E\0E0\0E1",
209 .str_sec_size = sizeof("\0A\0m\0n\0o\0p\0q\0r\0E\0E0\0E1"),
210 .map_type = BPF_MAP_TYPE_ARRAY,
211 .map_name = "struct_test1_map",
212 .key_size = sizeof(int),
219 /* typedef struct b Struct_B;
224 * const Struct_B o[4];
233 .descr = "struct test #2",
236 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
237 /* struct b [4] */ /* [2] */
238 BTF_TYPE_ARRAY_ENC(4, 1, 4),
240 /* struct A { */ /* [3] */
241 BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 3), 68),
242 BTF_MEMBER_ENC(NAME_TBD, 1, 0), /* int m; */
243 BTF_MEMBER_ENC(NAME_TBD, 2, 32),/* struct B n[4] */
244 BTF_MEMBER_ENC(NAME_TBD, 8, 288),/* const Struct_B o[4];*/
247 /* struct B { */ /* [4] */
248 BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 2), 8),
249 BTF_MEMBER_ENC(NAME_TBD, 1, 0), /* int m; */
250 BTF_MEMBER_ENC(NAME_TBD, 1, 32),/* int n; */
253 /* const int */ /* [5] */
254 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_CONST, 0, 0), 1),
255 /* typedef struct b Struct_B */ /* [6] */
256 BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_TYPEDEF, 0, 0), 4),
257 /* const Struct_B */ /* [7] */
258 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_CONST, 0, 0), 6),
259 /* const Struct_B [4] */ /* [8] */
260 BTF_TYPE_ARRAY_ENC(7, 1, 4),
263 .str_sec = "\0A\0m\0n\0o\0B\0m\0n\0Struct_B",
264 .str_sec_size = sizeof("\0A\0m\0n\0o\0B\0m\0n\0Struct_B"),
265 .map_type = BPF_MAP_TYPE_ARRAY,
266 .map_name = "struct_test2_map",
267 .key_size = sizeof(int),
275 .descr = "struct test #3 Invalid member offset",
278 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
279 /* int64 */ /* [2] */
280 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 64, 8),
282 /* struct A { */ /* [3] */
283 BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 2), 16),
284 BTF_MEMBER_ENC(NAME_TBD, 1, 64), /* int m; */
285 BTF_MEMBER_ENC(NAME_TBD, 2, 0), /* int64 n; */
289 .str_sec = "\0A\0m\0n\0",
290 .str_sec_size = sizeof("\0A\0m\0n\0"),
291 .map_type = BPF_MAP_TYPE_ARRAY,
292 .map_name = "struct_test3_map",
293 .key_size = sizeof(int),
298 .btf_load_err = true,
299 .err_str = "Invalid member bits_offset",
302 /* Test member exceeds the size of struct.
310 .descr = "size check test #1",
313 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
314 /* struct A { */ /* [2] */
315 BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 2), sizeof(int) * 2 - 1),
316 BTF_MEMBER_ENC(NAME_TBD, 1, 0), /* int m; */
317 BTF_MEMBER_ENC(NAME_TBD, 1, 32),/* int n; */
321 .str_sec = "\0A\0m\0n",
322 .str_sec_size = sizeof("\0A\0m\0n"),
323 .map_type = BPF_MAP_TYPE_ARRAY,
324 .map_name = "size_check1_map",
325 .key_size = sizeof(int),
330 .btf_load_err = true,
331 .err_str = "Member exceeds struct_size",
334 /* Test member exeeds the size of struct
342 .descr = "size check test #2",
345 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, sizeof(int)),
346 /* int[2] */ /* [2] */
347 BTF_TYPE_ARRAY_ENC(1, 1, 2),
348 /* struct A { */ /* [3] */
349 BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 2), sizeof(int) * 3 - 1),
350 BTF_MEMBER_ENC(NAME_TBD, 1, 0), /* int m; */
351 BTF_MEMBER_ENC(NAME_TBD, 2, 32),/* int n[2]; */
355 .str_sec = "\0A\0m\0n",
356 .str_sec_size = sizeof("\0A\0m\0n"),
357 .map_type = BPF_MAP_TYPE_ARRAY,
358 .map_name = "size_check2_map",
359 .key_size = sizeof(int),
364 .btf_load_err = true,
365 .err_str = "Member exceeds struct_size",
368 /* Test member exeeds the size of struct
376 .descr = "size check test #3",
379 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, sizeof(int)),
380 /* void* */ /* [2] */
381 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_PTR, 0, 0), 0),
382 /* struct A { */ /* [3] */
383 BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 2), sizeof(int) + sizeof(void *) - 1),
384 BTF_MEMBER_ENC(NAME_TBD, 1, 0), /* int m; */
385 BTF_MEMBER_ENC(NAME_TBD, 2, 32),/* void *n; */
389 .str_sec = "\0A\0m\0n",
390 .str_sec_size = sizeof("\0A\0m\0n"),
391 .map_type = BPF_MAP_TYPE_ARRAY,
392 .map_name = "size_check3_map",
393 .key_size = sizeof(int),
398 .btf_load_err = true,
399 .err_str = "Member exceeds struct_size",
402 /* Test member exceeds the size of struct
415 .descr = "size check test #4",
418 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, sizeof(int)),
419 /* enum E { */ /* [2] */
420 BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_ENUM, 0, 2), sizeof(int)),
421 BTF_ENUM_ENC(NAME_TBD, 0),
422 BTF_ENUM_ENC(NAME_TBD, 1),
424 /* struct A { */ /* [3] */
425 BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 2), sizeof(int) * 2 - 1),
426 BTF_MEMBER_ENC(NAME_TBD, 1, 0), /* int m; */
427 BTF_MEMBER_ENC(NAME_TBD, 2, 32),/* enum E n; */
431 .str_sec = "\0E\0E0\0E1\0A\0m\0n",
432 .str_sec_size = sizeof("\0E\0E0\0E1\0A\0m\0n"),
433 .map_type = BPF_MAP_TYPE_ARRAY,
434 .map_name = "size_check4_map",
435 .key_size = sizeof(int),
440 .btf_load_err = true,
441 .err_str = "Member exceeds struct_size",
444 /* typedef const void * const_void_ptr;
450 .descr = "void test #1",
453 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
454 /* const void */ /* [2] */
455 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_CONST, 0, 0), 0),
456 /* const void* */ /* [3] */
457 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_PTR, 0, 0), 2),
458 /* typedef const void * const_void_ptr */
459 BTF_TYPEDEF_ENC(NAME_TBD, 3), /* [4] */
460 /* struct A { */ /* [5] */
461 BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 1), sizeof(void *)),
462 /* const_void_ptr m; */
463 BTF_MEMBER_ENC(NAME_TBD, 4, 0),
467 .str_sec = "\0const_void_ptr\0A\0m",
468 .str_sec_size = sizeof("\0const_void_ptr\0A\0m"),
469 .map_type = BPF_MAP_TYPE_ARRAY,
470 .map_name = "void_test1_map",
471 .key_size = sizeof(int),
472 .value_size = sizeof(void *),
483 .descr = "void test #2",
486 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
487 /* const void */ /* [2] */
488 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_CONST, 0, 0), 0),
489 /* struct A { */ /* [3] */
490 BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 1), 8),
492 BTF_MEMBER_ENC(NAME_TBD, 2, 0),
497 .str_sec_size = sizeof("\0A\0m"),
498 .map_type = BPF_MAP_TYPE_ARRAY,
499 .map_name = "void_test2_map",
500 .key_size = sizeof(int),
501 .value_size = sizeof(void *),
505 .btf_load_err = true,
506 .err_str = "Invalid member",
509 /* typedef const void * const_void_ptr;
513 .descr = "void test #3",
516 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
517 /* const void */ /* [2] */
518 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_CONST, 0, 0), 0),
519 /* const void* */ /* [3] */
520 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_PTR, 0, 0), 2),
521 /* typedef const void * const_void_ptr */
522 BTF_TYPEDEF_ENC(NAME_TBD, 3), /* [4] */
523 /* const_void_ptr[4] */
524 BTF_TYPE_ARRAY_ENC(4, 1, 4), /* [5] */
527 .str_sec = "\0const_void_ptr",
528 .str_sec_size = sizeof("\0const_void_ptr"),
529 .map_type = BPF_MAP_TYPE_ARRAY,
530 .map_name = "void_test3_map",
531 .key_size = sizeof(int),
532 .value_size = sizeof(void *) * 4,
540 .descr = "void test #4",
543 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
544 /* const void */ /* [2] */
545 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_CONST, 0, 0), 0),
546 /* const void[4] */ /* [3] */
547 BTF_TYPE_ARRAY_ENC(2, 1, 4),
551 .str_sec_size = sizeof("\0A\0m"),
552 .map_type = BPF_MAP_TYPE_ARRAY,
553 .map_name = "void_test4_map",
554 .key_size = sizeof(int),
555 .value_size = sizeof(void *) * 4,
559 .btf_load_err = true,
560 .err_str = "Invalid elem",
563 /* Array_A <------------------+
564 * elem_type == Array_B |
567 * Array_B <-------- + |
568 * elem_type == Array A --+
571 .descr = "loop test #1",
574 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
575 /* Array_A */ /* [2] */
576 BTF_TYPE_ARRAY_ENC(3, 1, 8),
577 /* Array_B */ /* [3] */
578 BTF_TYPE_ARRAY_ENC(2, 1, 8),
582 .str_sec_size = sizeof(""),
583 .map_type = BPF_MAP_TYPE_ARRAY,
584 .map_name = "loop_test1_map",
585 .key_size = sizeof(int),
586 .value_size = sizeof(sizeof(int) * 8),
590 .btf_load_err = true,
591 .err_str = "Loop detected",
594 /* typedef is _before_ the BTF type of Array_A and Array_B
596 * typedef Array_B int_array;
598 * Array_A <------------------+
599 * elem_type == int_array |
602 * Array_B <-------- + |
603 * elem_type == Array_A --+
606 .descr = "loop test #2",
609 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
610 /* typedef Array_B int_array */
611 BTF_TYPEDEF_ENC(1, 4), /* [2] */
613 BTF_TYPE_ARRAY_ENC(2, 1, 8), /* [3] */
615 BTF_TYPE_ARRAY_ENC(3, 1, 8), /* [4] */
618 .str_sec = "\0int_array\0",
619 .str_sec_size = sizeof("\0int_array"),
620 .map_type = BPF_MAP_TYPE_ARRAY,
621 .map_name = "loop_test2_map",
622 .key_size = sizeof(int),
623 .value_size = sizeof(sizeof(int) * 8),
627 .btf_load_err = true,
628 .err_str = "Loop detected",
631 /* Array_A <------------------+
632 * elem_type == Array_B |
635 * Array_B <-------- + |
636 * elem_type == Array_A --+
639 .descr = "loop test #3",
642 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
643 /* Array_A */ /* [2] */
644 BTF_TYPE_ARRAY_ENC(3, 1, 8),
645 /* Array_B */ /* [3] */
646 BTF_TYPE_ARRAY_ENC(2, 1, 8),
650 .str_sec_size = sizeof(""),
651 .map_type = BPF_MAP_TYPE_ARRAY,
652 .map_name = "loop_test3_map",
653 .key_size = sizeof(int),
654 .value_size = sizeof(sizeof(int) * 8),
658 .btf_load_err = true,
659 .err_str = "Loop detected",
662 /* typedef is _between_ the BTF type of Array_A and Array_B
664 * typedef Array_B int_array;
666 * Array_A <------------------+
667 * elem_type == int_array |
670 * Array_B <-------- + |
671 * elem_type == Array_A --+
674 .descr = "loop test #4",
677 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
678 /* Array_A */ /* [2] */
679 BTF_TYPE_ARRAY_ENC(3, 1, 8),
680 /* typedef Array_B int_array */ /* [3] */
681 BTF_TYPEDEF_ENC(NAME_TBD, 4),
682 /* Array_B */ /* [4] */
683 BTF_TYPE_ARRAY_ENC(2, 1, 8),
686 .str_sec = "\0int_array\0",
687 .str_sec_size = sizeof("\0int_array"),
688 .map_type = BPF_MAP_TYPE_ARRAY,
689 .map_name = "loop_test4_map",
690 .key_size = sizeof(int),
691 .value_size = sizeof(sizeof(int) * 8),
695 .btf_load_err = true,
696 .err_str = "Loop detected",
699 /* typedef struct B Struct_B
712 .descr = "loop test #5",
715 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
716 /* struct A */ /* [2] */
717 BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 2), 8),
718 BTF_MEMBER_ENC(NAME_TBD, 1, 0), /* int x; */
719 BTF_MEMBER_ENC(NAME_TBD, 3, 32),/* Struct_B y; */
720 /* typedef struct B Struct_B */
721 BTF_TYPEDEF_ENC(NAME_TBD, 4), /* [3] */
722 /* struct B */ /* [4] */
723 BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 2), 8),
724 BTF_MEMBER_ENC(NAME_TBD, 1, 0), /* int x; */
725 BTF_MEMBER_ENC(NAME_TBD, 2, 32),/* struct A y; */
728 .str_sec = "\0A\0x\0y\0Struct_B\0B\0x\0y",
729 .str_sec_size = sizeof("\0A\0x\0y\0Struct_B\0B\0x\0y"),
730 .map_type = BPF_MAP_TYPE_ARRAY,
731 .map_name = "loop_test5_map",
732 .key_size = sizeof(int),
737 .btf_load_err = true,
738 .err_str = "Loop detected",
743 * struct A array_a[4];
747 .descr = "loop test #6",
750 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
751 BTF_TYPE_ARRAY_ENC(3, 1, 4), /* [2] */
752 /* struct A */ /* [3] */
753 BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 2), 8),
754 BTF_MEMBER_ENC(NAME_TBD, 1, 0), /* int x; */
755 BTF_MEMBER_ENC(NAME_TBD, 2, 32),/* struct A array_a[4]; */
758 .str_sec = "\0A\0x\0y",
759 .str_sec_size = sizeof("\0A\0x\0y"),
760 .map_type = BPF_MAP_TYPE_ARRAY,
761 .map_name = "loop_test6_map",
762 .key_size = sizeof(int),
767 .btf_load_err = true,
768 .err_str = "Loop detected",
772 .descr = "loop test #7",
775 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
776 /* struct A { */ /* [2] */
777 BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 1), sizeof(void *)),
779 BTF_MEMBER_ENC(NAME_TBD, 3, 0),
780 /* CONST type_id=3 */ /* [3] */
781 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_CONST, 0, 0), 4),
782 /* PTR type_id=2 */ /* [4] */
783 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_PTR, 0, 0), 3),
787 .str_sec_size = sizeof("\0A\0m"),
788 .map_type = BPF_MAP_TYPE_ARRAY,
789 .map_name = "loop_test7_map",
790 .key_size = sizeof(int),
791 .value_size = sizeof(void *),
795 .btf_load_err = true,
796 .err_str = "Loop detected",
800 .descr = "loop test #8",
803 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
804 /* struct A { */ /* [2] */
805 BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 1), sizeof(void *)),
807 BTF_MEMBER_ENC(NAME_TBD, 4, 0),
808 /* struct B { */ /* [3] */
809 BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 1), sizeof(void *)),
811 BTF_MEMBER_ENC(NAME_TBD, 6, 0),
812 /* CONST type_id=5 */ /* [4] */
813 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_CONST, 0, 0), 5),
814 /* PTR type_id=6 */ /* [5] */
815 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_PTR, 0, 0), 6),
816 /* CONST type_id=7 */ /* [6] */
817 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_CONST, 0, 0), 7),
818 /* PTR type_id=4 */ /* [7] */
819 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_PTR, 0, 0), 4),
822 .str_sec = "\0A\0m\0B\0n",
823 .str_sec_size = sizeof("\0A\0m\0B\0n"),
824 .map_type = BPF_MAP_TYPE_ARRAY,
825 .map_name = "loop_test8_map",
826 .key_size = sizeof(int),
827 .value_size = sizeof(void *),
831 .btf_load_err = true,
832 .err_str = "Loop detected",
836 .descr = "string section does not end with null",
839 BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),
843 .str_sec_size = sizeof("\0int") - 1,
844 .map_type = BPF_MAP_TYPE_ARRAY,
845 .map_name = "hdr_test_map",
846 .key_size = sizeof(int),
847 .value_size = sizeof(int),
851 .btf_load_err = true,
852 .err_str = "Invalid string section",
856 .descr = "empty string section",
859 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
864 .map_type = BPF_MAP_TYPE_ARRAY,
865 .map_name = "hdr_test_map",
866 .key_size = sizeof(int),
867 .value_size = sizeof(int),
871 .btf_load_err = true,
872 .err_str = "Invalid string section",
876 .descr = "empty type section",
881 .str_sec_size = sizeof("\0int"),
882 .map_type = BPF_MAP_TYPE_ARRAY,
883 .map_name = "hdr_test_map",
884 .key_size = sizeof(int),
885 .value_size = sizeof(int),
889 .btf_load_err = true,
890 .err_str = "No type found",
894 .descr = "btf_header test. Longer hdr_len",
897 BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),
901 .str_sec_size = sizeof("\0int"),
902 .map_type = BPF_MAP_TYPE_ARRAY,
903 .map_name = "hdr_test_map",
904 .key_size = sizeof(int),
905 .value_size = sizeof(int),
909 .btf_load_err = true,
911 .err_str = "Unsupported btf_header",
915 .descr = "btf_header test. Gap between hdr and type",
918 BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),
922 .str_sec_size = sizeof("\0int"),
923 .map_type = BPF_MAP_TYPE_ARRAY,
924 .map_name = "hdr_test_map",
925 .key_size = sizeof(int),
926 .value_size = sizeof(int),
930 .btf_load_err = true,
932 .err_str = "Unsupported section found",
936 .descr = "btf_header test. Gap between type and str",
939 BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),
943 .str_sec_size = sizeof("\0int"),
944 .map_type = BPF_MAP_TYPE_ARRAY,
945 .map_name = "hdr_test_map",
946 .key_size = sizeof(int),
947 .value_size = sizeof(int),
951 .btf_load_err = true,
953 .err_str = "Unsupported section found",
957 .descr = "btf_header test. Overlap between type and str",
960 BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),
964 .str_sec_size = sizeof("\0int"),
965 .map_type = BPF_MAP_TYPE_ARRAY,
966 .map_name = "hdr_test_map",
967 .key_size = sizeof(int),
968 .value_size = sizeof(int),
972 .btf_load_err = true,
974 .err_str = "Section overlap found",
978 .descr = "btf_header test. Larger BTF size",
981 BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),
985 .str_sec_size = sizeof("\0int"),
986 .map_type = BPF_MAP_TYPE_ARRAY,
987 .map_name = "hdr_test_map",
988 .key_size = sizeof(int),
989 .value_size = sizeof(int),
993 .btf_load_err = true,
995 .err_str = "Unsupported section found",
999 .descr = "btf_header test. Smaller BTF size",
1002 BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),
1006 .str_sec_size = sizeof("\0int"),
1007 .map_type = BPF_MAP_TYPE_ARRAY,
1008 .map_name = "hdr_test_map",
1009 .key_size = sizeof(int),
1010 .value_size = sizeof(int),
1014 .btf_load_err = true,
1016 .err_str = "Total section length too long",
1020 .descr = "array test. index_type/elem_type \"int\"",
1023 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
1024 /* int[16] */ /* [2] */
1025 BTF_TYPE_ARRAY_ENC(1, 1, 16),
1029 .str_sec_size = sizeof(""),
1030 .map_type = BPF_MAP_TYPE_ARRAY,
1031 .map_name = "array_test_map",
1032 .key_size = sizeof(int),
1033 .value_size = sizeof(int),
1040 .descr = "array test. index_type/elem_type \"const int\"",
1043 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
1044 /* int[16] */ /* [2] */
1045 BTF_TYPE_ARRAY_ENC(3, 3, 16),
1046 /* CONST type_id=1 */ /* [3] */
1047 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_CONST, 0, 0), 1),
1051 .str_sec_size = sizeof(""),
1052 .map_type = BPF_MAP_TYPE_ARRAY,
1053 .map_name = "array_test_map",
1054 .key_size = sizeof(int),
1055 .value_size = sizeof(int),
1062 .descr = "array test. index_type \"const int:31\"",
1065 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
1066 /* int:31 */ /* [2] */
1067 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 31, 4),
1068 /* int[16] */ /* [3] */
1069 BTF_TYPE_ARRAY_ENC(1, 4, 16),
1070 /* CONST type_id=2 */ /* [4] */
1071 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_CONST, 0, 0), 2),
1075 .str_sec_size = sizeof(""),
1076 .map_type = BPF_MAP_TYPE_ARRAY,
1077 .map_name = "array_test_map",
1078 .key_size = sizeof(int),
1079 .value_size = sizeof(int),
1083 .btf_load_err = true,
1084 .err_str = "Invalid index",
1088 .descr = "array test. elem_type \"const int:31\"",
1091 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
1092 /* int:31 */ /* [2] */
1093 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 31, 4),
1094 /* int[16] */ /* [3] */
1095 BTF_TYPE_ARRAY_ENC(4, 1, 16),
1096 /* CONST type_id=2 */ /* [4] */
1097 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_CONST, 0, 0), 2),
1101 .str_sec_size = sizeof(""),
1102 .map_type = BPF_MAP_TYPE_ARRAY,
1103 .map_name = "array_test_map",
1104 .key_size = sizeof(int),
1105 .value_size = sizeof(int),
1109 .btf_load_err = true,
1110 .err_str = "Invalid array of int",
1114 .descr = "array test. index_type \"void\"",
1117 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
1118 /* int[16] */ /* [2] */
1119 BTF_TYPE_ARRAY_ENC(1, 0, 16),
1123 .str_sec_size = sizeof(""),
1124 .map_type = BPF_MAP_TYPE_ARRAY,
1125 .map_name = "array_test_map",
1126 .key_size = sizeof(int),
1127 .value_size = sizeof(int),
1131 .btf_load_err = true,
1132 .err_str = "Invalid index",
1136 .descr = "array test. index_type \"const void\"",
1139 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
1140 /* int[16] */ /* [2] */
1141 BTF_TYPE_ARRAY_ENC(1, 3, 16),
1142 /* CONST type_id=0 (void) */ /* [3] */
1143 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_CONST, 0, 0), 0),
1147 .str_sec_size = sizeof(""),
1148 .map_type = BPF_MAP_TYPE_ARRAY,
1149 .map_name = "array_test_map",
1150 .key_size = sizeof(int),
1151 .value_size = sizeof(int),
1155 .btf_load_err = true,
1156 .err_str = "Invalid index",
1160 .descr = "array test. elem_type \"const void\"",
1163 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
1164 /* int[16] */ /* [2] */
1165 BTF_TYPE_ARRAY_ENC(3, 1, 16),
1166 /* CONST type_id=0 (void) */ /* [3] */
1167 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_CONST, 0, 0), 0),
1171 .str_sec_size = sizeof(""),
1172 .map_type = BPF_MAP_TYPE_ARRAY,
1173 .map_name = "array_test_map",
1174 .key_size = sizeof(int),
1175 .value_size = sizeof(int),
1179 .btf_load_err = true,
1180 .err_str = "Invalid elem",
1184 .descr = "array test. elem_type \"const void *\"",
1187 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
1188 /* const void *[16] */ /* [2] */
1189 BTF_TYPE_ARRAY_ENC(3, 1, 16),
1190 /* CONST type_id=4 */ /* [3] */
1191 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_CONST, 0, 0), 4),
1192 /* void* */ /* [4] */
1193 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_PTR, 0, 0), 0),
1197 .str_sec_size = sizeof(""),
1198 .map_type = BPF_MAP_TYPE_ARRAY,
1199 .map_name = "array_test_map",
1200 .key_size = sizeof(int),
1201 .value_size = sizeof(int),
1208 .descr = "array test. index_type \"const void *\"",
1211 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
1212 /* const void *[16] */ /* [2] */
1213 BTF_TYPE_ARRAY_ENC(3, 3, 16),
1214 /* CONST type_id=4 */ /* [3] */
1215 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_CONST, 0, 0), 4),
1216 /* void* */ /* [4] */
1217 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_PTR, 0, 0), 0),
1221 .str_sec_size = sizeof(""),
1222 .map_type = BPF_MAP_TYPE_ARRAY,
1223 .map_name = "array_test_map",
1224 .key_size = sizeof(int),
1225 .value_size = sizeof(int),
1229 .btf_load_err = true,
1230 .err_str = "Invalid index",
1234 .descr = "array test. t->size != 0\"",
1237 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
1238 /* int[16] */ /* [2] */
1239 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_ARRAY, 0, 0), 1),
1240 BTF_ARRAY_ENC(1, 1, 16),
1244 .str_sec_size = sizeof(""),
1245 .map_type = BPF_MAP_TYPE_ARRAY,
1246 .map_name = "array_test_map",
1247 .key_size = sizeof(int),
1248 .value_size = sizeof(int),
1252 .btf_load_err = true,
1253 .err_str = "size != 0",
1257 .descr = "int test. invalid int_data",
1259 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_INT, 0, 0), 4),
1264 .str_sec_size = sizeof(""),
1265 .map_type = BPF_MAP_TYPE_ARRAY,
1266 .map_name = "array_test_map",
1267 .key_size = sizeof(int),
1268 .value_size = sizeof(int),
1272 .btf_load_err = true,
1273 .err_str = "Invalid int_data",
1277 .descr = "invalid BTF_INFO",
1280 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
1281 BTF_TYPE_ENC(0, 0x10000000, 4),
1285 .str_sec_size = sizeof(""),
1286 .map_type = BPF_MAP_TYPE_ARRAY,
1287 .map_name = "array_test_map",
1288 .key_size = sizeof(int),
1289 .value_size = sizeof(int),
1293 .btf_load_err = true,
1294 .err_str = "Invalid btf_info",
1298 .descr = "fwd test. t->type != 0\"",
1301 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
1302 /* fwd type */ /* [2] */
1303 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_FWD, 0, 0), 1),
1307 .str_sec_size = sizeof(""),
1308 .map_type = BPF_MAP_TYPE_ARRAY,
1309 .map_name = "fwd_test_map",
1310 .key_size = sizeof(int),
1311 .value_size = sizeof(int),
1315 .btf_load_err = true,
1316 .err_str = "type != 0",
1320 .descr = "typedef (invalid name, name_off = 0)",
1322 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
1323 BTF_TYPEDEF_ENC(0, 1), /* [2] */
1326 .str_sec = "\0__int",
1327 .str_sec_size = sizeof("\0__int"),
1328 .map_type = BPF_MAP_TYPE_ARRAY,
1329 .map_name = "typedef_check_btf",
1330 .key_size = sizeof(int),
1331 .value_size = sizeof(int),
1335 .btf_load_err = true,
1336 .err_str = "Invalid name",
1340 .descr = "typedef (invalid name, invalid identifier)",
1342 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
1343 BTF_TYPEDEF_ENC(NAME_TBD, 1), /* [2] */
1346 .str_sec = "\0__!int",
1347 .str_sec_size = sizeof("\0__!int"),
1348 .map_type = BPF_MAP_TYPE_ARRAY,
1349 .map_name = "typedef_check_btf",
1350 .key_size = sizeof(int),
1351 .value_size = sizeof(int),
1355 .btf_load_err = true,
1356 .err_str = "Invalid name",
1360 .descr = "ptr type (invalid name, name_off <> 0)",
1362 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
1363 BTF_TYPE_ENC(NAME_TBD,
1364 BTF_INFO_ENC(BTF_KIND_PTR, 0, 0), 1), /* [2] */
1367 .str_sec = "\0__int",
1368 .str_sec_size = sizeof("\0__int"),
1369 .map_type = BPF_MAP_TYPE_ARRAY,
1370 .map_name = "ptr_type_check_btf",
1371 .key_size = sizeof(int),
1372 .value_size = sizeof(int),
1376 .btf_load_err = true,
1377 .err_str = "Invalid name",
1381 .descr = "volatile type (invalid name, name_off <> 0)",
1383 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
1384 BTF_TYPE_ENC(NAME_TBD,
1385 BTF_INFO_ENC(BTF_KIND_VOLATILE, 0, 0), 1), /* [2] */
1388 .str_sec = "\0__int",
1389 .str_sec_size = sizeof("\0__int"),
1390 .map_type = BPF_MAP_TYPE_ARRAY,
1391 .map_name = "volatile_type_check_btf",
1392 .key_size = sizeof(int),
1393 .value_size = sizeof(int),
1397 .btf_load_err = true,
1398 .err_str = "Invalid name",
1402 .descr = "const type (invalid name, name_off <> 0)",
1404 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
1405 BTF_TYPE_ENC(NAME_TBD,
1406 BTF_INFO_ENC(BTF_KIND_CONST, 0, 0), 1), /* [2] */
1409 .str_sec = "\0__int",
1410 .str_sec_size = sizeof("\0__int"),
1411 .map_type = BPF_MAP_TYPE_ARRAY,
1412 .map_name = "const_type_check_btf",
1413 .key_size = sizeof(int),
1414 .value_size = sizeof(int),
1418 .btf_load_err = true,
1419 .err_str = "Invalid name",
1423 .descr = "restrict type (invalid name, name_off <> 0)",
1425 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
1426 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_PTR, 0, 0), 1), /* [2] */
1427 BTF_TYPE_ENC(NAME_TBD,
1428 BTF_INFO_ENC(BTF_KIND_RESTRICT, 0, 0), 2), /* [3] */
1431 .str_sec = "\0__int",
1432 .str_sec_size = sizeof("\0__int"),
1433 .map_type = BPF_MAP_TYPE_ARRAY,
1434 .map_name = "restrict_type_check_btf",
1435 .key_size = sizeof(int),
1436 .value_size = sizeof(int),
1440 .btf_load_err = true,
1441 .err_str = "Invalid name",
1445 .descr = "fwd type (invalid name, name_off = 0)",
1447 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
1448 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_FWD, 0, 0), 0), /* [2] */
1451 .str_sec = "\0__skb",
1452 .str_sec_size = sizeof("\0__skb"),
1453 .map_type = BPF_MAP_TYPE_ARRAY,
1454 .map_name = "fwd_type_check_btf",
1455 .key_size = sizeof(int),
1456 .value_size = sizeof(int),
1460 .btf_load_err = true,
1461 .err_str = "Invalid name",
1465 .descr = "fwd type (invalid name, invalid identifier)",
1467 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
1468 BTF_TYPE_ENC(NAME_TBD,
1469 BTF_INFO_ENC(BTF_KIND_FWD, 0, 0), 0), /* [2] */
1472 .str_sec = "\0__!skb",
1473 .str_sec_size = sizeof("\0__!skb"),
1474 .map_type = BPF_MAP_TYPE_ARRAY,
1475 .map_name = "fwd_type_check_btf",
1476 .key_size = sizeof(int),
1477 .value_size = sizeof(int),
1481 .btf_load_err = true,
1482 .err_str = "Invalid name",
1486 .descr = "array type (invalid name, name_off <> 0)",
1488 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
1489 BTF_TYPE_ENC(NAME_TBD,
1490 BTF_INFO_ENC(BTF_KIND_ARRAY, 0, 0), 0), /* [2] */
1491 BTF_ARRAY_ENC(1, 1, 4),
1494 .str_sec = "\0__skb",
1495 .str_sec_size = sizeof("\0__skb"),
1496 .map_type = BPF_MAP_TYPE_ARRAY,
1497 .map_name = "array_type_check_btf",
1498 .key_size = sizeof(int),
1499 .value_size = sizeof(int),
1503 .btf_load_err = true,
1504 .err_str = "Invalid name",
1508 .descr = "struct type (name_off = 0)",
1510 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
1512 BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 1), 4), /* [2] */
1513 BTF_MEMBER_ENC(NAME_TBD, 1, 0),
1517 .str_sec_size = sizeof("\0A"),
1518 .map_type = BPF_MAP_TYPE_ARRAY,
1519 .map_name = "struct_type_check_btf",
1520 .key_size = sizeof(int),
1521 .value_size = sizeof(int),
1528 .descr = "struct type (invalid name, invalid identifier)",
1530 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
1531 BTF_TYPE_ENC(NAME_TBD,
1532 BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 1), 4), /* [2] */
1533 BTF_MEMBER_ENC(NAME_TBD, 1, 0),
1536 .str_sec = "\0A!\0B",
1537 .str_sec_size = sizeof("\0A!\0B"),
1538 .map_type = BPF_MAP_TYPE_ARRAY,
1539 .map_name = "struct_type_check_btf",
1540 .key_size = sizeof(int),
1541 .value_size = sizeof(int),
1545 .btf_load_err = true,
1546 .err_str = "Invalid name",
1550 .descr = "struct member (name_off = 0)",
1552 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
1554 BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 1), 4), /* [2] */
1555 BTF_MEMBER_ENC(NAME_TBD, 1, 0),
1559 .str_sec_size = sizeof("\0A"),
1560 .map_type = BPF_MAP_TYPE_ARRAY,
1561 .map_name = "struct_type_check_btf",
1562 .key_size = sizeof(int),
1563 .value_size = sizeof(int),
1570 .descr = "struct member (invalid name, invalid identifier)",
1572 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
1573 BTF_TYPE_ENC(NAME_TBD,
1574 BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 1), 4), /* [2] */
1575 BTF_MEMBER_ENC(NAME_TBD, 1, 0),
1578 .str_sec = "\0A\0B*",
1579 .str_sec_size = sizeof("\0A\0B*"),
1580 .map_type = BPF_MAP_TYPE_ARRAY,
1581 .map_name = "struct_type_check_btf",
1582 .key_size = sizeof(int),
1583 .value_size = sizeof(int),
1587 .btf_load_err = true,
1588 .err_str = "Invalid name",
1592 .descr = "enum type (name_off = 0)",
1594 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
1596 BTF_INFO_ENC(BTF_KIND_ENUM, 0, 1),
1597 sizeof(int)), /* [2] */
1598 BTF_ENUM_ENC(NAME_TBD, 0),
1601 .str_sec = "\0A\0B",
1602 .str_sec_size = sizeof("\0A\0B"),
1603 .map_type = BPF_MAP_TYPE_ARRAY,
1604 .map_name = "enum_type_check_btf",
1605 .key_size = sizeof(int),
1606 .value_size = sizeof(int),
1613 .descr = "enum type (invalid name, invalid identifier)",
1615 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
1616 BTF_TYPE_ENC(NAME_TBD,
1617 BTF_INFO_ENC(BTF_KIND_ENUM, 0, 1),
1618 sizeof(int)), /* [2] */
1619 BTF_ENUM_ENC(NAME_TBD, 0),
1622 .str_sec = "\0A!\0B",
1623 .str_sec_size = sizeof("\0A!\0B"),
1624 .map_type = BPF_MAP_TYPE_ARRAY,
1625 .map_name = "enum_type_check_btf",
1626 .key_size = sizeof(int),
1627 .value_size = sizeof(int),
1631 .btf_load_err = true,
1632 .err_str = "Invalid name",
1636 .descr = "enum member (invalid name, name_off = 0)",
1638 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
1640 BTF_INFO_ENC(BTF_KIND_ENUM, 0, 1),
1641 sizeof(int)), /* [2] */
1646 .str_sec_size = sizeof(""),
1647 .map_type = BPF_MAP_TYPE_ARRAY,
1648 .map_name = "enum_type_check_btf",
1649 .key_size = sizeof(int),
1650 .value_size = sizeof(int),
1654 .btf_load_err = true,
1655 .err_str = "Invalid name",
1659 .descr = "enum member (invalid name, invalid identifier)",
1661 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
1663 BTF_INFO_ENC(BTF_KIND_ENUM, 0, 1),
1664 sizeof(int)), /* [2] */
1665 BTF_ENUM_ENC(NAME_TBD, 0),
1669 .str_sec_size = sizeof("\0A!"),
1670 .map_type = BPF_MAP_TYPE_ARRAY,
1671 .map_name = "enum_type_check_btf",
1672 .key_size = sizeof(int),
1673 .value_size = sizeof(int),
1677 .btf_load_err = true,
1678 .err_str = "Invalid name",
1681 .descr = "arraymap invalid btf key (a bit field)",
1684 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
1685 /* 32 bit int with 32 bit offset */ /* [2] */
1686 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 32, 32, 8),
1690 .str_sec_size = sizeof(""),
1691 .map_type = BPF_MAP_TYPE_ARRAY,
1692 .map_name = "array_map_check_btf",
1693 .key_size = sizeof(int),
1694 .value_size = sizeof(int),
1698 .map_create_err = true,
1702 .descr = "arraymap invalid btf key (!= 32 bits)",
1705 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
1706 /* 16 bit int with 0 bit offset */ /* [2] */
1707 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 16, 2),
1711 .str_sec_size = sizeof(""),
1712 .map_type = BPF_MAP_TYPE_ARRAY,
1713 .map_name = "array_map_check_btf",
1714 .key_size = sizeof(int),
1715 .value_size = sizeof(int),
1719 .map_create_err = true,
1723 .descr = "arraymap invalid btf value (too small)",
1726 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
1730 .str_sec_size = sizeof(""),
1731 .map_type = BPF_MAP_TYPE_ARRAY,
1732 .map_name = "array_map_check_btf",
1733 .key_size = sizeof(int),
1734 /* btf_value_size < map->value_size */
1735 .value_size = sizeof(__u64),
1739 .map_create_err = true,
1743 .descr = "arraymap invalid btf value (too big)",
1746 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
1750 .str_sec_size = sizeof(""),
1751 .map_type = BPF_MAP_TYPE_ARRAY,
1752 .map_name = "array_map_check_btf",
1753 .key_size = sizeof(int),
1754 /* btf_value_size > map->value_size */
1755 .value_size = sizeof(__u16),
1759 .map_create_err = true,
1763 .descr = "func proto (int (*)(int, unsigned int))",
1765 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
1766 BTF_TYPE_INT_ENC(0, 0, 0, 32, 4), /* [2] */
1767 /* int (*)(int, unsigned int) */
1768 BTF_FUNC_PROTO_ENC(1, 2), /* [3] */
1769 BTF_FUNC_PROTO_ARG_ENC(0, 1),
1770 BTF_FUNC_PROTO_ARG_ENC(0, 2),
1774 .str_sec_size = sizeof(""),
1775 .map_type = BPF_MAP_TYPE_ARRAY,
1776 .map_name = "func_proto_type_check_btf",
1777 .key_size = sizeof(int),
1778 .value_size = sizeof(int),
1785 .descr = "func proto (vararg)",
1787 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
1788 BTF_TYPE_INT_ENC(0, 0, 0, 32, 4), /* [2] */
1789 /* void (*)(int, unsigned int, ...) */
1790 BTF_FUNC_PROTO_ENC(0, 3), /* [3] */
1791 BTF_FUNC_PROTO_ARG_ENC(0, 1),
1792 BTF_FUNC_PROTO_ARG_ENC(0, 2),
1793 BTF_FUNC_PROTO_ARG_ENC(0, 0),
1797 .str_sec_size = sizeof(""),
1798 .map_type = BPF_MAP_TYPE_ARRAY,
1799 .map_name = "func_proto_type_check_btf",
1800 .key_size = sizeof(int),
1801 .value_size = sizeof(int),
1808 .descr = "func proto (vararg with name)",
1810 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
1811 BTF_TYPE_INT_ENC(0, 0, 0, 32, 4), /* [2] */
1812 /* void (*)(int a, unsigned int b, ... c) */
1813 BTF_FUNC_PROTO_ENC(0, 3), /* [3] */
1814 BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
1815 BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 2),
1816 BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 0),
1819 .str_sec = "\0a\0b\0c",
1820 .str_sec_size = sizeof("\0a\0b\0c"),
1821 .map_type = BPF_MAP_TYPE_ARRAY,
1822 .map_name = "func_proto_type_check_btf",
1823 .key_size = sizeof(int),
1824 .value_size = sizeof(int),
1828 .btf_load_err = true,
1829 .err_str = "Invalid arg#3",
1833 .descr = "func proto (arg after vararg)",
1835 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
1836 BTF_TYPE_INT_ENC(0, 0, 0, 32, 4), /* [2] */
1837 /* void (*)(int a, ..., unsigned int b) */
1838 BTF_FUNC_PROTO_ENC(0, 3), /* [3] */
1839 BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
1840 BTF_FUNC_PROTO_ARG_ENC(0, 0),
1841 BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 2),
1844 .str_sec = "\0a\0b",
1845 .str_sec_size = sizeof("\0a\0b"),
1846 .map_type = BPF_MAP_TYPE_ARRAY,
1847 .map_name = "func_proto_type_check_btf",
1848 .key_size = sizeof(int),
1849 .value_size = sizeof(int),
1853 .btf_load_err = true,
1854 .err_str = "Invalid arg#2",
1858 .descr = "func proto (CONST=>TYPEDEF=>PTR=>FUNC_PROTO)",
1860 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
1861 BTF_TYPE_INT_ENC(0, 0, 0, 32, 4), /* [2] */
1862 /* typedef void (*func_ptr)(int, unsigned int) */
1863 BTF_TYPEDEF_ENC(NAME_TBD, 5), /* [3] */
1864 /* const func_ptr */
1865 BTF_CONST_ENC(3), /* [4] */
1866 BTF_PTR_ENC(6), /* [5] */
1867 BTF_FUNC_PROTO_ENC(0, 2), /* [6] */
1868 BTF_FUNC_PROTO_ARG_ENC(0, 1),
1869 BTF_FUNC_PROTO_ARG_ENC(0, 2),
1872 .str_sec = "\0func_ptr",
1873 .str_sec_size = sizeof("\0func_ptr"),
1874 .map_type = BPF_MAP_TYPE_ARRAY,
1875 .map_name = "func_proto_type_check_btf",
1876 .key_size = sizeof(int),
1877 .value_size = sizeof(int),
1884 .descr = "func proto (CONST=>TYPEDEF=>FUNC_PROTO)",
1886 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
1887 BTF_TYPE_INT_ENC(0, 0, 0, 32, 4), /* [2] */
1888 BTF_CONST_ENC(4), /* [3] */
1889 BTF_TYPEDEF_ENC(NAME_TBD, 5), /* [4] */
1890 BTF_FUNC_PROTO_ENC(0, 2), /* [5] */
1891 BTF_FUNC_PROTO_ARG_ENC(0, 1),
1892 BTF_FUNC_PROTO_ARG_ENC(0, 2),
1895 .str_sec = "\0func_typedef",
1896 .str_sec_size = sizeof("\0func_typedef"),
1897 .map_type = BPF_MAP_TYPE_ARRAY,
1898 .map_name = "func_proto_type_check_btf",
1899 .key_size = sizeof(int),
1900 .value_size = sizeof(int),
1904 .btf_load_err = true,
1905 .err_str = "Invalid type_id",
1909 .descr = "func proto (btf_resolve(arg))",
1911 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
1912 /* void (*)(const void *) */
1913 BTF_FUNC_PROTO_ENC(0, 1), /* [2] */
1914 BTF_FUNC_PROTO_ARG_ENC(0, 3),
1915 BTF_CONST_ENC(4), /* [3] */
1916 BTF_PTR_ENC(0), /* [4] */
1920 .str_sec_size = sizeof(""),
1921 .map_type = BPF_MAP_TYPE_ARRAY,
1922 .map_name = "func_proto_type_check_btf",
1923 .key_size = sizeof(int),
1924 .value_size = sizeof(int),
1931 .descr = "func proto (Not all arg has name)",
1933 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
1934 BTF_TYPE_INT_ENC(0, 0, 0, 32, 4), /* [2] */
1935 /* void (*)(int, unsigned int b) */
1936 BTF_FUNC_PROTO_ENC(0, 2), /* [3] */
1937 BTF_FUNC_PROTO_ARG_ENC(0, 1),
1938 BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 2),
1942 .str_sec_size = sizeof("\0b"),
1943 .map_type = BPF_MAP_TYPE_ARRAY,
1944 .map_name = "func_proto_type_check_btf",
1945 .key_size = sizeof(int),
1946 .value_size = sizeof(int),
1953 .descr = "func proto (Bad arg name_off)",
1955 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
1956 BTF_TYPE_INT_ENC(0, 0, 0, 32, 4), /* [2] */
1957 /* void (*)(int a, unsigned int <bad_name_off>) */
1958 BTF_FUNC_PROTO_ENC(0, 2), /* [3] */
1959 BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
1960 BTF_FUNC_PROTO_ARG_ENC(0xffffffff, 2),
1964 .str_sec_size = sizeof("\0a"),
1965 .map_type = BPF_MAP_TYPE_ARRAY,
1966 .map_name = "func_proto_type_check_btf",
1967 .key_size = sizeof(int),
1968 .value_size = sizeof(int),
1972 .btf_load_err = true,
1973 .err_str = "Invalid arg#2",
1977 .descr = "func proto (Bad arg name)",
1979 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
1980 BTF_TYPE_INT_ENC(0, 0, 0, 32, 4), /* [2] */
1981 /* void (*)(int a, unsigned int !!!) */
1982 BTF_FUNC_PROTO_ENC(0, 2), /* [3] */
1983 BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
1984 BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 2),
1987 .str_sec = "\0a\0!!!",
1988 .str_sec_size = sizeof("\0a\0!!!"),
1989 .map_type = BPF_MAP_TYPE_ARRAY,
1990 .map_name = "func_proto_type_check_btf",
1991 .key_size = sizeof(int),
1992 .value_size = sizeof(int),
1996 .btf_load_err = true,
1997 .err_str = "Invalid arg#2",
2001 .descr = "func proto (Invalid return type)",
2003 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
2004 BTF_TYPE_INT_ENC(0, 0, 0, 32, 4), /* [2] */
2005 /* <bad_ret_type> (*)(int, unsigned int) */
2006 BTF_FUNC_PROTO_ENC(100, 2), /* [3] */
2007 BTF_FUNC_PROTO_ARG_ENC(0, 1),
2008 BTF_FUNC_PROTO_ARG_ENC(0, 2),
2012 .str_sec_size = sizeof(""),
2013 .map_type = BPF_MAP_TYPE_ARRAY,
2014 .map_name = "func_proto_type_check_btf",
2015 .key_size = sizeof(int),
2016 .value_size = sizeof(int),
2020 .btf_load_err = true,
2021 .err_str = "Invalid return type",
2025 .descr = "func proto (with func name)",
2027 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
2028 BTF_TYPE_INT_ENC(0, 0, 0, 32, 4), /* [2] */
2029 /* void func_proto(int, unsigned int) */
2030 BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_FUNC_PROTO, 0, 2), 0), /* [3] */
2031 BTF_FUNC_PROTO_ARG_ENC(0, 1),
2032 BTF_FUNC_PROTO_ARG_ENC(0, 2),
2035 .str_sec = "\0func_proto",
2036 .str_sec_size = sizeof("\0func_proto"),
2037 .map_type = BPF_MAP_TYPE_ARRAY,
2038 .map_name = "func_proto_type_check_btf",
2039 .key_size = sizeof(int),
2040 .value_size = sizeof(int),
2044 .btf_load_err = true,
2045 .err_str = "Invalid name",
2049 .descr = "func proto (const void arg)",
2051 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
2052 BTF_TYPE_INT_ENC(0, 0, 0, 32, 4), /* [2] */
2053 /* void (*)(const void) */
2054 BTF_FUNC_PROTO_ENC(0, 1), /* [3] */
2055 BTF_FUNC_PROTO_ARG_ENC(0, 4),
2056 BTF_CONST_ENC(0), /* [4] */
2060 .str_sec_size = sizeof(""),
2061 .map_type = BPF_MAP_TYPE_ARRAY,
2062 .map_name = "func_proto_type_check_btf",
2063 .key_size = sizeof(int),
2064 .value_size = sizeof(int),
2068 .btf_load_err = true,
2069 .err_str = "Invalid arg#1",
2073 .descr = "func (void func(int a, unsigned int b))",
2075 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
2076 BTF_TYPE_INT_ENC(0, 0, 0, 32, 4), /* [2] */
2077 /* void (*)(int a, unsigned int b) */
2078 BTF_FUNC_PROTO_ENC(0, 2), /* [3] */
2079 BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
2080 BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 2),
2081 /* void func(int a, unsigned int b) */
2082 BTF_FUNC_ENC(NAME_TBD, 3), /* [4] */
2085 .str_sec = "\0a\0b\0func",
2086 .str_sec_size = sizeof("\0a\0b\0func"),
2087 .map_type = BPF_MAP_TYPE_ARRAY,
2088 .map_name = "func_type_check_btf",
2089 .key_size = sizeof(int),
2090 .value_size = sizeof(int),
2097 .descr = "func (No func name)",
2099 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
2100 BTF_TYPE_INT_ENC(0, 0, 0, 32, 4), /* [2] */
2101 /* void (*)(int a, unsigned int b) */
2102 BTF_FUNC_PROTO_ENC(0, 2), /* [3] */
2103 BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
2104 BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 2),
2105 /* void <no_name>(int a, unsigned int b) */
2106 BTF_FUNC_ENC(0, 3), /* [4] */
2109 .str_sec = "\0a\0b",
2110 .str_sec_size = sizeof("\0a\0b"),
2111 .map_type = BPF_MAP_TYPE_ARRAY,
2112 .map_name = "func_type_check_btf",
2113 .key_size = sizeof(int),
2114 .value_size = sizeof(int),
2118 .btf_load_err = true,
2119 .err_str = "Invalid name",
2123 .descr = "func (Invalid func name)",
2125 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
2126 BTF_TYPE_INT_ENC(0, 0, 0, 32, 4), /* [2] */
2127 /* void (*)(int a, unsigned int b) */
2128 BTF_FUNC_PROTO_ENC(0, 2), /* [3] */
2129 BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
2130 BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 2),
2131 /* void !!!(int a, unsigned int b) */
2132 BTF_FUNC_ENC(NAME_TBD, 3), /* [4] */
2135 .str_sec = "\0a\0b\0!!!",
2136 .str_sec_size = sizeof("\0a\0b\0!!!"),
2137 .map_type = BPF_MAP_TYPE_ARRAY,
2138 .map_name = "func_type_check_btf",
2139 .key_size = sizeof(int),
2140 .value_size = sizeof(int),
2144 .btf_load_err = true,
2145 .err_str = "Invalid name",
2149 .descr = "func (Some arg has no name)",
2151 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
2152 BTF_TYPE_INT_ENC(0, 0, 0, 32, 4), /* [2] */
2153 /* void (*)(int a, unsigned int) */
2154 BTF_FUNC_PROTO_ENC(0, 2), /* [3] */
2155 BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
2156 BTF_FUNC_PROTO_ARG_ENC(0, 2),
2157 /* void func(int a, unsigned int) */
2158 BTF_FUNC_ENC(NAME_TBD, 3), /* [4] */
2161 .str_sec = "\0a\0func",
2162 .str_sec_size = sizeof("\0a\0func"),
2163 .map_type = BPF_MAP_TYPE_ARRAY,
2164 .map_name = "func_type_check_btf",
2165 .key_size = sizeof(int),
2166 .value_size = sizeof(int),
2170 .btf_load_err = true,
2171 .err_str = "Invalid arg#2",
2175 .descr = "func (Non zero vlen)",
2177 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
2178 BTF_TYPE_INT_ENC(0, 0, 0, 32, 4), /* [2] */
2179 /* void (*)(int a, unsigned int b) */
2180 BTF_FUNC_PROTO_ENC(0, 2), /* [3] */
2181 BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
2182 BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 2),
2183 /* void func(int a, unsigned int b) */
2184 BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_FUNC, 0, 2), 3), /* [4] */
2187 .str_sec = "\0a\0b\0func",
2188 .str_sec_size = sizeof("\0a\0b\0func"),
2189 .map_type = BPF_MAP_TYPE_ARRAY,
2190 .map_name = "func_type_check_btf",
2191 .key_size = sizeof(int),
2192 .value_size = sizeof(int),
2196 .btf_load_err = true,
2197 .err_str = "vlen != 0",
2201 .descr = "func (Not referring to FUNC_PROTO)",
2203 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
2204 BTF_FUNC_ENC(NAME_TBD, 1), /* [2] */
2207 .str_sec = "\0func",
2208 .str_sec_size = sizeof("\0func"),
2209 .map_type = BPF_MAP_TYPE_ARRAY,
2210 .map_name = "func_type_check_btf",
2211 .key_size = sizeof(int),
2212 .value_size = sizeof(int),
2216 .btf_load_err = true,
2217 .err_str = "Invalid type_id",
2221 .descr = "invalid int kind_flag",
2223 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
2224 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_INT, 1, 0), 4), /* [2] */
2225 BTF_INT_ENC(0, 0, 32),
2229 .map_type = BPF_MAP_TYPE_ARRAY,
2230 .map_name = "int_type_check_btf",
2231 .key_size = sizeof(int),
2232 .value_size = sizeof(int),
2236 .btf_load_err = true,
2237 .err_str = "Invalid btf_info kind_flag",
2241 .descr = "invalid ptr kind_flag",
2243 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
2244 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_PTR, 1, 0), 1), /* [2] */
2248 .map_type = BPF_MAP_TYPE_ARRAY,
2249 .map_name = "ptr_type_check_btf",
2250 .key_size = sizeof(int),
2251 .value_size = sizeof(int),
2255 .btf_load_err = true,
2256 .err_str = "Invalid btf_info kind_flag",
2260 .descr = "invalid array kind_flag",
2262 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
2263 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_ARRAY, 1, 0), 0), /* [2] */
2264 BTF_ARRAY_ENC(1, 1, 1),
2268 .map_type = BPF_MAP_TYPE_ARRAY,
2269 .map_name = "array_type_check_btf",
2270 .key_size = sizeof(int),
2271 .value_size = sizeof(int),
2275 .btf_load_err = true,
2276 .err_str = "Invalid btf_info kind_flag",
2280 .descr = "invalid enum kind_flag",
2282 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
2283 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_ENUM, 1, 1), 4), /* [2] */
2284 BTF_ENUM_ENC(NAME_TBD, 0),
2288 .map_type = BPF_MAP_TYPE_ARRAY,
2289 .map_name = "enum_type_check_btf",
2290 .key_size = sizeof(int),
2291 .value_size = sizeof(int),
2295 .btf_load_err = true,
2296 .err_str = "Invalid btf_info kind_flag",
2300 .descr = "valid fwd kind_flag",
2302 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
2303 BTF_TYPE_ENC(NAME_TBD,
2304 BTF_INFO_ENC(BTF_KIND_FWD, 1, 0), 0), /* [2] */
2308 .map_type = BPF_MAP_TYPE_ARRAY,
2309 .map_name = "fwd_type_check_btf",
2310 .key_size = sizeof(int),
2311 .value_size = sizeof(int),
2318 .descr = "invalid typedef kind_flag",
2320 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
2321 BTF_TYPE_ENC(NAME_TBD,
2322 BTF_INFO_ENC(BTF_KIND_TYPEDEF, 1, 0), 1), /* [2] */
2326 .map_type = BPF_MAP_TYPE_ARRAY,
2327 .map_name = "typedef_type_check_btf",
2328 .key_size = sizeof(int),
2329 .value_size = sizeof(int),
2333 .btf_load_err = true,
2334 .err_str = "Invalid btf_info kind_flag",
2338 .descr = "invalid volatile kind_flag",
2340 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
2341 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_VOLATILE, 1, 0), 1), /* [2] */
2345 .map_type = BPF_MAP_TYPE_ARRAY,
2346 .map_name = "volatile_type_check_btf",
2347 .key_size = sizeof(int),
2348 .value_size = sizeof(int),
2352 .btf_load_err = true,
2353 .err_str = "Invalid btf_info kind_flag",
2357 .descr = "invalid const kind_flag",
2359 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
2360 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_CONST, 1, 0), 1), /* [2] */
2364 .map_type = BPF_MAP_TYPE_ARRAY,
2365 .map_name = "const_type_check_btf",
2366 .key_size = sizeof(int),
2367 .value_size = sizeof(int),
2371 .btf_load_err = true,
2372 .err_str = "Invalid btf_info kind_flag",
2376 .descr = "invalid restrict kind_flag",
2378 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
2379 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_RESTRICT, 1, 0), 1), /* [2] */
2383 .map_type = BPF_MAP_TYPE_ARRAY,
2384 .map_name = "restrict_type_check_btf",
2385 .key_size = sizeof(int),
2386 .value_size = sizeof(int),
2390 .btf_load_err = true,
2391 .err_str = "Invalid btf_info kind_flag",
2395 .descr = "invalid func kind_flag",
2397 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
2398 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_FUNC_PROTO, 0, 0), 0), /* [2] */
2399 BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_FUNC, 1, 0), 2), /* [3] */
2403 .map_type = BPF_MAP_TYPE_ARRAY,
2404 .map_name = "func_type_check_btf",
2405 .key_size = sizeof(int),
2406 .value_size = sizeof(int),
2410 .btf_load_err = true,
2411 .err_str = "Invalid btf_info kind_flag",
2415 .descr = "invalid func_proto kind_flag",
2417 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
2418 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_FUNC_PROTO, 1, 0), 0), /* [2] */
2422 .map_type = BPF_MAP_TYPE_ARRAY,
2423 .map_name = "func_proto_type_check_btf",
2424 .key_size = sizeof(int),
2425 .value_size = sizeof(int),
2429 .btf_load_err = true,
2430 .err_str = "Invalid btf_info kind_flag",
2434 .descr = "valid struct, kind_flag, bitfield_size = 0",
2436 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
2437 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_STRUCT, 1, 2), 8), /* [2] */
2438 BTF_MEMBER_ENC(NAME_TBD, 1, BTF_MEMBER_OFFSET(0, 0)),
2439 BTF_MEMBER_ENC(NAME_TBD, 1, BTF_MEMBER_OFFSET(0, 32)),
2442 BTF_STR_SEC("\0A\0B"),
2443 .map_type = BPF_MAP_TYPE_ARRAY,
2444 .map_name = "struct_type_check_btf",
2445 .key_size = sizeof(int),
2446 .value_size = sizeof(int),
2453 .descr = "valid struct, kind_flag, int member, bitfield_size != 0",
2455 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
2456 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_STRUCT, 1, 2), 4), /* [2] */
2457 BTF_MEMBER_ENC(NAME_TBD, 1, BTF_MEMBER_OFFSET(4, 0)),
2458 BTF_MEMBER_ENC(NAME_TBD, 1, BTF_MEMBER_OFFSET(4, 4)),
2461 BTF_STR_SEC("\0A\0B"),
2462 .map_type = BPF_MAP_TYPE_ARRAY,
2463 .map_name = "struct_type_check_btf",
2464 .key_size = sizeof(int),
2465 .value_size = sizeof(int),
2472 .descr = "valid union, kind_flag, int member, bitfield_size != 0",
2474 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
2475 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_UNION, 1, 2), 4), /* [2] */
2476 BTF_MEMBER_ENC(NAME_TBD, 1, BTF_MEMBER_OFFSET(4, 0)),
2477 BTF_MEMBER_ENC(NAME_TBD, 1, BTF_MEMBER_OFFSET(4, 0)),
2480 BTF_STR_SEC("\0A\0B"),
2481 .map_type = BPF_MAP_TYPE_ARRAY,
2482 .map_name = "union_type_check_btf",
2483 .key_size = sizeof(int),
2484 .value_size = sizeof(int),
2491 .descr = "valid struct, kind_flag, enum member, bitfield_size != 0",
2493 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
2494 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_ENUM, 0, 1), 4), /* [2] */
2495 BTF_ENUM_ENC(NAME_TBD, 0),
2496 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_STRUCT, 1, 2), 4),/* [3] */
2497 BTF_MEMBER_ENC(NAME_TBD, 2, BTF_MEMBER_OFFSET(4, 0)),
2498 BTF_MEMBER_ENC(NAME_TBD, 2, BTF_MEMBER_OFFSET(4, 4)),
2501 BTF_STR_SEC("\0A\0B\0C"),
2502 .map_type = BPF_MAP_TYPE_ARRAY,
2503 .map_name = "struct_type_check_btf",
2504 .key_size = sizeof(int),
2505 .value_size = sizeof(int),
2512 .descr = "valid union, kind_flag, enum member, bitfield_size != 0",
2514 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
2515 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_ENUM, 0, 1), 4), /* [2] */
2516 BTF_ENUM_ENC(NAME_TBD, 0),
2517 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_UNION, 1, 2), 4), /* [3] */
2518 BTF_MEMBER_ENC(NAME_TBD, 2, BTF_MEMBER_OFFSET(4, 0)),
2519 BTF_MEMBER_ENC(NAME_TBD, 2, BTF_MEMBER_OFFSET(4, 0)),
2522 BTF_STR_SEC("\0A\0B\0C"),
2523 .map_type = BPF_MAP_TYPE_ARRAY,
2524 .map_name = "union_type_check_btf",
2525 .key_size = sizeof(int),
2526 .value_size = sizeof(int),
2533 .descr = "valid struct, kind_flag, typedef member, bitfield_size != 0",
2535 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
2536 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_ENUM, 0, 1), 4), /* [2] */
2537 BTF_ENUM_ENC(NAME_TBD, 0),
2538 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_STRUCT, 1, 2), 4),/* [3] */
2539 BTF_MEMBER_ENC(NAME_TBD, 4, BTF_MEMBER_OFFSET(4, 0)),
2540 BTF_MEMBER_ENC(NAME_TBD, 5, BTF_MEMBER_OFFSET(4, 4)),
2541 BTF_TYPEDEF_ENC(NAME_TBD, 1), /* [4] */
2542 BTF_TYPEDEF_ENC(NAME_TBD, 2), /* [5] */
2545 BTF_STR_SEC("\0A\0B\0C\0D\0E"),
2546 .map_type = BPF_MAP_TYPE_ARRAY,
2547 .map_name = "struct_type_check_btf",
2548 .key_size = sizeof(int),
2549 .value_size = sizeof(int),
2556 .descr = "valid union, kind_flag, typedef member, bitfield_size != 0",
2558 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
2559 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_ENUM, 0, 1), 4), /* [2] */
2560 BTF_ENUM_ENC(NAME_TBD, 0),
2561 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_UNION, 1, 2), 4), /* [3] */
2562 BTF_MEMBER_ENC(NAME_TBD, 4, BTF_MEMBER_OFFSET(4, 0)),
2563 BTF_MEMBER_ENC(NAME_TBD, 5, BTF_MEMBER_OFFSET(4, 0)),
2564 BTF_TYPEDEF_ENC(NAME_TBD, 1), /* [4] */
2565 BTF_TYPEDEF_ENC(NAME_TBD, 2), /* [5] */
2568 BTF_STR_SEC("\0A\0B\0C\0D\0E"),
2569 .map_type = BPF_MAP_TYPE_ARRAY,
2570 .map_name = "union_type_check_btf",
2571 .key_size = sizeof(int),
2572 .value_size = sizeof(int),
2579 .descr = "invalid struct, kind_flag, bitfield_size greater than struct size",
2581 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
2582 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_STRUCT, 1, 2), 4), /* [2] */
2583 BTF_MEMBER_ENC(NAME_TBD, 1, BTF_MEMBER_OFFSET(20, 0)),
2584 BTF_MEMBER_ENC(NAME_TBD, 1, BTF_MEMBER_OFFSET(20, 20)),
2587 BTF_STR_SEC("\0A\0B"),
2588 .map_type = BPF_MAP_TYPE_ARRAY,
2589 .map_name = "struct_type_check_btf",
2590 .key_size = sizeof(int),
2591 .value_size = sizeof(int),
2595 .btf_load_err = true,
2596 .err_str = "Member exceeds struct_size",
2600 .descr = "invalid struct, kind_flag, bitfield base_type int not regular",
2602 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
2603 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 20, 4), /* [2] */
2604 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_STRUCT, 1, 2), 4), /* [3] */
2605 BTF_MEMBER_ENC(NAME_TBD, 2, BTF_MEMBER_OFFSET(20, 0)),
2606 BTF_MEMBER_ENC(NAME_TBD, 2, BTF_MEMBER_OFFSET(20, 20)),
2609 BTF_STR_SEC("\0A\0B"),
2610 .map_type = BPF_MAP_TYPE_ARRAY,
2611 .map_name = "struct_type_check_btf",
2612 .key_size = sizeof(int),
2613 .value_size = sizeof(int),
2617 .btf_load_err = true,
2618 .err_str = "Invalid member base type",
2622 .descr = "invalid struct, kind_flag, base_type int not regular",
2624 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
2625 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 12, 4), /* [2] */
2626 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_STRUCT, 1, 2), 4), /* [3] */
2627 BTF_MEMBER_ENC(NAME_TBD, 2, BTF_MEMBER_OFFSET(8, 0)),
2628 BTF_MEMBER_ENC(NAME_TBD, 2, BTF_MEMBER_OFFSET(8, 8)),
2631 BTF_STR_SEC("\0A\0B"),
2632 .map_type = BPF_MAP_TYPE_ARRAY,
2633 .map_name = "struct_type_check_btf",
2634 .key_size = sizeof(int),
2635 .value_size = sizeof(int),
2639 .btf_load_err = true,
2640 .err_str = "Invalid member base type",
2644 .descr = "invalid union, kind_flag, bitfield_size greater than struct size",
2646 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
2647 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_UNION, 1, 2), 2), /* [2] */
2648 BTF_MEMBER_ENC(NAME_TBD, 1, BTF_MEMBER_OFFSET(8, 0)),
2649 BTF_MEMBER_ENC(NAME_TBD, 1, BTF_MEMBER_OFFSET(20, 0)),
2652 BTF_STR_SEC("\0A\0B"),
2653 .map_type = BPF_MAP_TYPE_ARRAY,
2654 .map_name = "union_type_check_btf",
2655 .key_size = sizeof(int),
2656 .value_size = sizeof(int),
2660 .btf_load_err = true,
2661 .err_str = "Member exceeds struct_size",
2665 .descr = "invalid struct, kind_flag, int member, bitfield_size = 0, wrong byte alignment",
2667 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
2668 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [2] */
2669 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_STRUCT, 1, 2), 12), /* [3] */
2670 BTF_MEMBER_ENC(NAME_TBD, 2, BTF_MEMBER_OFFSET(0, 0)),
2671 BTF_MEMBER_ENC(NAME_TBD, 2, BTF_MEMBER_OFFSET(0, 36)),
2674 BTF_STR_SEC("\0A\0B"),
2675 .map_type = BPF_MAP_TYPE_ARRAY,
2676 .map_name = "struct_type_check_btf",
2677 .key_size = sizeof(int),
2678 .value_size = sizeof(int),
2682 .btf_load_err = true,
2683 .err_str = "Invalid member offset",
2687 .descr = "invalid struct, kind_flag, enum member, bitfield_size = 0, wrong byte alignment",
2689 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
2690 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [2] */
2691 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_ENUM, 0, 1), 4), /* [2] */
2692 BTF_ENUM_ENC(NAME_TBD, 0),
2693 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_STRUCT, 1, 2), 12), /* [3] */
2694 BTF_MEMBER_ENC(NAME_TBD, 2, BTF_MEMBER_OFFSET(0, 0)),
2695 BTF_MEMBER_ENC(NAME_TBD, 2, BTF_MEMBER_OFFSET(0, 36)),
2698 BTF_STR_SEC("\0A\0B\0C"),
2699 .map_type = BPF_MAP_TYPE_ARRAY,
2700 .map_name = "struct_type_check_btf",
2701 .key_size = sizeof(int),
2702 .value_size = sizeof(int),
2706 .btf_load_err = true,
2707 .err_str = "Invalid member offset",
2710 }; /* struct btf_raw_test raw_tests[] */
2712 static const char *get_next_str(const char *start, const char *end)
2714 return start < end - 1 ? start + 1 : NULL;
2717 static int get_raw_sec_size(const __u32 *raw_types)
2721 for (i = MAX_NR_RAW_U32 - 1;
2722 i >= 0 && raw_types[i] != BTF_END_RAW;
2726 return i < 0 ? i : i * sizeof(raw_types[0]);
2729 static void *btf_raw_create(const struct btf_header *hdr,
2730 const __u32 *raw_types,
2732 unsigned int str_sec_size,
2733 unsigned int *btf_size,
2734 const char **ret_next_str)
2736 const char *next_str = str, *end_str = str + str_sec_size;
2737 unsigned int size_needed, offset;
2738 struct btf_header *ret_hdr;
2739 int i, type_sec_size;
2740 uint32_t *ret_types;
2743 type_sec_size = get_raw_sec_size(raw_types);
2744 if (CHECK(type_sec_size < 0, "Cannot get nr_raw_types"))
2747 size_needed = sizeof(*hdr) + type_sec_size + str_sec_size;
2748 raw_btf = malloc(size_needed);
2749 if (CHECK(!raw_btf, "Cannot allocate memory for raw_btf"))
2753 memcpy(raw_btf, hdr, sizeof(*hdr));
2754 offset = sizeof(*hdr);
2756 /* Copy type section */
2757 ret_types = raw_btf + offset;
2758 for (i = 0; i < type_sec_size / sizeof(raw_types[0]); i++) {
2759 if (raw_types[i] == NAME_TBD) {
2760 next_str = get_next_str(next_str, end_str);
2761 if (CHECK(!next_str, "Error in getting next_str")) {
2765 ret_types[i] = next_str - str;
2766 next_str += strlen(next_str);
2768 ret_types[i] = raw_types[i];
2771 offset += type_sec_size;
2773 /* Copy string section */
2774 memcpy(raw_btf + offset, str, str_sec_size);
2776 ret_hdr = (struct btf_header *)raw_btf;
2777 ret_hdr->type_len = type_sec_size;
2778 ret_hdr->str_off = type_sec_size;
2779 ret_hdr->str_len = str_sec_size;
2781 *btf_size = size_needed;
2783 *ret_next_str = next_str;
2788 static int do_test_raw(unsigned int test_num)
2790 struct btf_raw_test *test = &raw_tests[test_num - 1];
2791 struct bpf_create_map_attr create_attr = {};
2792 int map_fd = -1, btf_fd = -1;
2793 unsigned int raw_btf_size;
2794 struct btf_header *hdr;
2798 fprintf(stderr, "BTF raw test[%u] (%s): ", test_num, test->descr);
2799 raw_btf = btf_raw_create(&hdr_tmpl,
2803 &raw_btf_size, NULL);
2810 hdr->hdr_len = (int)hdr->hdr_len + test->hdr_len_delta;
2811 hdr->type_off = (int)hdr->type_off + test->type_off_delta;
2812 hdr->str_off = (int)hdr->str_off + test->str_off_delta;
2813 hdr->str_len = (int)hdr->str_len + test->str_len_delta;
2815 *btf_log_buf = '\0';
2816 btf_fd = bpf_load_btf(raw_btf, raw_btf_size,
2817 btf_log_buf, BTF_LOG_BUF_SIZE,
2821 err = ((btf_fd == -1) != test->btf_load_err);
2822 if (CHECK(err, "btf_fd:%d test->btf_load_err:%u",
2823 btf_fd, test->btf_load_err) ||
2824 CHECK(test->err_str && !strstr(btf_log_buf, test->err_str),
2825 "expected err_str:%s", test->err_str)) {
2830 if (err || btf_fd == -1)
2833 create_attr.name = test->map_name;
2834 create_attr.map_type = test->map_type;
2835 create_attr.key_size = test->key_size;
2836 create_attr.value_size = test->value_size;
2837 create_attr.max_entries = test->max_entries;
2838 create_attr.btf_fd = btf_fd;
2839 create_attr.btf_key_type_id = test->key_type_id;
2840 create_attr.btf_value_type_id = test->value_type_id;
2842 map_fd = bpf_create_map_xattr(&create_attr);
2844 err = ((map_fd == -1) != test->map_create_err);
2845 CHECK(err, "map_fd:%d test->map_create_err:%u",
2846 map_fd, test->map_create_err);
2850 fprintf(stderr, "OK");
2852 if (*btf_log_buf && (err || args.always_log))
2853 fprintf(stderr, "\n%s", btf_log_buf);
2863 static int test_raw(void)
2868 if (args.raw_test_num)
2869 return count_result(do_test_raw(args.raw_test_num));
2871 for (i = 1; i <= ARRAY_SIZE(raw_tests); i++)
2872 err |= count_result(do_test_raw(i));
2877 struct btf_get_info_test {
2879 const char *str_sec;
2880 __u32 raw_types[MAX_NR_RAW_U32];
2883 int (*special_test)(unsigned int test_num);
2886 static int test_big_btf_info(unsigned int test_num);
2887 static int test_btf_id(unsigned int test_num);
2889 const struct btf_get_info_test get_info_tests[] = {
2891 .descr = "== raw_btf_size+1",
2894 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
2898 .str_sec_size = sizeof(""),
2899 .btf_size_delta = 1,
2902 .descr = "== raw_btf_size-3",
2905 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
2909 .str_sec_size = sizeof(""),
2910 .btf_size_delta = -3,
2913 .descr = "Large bpf_btf_info",
2916 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
2920 .str_sec_size = sizeof(""),
2921 .special_test = test_big_btf_info,
2927 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
2928 /* unsigned int */ /* [2] */
2929 BTF_TYPE_INT_ENC(0, 0, 0, 32, 4),
2933 .str_sec_size = sizeof(""),
2934 .special_test = test_btf_id,
2938 static inline __u64 ptr_to_u64(const void *ptr)
2940 return (__u64)(unsigned long)ptr;
2943 static int test_big_btf_info(unsigned int test_num)
2945 const struct btf_get_info_test *test = &get_info_tests[test_num - 1];
2946 uint8_t *raw_btf = NULL, *user_btf = NULL;
2947 unsigned int raw_btf_size;
2949 struct bpf_btf_info info;
2952 struct bpf_btf_info *info;
2953 int btf_fd = -1, err;
2956 raw_btf = btf_raw_create(&hdr_tmpl,
2960 &raw_btf_size, NULL);
2965 *btf_log_buf = '\0';
2967 user_btf = malloc(raw_btf_size);
2968 if (CHECK(!user_btf, "!user_btf")) {
2973 btf_fd = bpf_load_btf(raw_btf, raw_btf_size,
2974 btf_log_buf, BTF_LOG_BUF_SIZE,
2976 if (CHECK(btf_fd == -1, "errno:%d", errno)) {
2982 * GET_INFO should error out if the userspace info
2983 * has non zero tailing bytes.
2985 info = &info_garbage.info;
2986 memset(info, 0, sizeof(*info));
2987 info_garbage.garbage = 0xdeadbeef;
2988 info_len = sizeof(info_garbage);
2989 info->btf = ptr_to_u64(user_btf);
2990 info->btf_size = raw_btf_size;
2992 err = bpf_obj_get_info_by_fd(btf_fd, info, &info_len);
2993 if (CHECK(!err, "!err")) {
2999 * GET_INFO should succeed even info_len is larger than
3000 * the kernel supported as long as tailing bytes are zero.
3001 * The kernel supported info len should also be returned
3004 info_garbage.garbage = 0;
3005 err = bpf_obj_get_info_by_fd(btf_fd, info, &info_len);
3006 if (CHECK(err || info_len != sizeof(*info),
3007 "err:%d errno:%d info_len:%u sizeof(*info):%lu",
3008 err, errno, info_len, sizeof(*info))) {
3013 fprintf(stderr, "OK");
3016 if (*btf_log_buf && (err || args.always_log))
3017 fprintf(stderr, "\n%s", btf_log_buf);
3028 static int test_btf_id(unsigned int test_num)
3030 const struct btf_get_info_test *test = &get_info_tests[test_num - 1];
3031 struct bpf_create_map_attr create_attr = {};
3032 uint8_t *raw_btf = NULL, *user_btf[2] = {};
3033 int btf_fd[2] = {-1, -1}, map_fd = -1;
3034 struct bpf_map_info map_info = {};
3035 struct bpf_btf_info info[2] = {};
3036 unsigned int raw_btf_size;
3040 raw_btf = btf_raw_create(&hdr_tmpl,
3044 &raw_btf_size, NULL);
3049 *btf_log_buf = '\0';
3051 for (i = 0; i < 2; i++) {
3052 user_btf[i] = malloc(raw_btf_size);
3053 if (CHECK(!user_btf[i], "!user_btf[%d]", i)) {
3057 info[i].btf = ptr_to_u64(user_btf[i]);
3058 info[i].btf_size = raw_btf_size;
3061 btf_fd[0] = bpf_load_btf(raw_btf, raw_btf_size,
3062 btf_log_buf, BTF_LOG_BUF_SIZE,
3064 if (CHECK(btf_fd[0] == -1, "errno:%d", errno)) {
3069 /* Test BPF_OBJ_GET_INFO_BY_ID on btf_id */
3070 info_len = sizeof(info[0]);
3071 err = bpf_obj_get_info_by_fd(btf_fd[0], &info[0], &info_len);
3072 if (CHECK(err, "errno:%d", errno)) {
3077 btf_fd[1] = bpf_btf_get_fd_by_id(info[0].id);
3078 if (CHECK(btf_fd[1] == -1, "errno:%d", errno)) {
3084 err = bpf_obj_get_info_by_fd(btf_fd[1], &info[1], &info_len);
3085 if (CHECK(err || info[0].id != info[1].id ||
3086 info[0].btf_size != info[1].btf_size ||
3087 (ret = memcmp(user_btf[0], user_btf[1], info[0].btf_size)),
3088 "err:%d errno:%d id0:%u id1:%u btf_size0:%u btf_size1:%u memcmp:%d",
3089 err, errno, info[0].id, info[1].id,
3090 info[0].btf_size, info[1].btf_size, ret)) {
3095 /* Test btf members in struct bpf_map_info */
3096 create_attr.name = "test_btf_id";
3097 create_attr.map_type = BPF_MAP_TYPE_ARRAY;
3098 create_attr.key_size = sizeof(int);
3099 create_attr.value_size = sizeof(unsigned int);
3100 create_attr.max_entries = 4;
3101 create_attr.btf_fd = btf_fd[0];
3102 create_attr.btf_key_type_id = 1;
3103 create_attr.btf_value_type_id = 2;
3105 map_fd = bpf_create_map_xattr(&create_attr);
3106 if (CHECK(map_fd == -1, "errno:%d", errno)) {
3111 info_len = sizeof(map_info);
3112 err = bpf_obj_get_info_by_fd(map_fd, &map_info, &info_len);
3113 if (CHECK(err || map_info.btf_id != info[0].id ||
3114 map_info.btf_key_type_id != 1 || map_info.btf_value_type_id != 2,
3115 "err:%d errno:%d info.id:%u btf_id:%u btf_key_type_id:%u btf_value_type_id:%u",
3116 err, errno, info[0].id, map_info.btf_id, map_info.btf_key_type_id,
3117 map_info.btf_value_type_id)) {
3122 for (i = 0; i < 2; i++) {
3127 /* Test BTF ID is removed from the kernel */
3128 btf_fd[0] = bpf_btf_get_fd_by_id(map_info.btf_id);
3129 if (CHECK(btf_fd[0] == -1, "errno:%d", errno)) {
3136 /* The map holds the last ref to BTF and its btf_id */
3139 btf_fd[0] = bpf_btf_get_fd_by_id(map_info.btf_id);
3140 if (CHECK(btf_fd[0] != -1, "BTF lingers")) {
3145 fprintf(stderr, "OK");
3148 if (*btf_log_buf && (err || args.always_log))
3149 fprintf(stderr, "\n%s", btf_log_buf);
3154 for (i = 0; i < 2; i++) {
3156 if (btf_fd[i] != -1)
3163 static int do_test_get_info(unsigned int test_num)
3165 const struct btf_get_info_test *test = &get_info_tests[test_num - 1];
3166 unsigned int raw_btf_size, user_btf_size, expected_nbytes;
3167 uint8_t *raw_btf = NULL, *user_btf = NULL;
3168 struct bpf_btf_info info = {};
3169 int btf_fd = -1, err, ret;
3172 fprintf(stderr, "BTF GET_INFO test[%u] (%s): ",
3173 test_num, test->descr);
3175 if (test->special_test)
3176 return test->special_test(test_num);
3178 raw_btf = btf_raw_create(&hdr_tmpl,
3182 &raw_btf_size, NULL);
3187 *btf_log_buf = '\0';
3189 user_btf = malloc(raw_btf_size);
3190 if (CHECK(!user_btf, "!user_btf")) {
3195 btf_fd = bpf_load_btf(raw_btf, raw_btf_size,
3196 btf_log_buf, BTF_LOG_BUF_SIZE,
3198 if (CHECK(btf_fd == -1, "errno:%d", errno)) {
3203 user_btf_size = (int)raw_btf_size + test->btf_size_delta;
3204 expected_nbytes = min(raw_btf_size, user_btf_size);
3205 if (raw_btf_size > expected_nbytes)
3206 memset(user_btf + expected_nbytes, 0xff,
3207 raw_btf_size - expected_nbytes);
3209 info_len = sizeof(info);
3210 info.btf = ptr_to_u64(user_btf);
3211 info.btf_size = user_btf_size;
3214 err = bpf_obj_get_info_by_fd(btf_fd, &info, &info_len);
3215 if (CHECK(err || !info.id || info_len != sizeof(info) ||
3216 info.btf_size != raw_btf_size ||
3217 (ret = memcmp(raw_btf, user_btf, expected_nbytes)),
3218 "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",
3219 err, errno, info.id, info_len, sizeof(info),
3220 raw_btf_size, info.btf_size, expected_nbytes, ret)) {
3225 while (expected_nbytes < raw_btf_size) {
3226 fprintf(stderr, "%u...", expected_nbytes);
3227 if (CHECK(user_btf[expected_nbytes++] != 0xff,
3228 "user_btf[%u]:%x != 0xff", expected_nbytes - 1,
3229 user_btf[expected_nbytes - 1])) {
3235 fprintf(stderr, "OK");
3238 if (*btf_log_buf && (err || args.always_log))
3239 fprintf(stderr, "\n%s", btf_log_buf);
3250 static int test_get_info(void)
3255 if (args.get_info_test_num)
3256 return count_result(do_test_get_info(args.get_info_test_num));
3258 for (i = 1; i <= ARRAY_SIZE(get_info_tests); i++)
3259 err |= count_result(do_test_get_info(i));
3264 struct btf_file_test {
3266 bool btf_kv_notfound;
3269 static struct btf_file_test file_tests[] = {
3271 .file = "test_btf_haskv.o",
3274 .file = "test_btf_nokv.o",
3275 .btf_kv_notfound = true,
3279 static int file_has_btf_elf(const char *fn, bool *has_btf_ext)
3281 Elf_Scn *scn = NULL;
3287 if (CHECK(elf_version(EV_CURRENT) == EV_NONE,
3288 "elf_version(EV_CURRENT) == EV_NONE"))
3291 elf_fd = open(fn, O_RDONLY);
3292 if (CHECK(elf_fd == -1, "open(%s): errno:%d", fn, errno))
3295 elf = elf_begin(elf_fd, ELF_C_READ, NULL);
3296 if (CHECK(!elf, "elf_begin(%s): %s", fn, elf_errmsg(elf_errno()))) {
3301 if (CHECK(!gelf_getehdr(elf, &ehdr), "!gelf_getehdr(%s)", fn)) {
3306 while ((scn = elf_nextscn(elf, scn))) {
3307 const char *sh_name;
3310 if (CHECK(gelf_getshdr(scn, &sh) != &sh,
3311 "file:%s gelf_getshdr != &sh", fn)) {
3316 sh_name = elf_strptr(elf, ehdr.e_shstrndx, sh.sh_name);
3317 if (!strcmp(sh_name, BTF_ELF_SEC))
3319 if (!strcmp(sh_name, BTF_EXT_ELF_SEC))
3320 *has_btf_ext = true;
3329 static int do_test_file(unsigned int test_num)
3331 const struct btf_file_test *test = &file_tests[test_num - 1];
3332 const char *expected_fnames[] = {"_dummy_tracepoint",
3333 "test_long_fname_1",
3334 "test_long_fname_2"};
3335 struct bpf_prog_info info = {};
3336 struct bpf_object *obj = NULL;
3337 struct bpf_func_info *finfo;
3338 struct bpf_program *prog;
3339 __u32 info_len, rec_size;
3340 bool has_btf_ext = false;
3341 struct btf *btf = NULL;
3342 void *func_info = NULL;
3343 struct bpf_map *map;
3344 int i, err, prog_fd;
3346 fprintf(stderr, "BTF libbpf test[%u] (%s): ", test_num,
3349 err = file_has_btf_elf(test->file, &has_btf_ext);
3354 fprintf(stderr, "SKIP. No ELF %s found", BTF_ELF_SEC);
3359 obj = bpf_object__open(test->file);
3360 if (CHECK(IS_ERR(obj), "obj: %ld", PTR_ERR(obj)))
3361 return PTR_ERR(obj);
3363 err = bpf_object__btf_fd(obj);
3364 if (CHECK(err == -1, "bpf_object__btf_fd: -1"))
3367 prog = bpf_program__next(NULL, obj);
3368 if (CHECK(!prog, "Cannot find bpf_prog")) {
3373 bpf_program__set_type(prog, BPF_PROG_TYPE_TRACEPOINT);
3374 err = bpf_object__load(obj);
3375 if (CHECK(err < 0, "bpf_object__load: %d", err))
3377 prog_fd = bpf_program__fd(prog);
3379 map = bpf_object__find_map_by_name(obj, "btf_map");
3380 if (CHECK(!map, "btf_map not found")) {
3385 err = (bpf_map__btf_key_type_id(map) == 0 || bpf_map__btf_value_type_id(map) == 0)
3386 != test->btf_kv_notfound;
3387 if (CHECK(err, "btf_key_type_id:%u btf_value_type_id:%u test->btf_kv_notfound:%u",
3388 bpf_map__btf_key_type_id(map), bpf_map__btf_value_type_id(map),
3389 test->btf_kv_notfound))
3395 /* get necessary program info */
3396 info_len = sizeof(struct bpf_prog_info);
3397 err = bpf_obj_get_info_by_fd(prog_fd, &info, &info_len);
3399 if (CHECK(err == -1, "invalid get info (1st) errno:%d", errno)) {
3400 fprintf(stderr, "%s\n", btf_log_buf);
3404 if (CHECK(info.nr_func_info != 3,
3405 "incorrect info.nr_func_info (1st) %d",
3406 info.nr_func_info)) {
3410 rec_size = info.func_info_rec_size;
3411 if (CHECK(rec_size != sizeof(struct bpf_func_info),
3412 "incorrect info.func_info_rec_size (1st) %d\n", rec_size)) {
3417 func_info = malloc(info.nr_func_info * rec_size);
3418 if (CHECK(!func_info, "out of memory")) {
3423 /* reset info to only retrieve func_info related data */
3424 memset(&info, 0, sizeof(info));
3425 info.nr_func_info = 3;
3426 info.func_info_rec_size = rec_size;
3427 info.func_info = ptr_to_u64(func_info);
3429 err = bpf_obj_get_info_by_fd(prog_fd, &info, &info_len);
3431 if (CHECK(err == -1, "invalid get info (2nd) errno:%d", errno)) {
3432 fprintf(stderr, "%s\n", btf_log_buf);
3436 if (CHECK(info.nr_func_info != 3,
3437 "incorrect info.nr_func_info (2nd) %d",
3438 info.nr_func_info)) {
3442 if (CHECK(info.func_info_rec_size != rec_size,
3443 "incorrect info.func_info_rec_size (2nd) %d",
3444 info.func_info_rec_size)) {
3449 err = btf__get_from_id(info.btf_id, &btf);
3450 if (CHECK(err, "cannot get btf from kernel, err: %d", err))
3453 /* check three functions */
3455 for (i = 0; i < 3; i++) {
3456 const struct btf_type *t;
3459 t = btf__type_by_id(btf, finfo->type_id);
3460 if (CHECK(!t, "btf__type_by_id failure: id %u",
3466 fname = btf__name_by_offset(btf, t->name_off);
3467 err = strcmp(fname, expected_fnames[i]);
3468 /* for the second and third functions in .text section,
3469 * the compiler may order them either way.
3472 err = strcmp(fname, expected_fnames[3 - i]);
3473 if (CHECK(err, "incorrect fname %s", fname ? : "")) {
3478 finfo = (void *)finfo + rec_size;
3482 fprintf(stderr, "OK");
3486 bpf_object__close(obj);
3490 static int test_file(void)
3495 if (args.file_test_num)
3496 return count_result(do_test_file(args.file_test_num));
3498 for (i = 1; i <= ARRAY_SIZE(file_tests); i++)
3499 err |= count_result(do_test_file(i));
3504 const char *pprint_enum_str[] = {
3511 struct pprint_mapv {
3516 uint32_t unused_bits2a:2,
3533 static struct btf_raw_test pprint_test_template[] = {
3536 /* unsighed char */ /* [1] */
3537 BTF_TYPE_INT_ENC(NAME_TBD, 0, 0, 8, 1),
3538 /* unsigned short */ /* [2] */
3539 BTF_TYPE_INT_ENC(NAME_TBD, 0, 0, 16, 2),
3540 /* unsigned int */ /* [3] */
3541 BTF_TYPE_INT_ENC(NAME_TBD, 0, 0, 32, 4),
3543 BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),
3544 /* unsigned long long */ /* [5] */
3545 BTF_TYPE_INT_ENC(NAME_TBD, 0, 0, 64, 8),
3546 /* 2 bits */ /* [6] */
3547 BTF_TYPE_INT_ENC(0, 0, 0, 2, 2),
3548 /* 28 bits */ /* [7] */
3549 BTF_TYPE_INT_ENC(0, 0, 0, 28, 4),
3550 /* uint8_t[8] */ /* [8] */
3551 BTF_TYPE_ARRAY_ENC(9, 1, 8),
3552 /* typedef unsigned char uint8_t */ /* [9] */
3553 BTF_TYPEDEF_ENC(NAME_TBD, 1),
3554 /* typedef unsigned short uint16_t */ /* [10] */
3555 BTF_TYPEDEF_ENC(NAME_TBD, 2),
3556 /* typedef unsigned int uint32_t */ /* [11] */
3557 BTF_TYPEDEF_ENC(NAME_TBD, 3),
3558 /* typedef int int32_t */ /* [12] */
3559 BTF_TYPEDEF_ENC(NAME_TBD, 4),
3560 /* typedef unsigned long long uint64_t *//* [13] */
3561 BTF_TYPEDEF_ENC(NAME_TBD, 5),
3562 /* union (anon) */ /* [14] */
3563 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_UNION, 0, 2), 8),
3564 BTF_MEMBER_ENC(NAME_TBD, 13, 0),/* uint64_t ui64; */
3565 BTF_MEMBER_ENC(NAME_TBD, 8, 0), /* uint8_t ui8a[8]; */
3566 /* enum (anon) */ /* [15] */
3567 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_ENUM, 0, 4), 4),
3568 BTF_ENUM_ENC(NAME_TBD, 0),
3569 BTF_ENUM_ENC(NAME_TBD, 1),
3570 BTF_ENUM_ENC(NAME_TBD, 2),
3571 BTF_ENUM_ENC(NAME_TBD, 3),
3572 /* struct pprint_mapv */ /* [16] */
3573 BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 10), 40),
3574 BTF_MEMBER_ENC(NAME_TBD, 11, 0), /* uint32_t ui32 */
3575 BTF_MEMBER_ENC(NAME_TBD, 10, 32), /* uint16_t ui16 */
3576 BTF_MEMBER_ENC(NAME_TBD, 12, 64), /* int32_t si32 */
3577 BTF_MEMBER_ENC(NAME_TBD, 6, 96), /* unused_bits2a */
3578 BTF_MEMBER_ENC(NAME_TBD, 7, 98), /* bits28 */
3579 BTF_MEMBER_ENC(NAME_TBD, 6, 126), /* unused_bits2b */
3580 BTF_MEMBER_ENC(0, 14, 128), /* union (anon) */
3581 BTF_MEMBER_ENC(NAME_TBD, 15, 192), /* aenum */
3582 BTF_MEMBER_ENC(NAME_TBD, 11, 224), /* uint32_t ui32b */
3583 BTF_MEMBER_ENC(NAME_TBD, 6, 256), /* bits2c */
3586 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"),
3587 .key_size = sizeof(unsigned int),
3588 .value_size = sizeof(struct pprint_mapv),
3589 .key_type_id = 3, /* unsigned int */
3590 .value_type_id = 16, /* struct pprint_mapv */
3591 .max_entries = 128 * 1024,
3595 /* this type will have the same type as the
3596 * first .raw_types definition, but struct type will
3597 * be encoded with kind_flag set.
3600 /* unsighed char */ /* [1] */
3601 BTF_TYPE_INT_ENC(NAME_TBD, 0, 0, 8, 1),
3602 /* unsigned short */ /* [2] */
3603 BTF_TYPE_INT_ENC(NAME_TBD, 0, 0, 16, 2),
3604 /* unsigned int */ /* [3] */
3605 BTF_TYPE_INT_ENC(NAME_TBD, 0, 0, 32, 4),
3607 BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),
3608 /* unsigned long long */ /* [5] */
3609 BTF_TYPE_INT_ENC(NAME_TBD, 0, 0, 64, 8),
3610 BTF_TYPE_INT_ENC(0, 0, 0, 32, 4), /* [6] */
3611 BTF_TYPE_INT_ENC(0, 0, 0, 32, 4), /* [7] */
3612 /* uint8_t[8] */ /* [8] */
3613 BTF_TYPE_ARRAY_ENC(9, 1, 8),
3614 /* typedef unsigned char uint8_t */ /* [9] */
3615 BTF_TYPEDEF_ENC(NAME_TBD, 1),
3616 /* typedef unsigned short uint16_t */ /* [10] */
3617 BTF_TYPEDEF_ENC(NAME_TBD, 2),
3618 /* typedef unsigned int uint32_t */ /* [11] */
3619 BTF_TYPEDEF_ENC(NAME_TBD, 3),
3620 /* typedef int int32_t */ /* [12] */
3621 BTF_TYPEDEF_ENC(NAME_TBD, 4),
3622 /* typedef unsigned long long uint64_t *//* [13] */
3623 BTF_TYPEDEF_ENC(NAME_TBD, 5),
3624 /* union (anon) */ /* [14] */
3625 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_UNION, 0, 2), 8),
3626 BTF_MEMBER_ENC(NAME_TBD, 13, 0),/* uint64_t ui64; */
3627 BTF_MEMBER_ENC(NAME_TBD, 8, 0), /* uint8_t ui8a[8]; */
3628 /* enum (anon) */ /* [15] */
3629 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_ENUM, 0, 4), 4),
3630 BTF_ENUM_ENC(NAME_TBD, 0),
3631 BTF_ENUM_ENC(NAME_TBD, 1),
3632 BTF_ENUM_ENC(NAME_TBD, 2),
3633 BTF_ENUM_ENC(NAME_TBD, 3),
3634 /* struct pprint_mapv */ /* [16] */
3635 BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 1, 10), 40),
3636 BTF_MEMBER_ENC(NAME_TBD, 11, BTF_MEMBER_OFFSET(0, 0)), /* uint32_t ui32 */
3637 BTF_MEMBER_ENC(NAME_TBD, 10, BTF_MEMBER_OFFSET(0, 32)), /* uint16_t ui16 */
3638 BTF_MEMBER_ENC(NAME_TBD, 12, BTF_MEMBER_OFFSET(0, 64)), /* int32_t si32 */
3639 BTF_MEMBER_ENC(NAME_TBD, 6, BTF_MEMBER_OFFSET(2, 96)), /* unused_bits2a */
3640 BTF_MEMBER_ENC(NAME_TBD, 7, BTF_MEMBER_OFFSET(28, 98)), /* bits28 */
3641 BTF_MEMBER_ENC(NAME_TBD, 6, BTF_MEMBER_OFFSET(2, 126)), /* unused_bits2b */
3642 BTF_MEMBER_ENC(0, 14, BTF_MEMBER_OFFSET(0, 128)), /* union (anon) */
3643 BTF_MEMBER_ENC(NAME_TBD, 15, BTF_MEMBER_OFFSET(0, 192)), /* aenum */
3644 BTF_MEMBER_ENC(NAME_TBD, 11, BTF_MEMBER_OFFSET(0, 224)), /* uint32_t ui32b */
3645 BTF_MEMBER_ENC(NAME_TBD, 6, BTF_MEMBER_OFFSET(2, 256)), /* bits2c */
3648 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"),
3649 .key_size = sizeof(unsigned int),
3650 .value_size = sizeof(struct pprint_mapv),
3651 .key_type_id = 3, /* unsigned int */
3652 .value_type_id = 16, /* struct pprint_mapv */
3653 .max_entries = 128 * 1024,
3657 /* this type will have the same layout as the
3658 * first .raw_types definition. The struct type will
3659 * be encoded with kind_flag set, bitfield members
3660 * are added typedef/const/volatile, and bitfield members
3661 * will have both int and enum types.
3664 /* unsighed char */ /* [1] */
3665 BTF_TYPE_INT_ENC(NAME_TBD, 0, 0, 8, 1),
3666 /* unsigned short */ /* [2] */
3667 BTF_TYPE_INT_ENC(NAME_TBD, 0, 0, 16, 2),
3668 /* unsigned int */ /* [3] */
3669 BTF_TYPE_INT_ENC(NAME_TBD, 0, 0, 32, 4),
3671 BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),
3672 /* unsigned long long */ /* [5] */
3673 BTF_TYPE_INT_ENC(NAME_TBD, 0, 0, 64, 8),
3674 BTF_TYPE_INT_ENC(0, 0, 0, 32, 4), /* [6] */
3675 BTF_TYPE_INT_ENC(0, 0, 0, 32, 4), /* [7] */
3676 /* uint8_t[8] */ /* [8] */
3677 BTF_TYPE_ARRAY_ENC(9, 1, 8),
3678 /* typedef unsigned char uint8_t */ /* [9] */
3679 BTF_TYPEDEF_ENC(NAME_TBD, 1),
3680 /* typedef unsigned short uint16_t */ /* [10] */
3681 BTF_TYPEDEF_ENC(NAME_TBD, 2),
3682 /* typedef unsigned int uint32_t */ /* [11] */
3683 BTF_TYPEDEF_ENC(NAME_TBD, 3),
3684 /* typedef int int32_t */ /* [12] */
3685 BTF_TYPEDEF_ENC(NAME_TBD, 4),
3686 /* typedef unsigned long long uint64_t *//* [13] */
3687 BTF_TYPEDEF_ENC(NAME_TBD, 5),
3688 /* union (anon) */ /* [14] */
3689 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_UNION, 0, 2), 8),
3690 BTF_MEMBER_ENC(NAME_TBD, 13, 0),/* uint64_t ui64; */
3691 BTF_MEMBER_ENC(NAME_TBD, 8, 0), /* uint8_t ui8a[8]; */
3692 /* enum (anon) */ /* [15] */
3693 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_ENUM, 0, 4), 4),
3694 BTF_ENUM_ENC(NAME_TBD, 0),
3695 BTF_ENUM_ENC(NAME_TBD, 1),
3696 BTF_ENUM_ENC(NAME_TBD, 2),
3697 BTF_ENUM_ENC(NAME_TBD, 3),
3698 /* struct pprint_mapv */ /* [16] */
3699 BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 1, 10), 40),
3700 BTF_MEMBER_ENC(NAME_TBD, 11, BTF_MEMBER_OFFSET(0, 0)), /* uint32_t ui32 */
3701 BTF_MEMBER_ENC(NAME_TBD, 10, BTF_MEMBER_OFFSET(0, 32)), /* uint16_t ui16 */
3702 BTF_MEMBER_ENC(NAME_TBD, 12, BTF_MEMBER_OFFSET(0, 64)), /* int32_t si32 */
3703 BTF_MEMBER_ENC(NAME_TBD, 17, BTF_MEMBER_OFFSET(2, 96)), /* unused_bits2a */
3704 BTF_MEMBER_ENC(NAME_TBD, 7, BTF_MEMBER_OFFSET(28, 98)), /* bits28 */
3705 BTF_MEMBER_ENC(NAME_TBD, 19, BTF_MEMBER_OFFSET(2, 126)),/* unused_bits2b */
3706 BTF_MEMBER_ENC(0, 14, BTF_MEMBER_OFFSET(0, 128)), /* union (anon) */
3707 BTF_MEMBER_ENC(NAME_TBD, 15, BTF_MEMBER_OFFSET(0, 192)), /* aenum */
3708 BTF_MEMBER_ENC(NAME_TBD, 11, BTF_MEMBER_OFFSET(0, 224)), /* uint32_t ui32b */
3709 BTF_MEMBER_ENC(NAME_TBD, 17, BTF_MEMBER_OFFSET(2, 256)), /* bits2c */
3710 /* typedef unsigned int ___int */ /* [17] */
3711 BTF_TYPEDEF_ENC(NAME_TBD, 18),
3712 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_VOLATILE, 0, 0), 6), /* [18] */
3713 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_CONST, 0, 0), 15), /* [19] */
3716 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"),
3717 .key_size = sizeof(unsigned int),
3718 .value_size = sizeof(struct pprint_mapv),
3719 .key_type_id = 3, /* unsigned int */
3720 .value_type_id = 16, /* struct pprint_mapv */
3721 .max_entries = 128 * 1024,
3726 static struct btf_pprint_test_meta {
3728 enum bpf_map_type map_type;
3729 const char *map_name;
3733 } pprint_tests_meta[] = {
3735 .descr = "BTF pretty print array",
3736 .map_type = BPF_MAP_TYPE_ARRAY,
3737 .map_name = "pprint_test_array",
3738 .ordered_map = true,
3739 .lossless_map = true,
3740 .percpu_map = false,
3744 .descr = "BTF pretty print hash",
3745 .map_type = BPF_MAP_TYPE_HASH,
3746 .map_name = "pprint_test_hash",
3747 .ordered_map = false,
3748 .lossless_map = true,
3749 .percpu_map = false,
3753 .descr = "BTF pretty print lru hash",
3754 .map_type = BPF_MAP_TYPE_LRU_HASH,
3755 .map_name = "pprint_test_lru_hash",
3756 .ordered_map = false,
3757 .lossless_map = false,
3758 .percpu_map = false,
3762 .descr = "BTF pretty print percpu array",
3763 .map_type = BPF_MAP_TYPE_PERCPU_ARRAY,
3764 .map_name = "pprint_test_percpu_array",
3765 .ordered_map = true,
3766 .lossless_map = true,
3771 .descr = "BTF pretty print percpu hash",
3772 .map_type = BPF_MAP_TYPE_PERCPU_HASH,
3773 .map_name = "pprint_test_percpu_hash",
3774 .ordered_map = false,
3775 .lossless_map = true,
3780 .descr = "BTF pretty print lru percpu hash",
3781 .map_type = BPF_MAP_TYPE_LRU_PERCPU_HASH,
3782 .map_name = "pprint_test_lru_percpu_hash",
3783 .ordered_map = false,
3784 .lossless_map = false,
3791 static void set_pprint_mapv(struct pprint_mapv *v, uint32_t i,
3792 int num_cpus, int rounded_value_size)
3796 for (cpu = 0; cpu < num_cpus; cpu++) {
3799 v->unused_bits2a = 3;
3801 v->unused_bits2b = 3;
3803 v->aenum = i & 0x03;
3806 v = (void *)v + rounded_value_size;
3810 static int check_line(const char *expected_line, int nexpected_line,
3811 int expected_line_len, const char *line)
3813 if (CHECK(nexpected_line == expected_line_len,
3814 "expected_line is too long"))
3817 if (strcmp(expected_line, line)) {
3818 fprintf(stderr, "unexpected pprint output\n");
3819 fprintf(stderr, "expected: %s", expected_line);
3820 fprintf(stderr, " read: %s", line);
3828 static int do_test_pprint(int test_num)
3830 const struct btf_raw_test *test = &pprint_test_template[test_num];
3831 struct bpf_create_map_attr create_attr = {};
3832 bool ordered_map, lossless_map, percpu_map;
3833 int err, ret, num_cpus, rounded_value_size;
3834 struct pprint_mapv *mapv = NULL;
3835 unsigned int key, nr_read_elems;
3836 int map_fd = -1, btf_fd = -1;
3837 unsigned int raw_btf_size;
3838 char expected_line[255];
3839 FILE *pin_file = NULL;
3841 size_t line_len = 0;
3846 fprintf(stderr, "%s(#%d)......", test->descr, test_num);
3847 raw_btf = btf_raw_create(&hdr_tmpl, test->raw_types,
3848 test->str_sec, test->str_sec_size,
3849 &raw_btf_size, NULL);
3854 *btf_log_buf = '\0';
3855 btf_fd = bpf_load_btf(raw_btf, raw_btf_size,
3856 btf_log_buf, BTF_LOG_BUF_SIZE,
3860 if (CHECK(btf_fd == -1, "errno:%d", errno)) {
3865 create_attr.name = test->map_name;
3866 create_attr.map_type = test->map_type;
3867 create_attr.key_size = test->key_size;
3868 create_attr.value_size = test->value_size;
3869 create_attr.max_entries = test->max_entries;
3870 create_attr.btf_fd = btf_fd;
3871 create_attr.btf_key_type_id = test->key_type_id;
3872 create_attr.btf_value_type_id = test->value_type_id;
3874 map_fd = bpf_create_map_xattr(&create_attr);
3875 if (CHECK(map_fd == -1, "errno:%d", errno)) {
3880 ret = snprintf(pin_path, sizeof(pin_path), "%s/%s",
3881 "/sys/fs/bpf", test->map_name);
3883 if (CHECK(ret == sizeof(pin_path), "pin_path %s/%s is too long",
3884 "/sys/fs/bpf", test->map_name)) {
3889 err = bpf_obj_pin(map_fd, pin_path);
3890 if (CHECK(err, "bpf_obj_pin(%s): errno:%d.", pin_path, errno))
3893 percpu_map = test->percpu_map;
3894 num_cpus = percpu_map ? bpf_num_possible_cpus() : 1;
3895 rounded_value_size = round_up(sizeof(struct pprint_mapv), 8);
3896 mapv = calloc(num_cpus, rounded_value_size);
3897 if (CHECK(!mapv, "mapv allocation failure")) {
3902 for (key = 0; key < test->max_entries; key++) {
3903 set_pprint_mapv(mapv, key, num_cpus, rounded_value_size);
3904 bpf_map_update_elem(map_fd, &key, mapv, 0);
3907 pin_file = fopen(pin_path, "r");
3908 if (CHECK(!pin_file, "fopen(%s): errno:%d", pin_path, errno)) {
3913 /* Skip lines start with '#' */
3914 while ((nread = getline(&line, &line_len, pin_file)) > 0 &&
3918 if (CHECK(nread <= 0, "Unexpected EOF")) {
3924 ordered_map = test->ordered_map;
3925 lossless_map = test->lossless_map;
3927 struct pprint_mapv *cmapv;
3928 ssize_t nexpected_line;
3929 unsigned int next_key;
3932 next_key = ordered_map ? nr_read_elems : atoi(line);
3933 set_pprint_mapv(mapv, next_key, num_cpus, rounded_value_size);
3936 for (cpu = 0; cpu < num_cpus; cpu++) {
3938 /* for percpu map, the format looks like:
3940 * cpu0: <value_on_cpu0>
3941 * cpu1: <value_on_cpu1>
3943 * cpun: <value_on_cpun>
3946 * let us verify the line containing the key here.
3949 nexpected_line = snprintf(expected_line,
3950 sizeof(expected_line),
3954 err = check_line(expected_line, nexpected_line,
3955 sizeof(expected_line), line);
3960 /* read value@cpu */
3961 nread = getline(&line, &line_len, pin_file);
3966 nexpected_line = snprintf(expected_line, sizeof(expected_line),
3967 "%s%u: {%u,0,%d,0x%x,0x%x,0x%x,"
3968 "{%lu|[%u,%u,%u,%u,%u,%u,%u,%u]},%s,"
3970 percpu_map ? "\tcpu" : "",
3971 percpu_map ? cpu : next_key,
3972 cmapv->ui32, cmapv->si32,
3973 cmapv->unused_bits2a,
3975 cmapv->unused_bits2b,
3977 cmapv->ui8a[0], cmapv->ui8a[1],
3978 cmapv->ui8a[2], cmapv->ui8a[3],
3979 cmapv->ui8a[4], cmapv->ui8a[5],
3980 cmapv->ui8a[6], cmapv->ui8a[7],
3981 pprint_enum_str[cmapv->aenum],
3985 err = check_line(expected_line, nexpected_line,
3986 sizeof(expected_line), line);
3990 cmapv = (void *)cmapv + rounded_value_size;
3994 /* skip the last bracket for the percpu map */
3995 nread = getline(&line, &line_len, pin_file);
4000 nread = getline(&line, &line_len, pin_file);
4001 } while (++nr_read_elems < test->max_entries && nread > 0);
4004 CHECK(nr_read_elems < test->max_entries,
4005 "Unexpected EOF. nr_read_elems:%u test->max_entries:%u",
4006 nr_read_elems, test->max_entries)) {
4011 if (CHECK(nread > 0, "Unexpected extra pprint output: %s", line)) {
4022 fprintf(stderr, "OK");
4023 if (*btf_log_buf && (err || args.always_log))
4024 fprintf(stderr, "\n%s", btf_log_buf);
4037 static int test_pprint(void)
4042 /* test various maps with the first test template */
4043 for (i = 0; i < ARRAY_SIZE(pprint_tests_meta); i++) {
4044 pprint_test_template[0].descr = pprint_tests_meta[i].descr;
4045 pprint_test_template[0].map_type = pprint_tests_meta[i].map_type;
4046 pprint_test_template[0].map_name = pprint_tests_meta[i].map_name;
4047 pprint_test_template[0].ordered_map = pprint_tests_meta[i].ordered_map;
4048 pprint_test_template[0].lossless_map = pprint_tests_meta[i].lossless_map;
4049 pprint_test_template[0].percpu_map = pprint_tests_meta[i].percpu_map;
4051 err |= count_result(do_test_pprint(0));
4054 /* test rest test templates with the first map */
4055 for (i = 1; i < ARRAY_SIZE(pprint_test_template); i++) {
4056 pprint_test_template[i].descr = pprint_tests_meta[0].descr;
4057 pprint_test_template[i].map_type = pprint_tests_meta[0].map_type;
4058 pprint_test_template[i].map_name = pprint_tests_meta[0].map_name;
4059 pprint_test_template[i].ordered_map = pprint_tests_meta[0].ordered_map;
4060 pprint_test_template[i].lossless_map = pprint_tests_meta[0].lossless_map;
4061 pprint_test_template[i].percpu_map = pprint_tests_meta[0].percpu_map;
4062 err |= count_result(do_test_pprint(i));
4068 #define BPF_LINE_INFO_ENC(insn_off, file_off, line_off, line_num, line_col) \
4069 (insn_off), (file_off), (line_off), ((line_num) << 10 | ((line_col) & 0x3ff))
4071 static struct prog_info_raw_test {
4073 const char *str_sec;
4074 const char *err_str;
4075 __u32 raw_types[MAX_NR_RAW_U32];
4077 struct bpf_insn insns[MAX_INSNS];
4079 __u32 func_info[MAX_SUBPROGS][2];
4080 __u32 func_info_rec_size;
4081 __u32 func_info_cnt;
4082 __u32 line_info[MAX_NR_RAW_U32];
4083 __u32 line_info_rec_size;
4084 __u32 nr_jited_ksyms;
4085 bool expected_prog_load_failure;
4086 } info_raw_tests[] = {
4088 .descr = "func_type (main func + one sub)",
4090 BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
4091 BTF_TYPE_INT_ENC(NAME_TBD, 0, 0, 32, 4), /* [2] */
4092 BTF_FUNC_PROTO_ENC(1, 2), /* [3] */
4093 BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
4094 BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 2),
4095 BTF_FUNC_PROTO_ENC(1, 2), /* [4] */
4096 BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 2),
4097 BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
4098 BTF_FUNC_ENC(NAME_TBD, 3), /* [5] */
4099 BTF_FUNC_ENC(NAME_TBD, 4), /* [6] */
4102 .str_sec = "\0int\0unsigned int\0a\0b\0c\0d\0funcA\0funcB",
4103 .str_sec_size = sizeof("\0int\0unsigned int\0a\0b\0c\0d\0funcA\0funcB"),
4105 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2),
4106 BPF_MOV64_IMM(BPF_REG_0, 1),
4108 BPF_MOV64_IMM(BPF_REG_0, 2),
4111 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
4112 .func_info = { {0, 5}, {3, 6} },
4113 .func_info_rec_size = 8,
4115 .line_info = { BTF_END_RAW },
4119 .descr = "func_type (Incorrect func_info_rec_size)",
4121 BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
4122 BTF_TYPE_INT_ENC(NAME_TBD, 0, 0, 32, 4), /* [2] */
4123 BTF_FUNC_PROTO_ENC(1, 2), /* [3] */
4124 BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
4125 BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 2),
4126 BTF_FUNC_PROTO_ENC(1, 2), /* [4] */
4127 BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 2),
4128 BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
4129 BTF_FUNC_ENC(NAME_TBD, 3), /* [5] */
4130 BTF_FUNC_ENC(NAME_TBD, 4), /* [6] */
4133 .str_sec = "\0int\0unsigned int\0a\0b\0c\0d\0funcA\0funcB",
4134 .str_sec_size = sizeof("\0int\0unsigned int\0a\0b\0c\0d\0funcA\0funcB"),
4136 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2),
4137 BPF_MOV64_IMM(BPF_REG_0, 1),
4139 BPF_MOV64_IMM(BPF_REG_0, 2),
4142 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
4143 .func_info = { {0, 5}, {3, 6} },
4144 .func_info_rec_size = 4,
4146 .line_info = { BTF_END_RAW },
4147 .expected_prog_load_failure = true,
4151 .descr = "func_type (Incorrect func_info_cnt)",
4153 BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
4154 BTF_TYPE_INT_ENC(NAME_TBD, 0, 0, 32, 4), /* [2] */
4155 BTF_FUNC_PROTO_ENC(1, 2), /* [3] */
4156 BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
4157 BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 2),
4158 BTF_FUNC_PROTO_ENC(1, 2), /* [4] */
4159 BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 2),
4160 BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
4161 BTF_FUNC_ENC(NAME_TBD, 3), /* [5] */
4162 BTF_FUNC_ENC(NAME_TBD, 4), /* [6] */
4165 .str_sec = "\0int\0unsigned int\0a\0b\0c\0d\0funcA\0funcB",
4166 .str_sec_size = sizeof("\0int\0unsigned int\0a\0b\0c\0d\0funcA\0funcB"),
4168 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2),
4169 BPF_MOV64_IMM(BPF_REG_0, 1),
4171 BPF_MOV64_IMM(BPF_REG_0, 2),
4174 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
4175 .func_info = { {0, 5}, {3, 6} },
4176 .func_info_rec_size = 8,
4178 .line_info = { BTF_END_RAW },
4179 .expected_prog_load_failure = true,
4183 .descr = "func_type (Incorrect bpf_func_info.insn_off)",
4185 BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
4186 BTF_TYPE_INT_ENC(NAME_TBD, 0, 0, 32, 4), /* [2] */
4187 BTF_FUNC_PROTO_ENC(1, 2), /* [3] */
4188 BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
4189 BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 2),
4190 BTF_FUNC_PROTO_ENC(1, 2), /* [4] */
4191 BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 2),
4192 BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
4193 BTF_FUNC_ENC(NAME_TBD, 3), /* [5] */
4194 BTF_FUNC_ENC(NAME_TBD, 4), /* [6] */
4197 .str_sec = "\0int\0unsigned int\0a\0b\0c\0d\0funcA\0funcB",
4198 .str_sec_size = sizeof("\0int\0unsigned int\0a\0b\0c\0d\0funcA\0funcB"),
4200 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2),
4201 BPF_MOV64_IMM(BPF_REG_0, 1),
4203 BPF_MOV64_IMM(BPF_REG_0, 2),
4206 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
4207 .func_info = { {0, 5}, {2, 6} },
4208 .func_info_rec_size = 8,
4210 .line_info = { BTF_END_RAW },
4211 .expected_prog_load_failure = true,
4215 .descr = "line_info (No subprog)",
4217 BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
4220 BTF_STR_SEC("\0int\0int a=1;\0int b=2;\0return a + b;\0return a + b;"),
4222 BPF_MOV64_IMM(BPF_REG_0, 1),
4223 BPF_MOV64_IMM(BPF_REG_1, 2),
4224 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
4227 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
4230 BPF_LINE_INFO_ENC(0, 0, NAME_TBD, 1, 10),
4231 BPF_LINE_INFO_ENC(1, 0, NAME_TBD, 2, 9),
4232 BPF_LINE_INFO_ENC(2, 0, NAME_TBD, 3, 8),
4233 BPF_LINE_INFO_ENC(3, 0, NAME_TBD, 4, 7),
4236 .line_info_rec_size = sizeof(struct bpf_line_info),
4237 .nr_jited_ksyms = 1,
4241 .descr = "line_info (No subprog. insn_off >= prog->len)",
4243 BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
4246 BTF_STR_SEC("\0int\0int a=1;\0int b=2;\0return a + b;\0return a + b;"),
4248 BPF_MOV64_IMM(BPF_REG_0, 1),
4249 BPF_MOV64_IMM(BPF_REG_1, 2),
4250 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
4253 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
4256 BPF_LINE_INFO_ENC(0, 0, NAME_TBD, 1, 10),
4257 BPF_LINE_INFO_ENC(1, 0, NAME_TBD, 2, 9),
4258 BPF_LINE_INFO_ENC(2, 0, NAME_TBD, 3, 8),
4259 BPF_LINE_INFO_ENC(3, 0, NAME_TBD, 4, 7),
4260 BPF_LINE_INFO_ENC(4, 0, 0, 5, 6),
4263 .line_info_rec_size = sizeof(struct bpf_line_info),
4264 .nr_jited_ksyms = 1,
4265 .err_str = "line_info[4].insn_off",
4266 .expected_prog_load_failure = true,
4270 .descr = "line_info (Zero bpf insn code)",
4272 BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
4273 BTF_TYPE_INT_ENC(NAME_TBD, 0, 0, 64, 8), /* [2] */
4274 BTF_TYPEDEF_ENC(NAME_TBD, 2), /* [3] */
4277 BTF_STR_SEC("\0int\0unsigned long\0u64\0u64 a=1;\0return a;"),
4279 BPF_LD_IMM64(BPF_REG_0, 1),
4282 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
4285 BPF_LINE_INFO_ENC(0, 0, NAME_TBD, 1, 10),
4286 BPF_LINE_INFO_ENC(1, 0, 0, 2, 9),
4287 BPF_LINE_INFO_ENC(2, 0, NAME_TBD, 3, 8),
4290 .line_info_rec_size = sizeof(struct bpf_line_info),
4291 .nr_jited_ksyms = 1,
4292 .err_str = "Invalid insn code at line_info[1]",
4293 .expected_prog_load_failure = true,
4297 .descr = "line_info (No subprog. zero tailing line_info",
4299 BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
4302 BTF_STR_SEC("\0int\0int a=1;\0int b=2;\0return a + b;\0return a + b;"),
4304 BPF_MOV64_IMM(BPF_REG_0, 1),
4305 BPF_MOV64_IMM(BPF_REG_1, 2),
4306 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
4309 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
4312 BPF_LINE_INFO_ENC(0, 0, NAME_TBD, 1, 10), 0,
4313 BPF_LINE_INFO_ENC(1, 0, NAME_TBD, 2, 9), 0,
4314 BPF_LINE_INFO_ENC(2, 0, NAME_TBD, 3, 8), 0,
4315 BPF_LINE_INFO_ENC(3, 0, NAME_TBD, 4, 7), 0,
4318 .line_info_rec_size = sizeof(struct bpf_line_info) + sizeof(__u32),
4319 .nr_jited_ksyms = 1,
4323 .descr = "line_info (No subprog. nonzero tailing line_info)",
4325 BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
4328 BTF_STR_SEC("\0int\0int a=1;\0int b=2;\0return a + b;\0return a + b;"),
4330 BPF_MOV64_IMM(BPF_REG_0, 1),
4331 BPF_MOV64_IMM(BPF_REG_1, 2),
4332 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
4335 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
4338 BPF_LINE_INFO_ENC(0, 0, NAME_TBD, 1, 10), 0,
4339 BPF_LINE_INFO_ENC(1, 0, NAME_TBD, 2, 9), 0,
4340 BPF_LINE_INFO_ENC(2, 0, NAME_TBD, 3, 8), 0,
4341 BPF_LINE_INFO_ENC(3, 0, NAME_TBD, 4, 7), 1,
4344 .line_info_rec_size = sizeof(struct bpf_line_info) + sizeof(__u32),
4345 .nr_jited_ksyms = 1,
4346 .err_str = "nonzero tailing record in line_info",
4347 .expected_prog_load_failure = true,
4351 .descr = "line_info (subprog)",
4353 BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
4356 BTF_STR_SEC("\0int\0int a=1+1;\0return func(a);\0b+=1;\0return b;"),
4358 BPF_MOV64_IMM(BPF_REG_2, 1),
4359 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, 1),
4360 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
4363 BPF_MOV64_REG(BPF_REG_0, BPF_REG_1),
4364 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 1),
4367 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
4370 BPF_LINE_INFO_ENC(0, 0, NAME_TBD, 1, 10),
4371 BPF_LINE_INFO_ENC(2, 0, NAME_TBD, 2, 9),
4372 BPF_LINE_INFO_ENC(5, 0, NAME_TBD, 3, 8),
4373 BPF_LINE_INFO_ENC(7, 0, NAME_TBD, 4, 7),
4376 .line_info_rec_size = sizeof(struct bpf_line_info),
4377 .nr_jited_ksyms = 2,
4381 .descr = "line_info (subprog + func_info)",
4383 BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
4384 BTF_FUNC_PROTO_ENC(1, 1), /* [2] */
4385 BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
4386 BTF_FUNC_ENC(NAME_TBD, 2), /* [3] */
4387 BTF_FUNC_ENC(NAME_TBD, 2), /* [4] */
4390 BTF_STR_SEC("\0int\0x\0sub\0main\0int a=1+1;\0return func(a);\0b+=1;\0return b;"),
4392 BPF_MOV64_IMM(BPF_REG_2, 1),
4393 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, 1),
4394 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
4397 BPF_MOV64_REG(BPF_REG_0, BPF_REG_1),
4398 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 1),
4401 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
4403 .func_info_rec_size = 8,
4404 .func_info = { {0, 4}, {5, 3} },
4406 BPF_LINE_INFO_ENC(0, 0, NAME_TBD, 1, 10),
4407 BPF_LINE_INFO_ENC(2, 0, NAME_TBD, 2, 9),
4408 BPF_LINE_INFO_ENC(5, 0, NAME_TBD, 3, 8),
4409 BPF_LINE_INFO_ENC(7, 0, NAME_TBD, 4, 7),
4412 .line_info_rec_size = sizeof(struct bpf_line_info),
4413 .nr_jited_ksyms = 2,
4417 .descr = "line_info (subprog. missing 1st func line info)",
4419 BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
4422 BTF_STR_SEC("\0int\0int a=1+1;\0return func(a);\0b+=1;\0return b;"),
4424 BPF_MOV64_IMM(BPF_REG_2, 1),
4425 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, 1),
4426 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
4429 BPF_MOV64_REG(BPF_REG_0, BPF_REG_1),
4430 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 1),
4433 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
4436 BPF_LINE_INFO_ENC(1, 0, NAME_TBD, 1, 10),
4437 BPF_LINE_INFO_ENC(2, 0, NAME_TBD, 2, 9),
4438 BPF_LINE_INFO_ENC(5, 0, NAME_TBD, 3, 8),
4439 BPF_LINE_INFO_ENC(7, 0, NAME_TBD, 4, 7),
4442 .line_info_rec_size = sizeof(struct bpf_line_info),
4443 .nr_jited_ksyms = 2,
4444 .err_str = "missing bpf_line_info for func#0",
4445 .expected_prog_load_failure = true,
4449 .descr = "line_info (subprog. missing 2nd func line info)",
4451 BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
4454 BTF_STR_SEC("\0int\0int a=1+1;\0return func(a);\0b+=1;\0return b;"),
4456 BPF_MOV64_IMM(BPF_REG_2, 1),
4457 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, 1),
4458 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
4461 BPF_MOV64_REG(BPF_REG_0, BPF_REG_1),
4462 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 1),
4465 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
4468 BPF_LINE_INFO_ENC(0, 0, NAME_TBD, 1, 10),
4469 BPF_LINE_INFO_ENC(2, 0, NAME_TBD, 2, 9),
4470 BPF_LINE_INFO_ENC(6, 0, NAME_TBD, 3, 8),
4471 BPF_LINE_INFO_ENC(7, 0, NAME_TBD, 4, 7),
4474 .line_info_rec_size = sizeof(struct bpf_line_info),
4475 .nr_jited_ksyms = 2,
4476 .err_str = "missing bpf_line_info for func#1",
4477 .expected_prog_load_failure = true,
4481 .descr = "line_info (subprog. unordered insn offset)",
4483 BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
4486 BTF_STR_SEC("\0int\0int a=1+1;\0return func(a);\0b+=1;\0return b;"),
4488 BPF_MOV64_IMM(BPF_REG_2, 1),
4489 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, 1),
4490 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
4493 BPF_MOV64_REG(BPF_REG_0, BPF_REG_1),
4494 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 1),
4497 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
4500 BPF_LINE_INFO_ENC(0, 0, NAME_TBD, 1, 10),
4501 BPF_LINE_INFO_ENC(5, 0, NAME_TBD, 2, 9),
4502 BPF_LINE_INFO_ENC(2, 0, NAME_TBD, 3, 8),
4503 BPF_LINE_INFO_ENC(7, 0, NAME_TBD, 4, 7),
4506 .line_info_rec_size = sizeof(struct bpf_line_info),
4507 .nr_jited_ksyms = 2,
4508 .err_str = "Invalid line_info[2].insn_off",
4509 .expected_prog_load_failure = true,
4514 static size_t probe_prog_length(const struct bpf_insn *fp)
4518 for (len = MAX_INSNS - 1; len > 0; --len)
4519 if (fp[len].code != 0 || fp[len].imm != 0)
4524 static __u32 *patch_name_tbd(const __u32 *raw_u32,
4525 const char *str, __u32 str_off,
4526 unsigned int str_sec_size,
4527 unsigned int *ret_size)
4529 int i, raw_u32_size = get_raw_sec_size(raw_u32);
4530 const char *end_str = str + str_sec_size;
4531 const char *next_str = str + str_off;
4532 __u32 *new_u32 = NULL;
4534 if (raw_u32_size == -1)
4535 return ERR_PTR(-EINVAL);
4537 if (!raw_u32_size) {
4542 new_u32 = malloc(raw_u32_size);
4544 return ERR_PTR(-ENOMEM);
4546 for (i = 0; i < raw_u32_size / sizeof(raw_u32[0]); i++) {
4547 if (raw_u32[i] == NAME_TBD) {
4548 next_str = get_next_str(next_str, end_str);
4549 if (CHECK(!next_str, "Error in getting next_str\n")) {
4551 return ERR_PTR(-EINVAL);
4553 new_u32[i] = next_str - str;
4554 next_str += strlen(next_str);
4556 new_u32[i] = raw_u32[i];
4560 *ret_size = raw_u32_size;
4564 static int test_get_finfo(const struct prog_info_raw_test *test,
4567 struct bpf_prog_info info = {};
4568 struct bpf_func_info *finfo;
4569 __u32 info_len, rec_size, i;
4570 void *func_info = NULL;
4573 /* get necessary lens */
4574 info_len = sizeof(struct bpf_prog_info);
4575 err = bpf_obj_get_info_by_fd(prog_fd, &info, &info_len);
4576 if (CHECK(err == -1, "invalid get info (1st) errno:%d", errno)) {
4577 fprintf(stderr, "%s\n", btf_log_buf);
4580 if (CHECK(info.nr_func_info != test->func_info_cnt,
4581 "incorrect info.nr_func_info (1st) %d",
4582 info.nr_func_info)) {
4586 rec_size = info.func_info_rec_size;
4587 if (CHECK(rec_size != sizeof(struct bpf_func_info),
4588 "incorrect info.func_info_rec_size (1st) %d", rec_size)) {
4592 if (!info.nr_func_info)
4595 func_info = malloc(info.nr_func_info * rec_size);
4596 if (CHECK(!func_info, "out of memory"))
4599 /* reset info to only retrieve func_info related data */
4600 memset(&info, 0, sizeof(info));
4601 info.nr_func_info = test->func_info_cnt;
4602 info.func_info_rec_size = rec_size;
4603 info.func_info = ptr_to_u64(func_info);
4604 err = bpf_obj_get_info_by_fd(prog_fd, &info, &info_len);
4605 if (CHECK(err == -1, "invalid get info (2nd) errno:%d", errno)) {
4606 fprintf(stderr, "%s\n", btf_log_buf);
4610 if (CHECK(info.nr_func_info != test->func_info_cnt,
4611 "incorrect info.nr_func_info (2nd) %d",
4612 info.nr_func_info)) {
4616 if (CHECK(info.func_info_rec_size != rec_size,
4617 "incorrect info.func_info_rec_size (2nd) %d",
4618 info.func_info_rec_size)) {
4624 for (i = 0; i < test->func_info_cnt; i++) {
4625 if (CHECK(finfo->type_id != test->func_info[i][1],
4626 "incorrect func_type %u expected %u",
4627 finfo->type_id, test->func_info[i][1])) {
4631 finfo = (void *)finfo + rec_size;
4641 static int test_get_linfo(const struct prog_info_raw_test *test,
4642 const void *patched_linfo,
4643 __u32 cnt, int prog_fd)
4645 __u32 i, info_len, nr_jited_ksyms, nr_jited_func_lens;
4646 __u64 *jited_linfo = NULL, *jited_ksyms = NULL;
4647 __u32 rec_size, jited_rec_size, jited_cnt;
4648 struct bpf_line_info *linfo = NULL;
4649 __u32 cur_func_len, ksyms_found;
4650 struct bpf_prog_info info = {};
4651 __u32 *jited_func_lens = NULL;
4652 __u64 cur_func_ksyms;
4656 rec_size = sizeof(*linfo);
4657 jited_rec_size = sizeof(*jited_linfo);
4658 if (test->nr_jited_ksyms)
4659 nr_jited_ksyms = test->nr_jited_ksyms;
4661 nr_jited_ksyms = test->func_info_cnt;
4662 nr_jited_func_lens = nr_jited_ksyms;
4664 info_len = sizeof(struct bpf_prog_info);
4665 err = bpf_obj_get_info_by_fd(prog_fd, &info, &info_len);
4666 if (CHECK(err == -1, "err:%d errno:%d", err, errno)) {
4671 if (!info.jited_prog_len) {
4672 /* prog is not jited */
4675 nr_jited_func_lens = 1;
4678 if (CHECK(info.nr_line_info != cnt ||
4679 info.nr_jited_line_info != jited_cnt ||
4680 info.nr_jited_ksyms != nr_jited_ksyms ||
4681 info.nr_jited_func_lens != nr_jited_func_lens ||
4682 (!info.nr_line_info && info.nr_jited_line_info),
4683 "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)",
4684 info.nr_line_info, cnt,
4685 info.nr_jited_line_info, jited_cnt,
4686 info.nr_jited_ksyms, nr_jited_ksyms,
4687 info.nr_jited_func_lens, nr_jited_func_lens)) {
4692 if (CHECK(info.line_info_rec_size != sizeof(struct bpf_line_info) ||
4693 info.jited_line_info_rec_size != sizeof(__u64),
4694 "info: line_info_rec_size:%u(userspace expected:%u) jited_line_info_rec_size:%u(userspace expected:%u)",
4695 info.line_info_rec_size, rec_size,
4696 info.jited_line_info_rec_size, jited_rec_size)) {
4704 rec_size = info.line_info_rec_size;
4705 jited_rec_size = info.jited_line_info_rec_size;
4707 memset(&info, 0, sizeof(info));
4709 linfo = calloc(cnt, rec_size);
4710 if (CHECK(!linfo, "!linfo")) {
4714 info.nr_line_info = cnt;
4715 info.line_info_rec_size = rec_size;
4716 info.line_info = ptr_to_u64(linfo);
4719 jited_linfo = calloc(jited_cnt, jited_rec_size);
4720 jited_ksyms = calloc(nr_jited_ksyms, sizeof(*jited_ksyms));
4721 jited_func_lens = calloc(nr_jited_func_lens,
4722 sizeof(*jited_func_lens));
4723 if (CHECK(!jited_linfo || !jited_ksyms || !jited_func_lens,
4724 "jited_linfo:%p jited_ksyms:%p jited_func_lens:%p",
4725 jited_linfo, jited_ksyms, jited_func_lens)) {
4730 info.nr_jited_line_info = jited_cnt;
4731 info.jited_line_info_rec_size = jited_rec_size;
4732 info.jited_line_info = ptr_to_u64(jited_linfo);
4733 info.nr_jited_ksyms = nr_jited_ksyms;
4734 info.jited_ksyms = ptr_to_u64(jited_ksyms);
4735 info.nr_jited_func_lens = nr_jited_func_lens;
4736 info.jited_func_lens = ptr_to_u64(jited_func_lens);
4739 err = bpf_obj_get_info_by_fd(prog_fd, &info, &info_len);
4742 * Only recheck the info.*line_info* fields.
4743 * Other fields are not the concern of this test.
4745 if (CHECK(err == -1 ||
4746 info.nr_line_info != cnt ||
4747 (jited_cnt && !info.jited_line_info) ||
4748 info.nr_jited_line_info != jited_cnt ||
4749 info.line_info_rec_size != rec_size ||
4750 info.jited_line_info_rec_size != jited_rec_size,
4751 "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",
4753 info.nr_line_info, cnt,
4754 info.nr_jited_line_info, jited_cnt,
4755 info.line_info_rec_size, rec_size,
4756 info.jited_line_info_rec_size, jited_rec_size,
4757 (void *)(long)info.line_info,
4758 (void *)(long)info.jited_line_info)) {
4763 CHECK(linfo[0].insn_off, "linfo[0].insn_off:%u",
4765 for (i = 1; i < cnt; i++) {
4766 const struct bpf_line_info *expected_linfo;
4768 expected_linfo = patched_linfo + (i * test->line_info_rec_size);
4769 if (CHECK(linfo[i].insn_off <= linfo[i - 1].insn_off,
4770 "linfo[%u].insn_off:%u <= linfo[%u].insn_off:%u",
4771 i, linfo[i].insn_off,
4772 i - 1, linfo[i - 1].insn_off)) {
4776 if (CHECK(linfo[i].file_name_off != expected_linfo->file_name_off ||
4777 linfo[i].line_off != expected_linfo->line_off ||
4778 linfo[i].line_col != expected_linfo->line_col,
4779 "linfo[%u] (%u, %u, %u) != (%u, %u, %u)", i,
4780 linfo[i].file_name_off,
4783 expected_linfo->file_name_off,
4784 expected_linfo->line_off,
4785 expected_linfo->line_col)) {
4792 fprintf(stderr, "not jited. skipping jited_line_info check. ");
4797 if (CHECK(jited_linfo[0] != jited_ksyms[0],
4798 "jited_linfo[0]:%lx != jited_ksyms[0]:%lx",
4799 (long)(jited_linfo[0]), (long)(jited_ksyms[0]))) {
4805 cur_func_len = jited_func_lens[0];
4806 cur_func_ksyms = jited_ksyms[0];
4807 for (i = 1; i < jited_cnt; i++) {
4808 if (ksyms_found < nr_jited_ksyms &&
4809 jited_linfo[i] == jited_ksyms[ksyms_found]) {
4810 cur_func_ksyms = jited_ksyms[ksyms_found];
4811 cur_func_len = jited_ksyms[ksyms_found];
4816 if (CHECK(jited_linfo[i] <= jited_linfo[i - 1],
4817 "jited_linfo[%u]:%lx <= jited_linfo[%u]:%lx",
4818 i, (long)jited_linfo[i],
4819 i - 1, (long)(jited_linfo[i - 1]))) {
4824 if (CHECK(jited_linfo[i] - cur_func_ksyms > cur_func_len,
4825 "jited_linfo[%u]:%lx - %lx > %u",
4826 i, (long)jited_linfo[i], (long)cur_func_ksyms,
4833 if (CHECK(ksyms_found != nr_jited_ksyms,
4834 "ksyms_found:%u != nr_jited_ksyms:%u",
4835 ksyms_found, nr_jited_ksyms)) {
4846 free(jited_func_lens);
4850 static int do_test_info_raw(unsigned int test_num)
4852 const struct prog_info_raw_test *test = &info_raw_tests[test_num - 1];
4853 unsigned int raw_btf_size, linfo_str_off, linfo_size;
4854 int btf_fd = -1, prog_fd = -1, err = 0;
4855 void *raw_btf, *patched_linfo = NULL;
4856 const char *ret_next_str;
4857 union bpf_attr attr = {};
4859 fprintf(stderr, "BTF prog info raw test[%u] (%s): ", test_num, test->descr);
4860 raw_btf = btf_raw_create(&hdr_tmpl, test->raw_types,
4861 test->str_sec, test->str_sec_size,
4862 &raw_btf_size, &ret_next_str);
4867 *btf_log_buf = '\0';
4868 btf_fd = bpf_load_btf(raw_btf, raw_btf_size,
4869 btf_log_buf, BTF_LOG_BUF_SIZE,
4873 if (CHECK(btf_fd == -1, "invalid btf_fd errno:%d", errno)) {
4878 if (*btf_log_buf && args.always_log)
4879 fprintf(stderr, "\n%s", btf_log_buf);
4880 *btf_log_buf = '\0';
4882 linfo_str_off = ret_next_str - test->str_sec;
4883 patched_linfo = patch_name_tbd(test->line_info,
4884 test->str_sec, linfo_str_off,
4885 test->str_sec_size, &linfo_size);
4886 if (IS_ERR(patched_linfo)) {
4887 fprintf(stderr, "error in creating raw bpf_line_info");
4892 attr.prog_type = test->prog_type;
4893 attr.insns = ptr_to_u64(test->insns);
4894 attr.insn_cnt = probe_prog_length(test->insns);
4895 attr.license = ptr_to_u64("GPL");
4896 attr.prog_btf_fd = btf_fd;
4897 attr.func_info_rec_size = test->func_info_rec_size;
4898 attr.func_info_cnt = test->func_info_cnt;
4899 attr.func_info = ptr_to_u64(test->func_info);
4900 attr.log_buf = ptr_to_u64(btf_log_buf);
4901 attr.log_size = BTF_LOG_BUF_SIZE;
4904 attr.line_info_rec_size = test->line_info_rec_size;
4905 attr.line_info = ptr_to_u64(patched_linfo);
4906 attr.line_info_cnt = linfo_size / attr.line_info_rec_size;
4909 prog_fd = syscall(__NR_bpf, BPF_PROG_LOAD, &attr, sizeof(attr));
4910 err = ((prog_fd == -1) != test->expected_prog_load_failure);
4911 if (CHECK(err, "prog_fd:%d expected_prog_load_failure:%u errno:%d",
4912 prog_fd, test->expected_prog_load_failure, errno) ||
4913 CHECK(test->err_str && !strstr(btf_log_buf, test->err_str),
4914 "expected err_str:%s", test->err_str)) {
4922 err = test_get_finfo(test, prog_fd);
4926 err = test_get_linfo(test, patched_linfo, attr.line_info_cnt, prog_fd);
4932 fprintf(stderr, "OK");
4934 if (*btf_log_buf && (err || args.always_log))
4935 fprintf(stderr, "\n%s", btf_log_buf);
4942 if (!IS_ERR(patched_linfo))
4943 free(patched_linfo);
4948 static int test_info_raw(void)
4953 if (args.info_raw_test_num)
4954 return count_result(do_test_info_raw(args.info_raw_test_num));
4956 for (i = 1; i <= ARRAY_SIZE(info_raw_tests); i++)
4957 err |= count_result(do_test_info_raw(i));
4962 static void usage(const char *cmd)
4964 fprintf(stderr, "Usage: %s [-l] [[-r btf_raw_test_num (1 - %zu)] |\n"
4965 "\t[-g btf_get_info_test_num (1 - %zu)] |\n"
4966 "\t[-f btf_file_test_num (1 - %zu)] |\n"
4967 "\t[-k btf_prog_info_raw_test_num (1 - %zu)] |\n"
4968 "\t[-p (pretty print test)]]\n",
4969 cmd, ARRAY_SIZE(raw_tests), ARRAY_SIZE(get_info_tests),
4970 ARRAY_SIZE(file_tests), ARRAY_SIZE(info_raw_tests));
4973 static int parse_args(int argc, char **argv)
4975 const char *optstr = "lpk:f:r:g:";
4978 while ((opt = getopt(argc, argv, optstr)) != -1) {
4981 args.always_log = true;
4984 args.file_test_num = atoi(optarg);
4985 args.file_test = true;
4988 args.raw_test_num = atoi(optarg);
4989 args.raw_test = true;
4992 args.get_info_test_num = atoi(optarg);
4993 args.get_info_test = true;
4996 args.pprint_test = true;
4999 args.info_raw_test_num = atoi(optarg);
5000 args.info_raw_test = true;
5011 if (args.raw_test_num &&
5012 (args.raw_test_num < 1 ||
5013 args.raw_test_num > ARRAY_SIZE(raw_tests))) {
5014 fprintf(stderr, "BTF raw test number must be [1 - %zu]\n",
5015 ARRAY_SIZE(raw_tests));
5019 if (args.file_test_num &&
5020 (args.file_test_num < 1 ||
5021 args.file_test_num > ARRAY_SIZE(file_tests))) {
5022 fprintf(stderr, "BTF file test number must be [1 - %zu]\n",
5023 ARRAY_SIZE(file_tests));
5027 if (args.get_info_test_num &&
5028 (args.get_info_test_num < 1 ||
5029 args.get_info_test_num > ARRAY_SIZE(get_info_tests))) {
5030 fprintf(stderr, "BTF get info test number must be [1 - %zu]\n",
5031 ARRAY_SIZE(get_info_tests));
5035 if (args.info_raw_test_num &&
5036 (args.info_raw_test_num < 1 ||
5037 args.info_raw_test_num > ARRAY_SIZE(info_raw_tests))) {
5038 fprintf(stderr, "BTF prog info raw test number must be [1 - %zu]\n",
5039 ARRAY_SIZE(info_raw_tests));
5046 static void print_summary(void)
5048 fprintf(stderr, "PASS:%u SKIP:%u FAIL:%u\n",
5049 pass_cnt - skip_cnt, skip_cnt, error_cnt);
5052 int main(int argc, char **argv)
5056 err = parse_args(argc, argv);
5060 if (args.always_log)
5061 libbpf_set_print(__base_pr, __base_pr, __base_pr);
5066 if (args.get_info_test)
5067 err |= test_get_info();
5072 if (args.pprint_test)
5073 err |= test_pprint();
5075 if (args.info_raw_test)
5076 err |= test_info_raw();
5078 if (args.raw_test || args.get_info_test || args.file_test ||
5079 args.pprint_test || args.info_raw_test)
5083 err |= test_get_info();
5085 err |= test_info_raw();