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, root, vlen) \
69 ((!!(root) << 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)
90 #define BTF_TYPEDEF_ENC(name, type) \
91 BTF_TYPE_ENC(name, BTF_INFO_ENC(BTF_KIND_TYPEDEF, 0, 0), type)
93 #define BTF_PTR_ENC(type) \
94 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_PTR, 0, 0), type)
96 #define BTF_CONST_ENC(type) \
97 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_CONST, 0, 0), type)
99 #define BTF_FUNC_PROTO_ENC(ret_type, nargs) \
100 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_FUNC_PROTO, 0, nargs), ret_type)
102 #define BTF_FUNC_PROTO_ARG_ENC(name, type) \
105 #define BTF_FUNC_ENC(name, func_proto) \
106 BTF_TYPE_ENC(name, BTF_INFO_ENC(BTF_KIND_FUNC, 0, 0), func_proto)
108 #define BTF_END_RAW 0xdeadbeef
109 #define NAME_TBD 0xdeadb33f
111 #define MAX_NR_RAW_U32 1024
112 #define BTF_LOG_BUF_SIZE 65535
115 unsigned int raw_test_num;
116 unsigned int file_test_num;
117 unsigned int get_info_test_num;
118 unsigned int info_raw_test_num;
127 static char btf_log_buf[BTF_LOG_BUF_SIZE];
129 static struct btf_header hdr_tmpl = {
131 .version = BTF_VERSION,
132 .hdr_len = sizeof(struct btf_header),
135 struct btf_raw_test {
138 const char *map_name;
140 __u32 raw_types[MAX_NR_RAW_U32];
142 enum bpf_map_type map_type;
159 #define BTF_STR_SEC(str) \
160 .str_sec = str, .str_sec_size = sizeof(str)
162 static struct btf_raw_test raw_tests[] = {
169 * unsigned long long m;
179 .descr = "struct test #1",
182 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
183 /* unsigned long long */
184 BTF_TYPE_INT_ENC(0, 0, 0, 64, 8), /* [2] */
186 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 8, 1), /* [3] */
188 BTF_TYPE_ARRAY_ENC(1, 1, 8), /* [4] */
189 /* struct A { */ /* [5] */
190 BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 6), 180),
191 BTF_MEMBER_ENC(NAME_TBD, 2, 0), /* unsigned long long m;*/
192 BTF_MEMBER_ENC(NAME_TBD, 1, 64),/* int n; */
193 BTF_MEMBER_ENC(NAME_TBD, 3, 96),/* char o; */
194 BTF_MEMBER_ENC(NAME_TBD, 4, 128),/* int p[8] */
195 BTF_MEMBER_ENC(NAME_TBD, 6, 384),/* int q[4][8] */
196 BTF_MEMBER_ENC(NAME_TBD, 7, 1408), /* enum E r */
199 BTF_TYPE_ARRAY_ENC(4, 1, 4), /* [6] */
200 /* enum E */ /* [7] */
201 BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_ENUM, 0, 2), sizeof(int)),
202 BTF_ENUM_ENC(NAME_TBD, 0),
203 BTF_ENUM_ENC(NAME_TBD, 1),
206 .str_sec = "\0A\0m\0n\0o\0p\0q\0r\0E\0E0\0E1",
207 .str_sec_size = sizeof("\0A\0m\0n\0o\0p\0q\0r\0E\0E0\0E1"),
208 .map_type = BPF_MAP_TYPE_ARRAY,
209 .map_name = "struct_test1_map",
210 .key_size = sizeof(int),
217 /* typedef struct b Struct_B;
222 * const Struct_B o[4];
231 .descr = "struct test #2",
234 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
235 /* struct b [4] */ /* [2] */
236 BTF_TYPE_ARRAY_ENC(4, 1, 4),
238 /* struct A { */ /* [3] */
239 BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 3), 68),
240 BTF_MEMBER_ENC(NAME_TBD, 1, 0), /* int m; */
241 BTF_MEMBER_ENC(NAME_TBD, 2, 32),/* struct B n[4] */
242 BTF_MEMBER_ENC(NAME_TBD, 8, 288),/* const Struct_B o[4];*/
245 /* struct B { */ /* [4] */
246 BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 2), 8),
247 BTF_MEMBER_ENC(NAME_TBD, 1, 0), /* int m; */
248 BTF_MEMBER_ENC(NAME_TBD, 1, 32),/* int n; */
251 /* const int */ /* [5] */
252 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_CONST, 0, 0), 1),
253 /* typedef struct b Struct_B */ /* [6] */
254 BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_TYPEDEF, 0, 0), 4),
255 /* const Struct_B */ /* [7] */
256 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_CONST, 0, 0), 6),
257 /* const Struct_B [4] */ /* [8] */
258 BTF_TYPE_ARRAY_ENC(7, 1, 4),
261 .str_sec = "\0A\0m\0n\0o\0B\0m\0n\0Struct_B",
262 .str_sec_size = sizeof("\0A\0m\0n\0o\0B\0m\0n\0Struct_B"),
263 .map_type = BPF_MAP_TYPE_ARRAY,
264 .map_name = "struct_test2_map",
265 .key_size = sizeof(int),
273 .descr = "struct test #3 Invalid member offset",
276 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
277 /* int64 */ /* [2] */
278 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 64, 8),
280 /* struct A { */ /* [3] */
281 BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 2), 16),
282 BTF_MEMBER_ENC(NAME_TBD, 1, 64), /* int m; */
283 BTF_MEMBER_ENC(NAME_TBD, 2, 0), /* int64 n; */
287 .str_sec = "\0A\0m\0n\0",
288 .str_sec_size = sizeof("\0A\0m\0n\0"),
289 .map_type = BPF_MAP_TYPE_ARRAY,
290 .map_name = "struct_test3_map",
291 .key_size = sizeof(int),
296 .btf_load_err = true,
297 .err_str = "Invalid member bits_offset",
300 /* Test member exceeds the size of struct.
308 .descr = "size check test #1",
311 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
312 /* struct A { */ /* [2] */
313 BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 2), sizeof(int) * 2 - 1),
314 BTF_MEMBER_ENC(NAME_TBD, 1, 0), /* int m; */
315 BTF_MEMBER_ENC(NAME_TBD, 1, 32),/* int n; */
319 .str_sec = "\0A\0m\0n",
320 .str_sec_size = sizeof("\0A\0m\0n"),
321 .map_type = BPF_MAP_TYPE_ARRAY,
322 .map_name = "size_check1_map",
323 .key_size = sizeof(int),
328 .btf_load_err = true,
329 .err_str = "Member exceeds struct_size",
332 /* Test member exeeds the size of struct
340 .descr = "size check test #2",
343 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, sizeof(int)),
344 /* int[2] */ /* [2] */
345 BTF_TYPE_ARRAY_ENC(1, 1, 2),
346 /* struct A { */ /* [3] */
347 BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 2), sizeof(int) * 3 - 1),
348 BTF_MEMBER_ENC(NAME_TBD, 1, 0), /* int m; */
349 BTF_MEMBER_ENC(NAME_TBD, 2, 32),/* int n[2]; */
353 .str_sec = "\0A\0m\0n",
354 .str_sec_size = sizeof("\0A\0m\0n"),
355 .map_type = BPF_MAP_TYPE_ARRAY,
356 .map_name = "size_check2_map",
357 .key_size = sizeof(int),
362 .btf_load_err = true,
363 .err_str = "Member exceeds struct_size",
366 /* Test member exeeds the size of struct
374 .descr = "size check test #3",
377 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, sizeof(int)),
378 /* void* */ /* [2] */
379 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_PTR, 0, 0), 0),
380 /* struct A { */ /* [3] */
381 BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 2), sizeof(int) + sizeof(void *) - 1),
382 BTF_MEMBER_ENC(NAME_TBD, 1, 0), /* int m; */
383 BTF_MEMBER_ENC(NAME_TBD, 2, 32),/* void *n; */
387 .str_sec = "\0A\0m\0n",
388 .str_sec_size = sizeof("\0A\0m\0n"),
389 .map_type = BPF_MAP_TYPE_ARRAY,
390 .map_name = "size_check3_map",
391 .key_size = sizeof(int),
396 .btf_load_err = true,
397 .err_str = "Member exceeds struct_size",
400 /* Test member exceeds the size of struct
413 .descr = "size check test #4",
416 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, sizeof(int)),
417 /* enum E { */ /* [2] */
418 BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_ENUM, 0, 2), sizeof(int)),
419 BTF_ENUM_ENC(NAME_TBD, 0),
420 BTF_ENUM_ENC(NAME_TBD, 1),
422 /* struct A { */ /* [3] */
423 BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 2), sizeof(int) * 2 - 1),
424 BTF_MEMBER_ENC(NAME_TBD, 1, 0), /* int m; */
425 BTF_MEMBER_ENC(NAME_TBD, 2, 32),/* enum E n; */
429 .str_sec = "\0E\0E0\0E1\0A\0m\0n",
430 .str_sec_size = sizeof("\0E\0E0\0E1\0A\0m\0n"),
431 .map_type = BPF_MAP_TYPE_ARRAY,
432 .map_name = "size_check4_map",
433 .key_size = sizeof(int),
438 .btf_load_err = true,
439 .err_str = "Member exceeds struct_size",
442 /* typedef const void * const_void_ptr;
448 .descr = "void test #1",
451 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
452 /* const void */ /* [2] */
453 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_CONST, 0, 0), 0),
454 /* const void* */ /* [3] */
455 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_PTR, 0, 0), 2),
456 /* typedef const void * const_void_ptr */
457 BTF_TYPEDEF_ENC(NAME_TBD, 3), /* [4] */
458 /* struct A { */ /* [5] */
459 BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 1), sizeof(void *)),
460 /* const_void_ptr m; */
461 BTF_MEMBER_ENC(NAME_TBD, 4, 0),
465 .str_sec = "\0const_void_ptr\0A\0m",
466 .str_sec_size = sizeof("\0const_void_ptr\0A\0m"),
467 .map_type = BPF_MAP_TYPE_ARRAY,
468 .map_name = "void_test1_map",
469 .key_size = sizeof(int),
470 .value_size = sizeof(void *),
481 .descr = "void test #2",
484 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
485 /* const void */ /* [2] */
486 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_CONST, 0, 0), 0),
487 /* struct A { */ /* [3] */
488 BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 1), 8),
490 BTF_MEMBER_ENC(NAME_TBD, 2, 0),
495 .str_sec_size = sizeof("\0A\0m"),
496 .map_type = BPF_MAP_TYPE_ARRAY,
497 .map_name = "void_test2_map",
498 .key_size = sizeof(int),
499 .value_size = sizeof(void *),
503 .btf_load_err = true,
504 .err_str = "Invalid member",
507 /* typedef const void * const_void_ptr;
511 .descr = "void test #3",
514 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
515 /* const void */ /* [2] */
516 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_CONST, 0, 0), 0),
517 /* const void* */ /* [3] */
518 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_PTR, 0, 0), 2),
519 /* typedef const void * const_void_ptr */
520 BTF_TYPEDEF_ENC(NAME_TBD, 3), /* [4] */
521 /* const_void_ptr[4] */
522 BTF_TYPE_ARRAY_ENC(4, 1, 4), /* [5] */
525 .str_sec = "\0const_void_ptr",
526 .str_sec_size = sizeof("\0const_void_ptr"),
527 .map_type = BPF_MAP_TYPE_ARRAY,
528 .map_name = "void_test3_map",
529 .key_size = sizeof(int),
530 .value_size = sizeof(void *) * 4,
538 .descr = "void test #4",
541 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
542 /* const void */ /* [2] */
543 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_CONST, 0, 0), 0),
544 /* const void[4] */ /* [3] */
545 BTF_TYPE_ARRAY_ENC(2, 1, 4),
549 .str_sec_size = sizeof("\0A\0m"),
550 .map_type = BPF_MAP_TYPE_ARRAY,
551 .map_name = "void_test4_map",
552 .key_size = sizeof(int),
553 .value_size = sizeof(void *) * 4,
557 .btf_load_err = true,
558 .err_str = "Invalid elem",
561 /* Array_A <------------------+
562 * elem_type == Array_B |
565 * Array_B <-------- + |
566 * elem_type == Array A --+
569 .descr = "loop test #1",
572 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
573 /* Array_A */ /* [2] */
574 BTF_TYPE_ARRAY_ENC(3, 1, 8),
575 /* Array_B */ /* [3] */
576 BTF_TYPE_ARRAY_ENC(2, 1, 8),
580 .str_sec_size = sizeof(""),
581 .map_type = BPF_MAP_TYPE_ARRAY,
582 .map_name = "loop_test1_map",
583 .key_size = sizeof(int),
584 .value_size = sizeof(sizeof(int) * 8),
588 .btf_load_err = true,
589 .err_str = "Loop detected",
592 /* typedef is _before_ the BTF type of Array_A and Array_B
594 * typedef Array_B int_array;
596 * Array_A <------------------+
597 * elem_type == int_array |
600 * Array_B <-------- + |
601 * elem_type == Array_A --+
604 .descr = "loop test #2",
607 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
608 /* typedef Array_B int_array */
609 BTF_TYPEDEF_ENC(1, 4), /* [2] */
611 BTF_TYPE_ARRAY_ENC(2, 1, 8), /* [3] */
613 BTF_TYPE_ARRAY_ENC(3, 1, 8), /* [4] */
616 .str_sec = "\0int_array\0",
617 .str_sec_size = sizeof("\0int_array"),
618 .map_type = BPF_MAP_TYPE_ARRAY,
619 .map_name = "loop_test2_map",
620 .key_size = sizeof(int),
621 .value_size = sizeof(sizeof(int) * 8),
625 .btf_load_err = true,
626 .err_str = "Loop detected",
629 /* Array_A <------------------+
630 * elem_type == Array_B |
633 * Array_B <-------- + |
634 * elem_type == Array_A --+
637 .descr = "loop test #3",
640 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
641 /* Array_A */ /* [2] */
642 BTF_TYPE_ARRAY_ENC(3, 1, 8),
643 /* Array_B */ /* [3] */
644 BTF_TYPE_ARRAY_ENC(2, 1, 8),
648 .str_sec_size = sizeof(""),
649 .map_type = BPF_MAP_TYPE_ARRAY,
650 .map_name = "loop_test3_map",
651 .key_size = sizeof(int),
652 .value_size = sizeof(sizeof(int) * 8),
656 .btf_load_err = true,
657 .err_str = "Loop detected",
660 /* typedef is _between_ the BTF type of Array_A and Array_B
662 * typedef Array_B int_array;
664 * Array_A <------------------+
665 * elem_type == int_array |
668 * Array_B <-------- + |
669 * elem_type == Array_A --+
672 .descr = "loop test #4",
675 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
676 /* Array_A */ /* [2] */
677 BTF_TYPE_ARRAY_ENC(3, 1, 8),
678 /* typedef Array_B int_array */ /* [3] */
679 BTF_TYPEDEF_ENC(NAME_TBD, 4),
680 /* Array_B */ /* [4] */
681 BTF_TYPE_ARRAY_ENC(2, 1, 8),
684 .str_sec = "\0int_array\0",
685 .str_sec_size = sizeof("\0int_array"),
686 .map_type = BPF_MAP_TYPE_ARRAY,
687 .map_name = "loop_test4_map",
688 .key_size = sizeof(int),
689 .value_size = sizeof(sizeof(int) * 8),
693 .btf_load_err = true,
694 .err_str = "Loop detected",
697 /* typedef struct B Struct_B
710 .descr = "loop test #5",
713 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
714 /* struct A */ /* [2] */
715 BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 2), 8),
716 BTF_MEMBER_ENC(NAME_TBD, 1, 0), /* int x; */
717 BTF_MEMBER_ENC(NAME_TBD, 3, 32),/* Struct_B y; */
718 /* typedef struct B Struct_B */
719 BTF_TYPEDEF_ENC(NAME_TBD, 4), /* [3] */
720 /* struct B */ /* [4] */
721 BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 2), 8),
722 BTF_MEMBER_ENC(NAME_TBD, 1, 0), /* int x; */
723 BTF_MEMBER_ENC(NAME_TBD, 2, 32),/* struct A y; */
726 .str_sec = "\0A\0x\0y\0Struct_B\0B\0x\0y",
727 .str_sec_size = sizeof("\0A\0x\0y\0Struct_B\0B\0x\0y"),
728 .map_type = BPF_MAP_TYPE_ARRAY,
729 .map_name = "loop_test5_map",
730 .key_size = sizeof(int),
735 .btf_load_err = true,
736 .err_str = "Loop detected",
741 * struct A array_a[4];
745 .descr = "loop test #6",
748 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
749 BTF_TYPE_ARRAY_ENC(3, 1, 4), /* [2] */
750 /* struct A */ /* [3] */
751 BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 2), 8),
752 BTF_MEMBER_ENC(NAME_TBD, 1, 0), /* int x; */
753 BTF_MEMBER_ENC(NAME_TBD, 2, 32),/* struct A array_a[4]; */
756 .str_sec = "\0A\0x\0y",
757 .str_sec_size = sizeof("\0A\0x\0y"),
758 .map_type = BPF_MAP_TYPE_ARRAY,
759 .map_name = "loop_test6_map",
760 .key_size = sizeof(int),
765 .btf_load_err = true,
766 .err_str = "Loop detected",
770 .descr = "loop test #7",
773 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
774 /* struct A { */ /* [2] */
775 BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 1), sizeof(void *)),
777 BTF_MEMBER_ENC(NAME_TBD, 3, 0),
778 /* CONST type_id=3 */ /* [3] */
779 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_CONST, 0, 0), 4),
780 /* PTR type_id=2 */ /* [4] */
781 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_PTR, 0, 0), 3),
785 .str_sec_size = sizeof("\0A\0m"),
786 .map_type = BPF_MAP_TYPE_ARRAY,
787 .map_name = "loop_test7_map",
788 .key_size = sizeof(int),
789 .value_size = sizeof(void *),
793 .btf_load_err = true,
794 .err_str = "Loop detected",
798 .descr = "loop test #8",
801 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
802 /* struct A { */ /* [2] */
803 BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 1), sizeof(void *)),
805 BTF_MEMBER_ENC(NAME_TBD, 4, 0),
806 /* struct B { */ /* [3] */
807 BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 1), sizeof(void *)),
809 BTF_MEMBER_ENC(NAME_TBD, 6, 0),
810 /* CONST type_id=5 */ /* [4] */
811 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_CONST, 0, 0), 5),
812 /* PTR type_id=6 */ /* [5] */
813 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_PTR, 0, 0), 6),
814 /* CONST type_id=7 */ /* [6] */
815 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_CONST, 0, 0), 7),
816 /* PTR type_id=4 */ /* [7] */
817 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_PTR, 0, 0), 4),
820 .str_sec = "\0A\0m\0B\0n",
821 .str_sec_size = sizeof("\0A\0m\0B\0n"),
822 .map_type = BPF_MAP_TYPE_ARRAY,
823 .map_name = "loop_test8_map",
824 .key_size = sizeof(int),
825 .value_size = sizeof(void *),
829 .btf_load_err = true,
830 .err_str = "Loop detected",
834 .descr = "string section does not end with null",
837 BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),
841 .str_sec_size = sizeof("\0int") - 1,
842 .map_type = BPF_MAP_TYPE_ARRAY,
843 .map_name = "hdr_test_map",
844 .key_size = sizeof(int),
845 .value_size = sizeof(int),
849 .btf_load_err = true,
850 .err_str = "Invalid string section",
854 .descr = "empty string section",
857 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
862 .map_type = BPF_MAP_TYPE_ARRAY,
863 .map_name = "hdr_test_map",
864 .key_size = sizeof(int),
865 .value_size = sizeof(int),
869 .btf_load_err = true,
870 .err_str = "Invalid string section",
874 .descr = "empty type section",
879 .str_sec_size = sizeof("\0int"),
880 .map_type = BPF_MAP_TYPE_ARRAY,
881 .map_name = "hdr_test_map",
882 .key_size = sizeof(int),
883 .value_size = sizeof(int),
887 .btf_load_err = true,
888 .err_str = "No type found",
892 .descr = "btf_header test. Longer hdr_len",
895 BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),
899 .str_sec_size = sizeof("\0int"),
900 .map_type = BPF_MAP_TYPE_ARRAY,
901 .map_name = "hdr_test_map",
902 .key_size = sizeof(int),
903 .value_size = sizeof(int),
907 .btf_load_err = true,
909 .err_str = "Unsupported btf_header",
913 .descr = "btf_header test. Gap between hdr and type",
916 BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),
920 .str_sec_size = sizeof("\0int"),
921 .map_type = BPF_MAP_TYPE_ARRAY,
922 .map_name = "hdr_test_map",
923 .key_size = sizeof(int),
924 .value_size = sizeof(int),
928 .btf_load_err = true,
930 .err_str = "Unsupported section found",
934 .descr = "btf_header test. Gap between type and str",
937 BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),
941 .str_sec_size = sizeof("\0int"),
942 .map_type = BPF_MAP_TYPE_ARRAY,
943 .map_name = "hdr_test_map",
944 .key_size = sizeof(int),
945 .value_size = sizeof(int),
949 .btf_load_err = true,
951 .err_str = "Unsupported section found",
955 .descr = "btf_header test. Overlap between type and str",
958 BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),
962 .str_sec_size = sizeof("\0int"),
963 .map_type = BPF_MAP_TYPE_ARRAY,
964 .map_name = "hdr_test_map",
965 .key_size = sizeof(int),
966 .value_size = sizeof(int),
970 .btf_load_err = true,
972 .err_str = "Section overlap found",
976 .descr = "btf_header test. Larger BTF size",
979 BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),
983 .str_sec_size = sizeof("\0int"),
984 .map_type = BPF_MAP_TYPE_ARRAY,
985 .map_name = "hdr_test_map",
986 .key_size = sizeof(int),
987 .value_size = sizeof(int),
991 .btf_load_err = true,
993 .err_str = "Unsupported section found",
997 .descr = "btf_header test. Smaller BTF size",
1000 BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),
1004 .str_sec_size = sizeof("\0int"),
1005 .map_type = BPF_MAP_TYPE_ARRAY,
1006 .map_name = "hdr_test_map",
1007 .key_size = sizeof(int),
1008 .value_size = sizeof(int),
1012 .btf_load_err = true,
1014 .err_str = "Total section length too long",
1018 .descr = "array test. index_type/elem_type \"int\"",
1021 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
1022 /* int[16] */ /* [2] */
1023 BTF_TYPE_ARRAY_ENC(1, 1, 16),
1027 .str_sec_size = sizeof(""),
1028 .map_type = BPF_MAP_TYPE_ARRAY,
1029 .map_name = "array_test_map",
1030 .key_size = sizeof(int),
1031 .value_size = sizeof(int),
1038 .descr = "array test. index_type/elem_type \"const int\"",
1041 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
1042 /* int[16] */ /* [2] */
1043 BTF_TYPE_ARRAY_ENC(3, 3, 16),
1044 /* CONST type_id=1 */ /* [3] */
1045 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_CONST, 0, 0), 1),
1049 .str_sec_size = sizeof(""),
1050 .map_type = BPF_MAP_TYPE_ARRAY,
1051 .map_name = "array_test_map",
1052 .key_size = sizeof(int),
1053 .value_size = sizeof(int),
1060 .descr = "array test. index_type \"const int:31\"",
1063 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
1064 /* int:31 */ /* [2] */
1065 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 31, 4),
1066 /* int[16] */ /* [3] */
1067 BTF_TYPE_ARRAY_ENC(1, 4, 16),
1068 /* CONST type_id=2 */ /* [4] */
1069 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_CONST, 0, 0), 2),
1073 .str_sec_size = sizeof(""),
1074 .map_type = BPF_MAP_TYPE_ARRAY,
1075 .map_name = "array_test_map",
1076 .key_size = sizeof(int),
1077 .value_size = sizeof(int),
1081 .btf_load_err = true,
1082 .err_str = "Invalid index",
1086 .descr = "array test. elem_type \"const int:31\"",
1089 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
1090 /* int:31 */ /* [2] */
1091 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 31, 4),
1092 /* int[16] */ /* [3] */
1093 BTF_TYPE_ARRAY_ENC(4, 1, 16),
1094 /* CONST type_id=2 */ /* [4] */
1095 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_CONST, 0, 0), 2),
1099 .str_sec_size = sizeof(""),
1100 .map_type = BPF_MAP_TYPE_ARRAY,
1101 .map_name = "array_test_map",
1102 .key_size = sizeof(int),
1103 .value_size = sizeof(int),
1107 .btf_load_err = true,
1108 .err_str = "Invalid array of int",
1112 .descr = "array test. index_type \"void\"",
1115 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
1116 /* int[16] */ /* [2] */
1117 BTF_TYPE_ARRAY_ENC(1, 0, 16),
1121 .str_sec_size = sizeof(""),
1122 .map_type = BPF_MAP_TYPE_ARRAY,
1123 .map_name = "array_test_map",
1124 .key_size = sizeof(int),
1125 .value_size = sizeof(int),
1129 .btf_load_err = true,
1130 .err_str = "Invalid index",
1134 .descr = "array test. index_type \"const void\"",
1137 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
1138 /* int[16] */ /* [2] */
1139 BTF_TYPE_ARRAY_ENC(1, 3, 16),
1140 /* CONST type_id=0 (void) */ /* [3] */
1141 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_CONST, 0, 0), 0),
1145 .str_sec_size = sizeof(""),
1146 .map_type = BPF_MAP_TYPE_ARRAY,
1147 .map_name = "array_test_map",
1148 .key_size = sizeof(int),
1149 .value_size = sizeof(int),
1153 .btf_load_err = true,
1154 .err_str = "Invalid index",
1158 .descr = "array test. elem_type \"const void\"",
1161 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
1162 /* int[16] */ /* [2] */
1163 BTF_TYPE_ARRAY_ENC(3, 1, 16),
1164 /* CONST type_id=0 (void) */ /* [3] */
1165 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_CONST, 0, 0), 0),
1169 .str_sec_size = sizeof(""),
1170 .map_type = BPF_MAP_TYPE_ARRAY,
1171 .map_name = "array_test_map",
1172 .key_size = sizeof(int),
1173 .value_size = sizeof(int),
1177 .btf_load_err = true,
1178 .err_str = "Invalid elem",
1182 .descr = "array test. elem_type \"const void *\"",
1185 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
1186 /* const void *[16] */ /* [2] */
1187 BTF_TYPE_ARRAY_ENC(3, 1, 16),
1188 /* CONST type_id=4 */ /* [3] */
1189 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_CONST, 0, 0), 4),
1190 /* void* */ /* [4] */
1191 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_PTR, 0, 0), 0),
1195 .str_sec_size = sizeof(""),
1196 .map_type = BPF_MAP_TYPE_ARRAY,
1197 .map_name = "array_test_map",
1198 .key_size = sizeof(int),
1199 .value_size = sizeof(int),
1206 .descr = "array test. index_type \"const void *\"",
1209 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
1210 /* const void *[16] */ /* [2] */
1211 BTF_TYPE_ARRAY_ENC(3, 3, 16),
1212 /* CONST type_id=4 */ /* [3] */
1213 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_CONST, 0, 0), 4),
1214 /* void* */ /* [4] */
1215 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_PTR, 0, 0), 0),
1219 .str_sec_size = sizeof(""),
1220 .map_type = BPF_MAP_TYPE_ARRAY,
1221 .map_name = "array_test_map",
1222 .key_size = sizeof(int),
1223 .value_size = sizeof(int),
1227 .btf_load_err = true,
1228 .err_str = "Invalid index",
1232 .descr = "array test. t->size != 0\"",
1235 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
1236 /* int[16] */ /* [2] */
1237 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_ARRAY, 0, 0), 1),
1238 BTF_ARRAY_ENC(1, 1, 16),
1242 .str_sec_size = sizeof(""),
1243 .map_type = BPF_MAP_TYPE_ARRAY,
1244 .map_name = "array_test_map",
1245 .key_size = sizeof(int),
1246 .value_size = sizeof(int),
1250 .btf_load_err = true,
1251 .err_str = "size != 0",
1255 .descr = "int test. invalid int_data",
1257 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_INT, 0, 0), 4),
1262 .str_sec_size = sizeof(""),
1263 .map_type = BPF_MAP_TYPE_ARRAY,
1264 .map_name = "array_test_map",
1265 .key_size = sizeof(int),
1266 .value_size = sizeof(int),
1270 .btf_load_err = true,
1271 .err_str = "Invalid int_data",
1275 .descr = "invalid BTF_INFO",
1278 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
1279 BTF_TYPE_ENC(0, 0x10000000, 4),
1283 .str_sec_size = sizeof(""),
1284 .map_type = BPF_MAP_TYPE_ARRAY,
1285 .map_name = "array_test_map",
1286 .key_size = sizeof(int),
1287 .value_size = sizeof(int),
1291 .btf_load_err = true,
1292 .err_str = "Invalid btf_info",
1296 .descr = "fwd test. t->type != 0\"",
1299 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
1300 /* fwd type */ /* [2] */
1301 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_FWD, 0, 0), 1),
1305 .str_sec_size = sizeof(""),
1306 .map_type = BPF_MAP_TYPE_ARRAY,
1307 .map_name = "fwd_test_map",
1308 .key_size = sizeof(int),
1309 .value_size = sizeof(int),
1313 .btf_load_err = true,
1314 .err_str = "type != 0",
1318 .descr = "typedef (invalid name, name_off = 0)",
1320 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
1321 BTF_TYPEDEF_ENC(0, 1), /* [2] */
1324 .str_sec = "\0__int",
1325 .str_sec_size = sizeof("\0__int"),
1326 .map_type = BPF_MAP_TYPE_ARRAY,
1327 .map_name = "typedef_check_btf",
1328 .key_size = sizeof(int),
1329 .value_size = sizeof(int),
1333 .btf_load_err = true,
1334 .err_str = "Invalid name",
1338 .descr = "typedef (invalid name, invalid identifier)",
1340 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
1341 BTF_TYPEDEF_ENC(NAME_TBD, 1), /* [2] */
1344 .str_sec = "\0__!int",
1345 .str_sec_size = sizeof("\0__!int"),
1346 .map_type = BPF_MAP_TYPE_ARRAY,
1347 .map_name = "typedef_check_btf",
1348 .key_size = sizeof(int),
1349 .value_size = sizeof(int),
1353 .btf_load_err = true,
1354 .err_str = "Invalid name",
1358 .descr = "ptr type (invalid name, name_off <> 0)",
1360 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
1361 BTF_TYPE_ENC(NAME_TBD,
1362 BTF_INFO_ENC(BTF_KIND_PTR, 0, 0), 1), /* [2] */
1365 .str_sec = "\0__int",
1366 .str_sec_size = sizeof("\0__int"),
1367 .map_type = BPF_MAP_TYPE_ARRAY,
1368 .map_name = "ptr_type_check_btf",
1369 .key_size = sizeof(int),
1370 .value_size = sizeof(int),
1374 .btf_load_err = true,
1375 .err_str = "Invalid name",
1379 .descr = "volatile type (invalid name, name_off <> 0)",
1381 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
1382 BTF_TYPE_ENC(NAME_TBD,
1383 BTF_INFO_ENC(BTF_KIND_VOLATILE, 0, 0), 1), /* [2] */
1386 .str_sec = "\0__int",
1387 .str_sec_size = sizeof("\0__int"),
1388 .map_type = BPF_MAP_TYPE_ARRAY,
1389 .map_name = "volatile_type_check_btf",
1390 .key_size = sizeof(int),
1391 .value_size = sizeof(int),
1395 .btf_load_err = true,
1396 .err_str = "Invalid name",
1400 .descr = "const type (invalid name, name_off <> 0)",
1402 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
1403 BTF_TYPE_ENC(NAME_TBD,
1404 BTF_INFO_ENC(BTF_KIND_CONST, 0, 0), 1), /* [2] */
1407 .str_sec = "\0__int",
1408 .str_sec_size = sizeof("\0__int"),
1409 .map_type = BPF_MAP_TYPE_ARRAY,
1410 .map_name = "const_type_check_btf",
1411 .key_size = sizeof(int),
1412 .value_size = sizeof(int),
1416 .btf_load_err = true,
1417 .err_str = "Invalid name",
1421 .descr = "restrict type (invalid name, name_off <> 0)",
1423 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
1424 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_PTR, 0, 0), 1), /* [2] */
1425 BTF_TYPE_ENC(NAME_TBD,
1426 BTF_INFO_ENC(BTF_KIND_RESTRICT, 0, 0), 2), /* [3] */
1429 .str_sec = "\0__int",
1430 .str_sec_size = sizeof("\0__int"),
1431 .map_type = BPF_MAP_TYPE_ARRAY,
1432 .map_name = "restrict_type_check_btf",
1433 .key_size = sizeof(int),
1434 .value_size = sizeof(int),
1438 .btf_load_err = true,
1439 .err_str = "Invalid name",
1443 .descr = "fwd type (invalid name, name_off = 0)",
1445 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
1446 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_FWD, 0, 0), 0), /* [2] */
1449 .str_sec = "\0__skb",
1450 .str_sec_size = sizeof("\0__skb"),
1451 .map_type = BPF_MAP_TYPE_ARRAY,
1452 .map_name = "fwd_type_check_btf",
1453 .key_size = sizeof(int),
1454 .value_size = sizeof(int),
1458 .btf_load_err = true,
1459 .err_str = "Invalid name",
1463 .descr = "fwd type (invalid name, invalid identifier)",
1465 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
1466 BTF_TYPE_ENC(NAME_TBD,
1467 BTF_INFO_ENC(BTF_KIND_FWD, 0, 0), 0), /* [2] */
1470 .str_sec = "\0__!skb",
1471 .str_sec_size = sizeof("\0__!skb"),
1472 .map_type = BPF_MAP_TYPE_ARRAY,
1473 .map_name = "fwd_type_check_btf",
1474 .key_size = sizeof(int),
1475 .value_size = sizeof(int),
1479 .btf_load_err = true,
1480 .err_str = "Invalid name",
1484 .descr = "array type (invalid name, name_off <> 0)",
1486 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
1487 BTF_TYPE_ENC(NAME_TBD,
1488 BTF_INFO_ENC(BTF_KIND_ARRAY, 0, 0), 0), /* [2] */
1489 BTF_ARRAY_ENC(1, 1, 4),
1492 .str_sec = "\0__skb",
1493 .str_sec_size = sizeof("\0__skb"),
1494 .map_type = BPF_MAP_TYPE_ARRAY,
1495 .map_name = "array_type_check_btf",
1496 .key_size = sizeof(int),
1497 .value_size = sizeof(int),
1501 .btf_load_err = true,
1502 .err_str = "Invalid name",
1506 .descr = "struct type (name_off = 0)",
1508 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
1510 BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 1), 4), /* [2] */
1511 BTF_MEMBER_ENC(NAME_TBD, 1, 0),
1515 .str_sec_size = sizeof("\0A"),
1516 .map_type = BPF_MAP_TYPE_ARRAY,
1517 .map_name = "struct_type_check_btf",
1518 .key_size = sizeof(int),
1519 .value_size = sizeof(int),
1526 .descr = "struct type (invalid name, invalid identifier)",
1528 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
1529 BTF_TYPE_ENC(NAME_TBD,
1530 BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 1), 4), /* [2] */
1531 BTF_MEMBER_ENC(NAME_TBD, 1, 0),
1534 .str_sec = "\0A!\0B",
1535 .str_sec_size = sizeof("\0A!\0B"),
1536 .map_type = BPF_MAP_TYPE_ARRAY,
1537 .map_name = "struct_type_check_btf",
1538 .key_size = sizeof(int),
1539 .value_size = sizeof(int),
1543 .btf_load_err = true,
1544 .err_str = "Invalid name",
1548 .descr = "struct member (name_off = 0)",
1550 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
1552 BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 1), 4), /* [2] */
1553 BTF_MEMBER_ENC(NAME_TBD, 1, 0),
1557 .str_sec_size = sizeof("\0A"),
1558 .map_type = BPF_MAP_TYPE_ARRAY,
1559 .map_name = "struct_type_check_btf",
1560 .key_size = sizeof(int),
1561 .value_size = sizeof(int),
1568 .descr = "struct member (invalid name, invalid identifier)",
1570 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
1571 BTF_TYPE_ENC(NAME_TBD,
1572 BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 1), 4), /* [2] */
1573 BTF_MEMBER_ENC(NAME_TBD, 1, 0),
1576 .str_sec = "\0A\0B*",
1577 .str_sec_size = sizeof("\0A\0B*"),
1578 .map_type = BPF_MAP_TYPE_ARRAY,
1579 .map_name = "struct_type_check_btf",
1580 .key_size = sizeof(int),
1581 .value_size = sizeof(int),
1585 .btf_load_err = true,
1586 .err_str = "Invalid name",
1590 .descr = "enum type (name_off = 0)",
1592 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
1594 BTF_INFO_ENC(BTF_KIND_ENUM, 0, 1),
1595 sizeof(int)), /* [2] */
1596 BTF_ENUM_ENC(NAME_TBD, 0),
1599 .str_sec = "\0A\0B",
1600 .str_sec_size = sizeof("\0A\0B"),
1601 .map_type = BPF_MAP_TYPE_ARRAY,
1602 .map_name = "enum_type_check_btf",
1603 .key_size = sizeof(int),
1604 .value_size = sizeof(int),
1611 .descr = "enum type (invalid name, invalid identifier)",
1613 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
1614 BTF_TYPE_ENC(NAME_TBD,
1615 BTF_INFO_ENC(BTF_KIND_ENUM, 0, 1),
1616 sizeof(int)), /* [2] */
1617 BTF_ENUM_ENC(NAME_TBD, 0),
1620 .str_sec = "\0A!\0B",
1621 .str_sec_size = sizeof("\0A!\0B"),
1622 .map_type = BPF_MAP_TYPE_ARRAY,
1623 .map_name = "enum_type_check_btf",
1624 .key_size = sizeof(int),
1625 .value_size = sizeof(int),
1629 .btf_load_err = true,
1630 .err_str = "Invalid name",
1634 .descr = "enum member (invalid name, name_off = 0)",
1636 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
1638 BTF_INFO_ENC(BTF_KIND_ENUM, 0, 1),
1639 sizeof(int)), /* [2] */
1644 .str_sec_size = sizeof(""),
1645 .map_type = BPF_MAP_TYPE_ARRAY,
1646 .map_name = "enum_type_check_btf",
1647 .key_size = sizeof(int),
1648 .value_size = sizeof(int),
1652 .btf_load_err = true,
1653 .err_str = "Invalid name",
1657 .descr = "enum member (invalid name, invalid identifier)",
1659 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
1661 BTF_INFO_ENC(BTF_KIND_ENUM, 0, 1),
1662 sizeof(int)), /* [2] */
1663 BTF_ENUM_ENC(NAME_TBD, 0),
1667 .str_sec_size = sizeof("\0A!"),
1668 .map_type = BPF_MAP_TYPE_ARRAY,
1669 .map_name = "enum_type_check_btf",
1670 .key_size = sizeof(int),
1671 .value_size = sizeof(int),
1675 .btf_load_err = true,
1676 .err_str = "Invalid name",
1679 .descr = "arraymap invalid btf key (a bit field)",
1682 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
1683 /* 32 bit int with 32 bit offset */ /* [2] */
1684 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 32, 32, 8),
1688 .str_sec_size = sizeof(""),
1689 .map_type = BPF_MAP_TYPE_ARRAY,
1690 .map_name = "array_map_check_btf",
1691 .key_size = sizeof(int),
1692 .value_size = sizeof(int),
1696 .map_create_err = true,
1700 .descr = "arraymap invalid btf key (!= 32 bits)",
1703 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
1704 /* 16 bit int with 0 bit offset */ /* [2] */
1705 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 16, 2),
1709 .str_sec_size = sizeof(""),
1710 .map_type = BPF_MAP_TYPE_ARRAY,
1711 .map_name = "array_map_check_btf",
1712 .key_size = sizeof(int),
1713 .value_size = sizeof(int),
1717 .map_create_err = true,
1721 .descr = "arraymap invalid btf value (too small)",
1724 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
1728 .str_sec_size = sizeof(""),
1729 .map_type = BPF_MAP_TYPE_ARRAY,
1730 .map_name = "array_map_check_btf",
1731 .key_size = sizeof(int),
1732 /* btf_value_size < map->value_size */
1733 .value_size = sizeof(__u64),
1737 .map_create_err = true,
1741 .descr = "arraymap invalid btf value (too big)",
1744 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
1748 .str_sec_size = sizeof(""),
1749 .map_type = BPF_MAP_TYPE_ARRAY,
1750 .map_name = "array_map_check_btf",
1751 .key_size = sizeof(int),
1752 /* btf_value_size > map->value_size */
1753 .value_size = sizeof(__u16),
1757 .map_create_err = true,
1761 .descr = "func proto (int (*)(int, unsigned int))",
1763 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
1764 BTF_TYPE_INT_ENC(0, 0, 0, 32, 4), /* [2] */
1765 /* int (*)(int, unsigned int) */
1766 BTF_FUNC_PROTO_ENC(1, 2), /* [3] */
1767 BTF_FUNC_PROTO_ARG_ENC(0, 1),
1768 BTF_FUNC_PROTO_ARG_ENC(0, 2),
1772 .str_sec_size = sizeof(""),
1773 .map_type = BPF_MAP_TYPE_ARRAY,
1774 .map_name = "func_proto_type_check_btf",
1775 .key_size = sizeof(int),
1776 .value_size = sizeof(int),
1783 .descr = "func proto (vararg)",
1785 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
1786 BTF_TYPE_INT_ENC(0, 0, 0, 32, 4), /* [2] */
1787 /* void (*)(int, unsigned int, ...) */
1788 BTF_FUNC_PROTO_ENC(0, 3), /* [3] */
1789 BTF_FUNC_PROTO_ARG_ENC(0, 1),
1790 BTF_FUNC_PROTO_ARG_ENC(0, 2),
1791 BTF_FUNC_PROTO_ARG_ENC(0, 0),
1795 .str_sec_size = sizeof(""),
1796 .map_type = BPF_MAP_TYPE_ARRAY,
1797 .map_name = "func_proto_type_check_btf",
1798 .key_size = sizeof(int),
1799 .value_size = sizeof(int),
1806 .descr = "func proto (vararg with name)",
1808 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
1809 BTF_TYPE_INT_ENC(0, 0, 0, 32, 4), /* [2] */
1810 /* void (*)(int a, unsigned int b, ... c) */
1811 BTF_FUNC_PROTO_ENC(0, 3), /* [3] */
1812 BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
1813 BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 2),
1814 BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 0),
1817 .str_sec = "\0a\0b\0c",
1818 .str_sec_size = sizeof("\0a\0b\0c"),
1819 .map_type = BPF_MAP_TYPE_ARRAY,
1820 .map_name = "func_proto_type_check_btf",
1821 .key_size = sizeof(int),
1822 .value_size = sizeof(int),
1826 .btf_load_err = true,
1827 .err_str = "Invalid arg#3",
1831 .descr = "func proto (arg after vararg)",
1833 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
1834 BTF_TYPE_INT_ENC(0, 0, 0, 32, 4), /* [2] */
1835 /* void (*)(int a, ..., unsigned int b) */
1836 BTF_FUNC_PROTO_ENC(0, 3), /* [3] */
1837 BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
1838 BTF_FUNC_PROTO_ARG_ENC(0, 0),
1839 BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 2),
1842 .str_sec = "\0a\0b",
1843 .str_sec_size = sizeof("\0a\0b"),
1844 .map_type = BPF_MAP_TYPE_ARRAY,
1845 .map_name = "func_proto_type_check_btf",
1846 .key_size = sizeof(int),
1847 .value_size = sizeof(int),
1851 .btf_load_err = true,
1852 .err_str = "Invalid arg#2",
1856 .descr = "func proto (CONST=>TYPEDEF=>PTR=>FUNC_PROTO)",
1858 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
1859 BTF_TYPE_INT_ENC(0, 0, 0, 32, 4), /* [2] */
1860 /* typedef void (*func_ptr)(int, unsigned int) */
1861 BTF_TYPEDEF_ENC(NAME_TBD, 5), /* [3] */
1862 /* const func_ptr */
1863 BTF_CONST_ENC(3), /* [4] */
1864 BTF_PTR_ENC(6), /* [5] */
1865 BTF_FUNC_PROTO_ENC(0, 2), /* [6] */
1866 BTF_FUNC_PROTO_ARG_ENC(0, 1),
1867 BTF_FUNC_PROTO_ARG_ENC(0, 2),
1870 .str_sec = "\0func_ptr",
1871 .str_sec_size = sizeof("\0func_ptr"),
1872 .map_type = BPF_MAP_TYPE_ARRAY,
1873 .map_name = "func_proto_type_check_btf",
1874 .key_size = sizeof(int),
1875 .value_size = sizeof(int),
1882 .descr = "func proto (CONST=>TYPEDEF=>FUNC_PROTO)",
1884 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
1885 BTF_TYPE_INT_ENC(0, 0, 0, 32, 4), /* [2] */
1886 BTF_CONST_ENC(4), /* [3] */
1887 BTF_TYPEDEF_ENC(NAME_TBD, 5), /* [4] */
1888 BTF_FUNC_PROTO_ENC(0, 2), /* [5] */
1889 BTF_FUNC_PROTO_ARG_ENC(0, 1),
1890 BTF_FUNC_PROTO_ARG_ENC(0, 2),
1893 .str_sec = "\0func_typedef",
1894 .str_sec_size = sizeof("\0func_typedef"),
1895 .map_type = BPF_MAP_TYPE_ARRAY,
1896 .map_name = "func_proto_type_check_btf",
1897 .key_size = sizeof(int),
1898 .value_size = sizeof(int),
1902 .btf_load_err = true,
1903 .err_str = "Invalid type_id",
1907 .descr = "func proto (btf_resolve(arg))",
1909 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
1910 /* void (*)(const void *) */
1911 BTF_FUNC_PROTO_ENC(0, 1), /* [2] */
1912 BTF_FUNC_PROTO_ARG_ENC(0, 3),
1913 BTF_CONST_ENC(4), /* [3] */
1914 BTF_PTR_ENC(0), /* [4] */
1918 .str_sec_size = sizeof(""),
1919 .map_type = BPF_MAP_TYPE_ARRAY,
1920 .map_name = "func_proto_type_check_btf",
1921 .key_size = sizeof(int),
1922 .value_size = sizeof(int),
1929 .descr = "func proto (Not all arg has name)",
1931 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
1932 BTF_TYPE_INT_ENC(0, 0, 0, 32, 4), /* [2] */
1933 /* void (*)(int, unsigned int b) */
1934 BTF_FUNC_PROTO_ENC(0, 2), /* [3] */
1935 BTF_FUNC_PROTO_ARG_ENC(0, 1),
1936 BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 2),
1940 .str_sec_size = sizeof("\0b"),
1941 .map_type = BPF_MAP_TYPE_ARRAY,
1942 .map_name = "func_proto_type_check_btf",
1943 .key_size = sizeof(int),
1944 .value_size = sizeof(int),
1951 .descr = "func proto (Bad arg name_off)",
1953 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
1954 BTF_TYPE_INT_ENC(0, 0, 0, 32, 4), /* [2] */
1955 /* void (*)(int a, unsigned int <bad_name_off>) */
1956 BTF_FUNC_PROTO_ENC(0, 2), /* [3] */
1957 BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
1958 BTF_FUNC_PROTO_ARG_ENC(0xffffffff, 2),
1962 .str_sec_size = sizeof("\0a"),
1963 .map_type = BPF_MAP_TYPE_ARRAY,
1964 .map_name = "func_proto_type_check_btf",
1965 .key_size = sizeof(int),
1966 .value_size = sizeof(int),
1970 .btf_load_err = true,
1971 .err_str = "Invalid arg#2",
1975 .descr = "func proto (Bad arg name)",
1977 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
1978 BTF_TYPE_INT_ENC(0, 0, 0, 32, 4), /* [2] */
1979 /* void (*)(int a, unsigned int !!!) */
1980 BTF_FUNC_PROTO_ENC(0, 2), /* [3] */
1981 BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
1982 BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 2),
1985 .str_sec = "\0a\0!!!",
1986 .str_sec_size = sizeof("\0a\0!!!"),
1987 .map_type = BPF_MAP_TYPE_ARRAY,
1988 .map_name = "func_proto_type_check_btf",
1989 .key_size = sizeof(int),
1990 .value_size = sizeof(int),
1994 .btf_load_err = true,
1995 .err_str = "Invalid arg#2",
1999 .descr = "func proto (Invalid return type)",
2001 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
2002 BTF_TYPE_INT_ENC(0, 0, 0, 32, 4), /* [2] */
2003 /* <bad_ret_type> (*)(int, unsigned int) */
2004 BTF_FUNC_PROTO_ENC(100, 2), /* [3] */
2005 BTF_FUNC_PROTO_ARG_ENC(0, 1),
2006 BTF_FUNC_PROTO_ARG_ENC(0, 2),
2010 .str_sec_size = sizeof(""),
2011 .map_type = BPF_MAP_TYPE_ARRAY,
2012 .map_name = "func_proto_type_check_btf",
2013 .key_size = sizeof(int),
2014 .value_size = sizeof(int),
2018 .btf_load_err = true,
2019 .err_str = "Invalid return type",
2023 .descr = "func proto (with func name)",
2025 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
2026 BTF_TYPE_INT_ENC(0, 0, 0, 32, 4), /* [2] */
2027 /* void func_proto(int, unsigned int) */
2028 BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_FUNC_PROTO, 0, 2), 0), /* [3] */
2029 BTF_FUNC_PROTO_ARG_ENC(0, 1),
2030 BTF_FUNC_PROTO_ARG_ENC(0, 2),
2033 .str_sec = "\0func_proto",
2034 .str_sec_size = sizeof("\0func_proto"),
2035 .map_type = BPF_MAP_TYPE_ARRAY,
2036 .map_name = "func_proto_type_check_btf",
2037 .key_size = sizeof(int),
2038 .value_size = sizeof(int),
2042 .btf_load_err = true,
2043 .err_str = "Invalid name",
2047 .descr = "func proto (const void arg)",
2049 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
2050 BTF_TYPE_INT_ENC(0, 0, 0, 32, 4), /* [2] */
2051 /* void (*)(const void) */
2052 BTF_FUNC_PROTO_ENC(0, 1), /* [3] */
2053 BTF_FUNC_PROTO_ARG_ENC(0, 4),
2054 BTF_CONST_ENC(0), /* [4] */
2058 .str_sec_size = sizeof(""),
2059 .map_type = BPF_MAP_TYPE_ARRAY,
2060 .map_name = "func_proto_type_check_btf",
2061 .key_size = sizeof(int),
2062 .value_size = sizeof(int),
2066 .btf_load_err = true,
2067 .err_str = "Invalid arg#1",
2071 .descr = "func (void func(int a, unsigned int b))",
2073 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
2074 BTF_TYPE_INT_ENC(0, 0, 0, 32, 4), /* [2] */
2075 /* void (*)(int a, unsigned int b) */
2076 BTF_FUNC_PROTO_ENC(0, 2), /* [3] */
2077 BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
2078 BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 2),
2079 /* void func(int a, unsigned int b) */
2080 BTF_FUNC_ENC(NAME_TBD, 3), /* [4] */
2083 .str_sec = "\0a\0b\0func",
2084 .str_sec_size = sizeof("\0a\0b\0func"),
2085 .map_type = BPF_MAP_TYPE_ARRAY,
2086 .map_name = "func_type_check_btf",
2087 .key_size = sizeof(int),
2088 .value_size = sizeof(int),
2095 .descr = "func (No func name)",
2097 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
2098 BTF_TYPE_INT_ENC(0, 0, 0, 32, 4), /* [2] */
2099 /* void (*)(int a, unsigned int b) */
2100 BTF_FUNC_PROTO_ENC(0, 2), /* [3] */
2101 BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
2102 BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 2),
2103 /* void <no_name>(int a, unsigned int b) */
2104 BTF_FUNC_ENC(0, 3), /* [4] */
2107 .str_sec = "\0a\0b",
2108 .str_sec_size = sizeof("\0a\0b"),
2109 .map_type = BPF_MAP_TYPE_ARRAY,
2110 .map_name = "func_type_check_btf",
2111 .key_size = sizeof(int),
2112 .value_size = sizeof(int),
2116 .btf_load_err = true,
2117 .err_str = "Invalid name",
2121 .descr = "func (Invalid func name)",
2123 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
2124 BTF_TYPE_INT_ENC(0, 0, 0, 32, 4), /* [2] */
2125 /* void (*)(int a, unsigned int b) */
2126 BTF_FUNC_PROTO_ENC(0, 2), /* [3] */
2127 BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
2128 BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 2),
2129 /* void !!!(int a, unsigned int b) */
2130 BTF_FUNC_ENC(NAME_TBD, 3), /* [4] */
2133 .str_sec = "\0a\0b\0!!!",
2134 .str_sec_size = sizeof("\0a\0b\0!!!"),
2135 .map_type = BPF_MAP_TYPE_ARRAY,
2136 .map_name = "func_type_check_btf",
2137 .key_size = sizeof(int),
2138 .value_size = sizeof(int),
2142 .btf_load_err = true,
2143 .err_str = "Invalid name",
2147 .descr = "func (Some arg has no name)",
2149 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
2150 BTF_TYPE_INT_ENC(0, 0, 0, 32, 4), /* [2] */
2151 /* void (*)(int a, unsigned int) */
2152 BTF_FUNC_PROTO_ENC(0, 2), /* [3] */
2153 BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
2154 BTF_FUNC_PROTO_ARG_ENC(0, 2),
2155 /* void func(int a, unsigned int) */
2156 BTF_FUNC_ENC(NAME_TBD, 3), /* [4] */
2159 .str_sec = "\0a\0func",
2160 .str_sec_size = sizeof("\0a\0func"),
2161 .map_type = BPF_MAP_TYPE_ARRAY,
2162 .map_name = "func_type_check_btf",
2163 .key_size = sizeof(int),
2164 .value_size = sizeof(int),
2168 .btf_load_err = true,
2169 .err_str = "Invalid arg#2",
2173 .descr = "func (Non zero vlen)",
2175 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
2176 BTF_TYPE_INT_ENC(0, 0, 0, 32, 4), /* [2] */
2177 /* void (*)(int a, unsigned int b) */
2178 BTF_FUNC_PROTO_ENC(0, 2), /* [3] */
2179 BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
2180 BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 2),
2181 /* void func(int a, unsigned int b) */
2182 BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_FUNC, 0, 2), 3), /* [4] */
2185 .str_sec = "\0a\0b\0func",
2186 .str_sec_size = sizeof("\0a\0b\0func"),
2187 .map_type = BPF_MAP_TYPE_ARRAY,
2188 .map_name = "func_type_check_btf",
2189 .key_size = sizeof(int),
2190 .value_size = sizeof(int),
2194 .btf_load_err = true,
2195 .err_str = "vlen != 0",
2199 .descr = "func (Not referring to FUNC_PROTO)",
2201 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
2202 BTF_FUNC_ENC(NAME_TBD, 1), /* [2] */
2205 .str_sec = "\0func",
2206 .str_sec_size = sizeof("\0func"),
2207 .map_type = BPF_MAP_TYPE_ARRAY,
2208 .map_name = "func_type_check_btf",
2209 .key_size = sizeof(int),
2210 .value_size = sizeof(int),
2214 .btf_load_err = true,
2215 .err_str = "Invalid type_id",
2218 }; /* struct btf_raw_test raw_tests[] */
2220 static const char *get_next_str(const char *start, const char *end)
2222 return start < end - 1 ? start + 1 : NULL;
2225 static int get_raw_sec_size(const __u32 *raw_types)
2229 for (i = MAX_NR_RAW_U32 - 1;
2230 i >= 0 && raw_types[i] != BTF_END_RAW;
2234 return i < 0 ? i : i * sizeof(raw_types[0]);
2237 static void *btf_raw_create(const struct btf_header *hdr,
2238 const __u32 *raw_types,
2240 unsigned int str_sec_size,
2241 unsigned int *btf_size,
2242 const char **ret_next_str)
2244 const char *next_str = str, *end_str = str + str_sec_size;
2245 unsigned int size_needed, offset;
2246 struct btf_header *ret_hdr;
2247 int i, type_sec_size;
2248 uint32_t *ret_types;
2251 type_sec_size = get_raw_sec_size(raw_types);
2252 if (CHECK(type_sec_size < 0, "Cannot get nr_raw_types"))
2255 size_needed = sizeof(*hdr) + type_sec_size + str_sec_size;
2256 raw_btf = malloc(size_needed);
2257 if (CHECK(!raw_btf, "Cannot allocate memory for raw_btf"))
2261 memcpy(raw_btf, hdr, sizeof(*hdr));
2262 offset = sizeof(*hdr);
2264 /* Copy type section */
2265 ret_types = raw_btf + offset;
2266 for (i = 0; i < type_sec_size / sizeof(raw_types[0]); i++) {
2267 if (raw_types[i] == NAME_TBD) {
2268 next_str = get_next_str(next_str, end_str);
2269 if (CHECK(!next_str, "Error in getting next_str")) {
2273 ret_types[i] = next_str - str;
2274 next_str += strlen(next_str);
2276 ret_types[i] = raw_types[i];
2279 offset += type_sec_size;
2281 /* Copy string section */
2282 memcpy(raw_btf + offset, str, str_sec_size);
2284 ret_hdr = (struct btf_header *)raw_btf;
2285 ret_hdr->type_len = type_sec_size;
2286 ret_hdr->str_off = type_sec_size;
2287 ret_hdr->str_len = str_sec_size;
2289 *btf_size = size_needed;
2291 *ret_next_str = next_str;
2296 static int do_test_raw(unsigned int test_num)
2298 struct btf_raw_test *test = &raw_tests[test_num - 1];
2299 struct bpf_create_map_attr create_attr = {};
2300 int map_fd = -1, btf_fd = -1;
2301 unsigned int raw_btf_size;
2302 struct btf_header *hdr;
2306 fprintf(stderr, "BTF raw test[%u] (%s): ", test_num, test->descr);
2307 raw_btf = btf_raw_create(&hdr_tmpl,
2311 &raw_btf_size, NULL);
2318 hdr->hdr_len = (int)hdr->hdr_len + test->hdr_len_delta;
2319 hdr->type_off = (int)hdr->type_off + test->type_off_delta;
2320 hdr->str_off = (int)hdr->str_off + test->str_off_delta;
2321 hdr->str_len = (int)hdr->str_len + test->str_len_delta;
2323 *btf_log_buf = '\0';
2324 btf_fd = bpf_load_btf(raw_btf, raw_btf_size,
2325 btf_log_buf, BTF_LOG_BUF_SIZE,
2329 err = ((btf_fd == -1) != test->btf_load_err);
2330 if (CHECK(err, "btf_fd:%d test->btf_load_err:%u",
2331 btf_fd, test->btf_load_err) ||
2332 CHECK(test->err_str && !strstr(btf_log_buf, test->err_str),
2333 "expected err_str:%s", test->err_str)) {
2338 if (err || btf_fd == -1)
2341 create_attr.name = test->map_name;
2342 create_attr.map_type = test->map_type;
2343 create_attr.key_size = test->key_size;
2344 create_attr.value_size = test->value_size;
2345 create_attr.max_entries = test->max_entries;
2346 create_attr.btf_fd = btf_fd;
2347 create_attr.btf_key_type_id = test->key_type_id;
2348 create_attr.btf_value_type_id = test->value_type_id;
2350 map_fd = bpf_create_map_xattr(&create_attr);
2352 err = ((map_fd == -1) != test->map_create_err);
2353 CHECK(err, "map_fd:%d test->map_create_err:%u",
2354 map_fd, test->map_create_err);
2358 fprintf(stderr, "OK");
2360 if (*btf_log_buf && (err || args.always_log))
2361 fprintf(stderr, "\n%s", btf_log_buf);
2371 static int test_raw(void)
2376 if (args.raw_test_num)
2377 return count_result(do_test_raw(args.raw_test_num));
2379 for (i = 1; i <= ARRAY_SIZE(raw_tests); i++)
2380 err |= count_result(do_test_raw(i));
2385 struct btf_get_info_test {
2387 const char *str_sec;
2388 __u32 raw_types[MAX_NR_RAW_U32];
2391 int (*special_test)(unsigned int test_num);
2394 static int test_big_btf_info(unsigned int test_num);
2395 static int test_btf_id(unsigned int test_num);
2397 const struct btf_get_info_test get_info_tests[] = {
2399 .descr = "== raw_btf_size+1",
2402 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
2406 .str_sec_size = sizeof(""),
2407 .btf_size_delta = 1,
2410 .descr = "== raw_btf_size-3",
2413 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
2417 .str_sec_size = sizeof(""),
2418 .btf_size_delta = -3,
2421 .descr = "Large bpf_btf_info",
2424 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
2428 .str_sec_size = sizeof(""),
2429 .special_test = test_big_btf_info,
2435 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
2436 /* unsigned int */ /* [2] */
2437 BTF_TYPE_INT_ENC(0, 0, 0, 32, 4),
2441 .str_sec_size = sizeof(""),
2442 .special_test = test_btf_id,
2446 static inline __u64 ptr_to_u64(const void *ptr)
2448 return (__u64)(unsigned long)ptr;
2451 static int test_big_btf_info(unsigned int test_num)
2453 const struct btf_get_info_test *test = &get_info_tests[test_num - 1];
2454 uint8_t *raw_btf = NULL, *user_btf = NULL;
2455 unsigned int raw_btf_size;
2457 struct bpf_btf_info info;
2460 struct bpf_btf_info *info;
2461 int btf_fd = -1, err;
2464 raw_btf = btf_raw_create(&hdr_tmpl,
2468 &raw_btf_size, NULL);
2473 *btf_log_buf = '\0';
2475 user_btf = malloc(raw_btf_size);
2476 if (CHECK(!user_btf, "!user_btf")) {
2481 btf_fd = bpf_load_btf(raw_btf, raw_btf_size,
2482 btf_log_buf, BTF_LOG_BUF_SIZE,
2484 if (CHECK(btf_fd == -1, "errno:%d", errno)) {
2490 * GET_INFO should error out if the userspace info
2491 * has non zero tailing bytes.
2493 info = &info_garbage.info;
2494 memset(info, 0, sizeof(*info));
2495 info_garbage.garbage = 0xdeadbeef;
2496 info_len = sizeof(info_garbage);
2497 info->btf = ptr_to_u64(user_btf);
2498 info->btf_size = raw_btf_size;
2500 err = bpf_obj_get_info_by_fd(btf_fd, info, &info_len);
2501 if (CHECK(!err, "!err")) {
2507 * GET_INFO should succeed even info_len is larger than
2508 * the kernel supported as long as tailing bytes are zero.
2509 * The kernel supported info len should also be returned
2512 info_garbage.garbage = 0;
2513 err = bpf_obj_get_info_by_fd(btf_fd, info, &info_len);
2514 if (CHECK(err || info_len != sizeof(*info),
2515 "err:%d errno:%d info_len:%u sizeof(*info):%lu",
2516 err, errno, info_len, sizeof(*info))) {
2521 fprintf(stderr, "OK");
2524 if (*btf_log_buf && (err || args.always_log))
2525 fprintf(stderr, "\n%s", btf_log_buf);
2536 static int test_btf_id(unsigned int test_num)
2538 const struct btf_get_info_test *test = &get_info_tests[test_num - 1];
2539 struct bpf_create_map_attr create_attr = {};
2540 uint8_t *raw_btf = NULL, *user_btf[2] = {};
2541 int btf_fd[2] = {-1, -1}, map_fd = -1;
2542 struct bpf_map_info map_info = {};
2543 struct bpf_btf_info info[2] = {};
2544 unsigned int raw_btf_size;
2548 raw_btf = btf_raw_create(&hdr_tmpl,
2552 &raw_btf_size, NULL);
2557 *btf_log_buf = '\0';
2559 for (i = 0; i < 2; i++) {
2560 user_btf[i] = malloc(raw_btf_size);
2561 if (CHECK(!user_btf[i], "!user_btf[%d]", i)) {
2565 info[i].btf = ptr_to_u64(user_btf[i]);
2566 info[i].btf_size = raw_btf_size;
2569 btf_fd[0] = bpf_load_btf(raw_btf, raw_btf_size,
2570 btf_log_buf, BTF_LOG_BUF_SIZE,
2572 if (CHECK(btf_fd[0] == -1, "errno:%d", errno)) {
2577 /* Test BPF_OBJ_GET_INFO_BY_ID on btf_id */
2578 info_len = sizeof(info[0]);
2579 err = bpf_obj_get_info_by_fd(btf_fd[0], &info[0], &info_len);
2580 if (CHECK(err, "errno:%d", errno)) {
2585 btf_fd[1] = bpf_btf_get_fd_by_id(info[0].id);
2586 if (CHECK(btf_fd[1] == -1, "errno:%d", errno)) {
2592 err = bpf_obj_get_info_by_fd(btf_fd[1], &info[1], &info_len);
2593 if (CHECK(err || info[0].id != info[1].id ||
2594 info[0].btf_size != info[1].btf_size ||
2595 (ret = memcmp(user_btf[0], user_btf[1], info[0].btf_size)),
2596 "err:%d errno:%d id0:%u id1:%u btf_size0:%u btf_size1:%u memcmp:%d",
2597 err, errno, info[0].id, info[1].id,
2598 info[0].btf_size, info[1].btf_size, ret)) {
2603 /* Test btf members in struct bpf_map_info */
2604 create_attr.name = "test_btf_id";
2605 create_attr.map_type = BPF_MAP_TYPE_ARRAY;
2606 create_attr.key_size = sizeof(int);
2607 create_attr.value_size = sizeof(unsigned int);
2608 create_attr.max_entries = 4;
2609 create_attr.btf_fd = btf_fd[0];
2610 create_attr.btf_key_type_id = 1;
2611 create_attr.btf_value_type_id = 2;
2613 map_fd = bpf_create_map_xattr(&create_attr);
2614 if (CHECK(map_fd == -1, "errno:%d", errno)) {
2619 info_len = sizeof(map_info);
2620 err = bpf_obj_get_info_by_fd(map_fd, &map_info, &info_len);
2621 if (CHECK(err || map_info.btf_id != info[0].id ||
2622 map_info.btf_key_type_id != 1 || map_info.btf_value_type_id != 2,
2623 "err:%d errno:%d info.id:%u btf_id:%u btf_key_type_id:%u btf_value_type_id:%u",
2624 err, errno, info[0].id, map_info.btf_id, map_info.btf_key_type_id,
2625 map_info.btf_value_type_id)) {
2630 for (i = 0; i < 2; i++) {
2635 /* Test BTF ID is removed from the kernel */
2636 btf_fd[0] = bpf_btf_get_fd_by_id(map_info.btf_id);
2637 if (CHECK(btf_fd[0] == -1, "errno:%d", errno)) {
2644 /* The map holds the last ref to BTF and its btf_id */
2647 btf_fd[0] = bpf_btf_get_fd_by_id(map_info.btf_id);
2648 if (CHECK(btf_fd[0] != -1, "BTF lingers")) {
2653 fprintf(stderr, "OK");
2656 if (*btf_log_buf && (err || args.always_log))
2657 fprintf(stderr, "\n%s", btf_log_buf);
2662 for (i = 0; i < 2; i++) {
2664 if (btf_fd[i] != -1)
2671 static int do_test_get_info(unsigned int test_num)
2673 const struct btf_get_info_test *test = &get_info_tests[test_num - 1];
2674 unsigned int raw_btf_size, user_btf_size, expected_nbytes;
2675 uint8_t *raw_btf = NULL, *user_btf = NULL;
2676 struct bpf_btf_info info = {};
2677 int btf_fd = -1, err, ret;
2680 fprintf(stderr, "BTF GET_INFO test[%u] (%s): ",
2681 test_num, test->descr);
2683 if (test->special_test)
2684 return test->special_test(test_num);
2686 raw_btf = btf_raw_create(&hdr_tmpl,
2690 &raw_btf_size, NULL);
2695 *btf_log_buf = '\0';
2697 user_btf = malloc(raw_btf_size);
2698 if (CHECK(!user_btf, "!user_btf")) {
2703 btf_fd = bpf_load_btf(raw_btf, raw_btf_size,
2704 btf_log_buf, BTF_LOG_BUF_SIZE,
2706 if (CHECK(btf_fd == -1, "errno:%d", errno)) {
2711 user_btf_size = (int)raw_btf_size + test->btf_size_delta;
2712 expected_nbytes = min(raw_btf_size, user_btf_size);
2713 if (raw_btf_size > expected_nbytes)
2714 memset(user_btf + expected_nbytes, 0xff,
2715 raw_btf_size - expected_nbytes);
2717 info_len = sizeof(info);
2718 info.btf = ptr_to_u64(user_btf);
2719 info.btf_size = user_btf_size;
2722 err = bpf_obj_get_info_by_fd(btf_fd, &info, &info_len);
2723 if (CHECK(err || !info.id || info_len != sizeof(info) ||
2724 info.btf_size != raw_btf_size ||
2725 (ret = memcmp(raw_btf, user_btf, expected_nbytes)),
2726 "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",
2727 err, errno, info.id, info_len, sizeof(info),
2728 raw_btf_size, info.btf_size, expected_nbytes, ret)) {
2733 while (expected_nbytes < raw_btf_size) {
2734 fprintf(stderr, "%u...", expected_nbytes);
2735 if (CHECK(user_btf[expected_nbytes++] != 0xff,
2736 "user_btf[%u]:%x != 0xff", expected_nbytes - 1,
2737 user_btf[expected_nbytes - 1])) {
2743 fprintf(stderr, "OK");
2746 if (*btf_log_buf && (err || args.always_log))
2747 fprintf(stderr, "\n%s", btf_log_buf);
2758 static int test_get_info(void)
2763 if (args.get_info_test_num)
2764 return count_result(do_test_get_info(args.get_info_test_num));
2766 for (i = 1; i <= ARRAY_SIZE(get_info_tests); i++)
2767 err |= count_result(do_test_get_info(i));
2772 struct btf_file_test {
2774 bool btf_kv_notfound;
2777 static struct btf_file_test file_tests[] = {
2779 .file = "test_btf_haskv.o",
2782 .file = "test_btf_nokv.o",
2783 .btf_kv_notfound = true,
2787 static int file_has_btf_elf(const char *fn, bool *has_btf_ext)
2789 Elf_Scn *scn = NULL;
2795 if (CHECK(elf_version(EV_CURRENT) == EV_NONE,
2796 "elf_version(EV_CURRENT) == EV_NONE"))
2799 elf_fd = open(fn, O_RDONLY);
2800 if (CHECK(elf_fd == -1, "open(%s): errno:%d", fn, errno))
2803 elf = elf_begin(elf_fd, ELF_C_READ, NULL);
2804 if (CHECK(!elf, "elf_begin(%s): %s", fn, elf_errmsg(elf_errno()))) {
2809 if (CHECK(!gelf_getehdr(elf, &ehdr), "!gelf_getehdr(%s)", fn)) {
2814 while ((scn = elf_nextscn(elf, scn))) {
2815 const char *sh_name;
2818 if (CHECK(gelf_getshdr(scn, &sh) != &sh,
2819 "file:%s gelf_getshdr != &sh", fn)) {
2824 sh_name = elf_strptr(elf, ehdr.e_shstrndx, sh.sh_name);
2825 if (!strcmp(sh_name, BTF_ELF_SEC))
2827 if (!strcmp(sh_name, BTF_EXT_ELF_SEC))
2828 *has_btf_ext = true;
2837 static int do_test_file(unsigned int test_num)
2839 const struct btf_file_test *test = &file_tests[test_num - 1];
2840 const char *expected_fnames[] = {"_dummy_tracepoint",
2841 "test_long_fname_1",
2842 "test_long_fname_2"};
2843 struct bpf_prog_info info = {};
2844 struct bpf_object *obj = NULL;
2845 struct bpf_func_info *finfo;
2846 struct bpf_program *prog;
2847 __u32 info_len, rec_size;
2848 bool has_btf_ext = false;
2849 struct btf *btf = NULL;
2850 void *func_info = NULL;
2851 struct bpf_map *map;
2852 int i, err, prog_fd;
2854 fprintf(stderr, "BTF libbpf test[%u] (%s): ", test_num,
2857 err = file_has_btf_elf(test->file, &has_btf_ext);
2862 fprintf(stderr, "SKIP. No ELF %s found", BTF_ELF_SEC);
2867 obj = bpf_object__open(test->file);
2868 if (CHECK(IS_ERR(obj), "obj: %ld", PTR_ERR(obj)))
2869 return PTR_ERR(obj);
2871 err = bpf_object__btf_fd(obj);
2872 if (CHECK(err == -1, "bpf_object__btf_fd: -1"))
2875 prog = bpf_program__next(NULL, obj);
2876 if (CHECK(!prog, "Cannot find bpf_prog")) {
2881 bpf_program__set_type(prog, BPF_PROG_TYPE_TRACEPOINT);
2882 err = bpf_object__load(obj);
2883 if (CHECK(err < 0, "bpf_object__load: %d", err))
2885 prog_fd = bpf_program__fd(prog);
2887 map = bpf_object__find_map_by_name(obj, "btf_map");
2888 if (CHECK(!map, "btf_map not found")) {
2893 err = (bpf_map__btf_key_type_id(map) == 0 || bpf_map__btf_value_type_id(map) == 0)
2894 != test->btf_kv_notfound;
2895 if (CHECK(err, "btf_key_type_id:%u btf_value_type_id:%u test->btf_kv_notfound:%u",
2896 bpf_map__btf_key_type_id(map), bpf_map__btf_value_type_id(map),
2897 test->btf_kv_notfound))
2903 /* get necessary program info */
2904 info_len = sizeof(struct bpf_prog_info);
2905 err = bpf_obj_get_info_by_fd(prog_fd, &info, &info_len);
2907 if (CHECK(err == -1, "invalid get info (1st) errno:%d", errno)) {
2908 fprintf(stderr, "%s\n", btf_log_buf);
2912 if (CHECK(info.nr_func_info != 3,
2913 "incorrect info.nr_func_info (1st) %d",
2914 info.nr_func_info)) {
2918 rec_size = info.func_info_rec_size;
2919 if (CHECK(rec_size < 4,
2920 "incorrect info.func_info_rec_size (1st) %d\n", rec_size)) {
2925 func_info = malloc(info.nr_func_info * rec_size);
2926 if (CHECK(!func_info, "out of memory")) {
2931 /* reset info to only retrieve func_info related data */
2932 memset(&info, 0, sizeof(info));
2933 info.nr_func_info = 3;
2934 info.func_info_rec_size = rec_size;
2935 info.func_info = ptr_to_u64(func_info);
2937 err = bpf_obj_get_info_by_fd(prog_fd, &info, &info_len);
2939 if (CHECK(err == -1, "invalid get info (2nd) errno:%d", errno)) {
2940 fprintf(stderr, "%s\n", btf_log_buf);
2944 if (CHECK(info.nr_func_info != 3,
2945 "incorrect info.nr_func_info (2nd) %d",
2946 info.nr_func_info)) {
2950 if (CHECK(info.func_info_rec_size != rec_size,
2951 "incorrect info.func_info_rec_size (2nd) %d",
2952 info.func_info_rec_size)) {
2957 err = btf__get_from_id(info.btf_id, &btf);
2958 if (CHECK(err, "cannot get btf from kernel, err: %d", err))
2961 /* check three functions */
2963 for (i = 0; i < 3; i++) {
2964 const struct btf_type *t;
2967 t = btf__type_by_id(btf, finfo->type_id);
2968 if (CHECK(!t, "btf__type_by_id failure: id %u",
2974 fname = btf__name_by_offset(btf, t->name_off);
2975 err = strcmp(fname, expected_fnames[i]);
2976 /* for the second and third functions in .text section,
2977 * the compiler may order them either way.
2980 err = strcmp(fname, expected_fnames[3 - i]);
2981 if (CHECK(err, "incorrect fname %s", fname ? : "")) {
2986 finfo = (void *)finfo + rec_size;
2990 fprintf(stderr, "OK");
2994 bpf_object__close(obj);
2998 static int test_file(void)
3003 if (args.file_test_num)
3004 return count_result(do_test_file(args.file_test_num));
3006 for (i = 1; i <= ARRAY_SIZE(file_tests); i++)
3007 err |= count_result(do_test_file(i));
3012 const char *pprint_enum_str[] = {
3019 struct pprint_mapv {
3024 uint32_t unused_bits2a:2,
3039 static struct btf_raw_test pprint_test_template = {
3041 /* unsighed char */ /* [1] */
3042 BTF_TYPE_INT_ENC(NAME_TBD, 0, 0, 8, 1),
3043 /* unsigned short */ /* [2] */
3044 BTF_TYPE_INT_ENC(NAME_TBD, 0, 0, 16, 2),
3045 /* unsigned int */ /* [3] */
3046 BTF_TYPE_INT_ENC(NAME_TBD, 0, 0, 32, 4),
3048 BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),
3049 /* unsigned long long */ /* [5] */
3050 BTF_TYPE_INT_ENC(NAME_TBD, 0, 0, 64, 8),
3051 /* 2 bits */ /* [6] */
3052 BTF_TYPE_INT_ENC(0, 0, 0, 2, 2),
3053 /* 28 bits */ /* [7] */
3054 BTF_TYPE_INT_ENC(0, 0, 0, 28, 4),
3055 /* uint8_t[8] */ /* [8] */
3056 BTF_TYPE_ARRAY_ENC(9, 1, 8),
3057 /* typedef unsigned char uint8_t */ /* [9] */
3058 BTF_TYPEDEF_ENC(NAME_TBD, 1),
3059 /* typedef unsigned short uint16_t */ /* [10] */
3060 BTF_TYPEDEF_ENC(NAME_TBD, 2),
3061 /* typedef unsigned int uint32_t */ /* [11] */
3062 BTF_TYPEDEF_ENC(NAME_TBD, 3),
3063 /* typedef int int32_t */ /* [12] */
3064 BTF_TYPEDEF_ENC(NAME_TBD, 4),
3065 /* typedef unsigned long long uint64_t *//* [13] */
3066 BTF_TYPEDEF_ENC(NAME_TBD, 5),
3067 /* union (anon) */ /* [14] */
3068 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_UNION, 0, 2), 8),
3069 BTF_MEMBER_ENC(NAME_TBD, 13, 0),/* uint64_t ui64; */
3070 BTF_MEMBER_ENC(NAME_TBD, 8, 0), /* uint8_t ui8a[8]; */
3071 /* enum (anon) */ /* [15] */
3072 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_ENUM, 0, 4), 4),
3073 BTF_ENUM_ENC(NAME_TBD, 0),
3074 BTF_ENUM_ENC(NAME_TBD, 1),
3075 BTF_ENUM_ENC(NAME_TBD, 2),
3076 BTF_ENUM_ENC(NAME_TBD, 3),
3077 /* struct pprint_mapv */ /* [16] */
3078 BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 8), 32),
3079 BTF_MEMBER_ENC(NAME_TBD, 11, 0), /* uint32_t ui32 */
3080 BTF_MEMBER_ENC(NAME_TBD, 10, 32), /* uint16_t ui16 */
3081 BTF_MEMBER_ENC(NAME_TBD, 12, 64), /* int32_t si32 */
3082 BTF_MEMBER_ENC(NAME_TBD, 6, 96), /* unused_bits2a */
3083 BTF_MEMBER_ENC(NAME_TBD, 7, 98), /* bits28 */
3084 BTF_MEMBER_ENC(NAME_TBD, 6, 126), /* unused_bits2b */
3085 BTF_MEMBER_ENC(0, 14, 128), /* union (anon) */
3086 BTF_MEMBER_ENC(NAME_TBD, 15, 192), /* aenum */
3089 .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",
3090 .str_sec_size = sizeof("\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"),
3091 .key_size = sizeof(unsigned int),
3092 .value_size = sizeof(struct pprint_mapv),
3093 .key_type_id = 3, /* unsigned int */
3094 .value_type_id = 16, /* struct pprint_mapv */
3095 .max_entries = 128 * 1024,
3098 static struct btf_pprint_test_meta {
3100 enum bpf_map_type map_type;
3101 const char *map_name;
3105 } pprint_tests_meta[] = {
3107 .descr = "BTF pretty print array",
3108 .map_type = BPF_MAP_TYPE_ARRAY,
3109 .map_name = "pprint_test_array",
3110 .ordered_map = true,
3111 .lossless_map = true,
3112 .percpu_map = false,
3116 .descr = "BTF pretty print hash",
3117 .map_type = BPF_MAP_TYPE_HASH,
3118 .map_name = "pprint_test_hash",
3119 .ordered_map = false,
3120 .lossless_map = true,
3121 .percpu_map = false,
3125 .descr = "BTF pretty print lru hash",
3126 .map_type = BPF_MAP_TYPE_LRU_HASH,
3127 .map_name = "pprint_test_lru_hash",
3128 .ordered_map = false,
3129 .lossless_map = false,
3130 .percpu_map = false,
3134 .descr = "BTF pretty print percpu array",
3135 .map_type = BPF_MAP_TYPE_PERCPU_ARRAY,
3136 .map_name = "pprint_test_percpu_array",
3137 .ordered_map = true,
3138 .lossless_map = true,
3143 .descr = "BTF pretty print percpu hash",
3144 .map_type = BPF_MAP_TYPE_PERCPU_HASH,
3145 .map_name = "pprint_test_percpu_hash",
3146 .ordered_map = false,
3147 .lossless_map = true,
3152 .descr = "BTF pretty print lru percpu hash",
3153 .map_type = BPF_MAP_TYPE_LRU_PERCPU_HASH,
3154 .map_name = "pprint_test_lru_percpu_hash",
3155 .ordered_map = false,
3156 .lossless_map = false,
3163 static void set_pprint_mapv(struct pprint_mapv *v, uint32_t i,
3164 int num_cpus, int rounded_value_size)
3168 for (cpu = 0; cpu < num_cpus; cpu++) {
3171 v->unused_bits2a = 3;
3173 v->unused_bits2b = 3;
3175 v->aenum = i & 0x03;
3176 v = (void *)v + rounded_value_size;
3180 static int check_line(const char *expected_line, int nexpected_line,
3181 int expected_line_len, const char *line)
3183 if (CHECK(nexpected_line == expected_line_len,
3184 "expected_line is too long"))
3187 if (strcmp(expected_line, line)) {
3188 fprintf(stderr, "unexpected pprint output\n");
3189 fprintf(stderr, "expected: %s", expected_line);
3190 fprintf(stderr, " read: %s", line);
3198 static int do_test_pprint(void)
3200 const struct btf_raw_test *test = &pprint_test_template;
3201 struct bpf_create_map_attr create_attr = {};
3202 bool ordered_map, lossless_map, percpu_map;
3203 int err, ret, num_cpus, rounded_value_size;
3204 struct pprint_mapv *mapv = NULL;
3205 unsigned int key, nr_read_elems;
3206 int map_fd = -1, btf_fd = -1;
3207 unsigned int raw_btf_size;
3208 char expected_line[255];
3209 FILE *pin_file = NULL;
3211 size_t line_len = 0;
3216 fprintf(stderr, "%s......", test->descr);
3217 raw_btf = btf_raw_create(&hdr_tmpl, test->raw_types,
3218 test->str_sec, test->str_sec_size,
3219 &raw_btf_size, NULL);
3224 *btf_log_buf = '\0';
3225 btf_fd = bpf_load_btf(raw_btf, raw_btf_size,
3226 btf_log_buf, BTF_LOG_BUF_SIZE,
3230 if (CHECK(btf_fd == -1, "errno:%d", errno)) {
3235 create_attr.name = test->map_name;
3236 create_attr.map_type = test->map_type;
3237 create_attr.key_size = test->key_size;
3238 create_attr.value_size = test->value_size;
3239 create_attr.max_entries = test->max_entries;
3240 create_attr.btf_fd = btf_fd;
3241 create_attr.btf_key_type_id = test->key_type_id;
3242 create_attr.btf_value_type_id = test->value_type_id;
3244 map_fd = bpf_create_map_xattr(&create_attr);
3245 if (CHECK(map_fd == -1, "errno:%d", errno)) {
3250 ret = snprintf(pin_path, sizeof(pin_path), "%s/%s",
3251 "/sys/fs/bpf", test->map_name);
3253 if (CHECK(ret == sizeof(pin_path), "pin_path %s/%s is too long",
3254 "/sys/fs/bpf", test->map_name)) {
3259 err = bpf_obj_pin(map_fd, pin_path);
3260 if (CHECK(err, "bpf_obj_pin(%s): errno:%d.", pin_path, errno))
3263 percpu_map = test->percpu_map;
3264 num_cpus = percpu_map ? bpf_num_possible_cpus() : 1;
3265 rounded_value_size = round_up(sizeof(struct pprint_mapv), 8);
3266 mapv = calloc(num_cpus, rounded_value_size);
3267 if (CHECK(!mapv, "mapv allocation failure")) {
3272 for (key = 0; key < test->max_entries; key++) {
3273 set_pprint_mapv(mapv, key, num_cpus, rounded_value_size);
3274 bpf_map_update_elem(map_fd, &key, mapv, 0);
3277 pin_file = fopen(pin_path, "r");
3278 if (CHECK(!pin_file, "fopen(%s): errno:%d", pin_path, errno)) {
3283 /* Skip lines start with '#' */
3284 while ((nread = getline(&line, &line_len, pin_file)) > 0 &&
3288 if (CHECK(nread <= 0, "Unexpected EOF")) {
3294 ordered_map = test->ordered_map;
3295 lossless_map = test->lossless_map;
3297 struct pprint_mapv *cmapv;
3298 ssize_t nexpected_line;
3299 unsigned int next_key;
3302 next_key = ordered_map ? nr_read_elems : atoi(line);
3303 set_pprint_mapv(mapv, next_key, num_cpus, rounded_value_size);
3306 for (cpu = 0; cpu < num_cpus; cpu++) {
3308 /* for percpu map, the format looks like:
3310 * cpu0: <value_on_cpu0>
3311 * cpu1: <value_on_cpu1>
3313 * cpun: <value_on_cpun>
3316 * let us verify the line containing the key here.
3319 nexpected_line = snprintf(expected_line,
3320 sizeof(expected_line),
3324 err = check_line(expected_line, nexpected_line,
3325 sizeof(expected_line), line);
3330 /* read value@cpu */
3331 nread = getline(&line, &line_len, pin_file);
3336 nexpected_line = snprintf(expected_line, sizeof(expected_line),
3337 "%s%u: {%u,0,%d,0x%x,0x%x,0x%x,"
3338 "{%lu|[%u,%u,%u,%u,%u,%u,%u,%u]},%s}\n",
3339 percpu_map ? "\tcpu" : "",
3340 percpu_map ? cpu : next_key,
3341 cmapv->ui32, cmapv->si32,
3342 cmapv->unused_bits2a,
3344 cmapv->unused_bits2b,
3346 cmapv->ui8a[0], cmapv->ui8a[1],
3347 cmapv->ui8a[2], cmapv->ui8a[3],
3348 cmapv->ui8a[4], cmapv->ui8a[5],
3349 cmapv->ui8a[6], cmapv->ui8a[7],
3350 pprint_enum_str[cmapv->aenum]);
3352 err = check_line(expected_line, nexpected_line,
3353 sizeof(expected_line), line);
3357 cmapv = (void *)cmapv + rounded_value_size;
3361 /* skip the last bracket for the percpu map */
3362 nread = getline(&line, &line_len, pin_file);
3367 nread = getline(&line, &line_len, pin_file);
3368 } while (++nr_read_elems < test->max_entries && nread > 0);
3371 CHECK(nr_read_elems < test->max_entries,
3372 "Unexpected EOF. nr_read_elems:%u test->max_entries:%u",
3373 nr_read_elems, test->max_entries)) {
3378 if (CHECK(nread > 0, "Unexpected extra pprint output: %s", line)) {
3389 fprintf(stderr, "OK");
3390 if (*btf_log_buf && (err || args.always_log))
3391 fprintf(stderr, "\n%s", btf_log_buf);
3404 static int test_pprint(void)
3409 for (i = 0; i < ARRAY_SIZE(pprint_tests_meta); i++) {
3410 pprint_test_template.descr = pprint_tests_meta[i].descr;
3411 pprint_test_template.map_type = pprint_tests_meta[i].map_type;
3412 pprint_test_template.map_name = pprint_tests_meta[i].map_name;
3413 pprint_test_template.ordered_map = pprint_tests_meta[i].ordered_map;
3414 pprint_test_template.lossless_map = pprint_tests_meta[i].lossless_map;
3415 pprint_test_template.percpu_map = pprint_tests_meta[i].percpu_map;
3417 err |= count_result(do_test_pprint());
3423 #define BPF_LINE_INFO_ENC(insn_off, file_off, line_off, line_num, line_col) \
3424 (insn_off), (file_off), (line_off), ((line_num) << 10 | ((line_col) & 0x3ff))
3426 static struct prog_info_raw_test {
3428 const char *str_sec;
3429 const char *err_str;
3430 __u32 raw_types[MAX_NR_RAW_U32];
3432 struct bpf_insn insns[MAX_INSNS];
3434 __u32 func_info[MAX_SUBPROGS][2];
3435 __u32 func_info_rec_size;
3436 __u32 func_info_cnt;
3437 __u32 line_info[MAX_NR_RAW_U32];
3438 __u32 line_info_rec_size;
3439 __u32 nr_jited_ksyms;
3440 bool expected_prog_load_failure;
3441 } info_raw_tests[] = {
3443 .descr = "func_type (main func + one sub)",
3445 BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
3446 BTF_TYPE_INT_ENC(NAME_TBD, 0, 0, 32, 4), /* [2] */
3447 BTF_FUNC_PROTO_ENC(1, 2), /* [3] */
3448 BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
3449 BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 2),
3450 BTF_FUNC_PROTO_ENC(1, 2), /* [4] */
3451 BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 2),
3452 BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
3453 BTF_FUNC_ENC(NAME_TBD, 3), /* [5] */
3454 BTF_FUNC_ENC(NAME_TBD, 4), /* [6] */
3457 .str_sec = "\0int\0unsigned int\0a\0b\0c\0d\0funcA\0funcB",
3458 .str_sec_size = sizeof("\0int\0unsigned int\0a\0b\0c\0d\0funcA\0funcB"),
3460 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2),
3461 BPF_MOV64_IMM(BPF_REG_0, 1),
3463 BPF_MOV64_IMM(BPF_REG_0, 2),
3466 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
3467 .func_info = { {0, 5}, {3, 6} },
3468 .func_info_rec_size = 8,
3470 .line_info = { BTF_END_RAW },
3474 .descr = "func_type (Incorrect func_info_rec_size)",
3476 BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
3477 BTF_TYPE_INT_ENC(NAME_TBD, 0, 0, 32, 4), /* [2] */
3478 BTF_FUNC_PROTO_ENC(1, 2), /* [3] */
3479 BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
3480 BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 2),
3481 BTF_FUNC_PROTO_ENC(1, 2), /* [4] */
3482 BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 2),
3483 BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
3484 BTF_FUNC_ENC(NAME_TBD, 3), /* [5] */
3485 BTF_FUNC_ENC(NAME_TBD, 4), /* [6] */
3488 .str_sec = "\0int\0unsigned int\0a\0b\0c\0d\0funcA\0funcB",
3489 .str_sec_size = sizeof("\0int\0unsigned int\0a\0b\0c\0d\0funcA\0funcB"),
3491 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2),
3492 BPF_MOV64_IMM(BPF_REG_0, 1),
3494 BPF_MOV64_IMM(BPF_REG_0, 2),
3497 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
3498 .func_info = { {0, 5}, {3, 6} },
3499 .func_info_rec_size = 4,
3501 .line_info = { BTF_END_RAW },
3502 .expected_prog_load_failure = true,
3506 .descr = "func_type (Incorrect func_info_cnt)",
3508 BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
3509 BTF_TYPE_INT_ENC(NAME_TBD, 0, 0, 32, 4), /* [2] */
3510 BTF_FUNC_PROTO_ENC(1, 2), /* [3] */
3511 BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
3512 BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 2),
3513 BTF_FUNC_PROTO_ENC(1, 2), /* [4] */
3514 BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 2),
3515 BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
3516 BTF_FUNC_ENC(NAME_TBD, 3), /* [5] */
3517 BTF_FUNC_ENC(NAME_TBD, 4), /* [6] */
3520 .str_sec = "\0int\0unsigned int\0a\0b\0c\0d\0funcA\0funcB",
3521 .str_sec_size = sizeof("\0int\0unsigned int\0a\0b\0c\0d\0funcA\0funcB"),
3523 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2),
3524 BPF_MOV64_IMM(BPF_REG_0, 1),
3526 BPF_MOV64_IMM(BPF_REG_0, 2),
3529 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
3530 .func_info = { {0, 5}, {3, 6} },
3531 .func_info_rec_size = 8,
3533 .line_info = { BTF_END_RAW },
3534 .expected_prog_load_failure = true,
3538 .descr = "func_type (Incorrect bpf_func_info.insn_off)",
3540 BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
3541 BTF_TYPE_INT_ENC(NAME_TBD, 0, 0, 32, 4), /* [2] */
3542 BTF_FUNC_PROTO_ENC(1, 2), /* [3] */
3543 BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
3544 BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 2),
3545 BTF_FUNC_PROTO_ENC(1, 2), /* [4] */
3546 BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 2),
3547 BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
3548 BTF_FUNC_ENC(NAME_TBD, 3), /* [5] */
3549 BTF_FUNC_ENC(NAME_TBD, 4), /* [6] */
3552 .str_sec = "\0int\0unsigned int\0a\0b\0c\0d\0funcA\0funcB",
3553 .str_sec_size = sizeof("\0int\0unsigned int\0a\0b\0c\0d\0funcA\0funcB"),
3555 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2),
3556 BPF_MOV64_IMM(BPF_REG_0, 1),
3558 BPF_MOV64_IMM(BPF_REG_0, 2),
3561 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
3562 .func_info = { {0, 5}, {2, 6} },
3563 .func_info_rec_size = 8,
3565 .line_info = { BTF_END_RAW },
3566 .expected_prog_load_failure = true,
3570 .descr = "line_info (No subprog)",
3572 BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
3575 BTF_STR_SEC("\0int\0int a=1;\0int b=2;\0return a + b;\0return a + b;"),
3577 BPF_MOV64_IMM(BPF_REG_0, 1),
3578 BPF_MOV64_IMM(BPF_REG_1, 2),
3579 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
3582 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
3585 BPF_LINE_INFO_ENC(0, 0, NAME_TBD, 1, 10),
3586 BPF_LINE_INFO_ENC(1, 0, NAME_TBD, 2, 9),
3587 BPF_LINE_INFO_ENC(2, 0, NAME_TBD, 3, 8),
3588 BPF_LINE_INFO_ENC(3, 0, NAME_TBD, 4, 7),
3591 .line_info_rec_size = sizeof(struct bpf_line_info),
3592 .nr_jited_ksyms = 1,
3596 .descr = "line_info (No subprog. insn_off >= prog->len)",
3598 BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
3601 BTF_STR_SEC("\0int\0int a=1;\0int b=2;\0return a + b;\0return a + b;"),
3603 BPF_MOV64_IMM(BPF_REG_0, 1),
3604 BPF_MOV64_IMM(BPF_REG_1, 2),
3605 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
3608 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
3611 BPF_LINE_INFO_ENC(0, 0, NAME_TBD, 1, 10),
3612 BPF_LINE_INFO_ENC(1, 0, NAME_TBD, 2, 9),
3613 BPF_LINE_INFO_ENC(2, 0, NAME_TBD, 3, 8),
3614 BPF_LINE_INFO_ENC(3, 0, NAME_TBD, 4, 7),
3615 BPF_LINE_INFO_ENC(4, 0, 0, 5, 6),
3618 .line_info_rec_size = sizeof(struct bpf_line_info),
3619 .nr_jited_ksyms = 1,
3620 .err_str = "line_info[4].insn_off",
3621 .expected_prog_load_failure = true,
3625 .descr = "line_info (No subprog. zero tailing line_info",
3627 BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
3630 BTF_STR_SEC("\0int\0int a=1;\0int b=2;\0return a + b;\0return a + b;"),
3632 BPF_MOV64_IMM(BPF_REG_0, 1),
3633 BPF_MOV64_IMM(BPF_REG_1, 2),
3634 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
3637 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
3640 BPF_LINE_INFO_ENC(0, 0, NAME_TBD, 1, 10), 0,
3641 BPF_LINE_INFO_ENC(1, 0, NAME_TBD, 2, 9), 0,
3642 BPF_LINE_INFO_ENC(2, 0, NAME_TBD, 3, 8), 0,
3643 BPF_LINE_INFO_ENC(3, 0, NAME_TBD, 4, 7), 0,
3646 .line_info_rec_size = sizeof(struct bpf_line_info) + sizeof(__u32),
3647 .nr_jited_ksyms = 1,
3651 .descr = "line_info (No subprog. nonzero tailing line_info)",
3653 BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
3656 BTF_STR_SEC("\0int\0int a=1;\0int b=2;\0return a + b;\0return a + b;"),
3658 BPF_MOV64_IMM(BPF_REG_0, 1),
3659 BPF_MOV64_IMM(BPF_REG_1, 2),
3660 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
3663 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
3666 BPF_LINE_INFO_ENC(0, 0, NAME_TBD, 1, 10), 0,
3667 BPF_LINE_INFO_ENC(1, 0, NAME_TBD, 2, 9), 0,
3668 BPF_LINE_INFO_ENC(2, 0, NAME_TBD, 3, 8), 0,
3669 BPF_LINE_INFO_ENC(3, 0, NAME_TBD, 4, 7), 1,
3672 .line_info_rec_size = sizeof(struct bpf_line_info) + sizeof(__u32),
3673 .nr_jited_ksyms = 1,
3674 .err_str = "nonzero tailing record in line_info",
3675 .expected_prog_load_failure = true,
3679 .descr = "line_info (subprog)",
3681 BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
3684 BTF_STR_SEC("\0int\0int a=1+1;\0return func(a);\0b+=1;\0return b;"),
3686 BPF_MOV64_IMM(BPF_REG_2, 1),
3687 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, 1),
3688 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
3691 BPF_MOV64_REG(BPF_REG_0, BPF_REG_1),
3692 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 1),
3695 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
3698 BPF_LINE_INFO_ENC(0, 0, NAME_TBD, 1, 10),
3699 BPF_LINE_INFO_ENC(2, 0, NAME_TBD, 2, 9),
3700 BPF_LINE_INFO_ENC(5, 0, NAME_TBD, 3, 8),
3701 BPF_LINE_INFO_ENC(7, 0, NAME_TBD, 4, 7),
3704 .line_info_rec_size = sizeof(struct bpf_line_info),
3705 .nr_jited_ksyms = 2,
3709 .descr = "line_info (subprog + func_info)",
3711 BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
3712 BTF_FUNC_PROTO_ENC(1, 1), /* [2] */
3713 BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
3714 BTF_FUNC_ENC(NAME_TBD, 2), /* [3] */
3715 BTF_FUNC_ENC(NAME_TBD, 2), /* [4] */
3718 BTF_STR_SEC("\0int\0x\0sub\0main\0int a=1+1;\0return func(a);\0b+=1;\0return b;"),
3720 BPF_MOV64_IMM(BPF_REG_2, 1),
3721 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, 1),
3722 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
3725 BPF_MOV64_REG(BPF_REG_0, BPF_REG_1),
3726 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 1),
3729 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
3731 .func_info_rec_size = 8,
3732 .func_info = { {0, 4}, {5, 3} },
3734 BPF_LINE_INFO_ENC(0, 0, NAME_TBD, 1, 10),
3735 BPF_LINE_INFO_ENC(2, 0, NAME_TBD, 2, 9),
3736 BPF_LINE_INFO_ENC(5, 0, NAME_TBD, 3, 8),
3737 BPF_LINE_INFO_ENC(7, 0, NAME_TBD, 4, 7),
3740 .line_info_rec_size = sizeof(struct bpf_line_info),
3741 .nr_jited_ksyms = 2,
3745 .descr = "line_info (subprog. missing 1st func line info)",
3747 BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
3750 BTF_STR_SEC("\0int\0int a=1+1;\0return func(a);\0b+=1;\0return b;"),
3752 BPF_MOV64_IMM(BPF_REG_2, 1),
3753 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, 1),
3754 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
3757 BPF_MOV64_REG(BPF_REG_0, BPF_REG_1),
3758 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 1),
3761 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
3764 BPF_LINE_INFO_ENC(1, 0, NAME_TBD, 1, 10),
3765 BPF_LINE_INFO_ENC(2, 0, NAME_TBD, 2, 9),
3766 BPF_LINE_INFO_ENC(5, 0, NAME_TBD, 3, 8),
3767 BPF_LINE_INFO_ENC(7, 0, NAME_TBD, 4, 7),
3770 .line_info_rec_size = sizeof(struct bpf_line_info),
3771 .nr_jited_ksyms = 2,
3772 .err_str = "missing bpf_line_info for func#0",
3773 .expected_prog_load_failure = true,
3777 .descr = "line_info (subprog. missing 2nd func line info)",
3779 BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
3782 BTF_STR_SEC("\0int\0int a=1+1;\0return func(a);\0b+=1;\0return b;"),
3784 BPF_MOV64_IMM(BPF_REG_2, 1),
3785 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, 1),
3786 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
3789 BPF_MOV64_REG(BPF_REG_0, BPF_REG_1),
3790 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 1),
3793 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
3796 BPF_LINE_INFO_ENC(0, 0, NAME_TBD, 1, 10),
3797 BPF_LINE_INFO_ENC(2, 0, NAME_TBD, 2, 9),
3798 BPF_LINE_INFO_ENC(6, 0, NAME_TBD, 3, 8),
3799 BPF_LINE_INFO_ENC(7, 0, NAME_TBD, 4, 7),
3802 .line_info_rec_size = sizeof(struct bpf_line_info),
3803 .nr_jited_ksyms = 2,
3804 .err_str = "missing bpf_line_info for func#1",
3805 .expected_prog_load_failure = true,
3809 .descr = "line_info (subprog. unordered insn offset)",
3811 BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
3814 BTF_STR_SEC("\0int\0int a=1+1;\0return func(a);\0b+=1;\0return b;"),
3816 BPF_MOV64_IMM(BPF_REG_2, 1),
3817 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, 1),
3818 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
3821 BPF_MOV64_REG(BPF_REG_0, BPF_REG_1),
3822 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 1),
3825 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
3828 BPF_LINE_INFO_ENC(0, 0, NAME_TBD, 1, 10),
3829 BPF_LINE_INFO_ENC(5, 0, NAME_TBD, 2, 9),
3830 BPF_LINE_INFO_ENC(2, 0, NAME_TBD, 3, 8),
3831 BPF_LINE_INFO_ENC(7, 0, NAME_TBD, 4, 7),
3834 .line_info_rec_size = sizeof(struct bpf_line_info),
3835 .nr_jited_ksyms = 2,
3836 .err_str = "Invalid line_info[2].insn_off",
3837 .expected_prog_load_failure = true,
3842 static size_t probe_prog_length(const struct bpf_insn *fp)
3846 for (len = MAX_INSNS - 1; len > 0; --len)
3847 if (fp[len].code != 0 || fp[len].imm != 0)
3852 static __u32 *patch_name_tbd(const __u32 *raw_u32,
3853 const char *str, __u32 str_off,
3854 unsigned int str_sec_size,
3855 unsigned int *ret_size)
3857 int i, raw_u32_size = get_raw_sec_size(raw_u32);
3858 const char *end_str = str + str_sec_size;
3859 const char *next_str = str + str_off;
3860 __u32 *new_u32 = NULL;
3862 if (raw_u32_size == -1)
3863 return ERR_PTR(-EINVAL);
3865 if (!raw_u32_size) {
3870 new_u32 = malloc(raw_u32_size);
3872 return ERR_PTR(-ENOMEM);
3874 for (i = 0; i < raw_u32_size / sizeof(raw_u32[0]); i++) {
3875 if (raw_u32[i] == NAME_TBD) {
3876 next_str = get_next_str(next_str, end_str);
3877 if (CHECK(!next_str, "Error in getting next_str\n")) {
3879 return ERR_PTR(-EINVAL);
3881 new_u32[i] = next_str - str;
3882 next_str += strlen(next_str);
3884 new_u32[i] = raw_u32[i];
3888 *ret_size = raw_u32_size;
3892 static int test_get_finfo(const struct prog_info_raw_test *test,
3895 struct bpf_prog_info info = {};
3896 struct bpf_func_info *finfo;
3897 __u32 info_len, rec_size, i;
3898 void *func_info = NULL;
3901 /* get necessary lens */
3902 info_len = sizeof(struct bpf_prog_info);
3903 err = bpf_obj_get_info_by_fd(prog_fd, &info, &info_len);
3904 if (CHECK(err == -1, "invalid get info (1st) errno:%d", errno)) {
3905 fprintf(stderr, "%s\n", btf_log_buf);
3908 if (CHECK(info.nr_func_info != test->func_info_cnt,
3909 "incorrect info.nr_func_info (1st) %d",
3910 info.nr_func_info)) {
3914 rec_size = info.func_info_rec_size;
3915 if (CHECK(rec_size < 8,
3916 "incorrect info.func_info_rec_size (1st) %d", rec_size)) {
3920 if (!info.nr_func_info)
3923 func_info = malloc(info.nr_func_info * rec_size);
3924 if (CHECK(!func_info, "out of memory"))
3927 /* reset info to only retrieve func_info related data */
3928 memset(&info, 0, sizeof(info));
3929 info.nr_func_info = test->func_info_cnt;
3930 info.func_info_rec_size = rec_size;
3931 info.func_info = ptr_to_u64(func_info);
3932 err = bpf_obj_get_info_by_fd(prog_fd, &info, &info_len);
3933 if (CHECK(err == -1, "invalid get info (2nd) errno:%d", errno)) {
3934 fprintf(stderr, "%s\n", btf_log_buf);
3938 if (CHECK(info.nr_func_info != test->func_info_cnt,
3939 "incorrect info.nr_func_info (2nd) %d",
3940 info.nr_func_info)) {
3944 if (CHECK(info.func_info_rec_size < 8,
3945 "incorrect info.func_info_rec_size (2nd) %d",
3946 info.func_info_rec_size)) {
3951 if (CHECK(!info.func_info,
3952 "info.func_info == 0. kernel.kptr_restrict is set?")) {
3958 for (i = 0; i < test->func_info_cnt; i++) {
3959 if (CHECK(finfo->type_id != test->func_info[i][1],
3960 "incorrect func_type %u expected %u",
3961 finfo->type_id, test->func_info[i][1])) {
3965 finfo = (void *)finfo + rec_size;
3975 static int test_get_linfo(const struct prog_info_raw_test *test,
3976 const void *patched_linfo,
3977 __u32 cnt, int prog_fd)
3979 __u32 i, info_len, nr_jited_ksyms, nr_jited_func_lens;
3980 __u64 *jited_linfo = NULL, *jited_ksyms = NULL;
3981 __u32 rec_size, jited_rec_size, jited_cnt;
3982 struct bpf_line_info *linfo = NULL;
3983 __u32 cur_func_len, ksyms_found;
3984 struct bpf_prog_info info = {};
3985 __u32 *jited_func_lens = NULL;
3986 __u64 cur_func_ksyms;
3990 rec_size = sizeof(*linfo);
3991 jited_rec_size = sizeof(*jited_linfo);
3992 if (test->nr_jited_ksyms)
3993 nr_jited_ksyms = test->nr_jited_ksyms;
3995 nr_jited_ksyms = test->func_info_cnt;
3996 nr_jited_func_lens = nr_jited_ksyms;
3998 info_len = sizeof(struct bpf_prog_info);
3999 err = bpf_obj_get_info_by_fd(prog_fd, &info, &info_len);
4000 if (CHECK(err == -1, "err:%d errno:%d", err, errno)) {
4005 if (!info.jited_prog_len) {
4006 /* prog is not jited */
4009 nr_jited_func_lens = 1;
4012 if (CHECK(info.nr_line_info != cnt ||
4013 info.nr_jited_line_info != jited_cnt ||
4014 info.nr_jited_ksyms != nr_jited_ksyms ||
4015 info.nr_jited_func_lens != nr_jited_func_lens ||
4016 (!info.nr_line_info && info.nr_jited_line_info),
4017 "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)",
4018 info.nr_line_info, cnt,
4019 info.nr_jited_line_info, jited_cnt,
4020 info.nr_jited_ksyms, nr_jited_ksyms,
4021 info.nr_jited_func_lens, nr_jited_func_lens)) {
4026 if (CHECK(info.line_info_rec_size < 16 ||
4027 info.jited_line_info_rec_size < 8,
4028 "info: line_info_rec_size:%u(userspace expected:%u) jited_line_info_rec_size:%u(userspace expected:%u)",
4029 info.line_info_rec_size, rec_size,
4030 info.jited_line_info_rec_size, jited_rec_size)) {
4038 rec_size = info.line_info_rec_size;
4039 jited_rec_size = info.jited_line_info_rec_size;
4041 memset(&info, 0, sizeof(info));
4043 linfo = calloc(cnt, rec_size);
4044 if (CHECK(!linfo, "!linfo")) {
4048 info.nr_line_info = cnt;
4049 info.line_info_rec_size = rec_size;
4050 info.line_info = ptr_to_u64(linfo);
4053 jited_linfo = calloc(jited_cnt, jited_rec_size);
4054 jited_ksyms = calloc(nr_jited_ksyms, sizeof(*jited_ksyms));
4055 jited_func_lens = calloc(nr_jited_func_lens,
4056 sizeof(*jited_func_lens));
4057 if (CHECK(!jited_linfo || !jited_ksyms || !jited_func_lens,
4058 "jited_linfo:%p jited_ksyms:%p jited_func_lens:%p",
4059 jited_linfo, jited_ksyms, jited_func_lens)) {
4064 info.nr_jited_line_info = jited_cnt;
4065 info.jited_line_info_rec_size = jited_rec_size;
4066 info.jited_line_info = ptr_to_u64(jited_linfo);
4067 info.nr_jited_ksyms = nr_jited_ksyms;
4068 info.jited_ksyms = ptr_to_u64(jited_ksyms);
4069 info.nr_jited_func_lens = nr_jited_func_lens;
4070 info.jited_func_lens = ptr_to_u64(jited_func_lens);
4073 err = bpf_obj_get_info_by_fd(prog_fd, &info, &info_len);
4076 * Only recheck the info.*line_info* fields.
4077 * Other fields are not the concern of this test.
4079 if (CHECK(err == -1 ||
4081 info.nr_line_info != cnt ||
4082 (jited_cnt && !info.jited_line_info) ||
4083 info.nr_jited_line_info != jited_cnt ||
4084 info.line_info_rec_size != rec_size ||
4085 info.jited_line_info_rec_size != jited_rec_size,
4086 "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",
4088 info.nr_line_info, cnt,
4089 info.nr_jited_line_info, jited_cnt,
4090 info.line_info_rec_size, rec_size,
4091 info.jited_line_info_rec_size, jited_rec_size,
4092 (void *)(long)info.line_info,
4093 (void *)(long)info.jited_line_info)) {
4098 CHECK(linfo[0].insn_off, "linfo[0].insn_off:%u",
4100 for (i = 1; i < cnt; i++) {
4101 const struct bpf_line_info *expected_linfo;
4103 expected_linfo = patched_linfo + (i * test->line_info_rec_size);
4104 if (CHECK(linfo[i].insn_off <= linfo[i - 1].insn_off,
4105 "linfo[%u].insn_off:%u <= linfo[%u].insn_off:%u",
4106 i, linfo[i].insn_off,
4107 i - 1, linfo[i - 1].insn_off)) {
4111 if (CHECK(linfo[i].file_name_off != expected_linfo->file_name_off ||
4112 linfo[i].line_off != expected_linfo->line_off ||
4113 linfo[i].line_col != expected_linfo->line_col,
4114 "linfo[%u] (%u, %u, %u) != (%u, %u, %u)", i,
4115 linfo[i].file_name_off,
4118 expected_linfo->file_name_off,
4119 expected_linfo->line_off,
4120 expected_linfo->line_col)) {
4127 fprintf(stderr, "not jited. skipping jited_line_info check. ");
4132 if (CHECK(jited_linfo[0] != jited_ksyms[0],
4133 "jited_linfo[0]:%lx != jited_ksyms[0]:%lx",
4134 (long)(jited_linfo[0]), (long)(jited_ksyms[0]))) {
4140 cur_func_len = jited_func_lens[0];
4141 cur_func_ksyms = jited_ksyms[0];
4142 for (i = 1; i < jited_cnt; i++) {
4143 if (ksyms_found < nr_jited_ksyms &&
4144 jited_linfo[i] == jited_ksyms[ksyms_found]) {
4145 cur_func_ksyms = jited_ksyms[ksyms_found];
4146 cur_func_len = jited_ksyms[ksyms_found];
4151 if (CHECK(jited_linfo[i] <= jited_linfo[i - 1],
4152 "jited_linfo[%u]:%lx <= jited_linfo[%u]:%lx",
4153 i, (long)jited_linfo[i],
4154 i - 1, (long)(jited_linfo[i - 1]))) {
4159 if (CHECK(jited_linfo[i] - cur_func_ksyms > cur_func_len,
4160 "jited_linfo[%u]:%lx - %lx > %u",
4161 i, (long)jited_linfo[i], (long)cur_func_ksyms,
4168 if (CHECK(ksyms_found != nr_jited_ksyms,
4169 "ksyms_found:%u != nr_jited_ksyms:%u",
4170 ksyms_found, nr_jited_ksyms)) {
4181 free(jited_func_lens);
4185 static int do_test_info_raw(unsigned int test_num)
4187 const struct prog_info_raw_test *test = &info_raw_tests[test_num - 1];
4188 unsigned int raw_btf_size, linfo_str_off, linfo_size;
4189 int btf_fd = -1, prog_fd = -1, err = 0;
4190 void *raw_btf, *patched_linfo = NULL;
4191 const char *ret_next_str;
4192 union bpf_attr attr = {};
4194 fprintf(stderr, "BTF prog info raw test[%u] (%s): ", test_num, test->descr);
4195 raw_btf = btf_raw_create(&hdr_tmpl, test->raw_types,
4196 test->str_sec, test->str_sec_size,
4197 &raw_btf_size, &ret_next_str);
4202 *btf_log_buf = '\0';
4203 btf_fd = bpf_load_btf(raw_btf, raw_btf_size,
4204 btf_log_buf, BTF_LOG_BUF_SIZE,
4208 if (CHECK(btf_fd == -1, "invalid btf_fd errno:%d", errno)) {
4213 if (*btf_log_buf && args.always_log)
4214 fprintf(stderr, "\n%s", btf_log_buf);
4215 *btf_log_buf = '\0';
4217 linfo_str_off = ret_next_str - test->str_sec;
4218 patched_linfo = patch_name_tbd(test->line_info,
4219 test->str_sec, linfo_str_off,
4220 test->str_sec_size, &linfo_size);
4221 if (IS_ERR(patched_linfo)) {
4222 fprintf(stderr, "error in creating raw bpf_line_info");
4227 attr.prog_type = test->prog_type;
4228 attr.insns = ptr_to_u64(test->insns);
4229 attr.insn_cnt = probe_prog_length(test->insns);
4230 attr.license = ptr_to_u64("GPL");
4231 attr.prog_btf_fd = btf_fd;
4232 attr.func_info_rec_size = test->func_info_rec_size;
4233 attr.func_info_cnt = test->func_info_cnt;
4234 attr.func_info = ptr_to_u64(test->func_info);
4235 attr.log_buf = ptr_to_u64(btf_log_buf);
4236 attr.log_size = BTF_LOG_BUF_SIZE;
4239 attr.line_info_rec_size = test->line_info_rec_size;
4240 attr.line_info = ptr_to_u64(patched_linfo);
4241 attr.line_info_cnt = linfo_size / attr.line_info_rec_size;
4244 prog_fd = syscall(__NR_bpf, BPF_PROG_LOAD, &attr, sizeof(attr));
4245 err = ((prog_fd == -1) != test->expected_prog_load_failure);
4246 if (CHECK(err, "prog_fd:%d expected_prog_load_failure:%u errno:%d",
4247 prog_fd, test->expected_prog_load_failure, errno) ||
4248 CHECK(test->err_str && !strstr(btf_log_buf, test->err_str),
4249 "expected err_str:%s", test->err_str)) {
4257 err = test_get_finfo(test, prog_fd);
4261 err = test_get_linfo(test, patched_linfo, attr.line_info_cnt, prog_fd);
4267 fprintf(stderr, "OK");
4269 if (*btf_log_buf && (err || args.always_log))
4270 fprintf(stderr, "\n%s", btf_log_buf);
4277 if (!IS_ERR(patched_linfo))
4278 free(patched_linfo);
4283 static int test_info_raw(void)
4288 if (args.info_raw_test_num)
4289 return count_result(do_test_info_raw(args.info_raw_test_num));
4291 for (i = 1; i <= ARRAY_SIZE(info_raw_tests); i++)
4292 err |= count_result(do_test_info_raw(i));
4297 static void usage(const char *cmd)
4299 fprintf(stderr, "Usage: %s [-l] [[-r btf_raw_test_num (1 - %zu)] |\n"
4300 "\t[-g btf_get_info_test_num (1 - %zu)] |\n"
4301 "\t[-f btf_file_test_num (1 - %zu)] |\n"
4302 "\t[-k btf_prog_info_raw_test_num (1 - %zu)] |\n"
4303 "\t[-p (pretty print test)]]\n",
4304 cmd, ARRAY_SIZE(raw_tests), ARRAY_SIZE(get_info_tests),
4305 ARRAY_SIZE(file_tests), ARRAY_SIZE(info_raw_tests));
4308 static int parse_args(int argc, char **argv)
4310 const char *optstr = "lpk:f:r:g:";
4313 while ((opt = getopt(argc, argv, optstr)) != -1) {
4316 args.always_log = true;
4319 args.file_test_num = atoi(optarg);
4320 args.file_test = true;
4323 args.raw_test_num = atoi(optarg);
4324 args.raw_test = true;
4327 args.get_info_test_num = atoi(optarg);
4328 args.get_info_test = true;
4331 args.pprint_test = true;
4334 args.info_raw_test_num = atoi(optarg);
4335 args.info_raw_test = true;
4346 if (args.raw_test_num &&
4347 (args.raw_test_num < 1 ||
4348 args.raw_test_num > ARRAY_SIZE(raw_tests))) {
4349 fprintf(stderr, "BTF raw test number must be [1 - %zu]\n",
4350 ARRAY_SIZE(raw_tests));
4354 if (args.file_test_num &&
4355 (args.file_test_num < 1 ||
4356 args.file_test_num > ARRAY_SIZE(file_tests))) {
4357 fprintf(stderr, "BTF file test number must be [1 - %zu]\n",
4358 ARRAY_SIZE(file_tests));
4362 if (args.get_info_test_num &&
4363 (args.get_info_test_num < 1 ||
4364 args.get_info_test_num > ARRAY_SIZE(get_info_tests))) {
4365 fprintf(stderr, "BTF get info test number must be [1 - %zu]\n",
4366 ARRAY_SIZE(get_info_tests));
4370 if (args.info_raw_test_num &&
4371 (args.info_raw_test_num < 1 ||
4372 args.info_raw_test_num > ARRAY_SIZE(info_raw_tests))) {
4373 fprintf(stderr, "BTF prog info raw test number must be [1 - %zu]\n",
4374 ARRAY_SIZE(info_raw_tests));
4381 static void print_summary(void)
4383 fprintf(stderr, "PASS:%u SKIP:%u FAIL:%u\n",
4384 pass_cnt - skip_cnt, skip_cnt, error_cnt);
4387 int main(int argc, char **argv)
4391 err = parse_args(argc, argv);
4395 if (args.always_log)
4396 libbpf_set_print(__base_pr, __base_pr, __base_pr);
4401 if (args.get_info_test)
4402 err |= test_get_info();
4407 if (args.pprint_test)
4408 err |= test_pprint();
4410 if (args.info_raw_test)
4411 err |= test_info_raw();
4413 if (args.raw_test || args.get_info_test || args.file_test ||
4414 args.pprint_test || args.info_raw_test)
4418 err |= test_get_info();
4420 err |= test_info_raw();