1
2
3
4#include <linux/bpf.h>
5#include <linux/btf.h>
6#include <linux/err.h>
7#include <linux/kernel.h>
8#include <linux/filter.h>
9#include <linux/unistd.h>
10#include <bpf/bpf.h>
11#include <sys/resource.h>
12#include <libelf.h>
13#include <gelf.h>
14#include <string.h>
15#include <stdlib.h>
16#include <stdio.h>
17#include <stdarg.h>
18#include <unistd.h>
19#include <fcntl.h>
20#include <errno.h>
21#include <bpf/libbpf.h>
22#include <bpf/btf.h>
23
24#include "bpf_rlimit.h"
25#include "bpf_util.h"
26
27#define MAX_INSNS 512
28#define MAX_SUBPROGS 16
29
30static uint32_t pass_cnt;
31static uint32_t error_cnt;
32static uint32_t skip_cnt;
33
34#define CHECK(condition, format...) ({ \
35 int __ret = !!(condition); \
36 if (__ret) { \
37 fprintf(stderr, "%s:%d:FAIL ", __func__, __LINE__); \
38 fprintf(stderr, format); \
39 } \
40 __ret; \
41})
42
43static int count_result(int err)
44{
45 if (err)
46 error_cnt++;
47 else
48 pass_cnt++;
49
50 fprintf(stderr, "\n");
51 return err;
52}
53
54static int __base_pr(enum libbpf_print_level level __attribute__((unused)),
55 const char *format, va_list args)
56{
57 return vfprintf(stderr, format, args);
58}
59
60#define BTF_INFO_ENC(kind, kind_flag, vlen) \
61 ((!!(kind_flag) << 31) | ((kind) << 24) | ((vlen) & BTF_MAX_VLEN))
62
63#define BTF_TYPE_ENC(name, info, size_or_type) \
64 (name), (info), (size_or_type)
65
66#define BTF_INT_ENC(encoding, bits_offset, nr_bits) \
67 ((encoding) << 24 | (bits_offset) << 16 | (nr_bits))
68#define BTF_TYPE_INT_ENC(name, encoding, bits_offset, bits, sz) \
69 BTF_TYPE_ENC(name, BTF_INFO_ENC(BTF_KIND_INT, 0, 0), sz), \
70 BTF_INT_ENC(encoding, bits_offset, bits)
71
72#define BTF_FWD_ENC(name, kind_flag) \
73 BTF_TYPE_ENC(name, BTF_INFO_ENC(BTF_KIND_FWD, kind_flag, 0), 0)
74
75#define BTF_ARRAY_ENC(type, index_type, nr_elems) \
76 (type), (index_type), (nr_elems)
77#define BTF_TYPE_ARRAY_ENC(type, index_type, nr_elems) \
78 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_ARRAY, 0, 0), 0), \
79 BTF_ARRAY_ENC(type, index_type, nr_elems)
80
81#define BTF_STRUCT_ENC(name, nr_elems, sz) \
82 BTF_TYPE_ENC(name, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, nr_elems), sz)
83
84#define BTF_UNION_ENC(name, nr_elems, sz) \
85 BTF_TYPE_ENC(name, BTF_INFO_ENC(BTF_KIND_UNION, 0, nr_elems), sz)
86
87#define BTF_MEMBER_ENC(name, type, bits_offset) \
88 (name), (type), (bits_offset)
89#define BTF_ENUM_ENC(name, val) (name), (val)
90#define BTF_MEMBER_OFFSET(bitfield_size, bits_offset) \
91 ((bitfield_size) << 24 | (bits_offset))
92
93#define BTF_TYPEDEF_ENC(name, type) \
94 BTF_TYPE_ENC(name, BTF_INFO_ENC(BTF_KIND_TYPEDEF, 0, 0), type)
95
96#define BTF_PTR_ENC(type) \
97 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_PTR, 0, 0), type)
98
99#define BTF_CONST_ENC(type) \
100 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_CONST, 0, 0), type)
101
102#define BTF_VOLATILE_ENC(type) \
103 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_VOLATILE, 0, 0), type)
104
105#define BTF_RESTRICT_ENC(type) \
106 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_RESTRICT, 0, 0), type)
107
108#define BTF_FUNC_PROTO_ENC(ret_type, nargs) \
109 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_FUNC_PROTO, 0, nargs), ret_type)
110
111#define BTF_FUNC_PROTO_ARG_ENC(name, type) \
112 (name), (type)
113
114#define BTF_FUNC_ENC(name, func_proto) \
115 BTF_TYPE_ENC(name, BTF_INFO_ENC(BTF_KIND_FUNC, 0, 0), func_proto)
116
117#define BTF_END_RAW 0xdeadbeef
118#define NAME_TBD 0xdeadb33f
119
120#define NAME_NTH(N) (0xffff0000 | N)
121#define IS_NAME_NTH(X) ((X & 0xffff0000) == 0xffff0000)
122#define GET_NAME_NTH_IDX(X) (X & 0x0000ffff)
123
124#define MAX_NR_RAW_U32 1024
125#define BTF_LOG_BUF_SIZE 65535
126
127static struct args {
128 unsigned int raw_test_num;
129 unsigned int file_test_num;
130 unsigned int get_info_test_num;
131 unsigned int info_raw_test_num;
132 unsigned int dedup_test_num;
133 bool raw_test;
134 bool file_test;
135 bool get_info_test;
136 bool pprint_test;
137 bool always_log;
138 bool info_raw_test;
139 bool dedup_test;
140} args;
141
142static char btf_log_buf[BTF_LOG_BUF_SIZE];
143
144static struct btf_header hdr_tmpl = {
145 .magic = BTF_MAGIC,
146 .version = BTF_VERSION,
147 .hdr_len = sizeof(struct btf_header),
148};
149
150struct btf_raw_test {
151 const char *descr;
152 const char *str_sec;
153 const char *map_name;
154 const char *err_str;
155 __u32 raw_types[MAX_NR_RAW_U32];
156 __u32 str_sec_size;
157 enum bpf_map_type map_type;
158 __u32 key_size;
159 __u32 value_size;
160 __u32 key_type_id;
161 __u32 value_type_id;
162 __u32 max_entries;
163 bool btf_load_err;
164 bool map_create_err;
165 bool ordered_map;
166 bool lossless_map;
167 bool percpu_map;
168 int hdr_len_delta;
169 int type_off_delta;
170 int str_off_delta;
171 int str_len_delta;
172};
173
174#define BTF_STR_SEC(str) \
175 .str_sec = str, .str_sec_size = sizeof(str)
176
177static struct btf_raw_test raw_tests[] = {
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193{
194 .descr = "struct test #1",
195 .raw_types = {
196
197 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
198
199 BTF_TYPE_INT_ENC(0, 0, 0, 64, 8),
200
201 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 8, 1),
202
203 BTF_TYPE_ARRAY_ENC(1, 1, 8),
204
205 BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 6), 180),
206 BTF_MEMBER_ENC(NAME_TBD, 2, 0),
207 BTF_MEMBER_ENC(NAME_TBD, 1, 64),
208 BTF_MEMBER_ENC(NAME_TBD, 3, 96),
209 BTF_MEMBER_ENC(NAME_TBD, 4, 128),
210 BTF_MEMBER_ENC(NAME_TBD, 6, 384),
211 BTF_MEMBER_ENC(NAME_TBD, 7, 1408),
212
213
214 BTF_TYPE_ARRAY_ENC(4, 1, 4),
215
216 BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_ENUM, 0, 2), sizeof(int)),
217 BTF_ENUM_ENC(NAME_TBD, 0),
218 BTF_ENUM_ENC(NAME_TBD, 1),
219 BTF_END_RAW,
220 },
221 .str_sec = "\0A\0m\0n\0o\0p\0q\0r\0E\0E0\0E1",
222 .str_sec_size = sizeof("\0A\0m\0n\0o\0p\0q\0r\0E\0E0\0E1"),
223 .map_type = BPF_MAP_TYPE_ARRAY,
224 .map_name = "struct_test1_map",
225 .key_size = sizeof(int),
226 .value_size = 180,
227 .key_type_id = 1,
228 .value_type_id = 5,
229 .max_entries = 4,
230},
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245{
246 .descr = "struct test #2",
247 .raw_types = {
248
249 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
250
251 BTF_TYPE_ARRAY_ENC(4, 1, 4),
252
253
254 BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 3), 68),
255 BTF_MEMBER_ENC(NAME_TBD, 1, 0),
256 BTF_MEMBER_ENC(NAME_TBD, 2, 32),
257 BTF_MEMBER_ENC(NAME_TBD, 8, 288),
258
259
260
261 BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 2), 8),
262 BTF_MEMBER_ENC(NAME_TBD, 1, 0),
263 BTF_MEMBER_ENC(NAME_TBD, 1, 32),
264
265
266
267 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_CONST, 0, 0), 1),
268
269 BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_TYPEDEF, 0, 0), 4),
270
271 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_CONST, 0, 0), 6),
272
273 BTF_TYPE_ARRAY_ENC(7, 1, 4),
274 BTF_END_RAW,
275 },
276 .str_sec = "\0A\0m\0n\0o\0B\0m\0n\0Struct_B",
277 .str_sec_size = sizeof("\0A\0m\0n\0o\0B\0m\0n\0Struct_B"),
278 .map_type = BPF_MAP_TYPE_ARRAY,
279 .map_name = "struct_test2_map",
280 .key_size = sizeof(int),
281 .value_size = 68,
282 .key_type_id = 1,
283 .value_type_id = 3,
284 .max_entries = 4,
285},
286
287{
288 .descr = "struct test #3 Invalid member offset",
289 .raw_types = {
290
291 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
292
293 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 64, 8),
294
295
296 BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 2), 16),
297 BTF_MEMBER_ENC(NAME_TBD, 1, 64),
298 BTF_MEMBER_ENC(NAME_TBD, 2, 0),
299
300 BTF_END_RAW,
301 },
302 .str_sec = "\0A\0m\0n\0",
303 .str_sec_size = sizeof("\0A\0m\0n\0"),
304 .map_type = BPF_MAP_TYPE_ARRAY,
305 .map_name = "struct_test3_map",
306 .key_size = sizeof(int),
307 .value_size = 16,
308 .key_type_id = 1,
309 .value_type_id = 3,
310 .max_entries = 4,
311 .btf_load_err = true,
312 .err_str = "Invalid member bits_offset",
313},
314
315
316
317
318
319
320
321
322{
323 .descr = "size check test #1",
324 .raw_types = {
325
326 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
327
328 BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 2), sizeof(int) * 2 - 1),
329 BTF_MEMBER_ENC(NAME_TBD, 1, 0),
330 BTF_MEMBER_ENC(NAME_TBD, 1, 32),
331
332 BTF_END_RAW,
333 },
334 .str_sec = "\0A\0m\0n",
335 .str_sec_size = sizeof("\0A\0m\0n"),
336 .map_type = BPF_MAP_TYPE_ARRAY,
337 .map_name = "size_check1_map",
338 .key_size = sizeof(int),
339 .value_size = 1,
340 .key_type_id = 1,
341 .value_type_id = 2,
342 .max_entries = 4,
343 .btf_load_err = true,
344 .err_str = "Member exceeds struct_size",
345},
346
347
348
349
350
351
352
353
354{
355 .descr = "size check test #2",
356 .raw_types = {
357
358 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, sizeof(int)),
359
360 BTF_TYPE_ARRAY_ENC(1, 1, 2),
361
362 BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 2), sizeof(int) * 3 - 1),
363 BTF_MEMBER_ENC(NAME_TBD, 1, 0),
364 BTF_MEMBER_ENC(NAME_TBD, 2, 32),
365
366 BTF_END_RAW,
367 },
368 .str_sec = "\0A\0m\0n",
369 .str_sec_size = sizeof("\0A\0m\0n"),
370 .map_type = BPF_MAP_TYPE_ARRAY,
371 .map_name = "size_check2_map",
372 .key_size = sizeof(int),
373 .value_size = 1,
374 .key_type_id = 1,
375 .value_type_id = 3,
376 .max_entries = 4,
377 .btf_load_err = true,
378 .err_str = "Member exceeds struct_size",
379},
380
381
382
383
384
385
386
387
388{
389 .descr = "size check test #3",
390 .raw_types = {
391
392 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, sizeof(int)),
393
394 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_PTR, 0, 0), 0),
395
396 BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 2), sizeof(int) + sizeof(void *) - 1),
397 BTF_MEMBER_ENC(NAME_TBD, 1, 0),
398 BTF_MEMBER_ENC(NAME_TBD, 2, 32),
399
400 BTF_END_RAW,
401 },
402 .str_sec = "\0A\0m\0n",
403 .str_sec_size = sizeof("\0A\0m\0n"),
404 .map_type = BPF_MAP_TYPE_ARRAY,
405 .map_name = "size_check3_map",
406 .key_size = sizeof(int),
407 .value_size = 1,
408 .key_type_id = 1,
409 .value_type_id = 3,
410 .max_entries = 4,
411 .btf_load_err = true,
412 .err_str = "Member exceeds struct_size",
413},
414
415
416
417
418
419
420
421
422
423
424
425
426
427{
428 .descr = "size check test #4",
429 .raw_types = {
430
431 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, sizeof(int)),
432
433 BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_ENUM, 0, 2), sizeof(int)),
434 BTF_ENUM_ENC(NAME_TBD, 0),
435 BTF_ENUM_ENC(NAME_TBD, 1),
436
437
438 BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 2), sizeof(int) * 2 - 1),
439 BTF_MEMBER_ENC(NAME_TBD, 1, 0),
440 BTF_MEMBER_ENC(NAME_TBD, 2, 32),
441
442 BTF_END_RAW,
443 },
444 .str_sec = "\0E\0E0\0E1\0A\0m\0n",
445 .str_sec_size = sizeof("\0E\0E0\0E1\0A\0m\0n"),
446 .map_type = BPF_MAP_TYPE_ARRAY,
447 .map_name = "size_check4_map",
448 .key_size = sizeof(int),
449 .value_size = 1,
450 .key_type_id = 1,
451 .value_type_id = 3,
452 .max_entries = 4,
453 .btf_load_err = true,
454 .err_str = "Member exceeds struct_size",
455},
456
457
458
459
460
461
462{
463 .descr = "void test #1",
464 .raw_types = {
465
466 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
467
468 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_CONST, 0, 0), 0),
469
470 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_PTR, 0, 0), 2),
471
472 BTF_TYPEDEF_ENC(NAME_TBD, 3),
473
474 BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 1), sizeof(void *)),
475
476 BTF_MEMBER_ENC(NAME_TBD, 4, 0),
477
478 BTF_END_RAW,
479 },
480 .str_sec = "\0const_void_ptr\0A\0m",
481 .str_sec_size = sizeof("\0const_void_ptr\0A\0m"),
482 .map_type = BPF_MAP_TYPE_ARRAY,
483 .map_name = "void_test1_map",
484 .key_size = sizeof(int),
485 .value_size = sizeof(void *),
486 .key_type_id = 1,
487 .value_type_id = 4,
488 .max_entries = 4,
489},
490
491
492
493
494
495{
496 .descr = "void test #2",
497 .raw_types = {
498
499 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
500
501 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_CONST, 0, 0), 0),
502
503 BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 1), 8),
504
505 BTF_MEMBER_ENC(NAME_TBD, 2, 0),
506
507 BTF_END_RAW,
508 },
509 .str_sec = "\0A\0m",
510 .str_sec_size = sizeof("\0A\0m"),
511 .map_type = BPF_MAP_TYPE_ARRAY,
512 .map_name = "void_test2_map",
513 .key_size = sizeof(int),
514 .value_size = sizeof(void *),
515 .key_type_id = 1,
516 .value_type_id = 3,
517 .max_entries = 4,
518 .btf_load_err = true,
519 .err_str = "Invalid member",
520},
521
522
523
524
525{
526 .descr = "void test #3",
527 .raw_types = {
528
529 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
530
531 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_CONST, 0, 0), 0),
532
533 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_PTR, 0, 0), 2),
534
535 BTF_TYPEDEF_ENC(NAME_TBD, 3),
536
537 BTF_TYPE_ARRAY_ENC(4, 1, 4),
538 BTF_END_RAW,
539 },
540 .str_sec = "\0const_void_ptr",
541 .str_sec_size = sizeof("\0const_void_ptr"),
542 .map_type = BPF_MAP_TYPE_ARRAY,
543 .map_name = "void_test3_map",
544 .key_size = sizeof(int),
545 .value_size = sizeof(void *) * 4,
546 .key_type_id = 1,
547 .value_type_id = 5,
548 .max_entries = 4,
549},
550
551
552{
553 .descr = "void test #4",
554 .raw_types = {
555
556 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
557
558 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_CONST, 0, 0), 0),
559
560 BTF_TYPE_ARRAY_ENC(2, 1, 4),
561 BTF_END_RAW,
562 },
563 .str_sec = "\0A\0m",
564 .str_sec_size = sizeof("\0A\0m"),
565 .map_type = BPF_MAP_TYPE_ARRAY,
566 .map_name = "void_test4_map",
567 .key_size = sizeof(int),
568 .value_size = sizeof(void *) * 4,
569 .key_type_id = 1,
570 .value_type_id = 3,
571 .max_entries = 4,
572 .btf_load_err = true,
573 .err_str = "Invalid elem",
574},
575
576
577
578
579
580
581
582
583{
584 .descr = "loop test #1",
585 .raw_types = {
586
587 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
588
589 BTF_TYPE_ARRAY_ENC(3, 1, 8),
590
591 BTF_TYPE_ARRAY_ENC(2, 1, 8),
592 BTF_END_RAW,
593 },
594 .str_sec = "",
595 .str_sec_size = sizeof(""),
596 .map_type = BPF_MAP_TYPE_ARRAY,
597 .map_name = "loop_test1_map",
598 .key_size = sizeof(int),
599 .value_size = sizeof(sizeof(int) * 8),
600 .key_type_id = 1,
601 .value_type_id = 2,
602 .max_entries = 4,
603 .btf_load_err = true,
604 .err_str = "Loop detected",
605},
606
607
608
609
610
611
612
613
614
615
616
617
618{
619 .descr = "loop test #2",
620 .raw_types = {
621
622 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
623
624 BTF_TYPEDEF_ENC(1, 4),
625
626 BTF_TYPE_ARRAY_ENC(2, 1, 8),
627
628 BTF_TYPE_ARRAY_ENC(3, 1, 8),
629 BTF_END_RAW,
630 },
631 .str_sec = "\0int_array\0",
632 .str_sec_size = sizeof("\0int_array"),
633 .map_type = BPF_MAP_TYPE_ARRAY,
634 .map_name = "loop_test2_map",
635 .key_size = sizeof(int),
636 .value_size = sizeof(sizeof(int) * 8),
637 .key_type_id = 1,
638 .value_type_id = 2,
639 .max_entries = 4,
640 .btf_load_err = true,
641 .err_str = "Loop detected",
642},
643
644
645
646
647
648
649
650
651{
652 .descr = "loop test #3",
653 .raw_types = {
654
655 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
656
657 BTF_TYPE_ARRAY_ENC(3, 1, 8),
658
659 BTF_TYPE_ARRAY_ENC(2, 1, 8),
660 BTF_END_RAW,
661 },
662 .str_sec = "",
663 .str_sec_size = sizeof(""),
664 .map_type = BPF_MAP_TYPE_ARRAY,
665 .map_name = "loop_test3_map",
666 .key_size = sizeof(int),
667 .value_size = sizeof(sizeof(int) * 8),
668 .key_type_id = 1,
669 .value_type_id = 2,
670 .max_entries = 4,
671 .btf_load_err = true,
672 .err_str = "Loop detected",
673},
674
675
676
677
678
679
680
681
682
683
684
685
686{
687 .descr = "loop test #4",
688 .raw_types = {
689
690 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
691
692 BTF_TYPE_ARRAY_ENC(3, 1, 8),
693
694 BTF_TYPEDEF_ENC(NAME_TBD, 4),
695
696 BTF_TYPE_ARRAY_ENC(2, 1, 8),
697 BTF_END_RAW,
698 },
699 .str_sec = "\0int_array\0",
700 .str_sec_size = sizeof("\0int_array"),
701 .map_type = BPF_MAP_TYPE_ARRAY,
702 .map_name = "loop_test4_map",
703 .key_size = sizeof(int),
704 .value_size = sizeof(sizeof(int) * 8),
705 .key_type_id = 1,
706 .value_type_id = 2,
707 .max_entries = 4,
708 .btf_load_err = true,
709 .err_str = "Loop detected",
710},
711
712
713
714
715
716
717
718
719
720
721
722
723
724{
725 .descr = "loop test #5",
726 .raw_types = {
727
728 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
729
730 BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 2), 8),
731 BTF_MEMBER_ENC(NAME_TBD, 1, 0),
732 BTF_MEMBER_ENC(NAME_TBD, 3, 32),
733
734 BTF_TYPEDEF_ENC(NAME_TBD, 4),
735
736 BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 2), 8),
737 BTF_MEMBER_ENC(NAME_TBD, 1, 0),
738 BTF_MEMBER_ENC(NAME_TBD, 2, 32),
739 BTF_END_RAW,
740 },
741 .str_sec = "\0A\0x\0y\0Struct_B\0B\0x\0y",
742 .str_sec_size = sizeof("\0A\0x\0y\0Struct_B\0B\0x\0y"),
743 .map_type = BPF_MAP_TYPE_ARRAY,
744 .map_name = "loop_test5_map",
745 .key_size = sizeof(int),
746 .value_size = 8,
747 .key_type_id = 1,
748 .value_type_id = 2,
749 .max_entries = 4,
750 .btf_load_err = true,
751 .err_str = "Loop detected",
752},
753
754
755
756
757
758
759{
760 .descr = "loop test #6",
761 .raw_types = {
762
763 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
764 BTF_TYPE_ARRAY_ENC(3, 1, 4),
765
766 BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 2), 8),
767 BTF_MEMBER_ENC(NAME_TBD, 1, 0),
768 BTF_MEMBER_ENC(NAME_TBD, 2, 32),
769 BTF_END_RAW,
770 },
771 .str_sec = "\0A\0x\0y",
772 .str_sec_size = sizeof("\0A\0x\0y"),
773 .map_type = BPF_MAP_TYPE_ARRAY,
774 .map_name = "loop_test6_map",
775 .key_size = sizeof(int),
776 .value_size = 8,
777 .key_type_id = 1,
778 .value_type_id = 2,
779 .max_entries = 4,
780 .btf_load_err = true,
781 .err_str = "Loop detected",
782},
783
784{
785 .descr = "loop test #7",
786 .raw_types = {
787
788 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
789
790 BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 1), sizeof(void *)),
791
792 BTF_MEMBER_ENC(NAME_TBD, 3, 0),
793
794 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_CONST, 0, 0), 4),
795
796 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_PTR, 0, 0), 3),
797 BTF_END_RAW,
798 },
799 .str_sec = "\0A\0m",
800 .str_sec_size = sizeof("\0A\0m"),
801 .map_type = BPF_MAP_TYPE_ARRAY,
802 .map_name = "loop_test7_map",
803 .key_size = sizeof(int),
804 .value_size = sizeof(void *),
805 .key_type_id = 1,
806 .value_type_id = 2,
807 .max_entries = 4,
808 .btf_load_err = true,
809 .err_str = "Loop detected",
810},
811
812{
813 .descr = "loop test #8",
814 .raw_types = {
815
816 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
817
818 BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 1), sizeof(void *)),
819
820 BTF_MEMBER_ENC(NAME_TBD, 4, 0),
821
822 BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 1), sizeof(void *)),
823
824 BTF_MEMBER_ENC(NAME_TBD, 6, 0),
825
826 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_CONST, 0, 0), 5),
827
828 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_PTR, 0, 0), 6),
829
830 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_CONST, 0, 0), 7),
831
832 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_PTR, 0, 0), 4),
833 BTF_END_RAW,
834 },
835 .str_sec = "\0A\0m\0B\0n",
836 .str_sec_size = sizeof("\0A\0m\0B\0n"),
837 .map_type = BPF_MAP_TYPE_ARRAY,
838 .map_name = "loop_test8_map",
839 .key_size = sizeof(int),
840 .value_size = sizeof(void *),
841 .key_type_id = 1,
842 .value_type_id = 2,
843 .max_entries = 4,
844 .btf_load_err = true,
845 .err_str = "Loop detected",
846},
847
848{
849 .descr = "string section does not end with null",
850 .raw_types = {
851
852 BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),
853 BTF_END_RAW,
854 },
855 .str_sec = "\0int",
856 .str_sec_size = sizeof("\0int") - 1,
857 .map_type = BPF_MAP_TYPE_ARRAY,
858 .map_name = "hdr_test_map",
859 .key_size = sizeof(int),
860 .value_size = sizeof(int),
861 .key_type_id = 1,
862 .value_type_id = 1,
863 .max_entries = 4,
864 .btf_load_err = true,
865 .err_str = "Invalid string section",
866},
867
868{
869 .descr = "empty string section",
870 .raw_types = {
871
872 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
873 BTF_END_RAW,
874 },
875 .str_sec = "",
876 .str_sec_size = 0,
877 .map_type = BPF_MAP_TYPE_ARRAY,
878 .map_name = "hdr_test_map",
879 .key_size = sizeof(int),
880 .value_size = sizeof(int),
881 .key_type_id = 1,
882 .value_type_id = 1,
883 .max_entries = 4,
884 .btf_load_err = true,
885 .err_str = "Invalid string section",
886},
887
888{
889 .descr = "empty type section",
890 .raw_types = {
891 BTF_END_RAW,
892 },
893 .str_sec = "\0int",
894 .str_sec_size = sizeof("\0int"),
895 .map_type = BPF_MAP_TYPE_ARRAY,
896 .map_name = "hdr_test_map",
897 .key_size = sizeof(int),
898 .value_size = sizeof(int),
899 .key_type_id = 1,
900 .value_type_id = 1,
901 .max_entries = 4,
902 .btf_load_err = true,
903 .err_str = "No type found",
904},
905
906{
907 .descr = "btf_header test. Longer hdr_len",
908 .raw_types = {
909
910 BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),
911 BTF_END_RAW,
912 },
913 .str_sec = "\0int",
914 .str_sec_size = sizeof("\0int"),
915 .map_type = BPF_MAP_TYPE_ARRAY,
916 .map_name = "hdr_test_map",
917 .key_size = sizeof(int),
918 .value_size = sizeof(int),
919 .key_type_id = 1,
920 .value_type_id = 1,
921 .max_entries = 4,
922 .btf_load_err = true,
923 .hdr_len_delta = 4,
924 .err_str = "Unsupported btf_header",
925},
926
927{
928 .descr = "btf_header test. Gap between hdr and type",
929 .raw_types = {
930
931 BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),
932 BTF_END_RAW,
933 },
934 .str_sec = "\0int",
935 .str_sec_size = sizeof("\0int"),
936 .map_type = BPF_MAP_TYPE_ARRAY,
937 .map_name = "hdr_test_map",
938 .key_size = sizeof(int),
939 .value_size = sizeof(int),
940 .key_type_id = 1,
941 .value_type_id = 1,
942 .max_entries = 4,
943 .btf_load_err = true,
944 .type_off_delta = 4,
945 .err_str = "Unsupported section found",
946},
947
948{
949 .descr = "btf_header test. Gap between type and str",
950 .raw_types = {
951
952 BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),
953 BTF_END_RAW,
954 },
955 .str_sec = "\0int",
956 .str_sec_size = sizeof("\0int"),
957 .map_type = BPF_MAP_TYPE_ARRAY,
958 .map_name = "hdr_test_map",
959 .key_size = sizeof(int),
960 .value_size = sizeof(int),
961 .key_type_id = 1,
962 .value_type_id = 1,
963 .max_entries = 4,
964 .btf_load_err = true,
965 .str_off_delta = 4,
966 .err_str = "Unsupported section found",
967},
968
969{
970 .descr = "btf_header test. Overlap between type and str",
971 .raw_types = {
972
973 BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),
974 BTF_END_RAW,
975 },
976 .str_sec = "\0int",
977 .str_sec_size = sizeof("\0int"),
978 .map_type = BPF_MAP_TYPE_ARRAY,
979 .map_name = "hdr_test_map",
980 .key_size = sizeof(int),
981 .value_size = sizeof(int),
982 .key_type_id = 1,
983 .value_type_id = 1,
984 .max_entries = 4,
985 .btf_load_err = true,
986 .str_off_delta = -4,
987 .err_str = "Section overlap found",
988},
989
990{
991 .descr = "btf_header test. Larger BTF size",
992 .raw_types = {
993
994 BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),
995 BTF_END_RAW,
996 },
997 .str_sec = "\0int",
998 .str_sec_size = sizeof("\0int"),
999 .map_type = BPF_MAP_TYPE_ARRAY,
1000 .map_name = "hdr_test_map",
1001 .key_size = sizeof(int),
1002 .value_size = sizeof(int),
1003 .key_type_id = 1,
1004 .value_type_id = 1,
1005 .max_entries = 4,
1006 .btf_load_err = true,
1007 .str_len_delta = -4,
1008 .err_str = "Unsupported section found",
1009},
1010
1011{
1012 .descr = "btf_header test. Smaller BTF size",
1013 .raw_types = {
1014
1015 BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),
1016 BTF_END_RAW,
1017 },
1018 .str_sec = "\0int",
1019 .str_sec_size = sizeof("\0int"),
1020 .map_type = BPF_MAP_TYPE_ARRAY,
1021 .map_name = "hdr_test_map",
1022 .key_size = sizeof(int),
1023 .value_size = sizeof(int),
1024 .key_type_id = 1,
1025 .value_type_id = 1,
1026 .max_entries = 4,
1027 .btf_load_err = true,
1028 .str_len_delta = 4,
1029 .err_str = "Total section length too long",
1030},
1031
1032{
1033 .descr = "array test. index_type/elem_type \"int\"",
1034 .raw_types = {
1035
1036 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
1037
1038 BTF_TYPE_ARRAY_ENC(1, 1, 16),
1039 BTF_END_RAW,
1040 },
1041 .str_sec = "",
1042 .str_sec_size = sizeof(""),
1043 .map_type = BPF_MAP_TYPE_ARRAY,
1044 .map_name = "array_test_map",
1045 .key_size = sizeof(int),
1046 .value_size = sizeof(int),
1047 .key_type_id = 1,
1048 .value_type_id = 1,
1049 .max_entries = 4,
1050},
1051
1052{
1053 .descr = "array test. index_type/elem_type \"const int\"",
1054 .raw_types = {
1055
1056 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
1057
1058 BTF_TYPE_ARRAY_ENC(3, 3, 16),
1059
1060 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_CONST, 0, 0), 1),
1061 BTF_END_RAW,
1062 },
1063 .str_sec = "",
1064 .str_sec_size = sizeof(""),
1065 .map_type = BPF_MAP_TYPE_ARRAY,
1066 .map_name = "array_test_map",
1067 .key_size = sizeof(int),
1068 .value_size = sizeof(int),
1069 .key_type_id = 1,
1070 .value_type_id = 1,
1071 .max_entries = 4,
1072},
1073
1074{
1075 .descr = "array test. index_type \"const int:31\"",
1076 .raw_types = {
1077
1078 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
1079
1080 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 31, 4),
1081
1082 BTF_TYPE_ARRAY_ENC(1, 4, 16),
1083
1084 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_CONST, 0, 0), 2),
1085 BTF_END_RAW,
1086 },
1087 .str_sec = "",
1088 .str_sec_size = sizeof(""),
1089 .map_type = BPF_MAP_TYPE_ARRAY,
1090 .map_name = "array_test_map",
1091 .key_size = sizeof(int),
1092 .value_size = sizeof(int),
1093 .key_type_id = 1,
1094 .value_type_id = 1,
1095 .max_entries = 4,
1096 .btf_load_err = true,
1097 .err_str = "Invalid index",
1098},
1099
1100{
1101 .descr = "array test. elem_type \"const int:31\"",
1102 .raw_types = {
1103
1104 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
1105
1106 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 31, 4),
1107
1108 BTF_TYPE_ARRAY_ENC(4, 1, 16),
1109
1110 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_CONST, 0, 0), 2),
1111 BTF_END_RAW,
1112 },
1113 .str_sec = "",
1114 .str_sec_size = sizeof(""),
1115 .map_type = BPF_MAP_TYPE_ARRAY,
1116 .map_name = "array_test_map",
1117 .key_size = sizeof(int),
1118 .value_size = sizeof(int),
1119 .key_type_id = 1,
1120 .value_type_id = 1,
1121 .max_entries = 4,
1122 .btf_load_err = true,
1123 .err_str = "Invalid array of int",
1124},
1125
1126{
1127 .descr = "array test. index_type \"void\"",
1128 .raw_types = {
1129
1130 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
1131
1132 BTF_TYPE_ARRAY_ENC(1, 0, 16),
1133 BTF_END_RAW,
1134 },
1135 .str_sec = "",
1136 .str_sec_size = sizeof(""),
1137 .map_type = BPF_MAP_TYPE_ARRAY,
1138 .map_name = "array_test_map",
1139 .key_size = sizeof(int),
1140 .value_size = sizeof(int),
1141 .key_type_id = 1,
1142 .value_type_id = 1,
1143 .max_entries = 4,
1144 .btf_load_err = true,
1145 .err_str = "Invalid index",
1146},
1147
1148{
1149 .descr = "array test. index_type \"const void\"",
1150 .raw_types = {
1151
1152 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
1153
1154 BTF_TYPE_ARRAY_ENC(1, 3, 16),
1155
1156 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_CONST, 0, 0), 0),
1157 BTF_END_RAW,
1158 },
1159 .str_sec = "",
1160 .str_sec_size = sizeof(""),
1161 .map_type = BPF_MAP_TYPE_ARRAY,
1162 .map_name = "array_test_map",
1163 .key_size = sizeof(int),
1164 .value_size = sizeof(int),
1165 .key_type_id = 1,
1166 .value_type_id = 1,
1167 .max_entries = 4,
1168 .btf_load_err = true,
1169 .err_str = "Invalid index",
1170},
1171
1172{
1173 .descr = "array test. elem_type \"const void\"",
1174 .raw_types = {
1175
1176 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
1177
1178 BTF_TYPE_ARRAY_ENC(3, 1, 16),
1179
1180 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_CONST, 0, 0), 0),
1181 BTF_END_RAW,
1182 },
1183 .str_sec = "",
1184 .str_sec_size = sizeof(""),
1185 .map_type = BPF_MAP_TYPE_ARRAY,
1186 .map_name = "array_test_map",
1187 .key_size = sizeof(int),
1188 .value_size = sizeof(int),
1189 .key_type_id = 1,
1190 .value_type_id = 1,
1191 .max_entries = 4,
1192 .btf_load_err = true,
1193 .err_str = "Invalid elem",
1194},
1195
1196{
1197 .descr = "array test. elem_type \"const void *\"",
1198 .raw_types = {
1199
1200 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
1201
1202 BTF_TYPE_ARRAY_ENC(3, 1, 16),
1203
1204 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_CONST, 0, 0), 4),
1205
1206 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_PTR, 0, 0), 0),
1207 BTF_END_RAW,
1208 },
1209 .str_sec = "",
1210 .str_sec_size = sizeof(""),
1211 .map_type = BPF_MAP_TYPE_ARRAY,
1212 .map_name = "array_test_map",
1213 .key_size = sizeof(int),
1214 .value_size = sizeof(int),
1215 .key_type_id = 1,
1216 .value_type_id = 1,
1217 .max_entries = 4,
1218},
1219
1220{
1221 .descr = "array test. index_type \"const void *\"",
1222 .raw_types = {
1223
1224 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
1225
1226 BTF_TYPE_ARRAY_ENC(3, 3, 16),
1227
1228 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_CONST, 0, 0), 4),
1229
1230 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_PTR, 0, 0), 0),
1231 BTF_END_RAW,
1232 },
1233 .str_sec = "",
1234 .str_sec_size = sizeof(""),
1235 .map_type = BPF_MAP_TYPE_ARRAY,
1236 .map_name = "array_test_map",
1237 .key_size = sizeof(int),
1238 .value_size = sizeof(int),
1239 .key_type_id = 1,
1240 .value_type_id = 1,
1241 .max_entries = 4,
1242 .btf_load_err = true,
1243 .err_str = "Invalid index",
1244},
1245
1246{
1247 .descr = "array test. t->size != 0\"",
1248 .raw_types = {
1249
1250 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
1251
1252 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_ARRAY, 0, 0), 1),
1253 BTF_ARRAY_ENC(1, 1, 16),
1254 BTF_END_RAW,
1255 },
1256 .str_sec = "",
1257 .str_sec_size = sizeof(""),
1258 .map_type = BPF_MAP_TYPE_ARRAY,
1259 .map_name = "array_test_map",
1260 .key_size = sizeof(int),
1261 .value_size = sizeof(int),
1262 .key_type_id = 1,
1263 .value_type_id = 1,
1264 .max_entries = 4,
1265 .btf_load_err = true,
1266 .err_str = "size != 0",
1267},
1268
1269{
1270 .descr = "int test. invalid int_data",
1271 .raw_types = {
1272 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_INT, 0, 0), 4),
1273 0x10000000,
1274 BTF_END_RAW,
1275 },
1276 .str_sec = "",
1277 .str_sec_size = sizeof(""),
1278 .map_type = BPF_MAP_TYPE_ARRAY,
1279 .map_name = "array_test_map",
1280 .key_size = sizeof(int),
1281 .value_size = sizeof(int),
1282 .key_type_id = 1,
1283 .value_type_id = 1,
1284 .max_entries = 4,
1285 .btf_load_err = true,
1286 .err_str = "Invalid int_data",
1287},
1288
1289{
1290 .descr = "invalid BTF_INFO",
1291 .raw_types = {
1292
1293 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
1294 BTF_TYPE_ENC(0, 0x10000000, 4),
1295 BTF_END_RAW,
1296 },
1297 .str_sec = "",
1298 .str_sec_size = sizeof(""),
1299 .map_type = BPF_MAP_TYPE_ARRAY,
1300 .map_name = "array_test_map",
1301 .key_size = sizeof(int),
1302 .value_size = sizeof(int),
1303 .key_type_id = 1,
1304 .value_type_id = 1,
1305 .max_entries = 4,
1306 .btf_load_err = true,
1307 .err_str = "Invalid btf_info",
1308},
1309
1310{
1311 .descr = "fwd test. t->type != 0\"",
1312 .raw_types = {
1313
1314 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
1315
1316 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_FWD, 0, 0), 1),
1317 BTF_END_RAW,
1318 },
1319 .str_sec = "",
1320 .str_sec_size = sizeof(""),
1321 .map_type = BPF_MAP_TYPE_ARRAY,
1322 .map_name = "fwd_test_map",
1323 .key_size = sizeof(int),
1324 .value_size = sizeof(int),
1325 .key_type_id = 1,
1326 .value_type_id = 1,
1327 .max_entries = 4,
1328 .btf_load_err = true,
1329 .err_str = "type != 0",
1330},
1331
1332{
1333 .descr = "typedef (invalid name, name_off = 0)",
1334 .raw_types = {
1335 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
1336 BTF_TYPEDEF_ENC(0, 1),
1337 BTF_END_RAW,
1338 },
1339 .str_sec = "\0__int",
1340 .str_sec_size = sizeof("\0__int"),
1341 .map_type = BPF_MAP_TYPE_ARRAY,
1342 .map_name = "typedef_check_btf",
1343 .key_size = sizeof(int),
1344 .value_size = sizeof(int),
1345 .key_type_id = 1,
1346 .value_type_id = 1,
1347 .max_entries = 4,
1348 .btf_load_err = true,
1349 .err_str = "Invalid name",
1350},
1351
1352{
1353 .descr = "typedef (invalid name, invalid identifier)",
1354 .raw_types = {
1355 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
1356 BTF_TYPEDEF_ENC(NAME_TBD, 1),
1357 BTF_END_RAW,
1358 },
1359 .str_sec = "\0__!int",
1360 .str_sec_size = sizeof("\0__!int"),
1361 .map_type = BPF_MAP_TYPE_ARRAY,
1362 .map_name = "typedef_check_btf",
1363 .key_size = sizeof(int),
1364 .value_size = sizeof(int),
1365 .key_type_id = 1,
1366 .value_type_id = 1,
1367 .max_entries = 4,
1368 .btf_load_err = true,
1369 .err_str = "Invalid name",
1370},
1371
1372{
1373 .descr = "ptr type (invalid name, name_off <> 0)",
1374 .raw_types = {
1375 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
1376 BTF_TYPE_ENC(NAME_TBD,
1377 BTF_INFO_ENC(BTF_KIND_PTR, 0, 0), 1),
1378 BTF_END_RAW,
1379 },
1380 .str_sec = "\0__int",
1381 .str_sec_size = sizeof("\0__int"),
1382 .map_type = BPF_MAP_TYPE_ARRAY,
1383 .map_name = "ptr_type_check_btf",
1384 .key_size = sizeof(int),
1385 .value_size = sizeof(int),
1386 .key_type_id = 1,
1387 .value_type_id = 1,
1388 .max_entries = 4,
1389 .btf_load_err = true,
1390 .err_str = "Invalid name",
1391},
1392
1393{
1394 .descr = "volatile type (invalid name, name_off <> 0)",
1395 .raw_types = {
1396 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
1397 BTF_TYPE_ENC(NAME_TBD,
1398 BTF_INFO_ENC(BTF_KIND_VOLATILE, 0, 0), 1),
1399 BTF_END_RAW,
1400 },
1401 .str_sec = "\0__int",
1402 .str_sec_size = sizeof("\0__int"),
1403 .map_type = BPF_MAP_TYPE_ARRAY,
1404 .map_name = "volatile_type_check_btf",
1405 .key_size = sizeof(int),
1406 .value_size = sizeof(int),
1407 .key_type_id = 1,
1408 .value_type_id = 1,
1409 .max_entries = 4,
1410 .btf_load_err = true,
1411 .err_str = "Invalid name",
1412},
1413
1414{
1415 .descr = "const type (invalid name, name_off <> 0)",
1416 .raw_types = {
1417 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
1418 BTF_TYPE_ENC(NAME_TBD,
1419 BTF_INFO_ENC(BTF_KIND_CONST, 0, 0), 1),
1420 BTF_END_RAW,
1421 },
1422 .str_sec = "\0__int",
1423 .str_sec_size = sizeof("\0__int"),
1424 .map_type = BPF_MAP_TYPE_ARRAY,
1425 .map_name = "const_type_check_btf",
1426 .key_size = sizeof(int),
1427 .value_size = sizeof(int),
1428 .key_type_id = 1,
1429 .value_type_id = 1,
1430 .max_entries = 4,
1431 .btf_load_err = true,
1432 .err_str = "Invalid name",
1433},
1434
1435{
1436 .descr = "restrict type (invalid name, name_off <> 0)",
1437 .raw_types = {
1438 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
1439 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_PTR, 0, 0), 1),
1440 BTF_TYPE_ENC(NAME_TBD,
1441 BTF_INFO_ENC(BTF_KIND_RESTRICT, 0, 0), 2),
1442 BTF_END_RAW,
1443 },
1444 .str_sec = "\0__int",
1445 .str_sec_size = sizeof("\0__int"),
1446 .map_type = BPF_MAP_TYPE_ARRAY,
1447 .map_name = "restrict_type_check_btf",
1448 .key_size = sizeof(int),
1449 .value_size = sizeof(int),
1450 .key_type_id = 1,
1451 .value_type_id = 1,
1452 .max_entries = 4,
1453 .btf_load_err = true,
1454 .err_str = "Invalid name",
1455},
1456
1457{
1458 .descr = "fwd type (invalid name, name_off = 0)",
1459 .raw_types = {
1460 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
1461 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_FWD, 0, 0), 0),
1462 BTF_END_RAW,
1463 },
1464 .str_sec = "\0__skb",
1465 .str_sec_size = sizeof("\0__skb"),
1466 .map_type = BPF_MAP_TYPE_ARRAY,
1467 .map_name = "fwd_type_check_btf",
1468 .key_size = sizeof(int),
1469 .value_size = sizeof(int),
1470 .key_type_id = 1,
1471 .value_type_id = 1,
1472 .max_entries = 4,
1473 .btf_load_err = true,
1474 .err_str = "Invalid name",
1475},
1476
1477{
1478 .descr = "fwd type (invalid name, invalid identifier)",
1479 .raw_types = {
1480 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
1481 BTF_TYPE_ENC(NAME_TBD,
1482 BTF_INFO_ENC(BTF_KIND_FWD, 0, 0), 0),
1483 BTF_END_RAW,
1484 },
1485 .str_sec = "\0__!skb",
1486 .str_sec_size = sizeof("\0__!skb"),
1487 .map_type = BPF_MAP_TYPE_ARRAY,
1488 .map_name = "fwd_type_check_btf",
1489 .key_size = sizeof(int),
1490 .value_size = sizeof(int),
1491 .key_type_id = 1,
1492 .value_type_id = 1,
1493 .max_entries = 4,
1494 .btf_load_err = true,
1495 .err_str = "Invalid name",
1496},
1497
1498{
1499 .descr = "array type (invalid name, name_off <> 0)",
1500 .raw_types = {
1501 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
1502 BTF_TYPE_ENC(NAME_TBD,
1503 BTF_INFO_ENC(BTF_KIND_ARRAY, 0, 0), 0),
1504 BTF_ARRAY_ENC(1, 1, 4),
1505 BTF_END_RAW,
1506 },
1507 .str_sec = "\0__skb",
1508 .str_sec_size = sizeof("\0__skb"),
1509 .map_type = BPF_MAP_TYPE_ARRAY,
1510 .map_name = "array_type_check_btf",
1511 .key_size = sizeof(int),
1512 .value_size = sizeof(int),
1513 .key_type_id = 1,
1514 .value_type_id = 1,
1515 .max_entries = 4,
1516 .btf_load_err = true,
1517 .err_str = "Invalid name",
1518},
1519
1520{
1521 .descr = "struct type (name_off = 0)",
1522 .raw_types = {
1523 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
1524 BTF_TYPE_ENC(0,
1525 BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 1), 4),
1526 BTF_MEMBER_ENC(NAME_TBD, 1, 0),
1527 BTF_END_RAW,
1528 },
1529 .str_sec = "\0A",
1530 .str_sec_size = sizeof("\0A"),
1531 .map_type = BPF_MAP_TYPE_ARRAY,
1532 .map_name = "struct_type_check_btf",
1533 .key_size = sizeof(int),
1534 .value_size = sizeof(int),
1535 .key_type_id = 1,
1536 .value_type_id = 1,
1537 .max_entries = 4,
1538},
1539
1540{
1541 .descr = "struct type (invalid name, invalid identifier)",
1542 .raw_types = {
1543 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
1544 BTF_TYPE_ENC(NAME_TBD,
1545 BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 1), 4),
1546 BTF_MEMBER_ENC(NAME_TBD, 1, 0),
1547 BTF_END_RAW,
1548 },
1549 .str_sec = "\0A!\0B",
1550 .str_sec_size = sizeof("\0A!\0B"),
1551 .map_type = BPF_MAP_TYPE_ARRAY,
1552 .map_name = "struct_type_check_btf",
1553 .key_size = sizeof(int),
1554 .value_size = sizeof(int),
1555 .key_type_id = 1,
1556 .value_type_id = 1,
1557 .max_entries = 4,
1558 .btf_load_err = true,
1559 .err_str = "Invalid name",
1560},
1561
1562{
1563 .descr = "struct member (name_off = 0)",
1564 .raw_types = {
1565 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
1566 BTF_TYPE_ENC(0,
1567 BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 1), 4),
1568 BTF_MEMBER_ENC(NAME_TBD, 1, 0),
1569 BTF_END_RAW,
1570 },
1571 .str_sec = "\0A",
1572 .str_sec_size = sizeof("\0A"),
1573 .map_type = BPF_MAP_TYPE_ARRAY,
1574 .map_name = "struct_type_check_btf",
1575 .key_size = sizeof(int),
1576 .value_size = sizeof(int),
1577 .key_type_id = 1,
1578 .value_type_id = 1,
1579 .max_entries = 4,
1580},
1581
1582{
1583 .descr = "struct member (invalid name, invalid identifier)",
1584 .raw_types = {
1585 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
1586 BTF_TYPE_ENC(NAME_TBD,
1587 BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 1), 4),
1588 BTF_MEMBER_ENC(NAME_TBD, 1, 0),
1589 BTF_END_RAW,
1590 },
1591 .str_sec = "\0A\0B*",
1592 .str_sec_size = sizeof("\0A\0B*"),
1593 .map_type = BPF_MAP_TYPE_ARRAY,
1594 .map_name = "struct_type_check_btf",
1595 .key_size = sizeof(int),
1596 .value_size = sizeof(int),
1597 .key_type_id = 1,
1598 .value_type_id = 1,
1599 .max_entries = 4,
1600 .btf_load_err = true,
1601 .err_str = "Invalid name",
1602},
1603
1604{
1605 .descr = "enum type (name_off = 0)",
1606 .raw_types = {
1607 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
1608 BTF_TYPE_ENC(0,
1609 BTF_INFO_ENC(BTF_KIND_ENUM, 0, 1),
1610 sizeof(int)),
1611 BTF_ENUM_ENC(NAME_TBD, 0),
1612 BTF_END_RAW,
1613 },
1614 .str_sec = "\0A\0B",
1615 .str_sec_size = sizeof("\0A\0B"),
1616 .map_type = BPF_MAP_TYPE_ARRAY,
1617 .map_name = "enum_type_check_btf",
1618 .key_size = sizeof(int),
1619 .value_size = sizeof(int),
1620 .key_type_id = 1,
1621 .value_type_id = 1,
1622 .max_entries = 4,
1623},
1624
1625{
1626 .descr = "enum type (invalid name, invalid identifier)",
1627 .raw_types = {
1628 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
1629 BTF_TYPE_ENC(NAME_TBD,
1630 BTF_INFO_ENC(BTF_KIND_ENUM, 0, 1),
1631 sizeof(int)),
1632 BTF_ENUM_ENC(NAME_TBD, 0),
1633 BTF_END_RAW,
1634 },
1635 .str_sec = "\0A!\0B",
1636 .str_sec_size = sizeof("\0A!\0B"),
1637 .map_type = BPF_MAP_TYPE_ARRAY,
1638 .map_name = "enum_type_check_btf",
1639 .key_size = sizeof(int),
1640 .value_size = sizeof(int),
1641 .key_type_id = 1,
1642 .value_type_id = 1,
1643 .max_entries = 4,
1644 .btf_load_err = true,
1645 .err_str = "Invalid name",
1646},
1647
1648{
1649 .descr = "enum member (invalid name, name_off = 0)",
1650 .raw_types = {
1651 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
1652 BTF_TYPE_ENC(0,
1653 BTF_INFO_ENC(BTF_KIND_ENUM, 0, 1),
1654 sizeof(int)),
1655 BTF_ENUM_ENC(0, 0),
1656 BTF_END_RAW,
1657 },
1658 .str_sec = "",
1659 .str_sec_size = sizeof(""),
1660 .map_type = BPF_MAP_TYPE_ARRAY,
1661 .map_name = "enum_type_check_btf",
1662 .key_size = sizeof(int),
1663 .value_size = sizeof(int),
1664 .key_type_id = 1,
1665 .value_type_id = 1,
1666 .max_entries = 4,
1667 .btf_load_err = true,
1668 .err_str = "Invalid name",
1669},
1670
1671{
1672 .descr = "enum member (invalid name, invalid identifier)",
1673 .raw_types = {
1674 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
1675 BTF_TYPE_ENC(0,
1676 BTF_INFO_ENC(BTF_KIND_ENUM, 0, 1),
1677 sizeof(int)),
1678 BTF_ENUM_ENC(NAME_TBD, 0),
1679 BTF_END_RAW,
1680 },
1681 .str_sec = "\0A!",
1682 .str_sec_size = sizeof("\0A!"),
1683 .map_type = BPF_MAP_TYPE_ARRAY,
1684 .map_name = "enum_type_check_btf",
1685 .key_size = sizeof(int),
1686 .value_size = sizeof(int),
1687 .key_type_id = 1,
1688 .value_type_id = 1,
1689 .max_entries = 4,
1690 .btf_load_err = true,
1691 .err_str = "Invalid name",
1692},
1693{
1694 .descr = "arraymap invalid btf key (a bit field)",
1695 .raw_types = {
1696
1697 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
1698
1699 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 32, 32, 8),
1700 BTF_END_RAW,
1701 },
1702 .str_sec = "",
1703 .str_sec_size = sizeof(""),
1704 .map_type = BPF_MAP_TYPE_ARRAY,
1705 .map_name = "array_map_check_btf",
1706 .key_size = sizeof(int),
1707 .value_size = sizeof(int),
1708 .key_type_id = 2,
1709 .value_type_id = 1,
1710 .max_entries = 4,
1711 .map_create_err = true,
1712},
1713
1714{
1715 .descr = "arraymap invalid btf key (!= 32 bits)",
1716 .raw_types = {
1717
1718 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
1719
1720 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 16, 2),
1721 BTF_END_RAW,
1722 },
1723 .str_sec = "",
1724 .str_sec_size = sizeof(""),
1725 .map_type = BPF_MAP_TYPE_ARRAY,
1726 .map_name = "array_map_check_btf",
1727 .key_size = sizeof(int),
1728 .value_size = sizeof(int),
1729 .key_type_id = 2,
1730 .value_type_id = 1,
1731 .max_entries = 4,
1732 .map_create_err = true,
1733},
1734
1735{
1736 .descr = "arraymap invalid btf value (too small)",
1737 .raw_types = {
1738
1739 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
1740 BTF_END_RAW,
1741 },
1742 .str_sec = "",
1743 .str_sec_size = sizeof(""),
1744 .map_type = BPF_MAP_TYPE_ARRAY,
1745 .map_name = "array_map_check_btf",
1746 .key_size = sizeof(int),
1747
1748 .value_size = sizeof(__u64),
1749 .key_type_id = 1,
1750 .value_type_id = 1,
1751 .max_entries = 4,
1752 .map_create_err = true,
1753},
1754
1755{
1756 .descr = "arraymap invalid btf value (too big)",
1757 .raw_types = {
1758
1759 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
1760 BTF_END_RAW,
1761 },
1762 .str_sec = "",
1763 .str_sec_size = sizeof(""),
1764 .map_type = BPF_MAP_TYPE_ARRAY,
1765 .map_name = "array_map_check_btf",
1766 .key_size = sizeof(int),
1767
1768 .value_size = sizeof(__u16),
1769 .key_type_id = 1,
1770 .value_type_id = 1,
1771 .max_entries = 4,
1772 .map_create_err = true,
1773},
1774
1775{
1776 .descr = "func proto (int (*)(int, unsigned int))",
1777 .raw_types = {
1778 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
1779 BTF_TYPE_INT_ENC(0, 0, 0, 32, 4),
1780
1781 BTF_FUNC_PROTO_ENC(1, 2),
1782 BTF_FUNC_PROTO_ARG_ENC(0, 1),
1783 BTF_FUNC_PROTO_ARG_ENC(0, 2),
1784 BTF_END_RAW,
1785 },
1786 .str_sec = "",
1787 .str_sec_size = sizeof(""),
1788 .map_type = BPF_MAP_TYPE_ARRAY,
1789 .map_name = "func_proto_type_check_btf",
1790 .key_size = sizeof(int),
1791 .value_size = sizeof(int),
1792 .key_type_id = 1,
1793 .value_type_id = 1,
1794 .max_entries = 4,
1795},
1796
1797{
1798 .descr = "func proto (vararg)",
1799 .raw_types = {
1800 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
1801 BTF_TYPE_INT_ENC(0, 0, 0, 32, 4),
1802
1803 BTF_FUNC_PROTO_ENC(0, 3),
1804 BTF_FUNC_PROTO_ARG_ENC(0, 1),
1805 BTF_FUNC_PROTO_ARG_ENC(0, 2),
1806 BTF_FUNC_PROTO_ARG_ENC(0, 0),
1807 BTF_END_RAW,
1808 },
1809 .str_sec = "",
1810 .str_sec_size = sizeof(""),
1811 .map_type = BPF_MAP_TYPE_ARRAY,
1812 .map_name = "func_proto_type_check_btf",
1813 .key_size = sizeof(int),
1814 .value_size = sizeof(int),
1815 .key_type_id = 1,
1816 .value_type_id = 1,
1817 .max_entries = 4,
1818},
1819
1820{
1821 .descr = "func proto (vararg with name)",
1822 .raw_types = {
1823 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
1824 BTF_TYPE_INT_ENC(0, 0, 0, 32, 4),
1825
1826 BTF_FUNC_PROTO_ENC(0, 3),
1827 BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
1828 BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 2),
1829 BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 0),
1830 BTF_END_RAW,
1831 },
1832 .str_sec = "\0a\0b\0c",
1833 .str_sec_size = sizeof("\0a\0b\0c"),
1834 .map_type = BPF_MAP_TYPE_ARRAY,
1835 .map_name = "func_proto_type_check_btf",
1836 .key_size = sizeof(int),
1837 .value_size = sizeof(int),
1838 .key_type_id = 1,
1839 .value_type_id = 1,
1840 .max_entries = 4,
1841 .btf_load_err = true,
1842 .err_str = "Invalid arg#3",
1843},
1844
1845{
1846 .descr = "func proto (arg after vararg)",
1847 .raw_types = {
1848 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
1849 BTF_TYPE_INT_ENC(0, 0, 0, 32, 4),
1850
1851 BTF_FUNC_PROTO_ENC(0, 3),
1852 BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
1853 BTF_FUNC_PROTO_ARG_ENC(0, 0),
1854 BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 2),
1855 BTF_END_RAW,
1856 },
1857 .str_sec = "\0a\0b",
1858 .str_sec_size = sizeof("\0a\0b"),
1859 .map_type = BPF_MAP_TYPE_ARRAY,
1860 .map_name = "func_proto_type_check_btf",
1861 .key_size = sizeof(int),
1862 .value_size = sizeof(int),
1863 .key_type_id = 1,
1864 .value_type_id = 1,
1865 .max_entries = 4,
1866 .btf_load_err = true,
1867 .err_str = "Invalid arg#2",
1868},
1869
1870{
1871 .descr = "func proto (CONST=>TYPEDEF=>PTR=>FUNC_PROTO)",
1872 .raw_types = {
1873 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
1874 BTF_TYPE_INT_ENC(0, 0, 0, 32, 4),
1875
1876 BTF_TYPEDEF_ENC(NAME_TBD, 5),
1877
1878 BTF_CONST_ENC(3),
1879 BTF_PTR_ENC(6),
1880 BTF_FUNC_PROTO_ENC(0, 2),
1881 BTF_FUNC_PROTO_ARG_ENC(0, 1),
1882 BTF_FUNC_PROTO_ARG_ENC(0, 2),
1883 BTF_END_RAW,
1884 },
1885 .str_sec = "\0func_ptr",
1886 .str_sec_size = sizeof("\0func_ptr"),
1887 .map_type = BPF_MAP_TYPE_ARRAY,
1888 .map_name = "func_proto_type_check_btf",
1889 .key_size = sizeof(int),
1890 .value_size = sizeof(int),
1891 .key_type_id = 1,
1892 .value_type_id = 1,
1893 .max_entries = 4,
1894},
1895
1896{
1897 .descr = "func proto (TYPEDEF=>FUNC_PROTO)",
1898 .raw_types = {
1899 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
1900 BTF_TYPE_INT_ENC(0, 0, 0, 32, 4),
1901 BTF_TYPEDEF_ENC(NAME_TBD, 4),
1902 BTF_FUNC_PROTO_ENC(0, 2),
1903 BTF_FUNC_PROTO_ARG_ENC(0, 1),
1904 BTF_FUNC_PROTO_ARG_ENC(0, 2),
1905 BTF_END_RAW,
1906 },
1907 .str_sec = "\0func_typedef",
1908 .str_sec_size = sizeof("\0func_typedef"),
1909 .map_type = BPF_MAP_TYPE_ARRAY,
1910 .map_name = "func_proto_type_check_btf",
1911 .key_size = sizeof(int),
1912 .value_size = sizeof(int),
1913 .key_type_id = 1,
1914 .value_type_id = 1,
1915 .max_entries = 4,
1916},
1917
1918{
1919 .descr = "func proto (btf_resolve(arg))",
1920 .raw_types = {
1921 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
1922
1923 BTF_FUNC_PROTO_ENC(0, 1),
1924 BTF_FUNC_PROTO_ARG_ENC(0, 3),
1925 BTF_CONST_ENC(4),
1926 BTF_PTR_ENC(0),
1927 BTF_END_RAW,
1928 },
1929 .str_sec = "",
1930 .str_sec_size = sizeof(""),
1931 .map_type = BPF_MAP_TYPE_ARRAY,
1932 .map_name = "func_proto_type_check_btf",
1933 .key_size = sizeof(int),
1934 .value_size = sizeof(int),
1935 .key_type_id = 1,
1936 .value_type_id = 1,
1937 .max_entries = 4,
1938},
1939
1940{
1941 .descr = "func proto (Not all arg has name)",
1942 .raw_types = {
1943 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
1944 BTF_TYPE_INT_ENC(0, 0, 0, 32, 4),
1945
1946 BTF_FUNC_PROTO_ENC(0, 2),
1947 BTF_FUNC_PROTO_ARG_ENC(0, 1),
1948 BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 2),
1949 BTF_END_RAW,
1950 },
1951 .str_sec = "\0b",
1952 .str_sec_size = sizeof("\0b"),
1953 .map_type = BPF_MAP_TYPE_ARRAY,
1954 .map_name = "func_proto_type_check_btf",
1955 .key_size = sizeof(int),
1956 .value_size = sizeof(int),
1957 .key_type_id = 1,
1958 .value_type_id = 1,
1959 .max_entries = 4,
1960},
1961
1962{
1963 .descr = "func proto (Bad arg name_off)",
1964 .raw_types = {
1965 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
1966 BTF_TYPE_INT_ENC(0, 0, 0, 32, 4),
1967
1968 BTF_FUNC_PROTO_ENC(0, 2),
1969 BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
1970 BTF_FUNC_PROTO_ARG_ENC(0x0fffffff, 2),
1971 BTF_END_RAW,
1972 },
1973 .str_sec = "\0a",
1974 .str_sec_size = sizeof("\0a"),
1975 .map_type = BPF_MAP_TYPE_ARRAY,
1976 .map_name = "func_proto_type_check_btf",
1977 .key_size = sizeof(int),
1978 .value_size = sizeof(int),
1979 .key_type_id = 1,
1980 .value_type_id = 1,
1981 .max_entries = 4,
1982 .btf_load_err = true,
1983 .err_str = "Invalid arg#2",
1984},
1985
1986{
1987 .descr = "func proto (Bad arg name)",
1988 .raw_types = {
1989 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
1990 BTF_TYPE_INT_ENC(0, 0, 0, 32, 4),
1991
1992 BTF_FUNC_PROTO_ENC(0, 2),
1993 BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
1994 BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 2),
1995 BTF_END_RAW,
1996 },
1997 .str_sec = "\0a\0!!!",
1998 .str_sec_size = sizeof("\0a\0!!!"),
1999 .map_type = BPF_MAP_TYPE_ARRAY,
2000 .map_name = "func_proto_type_check_btf",
2001 .key_size = sizeof(int),
2002 .value_size = sizeof(int),
2003 .key_type_id = 1,
2004 .value_type_id = 1,
2005 .max_entries = 4,
2006 .btf_load_err = true,
2007 .err_str = "Invalid arg#2",
2008},
2009
2010{
2011 .descr = "func proto (Invalid return type)",
2012 .raw_types = {
2013 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
2014 BTF_TYPE_INT_ENC(0, 0, 0, 32, 4),
2015
2016 BTF_FUNC_PROTO_ENC(100, 2),
2017 BTF_FUNC_PROTO_ARG_ENC(0, 1),
2018 BTF_FUNC_PROTO_ARG_ENC(0, 2),
2019 BTF_END_RAW,
2020 },
2021 .str_sec = "",
2022 .str_sec_size = sizeof(""),
2023 .map_type = BPF_MAP_TYPE_ARRAY,
2024 .map_name = "func_proto_type_check_btf",
2025 .key_size = sizeof(int),
2026 .value_size = sizeof(int),
2027 .key_type_id = 1,
2028 .value_type_id = 1,
2029 .max_entries = 4,
2030 .btf_load_err = true,
2031 .err_str = "Invalid return type",
2032},
2033
2034{
2035 .descr = "func proto (with func name)",
2036 .raw_types = {
2037 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
2038 BTF_TYPE_INT_ENC(0, 0, 0, 32, 4),
2039
2040 BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_FUNC_PROTO, 0, 2), 0),
2041 BTF_FUNC_PROTO_ARG_ENC(0, 1),
2042 BTF_FUNC_PROTO_ARG_ENC(0, 2),
2043 BTF_END_RAW,
2044 },
2045 .str_sec = "\0func_proto",
2046 .str_sec_size = sizeof("\0func_proto"),
2047 .map_type = BPF_MAP_TYPE_ARRAY,
2048 .map_name = "func_proto_type_check_btf",
2049 .key_size = sizeof(int),
2050 .value_size = sizeof(int),
2051 .key_type_id = 1,
2052 .value_type_id = 1,
2053 .max_entries = 4,
2054 .btf_load_err = true,
2055 .err_str = "Invalid name",
2056},
2057
2058{
2059 .descr = "func proto (const void arg)",
2060 .raw_types = {
2061 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
2062 BTF_TYPE_INT_ENC(0, 0, 0, 32, 4),
2063
2064 BTF_FUNC_PROTO_ENC(0, 1),
2065 BTF_FUNC_PROTO_ARG_ENC(0, 4),
2066 BTF_CONST_ENC(0),
2067 BTF_END_RAW,
2068 },
2069 .str_sec = "",
2070 .str_sec_size = sizeof(""),
2071 .map_type = BPF_MAP_TYPE_ARRAY,
2072 .map_name = "func_proto_type_check_btf",
2073 .key_size = sizeof(int),
2074 .value_size = sizeof(int),
2075 .key_type_id = 1,
2076 .value_type_id = 1,
2077 .max_entries = 4,
2078 .btf_load_err = true,
2079 .err_str = "Invalid arg#1",
2080},
2081
2082{
2083 .descr = "func (void func(int a, unsigned int b))",
2084 .raw_types = {
2085 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
2086 BTF_TYPE_INT_ENC(0, 0, 0, 32, 4),
2087
2088 BTF_FUNC_PROTO_ENC(0, 2),
2089 BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
2090 BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 2),
2091
2092 BTF_FUNC_ENC(NAME_TBD, 3),
2093 BTF_END_RAW,
2094 },
2095 .str_sec = "\0a\0b\0func",
2096 .str_sec_size = sizeof("\0a\0b\0func"),
2097 .map_type = BPF_MAP_TYPE_ARRAY,
2098 .map_name = "func_type_check_btf",
2099 .key_size = sizeof(int),
2100 .value_size = sizeof(int),
2101 .key_type_id = 1,
2102 .value_type_id = 1,
2103 .max_entries = 4,
2104},
2105
2106{
2107 .descr = "func (No func name)",
2108 .raw_types = {
2109 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
2110 BTF_TYPE_INT_ENC(0, 0, 0, 32, 4),
2111
2112 BTF_FUNC_PROTO_ENC(0, 2),
2113 BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
2114 BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 2),
2115
2116 BTF_FUNC_ENC(0, 3),
2117 BTF_END_RAW,
2118 },
2119 .str_sec = "\0a\0b",
2120 .str_sec_size = sizeof("\0a\0b"),
2121 .map_type = BPF_MAP_TYPE_ARRAY,
2122 .map_name = "func_type_check_btf",
2123 .key_size = sizeof(int),
2124 .value_size = sizeof(int),
2125 .key_type_id = 1,
2126 .value_type_id = 1,
2127 .max_entries = 4,
2128 .btf_load_err = true,
2129 .err_str = "Invalid name",
2130},
2131
2132{
2133 .descr = "func (Invalid func name)",
2134 .raw_types = {
2135 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
2136 BTF_TYPE_INT_ENC(0, 0, 0, 32, 4),
2137
2138 BTF_FUNC_PROTO_ENC(0, 2),
2139 BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
2140 BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 2),
2141
2142 BTF_FUNC_ENC(NAME_TBD, 3),
2143 BTF_END_RAW,
2144 },
2145 .str_sec = "\0a\0b\0!!!",
2146 .str_sec_size = sizeof("\0a\0b\0!!!"),
2147 .map_type = BPF_MAP_TYPE_ARRAY,
2148 .map_name = "func_type_check_btf",
2149 .key_size = sizeof(int),
2150 .value_size = sizeof(int),
2151 .key_type_id = 1,
2152 .value_type_id = 1,
2153 .max_entries = 4,
2154 .btf_load_err = true,
2155 .err_str = "Invalid name",
2156},
2157
2158{
2159 .descr = "func (Some arg has no name)",
2160 .raw_types = {
2161 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
2162 BTF_TYPE_INT_ENC(0, 0, 0, 32, 4),
2163
2164 BTF_FUNC_PROTO_ENC(0, 2),
2165 BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
2166 BTF_FUNC_PROTO_ARG_ENC(0, 2),
2167
2168 BTF_FUNC_ENC(NAME_TBD, 3),
2169 BTF_END_RAW,
2170 },
2171 .str_sec = "\0a\0func",
2172 .str_sec_size = sizeof("\0a\0func"),
2173 .map_type = BPF_MAP_TYPE_ARRAY,
2174 .map_name = "func_type_check_btf",
2175 .key_size = sizeof(int),
2176 .value_size = sizeof(int),
2177 .key_type_id = 1,
2178 .value_type_id = 1,
2179 .max_entries = 4,
2180 .btf_load_err = true,
2181 .err_str = "Invalid arg#2",
2182},
2183
2184{
2185 .descr = "func (Non zero vlen)",
2186 .raw_types = {
2187 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
2188 BTF_TYPE_INT_ENC(0, 0, 0, 32, 4),
2189
2190 BTF_FUNC_PROTO_ENC(0, 2),
2191 BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
2192 BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 2),
2193
2194 BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_FUNC, 0, 2), 3),
2195 BTF_END_RAW,
2196 },
2197 .str_sec = "\0a\0b\0func",
2198 .str_sec_size = sizeof("\0a\0b\0func"),
2199 .map_type = BPF_MAP_TYPE_ARRAY,
2200 .map_name = "func_type_check_btf",
2201 .key_size = sizeof(int),
2202 .value_size = sizeof(int),
2203 .key_type_id = 1,
2204 .value_type_id = 1,
2205 .max_entries = 4,
2206 .btf_load_err = true,
2207 .err_str = "vlen != 0",
2208},
2209
2210{
2211 .descr = "func (Not referring to FUNC_PROTO)",
2212 .raw_types = {
2213 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
2214 BTF_FUNC_ENC(NAME_TBD, 1),
2215 BTF_END_RAW,
2216 },
2217 .str_sec = "\0func",
2218 .str_sec_size = sizeof("\0func"),
2219 .map_type = BPF_MAP_TYPE_ARRAY,
2220 .map_name = "func_type_check_btf",
2221 .key_size = sizeof(int),
2222 .value_size = sizeof(int),
2223 .key_type_id = 1,
2224 .value_type_id = 1,
2225 .max_entries = 4,
2226 .btf_load_err = true,
2227 .err_str = "Invalid type_id",
2228},
2229
2230{
2231 .descr = "invalid int kind_flag",
2232 .raw_types = {
2233 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
2234 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_INT, 1, 0), 4),
2235 BTF_INT_ENC(0, 0, 32),
2236 BTF_END_RAW,
2237 },
2238 BTF_STR_SEC(""),
2239 .map_type = BPF_MAP_TYPE_ARRAY,
2240 .map_name = "int_type_check_btf",
2241 .key_size = sizeof(int),
2242 .value_size = sizeof(int),
2243 .key_type_id = 1,
2244 .value_type_id = 1,
2245 .max_entries = 4,
2246 .btf_load_err = true,
2247 .err_str = "Invalid btf_info kind_flag",
2248},
2249
2250{
2251 .descr = "invalid ptr kind_flag",
2252 .raw_types = {
2253 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
2254 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_PTR, 1, 0), 1),
2255 BTF_END_RAW,
2256 },
2257 BTF_STR_SEC(""),
2258 .map_type = BPF_MAP_TYPE_ARRAY,
2259 .map_name = "ptr_type_check_btf",
2260 .key_size = sizeof(int),
2261 .value_size = sizeof(int),
2262 .key_type_id = 1,
2263 .value_type_id = 1,
2264 .max_entries = 4,
2265 .btf_load_err = true,
2266 .err_str = "Invalid btf_info kind_flag",
2267},
2268
2269{
2270 .descr = "invalid array kind_flag",
2271 .raw_types = {
2272 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
2273 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_ARRAY, 1, 0), 0),
2274 BTF_ARRAY_ENC(1, 1, 1),
2275 BTF_END_RAW,
2276 },
2277 BTF_STR_SEC(""),
2278 .map_type = BPF_MAP_TYPE_ARRAY,
2279 .map_name = "array_type_check_btf",
2280 .key_size = sizeof(int),
2281 .value_size = sizeof(int),
2282 .key_type_id = 1,
2283 .value_type_id = 1,
2284 .max_entries = 4,
2285 .btf_load_err = true,
2286 .err_str = "Invalid btf_info kind_flag",
2287},
2288
2289{
2290 .descr = "invalid enum kind_flag",
2291 .raw_types = {
2292 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
2293 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_ENUM, 1, 1), 4),
2294 BTF_ENUM_ENC(NAME_TBD, 0),
2295 BTF_END_RAW,
2296 },
2297 BTF_STR_SEC("\0A"),
2298 .map_type = BPF_MAP_TYPE_ARRAY,
2299 .map_name = "enum_type_check_btf",
2300 .key_size = sizeof(int),
2301 .value_size = sizeof(int),
2302 .key_type_id = 1,
2303 .value_type_id = 1,
2304 .max_entries = 4,
2305 .btf_load_err = true,
2306 .err_str = "Invalid btf_info kind_flag",
2307},
2308
2309{
2310 .descr = "valid fwd kind_flag",
2311 .raw_types = {
2312 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
2313 BTF_TYPE_ENC(NAME_TBD,
2314 BTF_INFO_ENC(BTF_KIND_FWD, 1, 0), 0),
2315 BTF_END_RAW,
2316 },
2317 BTF_STR_SEC("\0A"),
2318 .map_type = BPF_MAP_TYPE_ARRAY,
2319 .map_name = "fwd_type_check_btf",
2320 .key_size = sizeof(int),
2321 .value_size = sizeof(int),
2322 .key_type_id = 1,
2323 .value_type_id = 1,
2324 .max_entries = 4,
2325},
2326
2327{
2328 .descr = "invalid typedef kind_flag",
2329 .raw_types = {
2330 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
2331 BTF_TYPE_ENC(NAME_TBD,
2332 BTF_INFO_ENC(BTF_KIND_TYPEDEF, 1, 0), 1),
2333 BTF_END_RAW,
2334 },
2335 BTF_STR_SEC("\0A"),
2336 .map_type = BPF_MAP_TYPE_ARRAY,
2337 .map_name = "typedef_type_check_btf",
2338 .key_size = sizeof(int),
2339 .value_size = sizeof(int),
2340 .key_type_id = 1,
2341 .value_type_id = 1,
2342 .max_entries = 4,
2343 .btf_load_err = true,
2344 .err_str = "Invalid btf_info kind_flag",
2345},
2346
2347{
2348 .descr = "invalid volatile kind_flag",
2349 .raw_types = {
2350 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
2351 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_VOLATILE, 1, 0), 1),
2352 BTF_END_RAW,
2353 },
2354 BTF_STR_SEC(""),
2355 .map_type = BPF_MAP_TYPE_ARRAY,
2356 .map_name = "volatile_type_check_btf",
2357 .key_size = sizeof(int),
2358 .value_size = sizeof(int),
2359 .key_type_id = 1,
2360 .value_type_id = 1,
2361 .max_entries = 4,
2362 .btf_load_err = true,
2363 .err_str = "Invalid btf_info kind_flag",
2364},
2365
2366{
2367 .descr = "invalid const kind_flag",
2368 .raw_types = {
2369 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
2370 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_CONST, 1, 0), 1),
2371 BTF_END_RAW,
2372 },
2373 BTF_STR_SEC(""),
2374 .map_type = BPF_MAP_TYPE_ARRAY,
2375 .map_name = "const_type_check_btf",
2376 .key_size = sizeof(int),
2377 .value_size = sizeof(int),
2378 .key_type_id = 1,
2379 .value_type_id = 1,
2380 .max_entries = 4,
2381 .btf_load_err = true,
2382 .err_str = "Invalid btf_info kind_flag",
2383},
2384
2385{
2386 .descr = "invalid restrict kind_flag",
2387 .raw_types = {
2388 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
2389 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_RESTRICT, 1, 0), 1),
2390 BTF_END_RAW,
2391 },
2392 BTF_STR_SEC(""),
2393 .map_type = BPF_MAP_TYPE_ARRAY,
2394 .map_name = "restrict_type_check_btf",
2395 .key_size = sizeof(int),
2396 .value_size = sizeof(int),
2397 .key_type_id = 1,
2398 .value_type_id = 1,
2399 .max_entries = 4,
2400 .btf_load_err = true,
2401 .err_str = "Invalid btf_info kind_flag",
2402},
2403
2404{
2405 .descr = "invalid func kind_flag",
2406 .raw_types = {
2407 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
2408 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_FUNC_PROTO, 0, 0), 0),
2409 BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_FUNC, 1, 0), 2),
2410 BTF_END_RAW,
2411 },
2412 BTF_STR_SEC("\0A"),
2413 .map_type = BPF_MAP_TYPE_ARRAY,
2414 .map_name = "func_type_check_btf",
2415 .key_size = sizeof(int),
2416 .value_size = sizeof(int),
2417 .key_type_id = 1,
2418 .value_type_id = 1,
2419 .max_entries = 4,
2420 .btf_load_err = true,
2421 .err_str = "Invalid btf_info kind_flag",
2422},
2423
2424{
2425 .descr = "invalid func_proto kind_flag",
2426 .raw_types = {
2427 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
2428 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_FUNC_PROTO, 1, 0), 0),
2429 BTF_END_RAW,
2430 },
2431 BTF_STR_SEC(""),
2432 .map_type = BPF_MAP_TYPE_ARRAY,
2433 .map_name = "func_proto_type_check_btf",
2434 .key_size = sizeof(int),
2435 .value_size = sizeof(int),
2436 .key_type_id = 1,
2437 .value_type_id = 1,
2438 .max_entries = 4,
2439 .btf_load_err = true,
2440 .err_str = "Invalid btf_info kind_flag",
2441},
2442
2443{
2444 .descr = "valid struct, kind_flag, bitfield_size = 0",
2445 .raw_types = {
2446 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
2447 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_STRUCT, 1, 2), 8),
2448 BTF_MEMBER_ENC(NAME_TBD, 1, BTF_MEMBER_OFFSET(0, 0)),
2449 BTF_MEMBER_ENC(NAME_TBD, 1, BTF_MEMBER_OFFSET(0, 32)),
2450 BTF_END_RAW,
2451 },
2452 BTF_STR_SEC("\0A\0B"),
2453 .map_type = BPF_MAP_TYPE_ARRAY,
2454 .map_name = "struct_type_check_btf",
2455 .key_size = sizeof(int),
2456 .value_size = sizeof(int),
2457 .key_type_id = 1,
2458 .value_type_id = 1,
2459 .max_entries = 4,
2460},
2461
2462{
2463 .descr = "valid struct, kind_flag, int member, bitfield_size != 0",
2464 .raw_types = {
2465 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
2466 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_STRUCT, 1, 2), 4),
2467 BTF_MEMBER_ENC(NAME_TBD, 1, BTF_MEMBER_OFFSET(4, 0)),
2468 BTF_MEMBER_ENC(NAME_TBD, 1, BTF_MEMBER_OFFSET(4, 4)),
2469 BTF_END_RAW,
2470 },
2471 BTF_STR_SEC("\0A\0B"),
2472 .map_type = BPF_MAP_TYPE_ARRAY,
2473 .map_name = "struct_type_check_btf",
2474 .key_size = sizeof(int),
2475 .value_size = sizeof(int),
2476 .key_type_id = 1,
2477 .value_type_id = 1,
2478 .max_entries = 4,
2479},
2480
2481{
2482 .descr = "valid union, kind_flag, int member, bitfield_size != 0",
2483 .raw_types = {
2484 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
2485 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_UNION, 1, 2), 4),
2486 BTF_MEMBER_ENC(NAME_TBD, 1, BTF_MEMBER_OFFSET(4, 0)),
2487 BTF_MEMBER_ENC(NAME_TBD, 1, BTF_MEMBER_OFFSET(4, 0)),
2488 BTF_END_RAW,
2489 },
2490 BTF_STR_SEC("\0A\0B"),
2491 .map_type = BPF_MAP_TYPE_ARRAY,
2492 .map_name = "union_type_check_btf",
2493 .key_size = sizeof(int),
2494 .value_size = sizeof(int),
2495 .key_type_id = 1,
2496 .value_type_id = 1,
2497 .max_entries = 4,
2498},
2499
2500{
2501 .descr = "valid struct, kind_flag, enum member, bitfield_size != 0",
2502 .raw_types = {
2503 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
2504 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_ENUM, 0, 1), 4),
2505 BTF_ENUM_ENC(NAME_TBD, 0),
2506 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_STRUCT, 1, 2), 4),
2507 BTF_MEMBER_ENC(NAME_TBD, 2, BTF_MEMBER_OFFSET(4, 0)),
2508 BTF_MEMBER_ENC(NAME_TBD, 2, BTF_MEMBER_OFFSET(4, 4)),
2509 BTF_END_RAW,
2510 },
2511 BTF_STR_SEC("\0A\0B\0C"),
2512 .map_type = BPF_MAP_TYPE_ARRAY,
2513 .map_name = "struct_type_check_btf",
2514 .key_size = sizeof(int),
2515 .value_size = sizeof(int),
2516 .key_type_id = 1,
2517 .value_type_id = 1,
2518 .max_entries = 4,
2519},
2520
2521{
2522 .descr = "valid union, kind_flag, enum member, bitfield_size != 0",
2523 .raw_types = {
2524 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
2525 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_ENUM, 0, 1), 4),
2526 BTF_ENUM_ENC(NAME_TBD, 0),
2527 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_UNION, 1, 2), 4),
2528 BTF_MEMBER_ENC(NAME_TBD, 2, BTF_MEMBER_OFFSET(4, 0)),
2529 BTF_MEMBER_ENC(NAME_TBD, 2, BTF_MEMBER_OFFSET(4, 0)),
2530 BTF_END_RAW,
2531 },
2532 BTF_STR_SEC("\0A\0B\0C"),
2533 .map_type = BPF_MAP_TYPE_ARRAY,
2534 .map_name = "union_type_check_btf",
2535 .key_size = sizeof(int),
2536 .value_size = sizeof(int),
2537 .key_type_id = 1,
2538 .value_type_id = 1,
2539 .max_entries = 4,
2540},
2541
2542{
2543 .descr = "valid struct, kind_flag, typedef member, bitfield_size != 0",
2544 .raw_types = {
2545 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
2546 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_ENUM, 0, 1), 4),
2547 BTF_ENUM_ENC(NAME_TBD, 0),
2548 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_STRUCT, 1, 2), 4),
2549 BTF_MEMBER_ENC(NAME_TBD, 4, BTF_MEMBER_OFFSET(4, 0)),
2550 BTF_MEMBER_ENC(NAME_TBD, 5, BTF_MEMBER_OFFSET(4, 4)),
2551 BTF_TYPEDEF_ENC(NAME_TBD, 1),
2552 BTF_TYPEDEF_ENC(NAME_TBD, 2),
2553 BTF_END_RAW,
2554 },
2555 BTF_STR_SEC("\0A\0B\0C\0D\0E"),
2556 .map_type = BPF_MAP_TYPE_ARRAY,
2557 .map_name = "struct_type_check_btf",
2558 .key_size = sizeof(int),
2559 .value_size = sizeof(int),
2560 .key_type_id = 1,
2561 .value_type_id = 1,
2562 .max_entries = 4,
2563},
2564
2565{
2566 .descr = "valid union, kind_flag, typedef member, bitfield_size != 0",
2567 .raw_types = {
2568 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
2569 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_ENUM, 0, 1), 4),
2570 BTF_ENUM_ENC(NAME_TBD, 0),
2571 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_UNION, 1, 2), 4),
2572 BTF_MEMBER_ENC(NAME_TBD, 4, BTF_MEMBER_OFFSET(4, 0)),
2573 BTF_MEMBER_ENC(NAME_TBD, 5, BTF_MEMBER_OFFSET(4, 0)),
2574 BTF_TYPEDEF_ENC(NAME_TBD, 1),
2575 BTF_TYPEDEF_ENC(NAME_TBD, 2),
2576 BTF_END_RAW,
2577 },
2578 BTF_STR_SEC("\0A\0B\0C\0D\0E"),
2579 .map_type = BPF_MAP_TYPE_ARRAY,
2580 .map_name = "union_type_check_btf",
2581 .key_size = sizeof(int),
2582 .value_size = sizeof(int),
2583 .key_type_id = 1,
2584 .value_type_id = 1,
2585 .max_entries = 4,
2586},
2587
2588{
2589 .descr = "invalid struct, kind_flag, bitfield_size greater than struct size",
2590 .raw_types = {
2591 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
2592 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_STRUCT, 1, 2), 4),
2593 BTF_MEMBER_ENC(NAME_TBD, 1, BTF_MEMBER_OFFSET(20, 0)),
2594 BTF_MEMBER_ENC(NAME_TBD, 1, BTF_MEMBER_OFFSET(20, 20)),
2595 BTF_END_RAW,
2596 },
2597 BTF_STR_SEC("\0A\0B"),
2598 .map_type = BPF_MAP_TYPE_ARRAY,
2599 .map_name = "struct_type_check_btf",
2600 .key_size = sizeof(int),
2601 .value_size = sizeof(int),
2602 .key_type_id = 1,
2603 .value_type_id = 1,
2604 .max_entries = 4,
2605 .btf_load_err = true,
2606 .err_str = "Member exceeds struct_size",
2607},
2608
2609{
2610 .descr = "invalid struct, kind_flag, bitfield base_type int not regular",
2611 .raw_types = {
2612 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
2613 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 20, 4),
2614 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_STRUCT, 1, 2), 4),
2615 BTF_MEMBER_ENC(NAME_TBD, 2, BTF_MEMBER_OFFSET(20, 0)),
2616 BTF_MEMBER_ENC(NAME_TBD, 2, BTF_MEMBER_OFFSET(20, 20)),
2617 BTF_END_RAW,
2618 },
2619 BTF_STR_SEC("\0A\0B"),
2620 .map_type = BPF_MAP_TYPE_ARRAY,
2621 .map_name = "struct_type_check_btf",
2622 .key_size = sizeof(int),
2623 .value_size = sizeof(int),
2624 .key_type_id = 1,
2625 .value_type_id = 1,
2626 .max_entries = 4,
2627 .btf_load_err = true,
2628 .err_str = "Invalid member base type",
2629},
2630
2631{
2632 .descr = "invalid struct, kind_flag, base_type int not regular",
2633 .raw_types = {
2634 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
2635 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 12, 4),
2636 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_STRUCT, 1, 2), 4),
2637 BTF_MEMBER_ENC(NAME_TBD, 2, BTF_MEMBER_OFFSET(8, 0)),
2638 BTF_MEMBER_ENC(NAME_TBD, 2, BTF_MEMBER_OFFSET(8, 8)),
2639 BTF_END_RAW,
2640 },
2641 BTF_STR_SEC("\0A\0B"),
2642 .map_type = BPF_MAP_TYPE_ARRAY,
2643 .map_name = "struct_type_check_btf",
2644 .key_size = sizeof(int),
2645 .value_size = sizeof(int),
2646 .key_type_id = 1,
2647 .value_type_id = 1,
2648 .max_entries = 4,
2649 .btf_load_err = true,
2650 .err_str = "Invalid member base type",
2651},
2652
2653{
2654 .descr = "invalid union, kind_flag, bitfield_size greater than struct size",
2655 .raw_types = {
2656 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
2657 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_UNION, 1, 2), 2),
2658 BTF_MEMBER_ENC(NAME_TBD, 1, BTF_MEMBER_OFFSET(8, 0)),
2659 BTF_MEMBER_ENC(NAME_TBD, 1, BTF_MEMBER_OFFSET(20, 0)),
2660 BTF_END_RAW,
2661 },
2662 BTF_STR_SEC("\0A\0B"),
2663 .map_type = BPF_MAP_TYPE_ARRAY,
2664 .map_name = "union_type_check_btf",
2665 .key_size = sizeof(int),
2666 .value_size = sizeof(int),
2667 .key_type_id = 1,
2668 .value_type_id = 1,
2669 .max_entries = 4,
2670 .btf_load_err = true,
2671 .err_str = "Member exceeds struct_size",
2672},
2673
2674{
2675 .descr = "invalid struct, kind_flag, int member, bitfield_size = 0, wrong byte alignment",
2676 .raw_types = {
2677 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
2678 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
2679 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_STRUCT, 1, 2), 12),
2680 BTF_MEMBER_ENC(NAME_TBD, 2, BTF_MEMBER_OFFSET(0, 0)),
2681 BTF_MEMBER_ENC(NAME_TBD, 2, BTF_MEMBER_OFFSET(0, 36)),
2682 BTF_END_RAW,
2683 },
2684 BTF_STR_SEC("\0A\0B"),
2685 .map_type = BPF_MAP_TYPE_ARRAY,
2686 .map_name = "struct_type_check_btf",
2687 .key_size = sizeof(int),
2688 .value_size = sizeof(int),
2689 .key_type_id = 1,
2690 .value_type_id = 1,
2691 .max_entries = 4,
2692 .btf_load_err = true,
2693 .err_str = "Invalid member offset",
2694},
2695
2696{
2697 .descr = "invalid struct, kind_flag, enum member, bitfield_size = 0, wrong byte alignment",
2698 .raw_types = {
2699 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
2700 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
2701 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_ENUM, 0, 1), 4),
2702 BTF_ENUM_ENC(NAME_TBD, 0),
2703 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_STRUCT, 1, 2), 12),
2704 BTF_MEMBER_ENC(NAME_TBD, 2, BTF_MEMBER_OFFSET(0, 0)),
2705 BTF_MEMBER_ENC(NAME_TBD, 2, BTF_MEMBER_OFFSET(0, 36)),
2706 BTF_END_RAW,
2707 },
2708 BTF_STR_SEC("\0A\0B\0C"),
2709 .map_type = BPF_MAP_TYPE_ARRAY,
2710 .map_name = "struct_type_check_btf",
2711 .key_size = sizeof(int),
2712 .value_size = sizeof(int),
2713 .key_type_id = 1,
2714 .value_type_id = 1,
2715 .max_entries = 4,
2716 .btf_load_err = true,
2717 .err_str = "Invalid member offset",
2718},
2719
2720};
2721
2722static const char *get_next_str(const char *start, const char *end)
2723{
2724 return start < end - 1 ? start + 1 : NULL;
2725}
2726
2727static int get_raw_sec_size(const __u32 *raw_types)
2728{
2729 int i;
2730
2731 for (i = MAX_NR_RAW_U32 - 1;
2732 i >= 0 && raw_types[i] != BTF_END_RAW;
2733 i--)
2734 ;
2735
2736 return i < 0 ? i : i * sizeof(raw_types[0]);
2737}
2738
2739static void *btf_raw_create(const struct btf_header *hdr,
2740 const __u32 *raw_types,
2741 const char *str,
2742 unsigned int str_sec_size,
2743 unsigned int *btf_size,
2744 const char **ret_next_str)
2745{
2746 const char *next_str = str, *end_str = str + str_sec_size;
2747 const char **strs_idx = NULL, **tmp_strs_idx;
2748 int strs_cap = 0, strs_cnt = 0, next_str_idx = 0;
2749 unsigned int size_needed, offset;
2750 struct btf_header *ret_hdr;
2751 int i, type_sec_size, err = 0;
2752 uint32_t *ret_types;
2753 void *raw_btf = NULL;
2754
2755 type_sec_size = get_raw_sec_size(raw_types);
2756 if (CHECK(type_sec_size < 0, "Cannot get nr_raw_types"))
2757 return NULL;
2758
2759 size_needed = sizeof(*hdr) + type_sec_size + str_sec_size;
2760 raw_btf = malloc(size_needed);
2761 if (CHECK(!raw_btf, "Cannot allocate memory for raw_btf"))
2762 return NULL;
2763
2764
2765 memcpy(raw_btf, hdr, sizeof(*hdr));
2766 offset = sizeof(*hdr);
2767
2768
2769 while ((next_str = get_next_str(next_str, end_str))) {
2770 if (strs_cnt == strs_cap) {
2771 strs_cap += max(16, strs_cap / 2);
2772 tmp_strs_idx = realloc(strs_idx,
2773 sizeof(*strs_idx) * strs_cap);
2774 if (CHECK(!tmp_strs_idx,
2775 "Cannot allocate memory for strs_idx")) {
2776 err = -1;
2777 goto done;
2778 }
2779 strs_idx = tmp_strs_idx;
2780 }
2781 strs_idx[strs_cnt++] = next_str;
2782 next_str += strlen(next_str);
2783 }
2784
2785
2786 ret_types = raw_btf + offset;
2787 for (i = 0; i < type_sec_size / sizeof(raw_types[0]); i++) {
2788 if (raw_types[i] == NAME_TBD) {
2789 if (CHECK(next_str_idx == strs_cnt,
2790 "Error in getting next_str #%d",
2791 next_str_idx)) {
2792 err = -1;
2793 goto done;
2794 }
2795 ret_types[i] = strs_idx[next_str_idx++] - str;
2796 } else if (IS_NAME_NTH(raw_types[i])) {
2797 int idx = GET_NAME_NTH_IDX(raw_types[i]);
2798
2799 if (CHECK(idx <= 0 || idx > strs_cnt,
2800 "Error getting string #%d, strs_cnt:%d",
2801 idx, strs_cnt)) {
2802 err = -1;
2803 goto done;
2804 }
2805 ret_types[i] = strs_idx[idx-1] - str;
2806 } else {
2807 ret_types[i] = raw_types[i];
2808 }
2809 }
2810 offset += type_sec_size;
2811
2812
2813 memcpy(raw_btf + offset, str, str_sec_size);
2814
2815 ret_hdr = (struct btf_header *)raw_btf;
2816 ret_hdr->type_len = type_sec_size;
2817 ret_hdr->str_off = type_sec_size;
2818 ret_hdr->str_len = str_sec_size;
2819
2820 *btf_size = size_needed;
2821 if (ret_next_str)
2822 *ret_next_str =
2823 next_str_idx < strs_cnt ? strs_idx[next_str_idx] : NULL;
2824
2825done:
2826 if (err) {
2827 if (raw_btf)
2828 free(raw_btf);
2829 if (strs_idx)
2830 free(strs_idx);
2831 return NULL;
2832 }
2833 return raw_btf;
2834}
2835
2836static int do_test_raw(unsigned int test_num)
2837{
2838 struct btf_raw_test *test = &raw_tests[test_num - 1];
2839 struct bpf_create_map_attr create_attr = {};
2840 int map_fd = -1, btf_fd = -1;
2841 unsigned int raw_btf_size;
2842 struct btf_header *hdr;
2843 void *raw_btf;
2844 int err;
2845
2846 fprintf(stderr, "BTF raw test[%u] (%s): ", test_num, test->descr);
2847 raw_btf = btf_raw_create(&hdr_tmpl,
2848 test->raw_types,
2849 test->str_sec,
2850 test->str_sec_size,
2851 &raw_btf_size, NULL);
2852
2853 if (!raw_btf)
2854 return -1;
2855
2856 hdr = raw_btf;
2857
2858 hdr->hdr_len = (int)hdr->hdr_len + test->hdr_len_delta;
2859 hdr->type_off = (int)hdr->type_off + test->type_off_delta;
2860 hdr->str_off = (int)hdr->str_off + test->str_off_delta;
2861 hdr->str_len = (int)hdr->str_len + test->str_len_delta;
2862
2863 *btf_log_buf = '\0';
2864 btf_fd = bpf_load_btf(raw_btf, raw_btf_size,
2865 btf_log_buf, BTF_LOG_BUF_SIZE,
2866 args.always_log);
2867 free(raw_btf);
2868
2869 err = ((btf_fd == -1) != test->btf_load_err);
2870 if (CHECK(err, "btf_fd:%d test->btf_load_err:%u",
2871 btf_fd, test->btf_load_err) ||
2872 CHECK(test->err_str && !strstr(btf_log_buf, test->err_str),
2873 "expected err_str:%s", test->err_str)) {
2874 err = -1;
2875 goto done;
2876 }
2877
2878 if (err || btf_fd == -1)
2879 goto done;
2880
2881 create_attr.name = test->map_name;
2882 create_attr.map_type = test->map_type;
2883 create_attr.key_size = test->key_size;
2884 create_attr.value_size = test->value_size;
2885 create_attr.max_entries = test->max_entries;
2886 create_attr.btf_fd = btf_fd;
2887 create_attr.btf_key_type_id = test->key_type_id;
2888 create_attr.btf_value_type_id = test->value_type_id;
2889
2890 map_fd = bpf_create_map_xattr(&create_attr);
2891
2892 err = ((map_fd == -1) != test->map_create_err);
2893 CHECK(err, "map_fd:%d test->map_create_err:%u",
2894 map_fd, test->map_create_err);
2895
2896done:
2897 if (!err)
2898 fprintf(stderr, "OK");
2899
2900 if (*btf_log_buf && (err || args.always_log))
2901 fprintf(stderr, "\n%s", btf_log_buf);
2902
2903 if (btf_fd != -1)
2904 close(btf_fd);
2905 if (map_fd != -1)
2906 close(map_fd);
2907
2908 return err;
2909}
2910
2911static int test_raw(void)
2912{
2913 unsigned int i;
2914 int err = 0;
2915
2916 if (args.raw_test_num)
2917 return count_result(do_test_raw(args.raw_test_num));
2918
2919 for (i = 1; i <= ARRAY_SIZE(raw_tests); i++)
2920 err |= count_result(do_test_raw(i));
2921
2922 return err;
2923}
2924
2925struct btf_get_info_test {
2926 const char *descr;
2927 const char *str_sec;
2928 __u32 raw_types[MAX_NR_RAW_U32];
2929 __u32 str_sec_size;
2930 int btf_size_delta;
2931 int (*special_test)(unsigned int test_num);
2932};
2933
2934static int test_big_btf_info(unsigned int test_num);
2935static int test_btf_id(unsigned int test_num);
2936
2937const struct btf_get_info_test get_info_tests[] = {
2938{
2939 .descr = "== raw_btf_size+1",
2940 .raw_types = {
2941
2942 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
2943 BTF_END_RAW,
2944 },
2945 .str_sec = "",
2946 .str_sec_size = sizeof(""),
2947 .btf_size_delta = 1,
2948},
2949{
2950 .descr = "== raw_btf_size-3",
2951 .raw_types = {
2952
2953 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
2954 BTF_END_RAW,
2955 },
2956 .str_sec = "",
2957 .str_sec_size = sizeof(""),
2958 .btf_size_delta = -3,
2959},
2960{
2961 .descr = "Large bpf_btf_info",
2962 .raw_types = {
2963
2964 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
2965 BTF_END_RAW,
2966 },
2967 .str_sec = "",
2968 .str_sec_size = sizeof(""),
2969 .special_test = test_big_btf_info,
2970},
2971{
2972 .descr = "BTF ID",
2973 .raw_types = {
2974
2975 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
2976
2977 BTF_TYPE_INT_ENC(0, 0, 0, 32, 4),
2978 BTF_END_RAW,
2979 },
2980 .str_sec = "",
2981 .str_sec_size = sizeof(""),
2982 .special_test = test_btf_id,
2983},
2984};
2985
2986static inline __u64 ptr_to_u64(const void *ptr)
2987{
2988 return (__u64)(unsigned long)ptr;
2989}
2990
2991static int test_big_btf_info(unsigned int test_num)
2992{
2993 const struct btf_get_info_test *test = &get_info_tests[test_num - 1];
2994 uint8_t *raw_btf = NULL, *user_btf = NULL;
2995 unsigned int raw_btf_size;
2996 struct {
2997 struct bpf_btf_info info;
2998 uint64_t garbage;
2999 } info_garbage;
3000 struct bpf_btf_info *info;
3001 int btf_fd = -1, err;
3002 uint32_t info_len;
3003
3004 raw_btf = btf_raw_create(&hdr_tmpl,
3005 test->raw_types,
3006 test->str_sec,
3007 test->str_sec_size,
3008 &raw_btf_size, NULL);
3009
3010 if (!raw_btf)
3011 return -1;
3012
3013 *btf_log_buf = '\0';
3014
3015 user_btf = malloc(raw_btf_size);
3016 if (CHECK(!user_btf, "!user_btf")) {
3017 err = -1;
3018 goto done;
3019 }
3020
3021 btf_fd = bpf_load_btf(raw_btf, raw_btf_size,
3022 btf_log_buf, BTF_LOG_BUF_SIZE,
3023 args.always_log);
3024 if (CHECK(btf_fd == -1, "errno:%d", errno)) {
3025 err = -1;
3026 goto done;
3027 }
3028
3029
3030
3031
3032
3033 info = &info_garbage.info;
3034 memset(info, 0, sizeof(*info));
3035 info_garbage.garbage = 0xdeadbeef;
3036 info_len = sizeof(info_garbage);
3037 info->btf = ptr_to_u64(user_btf);
3038 info->btf_size = raw_btf_size;
3039
3040 err = bpf_obj_get_info_by_fd(btf_fd, info, &info_len);
3041 if (CHECK(!err, "!err")) {
3042 err = -1;
3043 goto done;
3044 }
3045
3046
3047
3048
3049
3050
3051
3052 info_garbage.garbage = 0;
3053 err = bpf_obj_get_info_by_fd(btf_fd, info, &info_len);
3054 if (CHECK(err || info_len != sizeof(*info),
3055 "err:%d errno:%d info_len:%u sizeof(*info):%lu",
3056 err, errno, info_len, sizeof(*info))) {
3057 err = -1;
3058 goto done;
3059 }
3060
3061 fprintf(stderr, "OK");
3062
3063done:
3064 if (*btf_log_buf && (err || args.always_log))
3065 fprintf(stderr, "\n%s", btf_log_buf);
3066
3067 free(raw_btf);
3068 free(user_btf);
3069
3070 if (btf_fd != -1)
3071 close(btf_fd);
3072
3073 return err;
3074}
3075
3076static int test_btf_id(unsigned int test_num)
3077{
3078 const struct btf_get_info_test *test = &get_info_tests[test_num - 1];
3079 struct bpf_create_map_attr create_attr = {};
3080 uint8_t *raw_btf = NULL, *user_btf[2] = {};
3081 int btf_fd[2] = {-1, -1}, map_fd = -1;
3082 struct bpf_map_info map_info = {};
3083 struct bpf_btf_info info[2] = {};
3084 unsigned int raw_btf_size;
3085 uint32_t info_len;
3086 int err, i, ret;
3087
3088 raw_btf = btf_raw_create(&hdr_tmpl,
3089 test->raw_types,
3090 test->str_sec,
3091 test->str_sec_size,
3092 &raw_btf_size, NULL);
3093
3094 if (!raw_btf)
3095 return -1;
3096
3097 *btf_log_buf = '\0';
3098
3099 for (i = 0; i < 2; i++) {
3100 user_btf[i] = malloc(raw_btf_size);
3101 if (CHECK(!user_btf[i], "!user_btf[%d]", i)) {
3102 err = -1;
3103 goto done;
3104 }
3105 info[i].btf = ptr_to_u64(user_btf[i]);
3106 info[i].btf_size = raw_btf_size;
3107 }
3108
3109 btf_fd[0] = bpf_load_btf(raw_btf, raw_btf_size,
3110 btf_log_buf, BTF_LOG_BUF_SIZE,
3111 args.always_log);
3112 if (CHECK(btf_fd[0] == -1, "errno:%d", errno)) {
3113 err = -1;
3114 goto done;
3115 }
3116
3117
3118 info_len = sizeof(info[0]);
3119 err = bpf_obj_get_info_by_fd(btf_fd[0], &info[0], &info_len);
3120 if (CHECK(err, "errno:%d", errno)) {
3121 err = -1;
3122 goto done;
3123 }
3124
3125 btf_fd[1] = bpf_btf_get_fd_by_id(info[0].id);
3126 if (CHECK(btf_fd[1] == -1, "errno:%d", errno)) {
3127 err = -1;
3128 goto done;
3129 }
3130
3131 ret = 0;
3132 err = bpf_obj_get_info_by_fd(btf_fd[1], &info[1], &info_len);
3133 if (CHECK(err || info[0].id != info[1].id ||
3134 info[0].btf_size != info[1].btf_size ||
3135 (ret = memcmp(user_btf[0], user_btf[1], info[0].btf_size)),
3136 "err:%d errno:%d id0:%u id1:%u btf_size0:%u btf_size1:%u memcmp:%d",
3137 err, errno, info[0].id, info[1].id,
3138 info[0].btf_size, info[1].btf_size, ret)) {
3139 err = -1;
3140 goto done;
3141 }
3142
3143
3144 create_attr.name = "test_btf_id";
3145 create_attr.map_type = BPF_MAP_TYPE_ARRAY;
3146 create_attr.key_size = sizeof(int);
3147 create_attr.value_size = sizeof(unsigned int);
3148 create_attr.max_entries = 4;
3149 create_attr.btf_fd = btf_fd[0];
3150 create_attr.btf_key_type_id = 1;
3151 create_attr.btf_value_type_id = 2;
3152
3153 map_fd = bpf_create_map_xattr(&create_attr);
3154 if (CHECK(map_fd == -1, "errno:%d", errno)) {
3155 err = -1;
3156 goto done;
3157 }
3158
3159 info_len = sizeof(map_info);
3160 err = bpf_obj_get_info_by_fd(map_fd, &map_info, &info_len);
3161 if (CHECK(err || map_info.btf_id != info[0].id ||
3162 map_info.btf_key_type_id != 1 || map_info.btf_value_type_id != 2,
3163 "err:%d errno:%d info.id:%u btf_id:%u btf_key_type_id:%u btf_value_type_id:%u",
3164 err, errno, info[0].id, map_info.btf_id, map_info.btf_key_type_id,
3165 map_info.btf_value_type_id)) {
3166 err = -1;
3167 goto done;
3168 }
3169
3170 for (i = 0; i < 2; i++) {
3171 close(btf_fd[i]);
3172 btf_fd[i] = -1;
3173 }
3174
3175
3176 btf_fd[0] = bpf_btf_get_fd_by_id(map_info.btf_id);
3177 if (CHECK(btf_fd[0] == -1, "errno:%d", errno)) {
3178 err = -1;
3179 goto done;
3180 }
3181 close(btf_fd[0]);
3182 btf_fd[0] = -1;
3183
3184
3185 close(map_fd);
3186 map_fd = -1;
3187 btf_fd[0] = bpf_btf_get_fd_by_id(map_info.btf_id);
3188 if (CHECK(btf_fd[0] != -1, "BTF lingers")) {
3189 err = -1;
3190 goto done;
3191 }
3192
3193 fprintf(stderr, "OK");
3194
3195done:
3196 if (*btf_log_buf && (err || args.always_log))
3197 fprintf(stderr, "\n%s", btf_log_buf);
3198
3199 free(raw_btf);
3200 if (map_fd != -1)
3201 close(map_fd);
3202 for (i = 0; i < 2; i++) {
3203 free(user_btf[i]);
3204 if (btf_fd[i] != -1)
3205 close(btf_fd[i]);
3206 }
3207
3208 return err;
3209}
3210
3211static int do_test_get_info(unsigned int test_num)
3212{
3213 const struct btf_get_info_test *test = &get_info_tests[test_num - 1];
3214 unsigned int raw_btf_size, user_btf_size, expected_nbytes;
3215 uint8_t *raw_btf = NULL, *user_btf = NULL;
3216 struct bpf_btf_info info = {};
3217 int btf_fd = -1, err, ret;
3218 uint32_t info_len;
3219
3220 fprintf(stderr, "BTF GET_INFO test[%u] (%s): ",
3221 test_num, test->descr);
3222
3223 if (test->special_test)
3224 return test->special_test(test_num);
3225
3226 raw_btf = btf_raw_create(&hdr_tmpl,
3227 test->raw_types,
3228 test->str_sec,
3229 test->str_sec_size,
3230 &raw_btf_size, NULL);
3231
3232 if (!raw_btf)
3233 return -1;
3234
3235 *btf_log_buf = '\0';
3236
3237 user_btf = malloc(raw_btf_size);
3238 if (CHECK(!user_btf, "!user_btf")) {
3239 err = -1;
3240 goto done;
3241 }
3242
3243 btf_fd = bpf_load_btf(raw_btf, raw_btf_size,
3244 btf_log_buf, BTF_LOG_BUF_SIZE,
3245 args.always_log);
3246 if (CHECK(btf_fd == -1, "errno:%d", errno)) {
3247 err = -1;
3248 goto done;
3249 }
3250
3251 user_btf_size = (int)raw_btf_size + test->btf_size_delta;
3252 expected_nbytes = min(raw_btf_size, user_btf_size);
3253 if (raw_btf_size > expected_nbytes)
3254 memset(user_btf + expected_nbytes, 0xff,
3255 raw_btf_size - expected_nbytes);
3256
3257 info_len = sizeof(info);
3258 info.btf = ptr_to_u64(user_btf);
3259 info.btf_size = user_btf_size;
3260
3261 ret = 0;
3262 err = bpf_obj_get_info_by_fd(btf_fd, &info, &info_len);
3263 if (CHECK(err || !info.id || info_len != sizeof(info) ||
3264 info.btf_size != raw_btf_size ||
3265 (ret = memcmp(raw_btf, user_btf, expected_nbytes)),
3266 "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",
3267 err, errno, info.id, info_len, sizeof(info),
3268 raw_btf_size, info.btf_size, expected_nbytes, ret)) {
3269 err = -1;
3270 goto done;
3271 }
3272
3273 while (expected_nbytes < raw_btf_size) {
3274 fprintf(stderr, "%u...", expected_nbytes);
3275 if (CHECK(user_btf[expected_nbytes++] != 0xff,
3276 "user_btf[%u]:%x != 0xff", expected_nbytes - 1,
3277 user_btf[expected_nbytes - 1])) {
3278 err = -1;
3279 goto done;
3280 }
3281 }
3282
3283 fprintf(stderr, "OK");
3284
3285done:
3286 if (*btf_log_buf && (err || args.always_log))
3287 fprintf(stderr, "\n%s", btf_log_buf);
3288
3289 free(raw_btf);
3290 free(user_btf);
3291
3292 if (btf_fd != -1)
3293 close(btf_fd);
3294
3295 return err;
3296}
3297
3298static int test_get_info(void)
3299{
3300 unsigned int i;
3301 int err = 0;
3302
3303 if (args.get_info_test_num)
3304 return count_result(do_test_get_info(args.get_info_test_num));
3305
3306 for (i = 1; i <= ARRAY_SIZE(get_info_tests); i++)
3307 err |= count_result(do_test_get_info(i));
3308
3309 return err;
3310}
3311
3312struct btf_file_test {
3313 const char *file;
3314 bool btf_kv_notfound;
3315};
3316
3317static struct btf_file_test file_tests[] = {
3318{
3319 .file = "test_btf_haskv.o",
3320},
3321{
3322 .file = "test_btf_nokv.o",
3323 .btf_kv_notfound = true,
3324},
3325};
3326
3327static int file_has_btf_elf(const char *fn, bool *has_btf_ext)
3328{
3329 Elf_Scn *scn = NULL;
3330 GElf_Ehdr ehdr;
3331 int ret = 0;
3332 int elf_fd;
3333 Elf *elf;
3334
3335 if (CHECK(elf_version(EV_CURRENT) == EV_NONE,
3336 "elf_version(EV_CURRENT) == EV_NONE"))
3337 return -1;
3338
3339 elf_fd = open(fn, O_RDONLY);
3340 if (CHECK(elf_fd == -1, "open(%s): errno:%d", fn, errno))
3341 return -1;
3342
3343 elf = elf_begin(elf_fd, ELF_C_READ, NULL);
3344 if (CHECK(!elf, "elf_begin(%s): %s", fn, elf_errmsg(elf_errno()))) {
3345 ret = -1;
3346 goto done;
3347 }
3348
3349 if (CHECK(!gelf_getehdr(elf, &ehdr), "!gelf_getehdr(%s)", fn)) {
3350 ret = -1;
3351 goto done;
3352 }
3353
3354 while ((scn = elf_nextscn(elf, scn))) {
3355 const char *sh_name;
3356 GElf_Shdr sh;
3357
3358 if (CHECK(gelf_getshdr(scn, &sh) != &sh,
3359 "file:%s gelf_getshdr != &sh", fn)) {
3360 ret = -1;
3361 goto done;
3362 }
3363
3364 sh_name = elf_strptr(elf, ehdr.e_shstrndx, sh.sh_name);
3365 if (!strcmp(sh_name, BTF_ELF_SEC))
3366 ret = 1;
3367 if (!strcmp(sh_name, BTF_EXT_ELF_SEC))
3368 *has_btf_ext = true;
3369 }
3370
3371done:
3372 close(elf_fd);
3373 elf_end(elf);
3374 return ret;
3375}
3376
3377static int do_test_file(unsigned int test_num)
3378{
3379 const struct btf_file_test *test = &file_tests[test_num - 1];
3380 const char *expected_fnames[] = {"_dummy_tracepoint",
3381 "test_long_fname_1",
3382 "test_long_fname_2"};
3383 struct bpf_prog_info info = {};
3384 struct bpf_object *obj = NULL;
3385 struct bpf_func_info *finfo;
3386 struct bpf_program *prog;
3387 __u32 info_len, rec_size;
3388 bool has_btf_ext = false;
3389 struct btf *btf = NULL;
3390 void *func_info = NULL;
3391 struct bpf_map *map;
3392 int i, err, prog_fd;
3393
3394 fprintf(stderr, "BTF libbpf test[%u] (%s): ", test_num,
3395 test->file);
3396
3397 err = file_has_btf_elf(test->file, &has_btf_ext);
3398 if (err == -1)
3399 return err;
3400
3401 if (err == 0) {
3402 fprintf(stderr, "SKIP. No ELF %s found", BTF_ELF_SEC);
3403 skip_cnt++;
3404 return 0;
3405 }
3406
3407 obj = bpf_object__open(test->file);
3408 if (CHECK(IS_ERR(obj), "obj: %ld", PTR_ERR(obj)))
3409 return PTR_ERR(obj);
3410
3411 err = bpf_object__btf_fd(obj);
3412 if (CHECK(err == -1, "bpf_object__btf_fd: -1"))
3413 goto done;
3414
3415 prog = bpf_program__next(NULL, obj);
3416 if (CHECK(!prog, "Cannot find bpf_prog")) {
3417 err = -1;
3418 goto done;
3419 }
3420
3421 bpf_program__set_type(prog, BPF_PROG_TYPE_TRACEPOINT);
3422 err = bpf_object__load(obj);
3423 if (CHECK(err < 0, "bpf_object__load: %d", err))
3424 goto done;
3425 prog_fd = bpf_program__fd(prog);
3426
3427 map = bpf_object__find_map_by_name(obj, "btf_map");
3428 if (CHECK(!map, "btf_map not found")) {
3429 err = -1;
3430 goto done;
3431 }
3432
3433 err = (bpf_map__btf_key_type_id(map) == 0 || bpf_map__btf_value_type_id(map) == 0)
3434 != test->btf_kv_notfound;
3435 if (CHECK(err, "btf_key_type_id:%u btf_value_type_id:%u test->btf_kv_notfound:%u",
3436 bpf_map__btf_key_type_id(map), bpf_map__btf_value_type_id(map),
3437 test->btf_kv_notfound))
3438 goto done;
3439
3440 if (!has_btf_ext)
3441 goto skip;
3442
3443
3444 info_len = sizeof(struct bpf_prog_info);
3445 err = bpf_obj_get_info_by_fd(prog_fd, &info, &info_len);
3446
3447 if (CHECK(err == -1, "invalid get info (1st) errno:%d", errno)) {
3448 fprintf(stderr, "%s\n", btf_log_buf);
3449 err = -1;
3450 goto done;
3451 }
3452 if (CHECK(info.nr_func_info != 3,
3453 "incorrect info.nr_func_info (1st) %d",
3454 info.nr_func_info)) {
3455 err = -1;
3456 goto done;
3457 }
3458 rec_size = info.func_info_rec_size;
3459 if (CHECK(rec_size != sizeof(struct bpf_func_info),
3460 "incorrect info.func_info_rec_size (1st) %d\n", rec_size)) {
3461 err = -1;
3462 goto done;
3463 }
3464
3465 func_info = malloc(info.nr_func_info * rec_size);
3466 if (CHECK(!func_info, "out of memory")) {
3467 err = -1;
3468 goto done;
3469 }
3470
3471
3472 memset(&info, 0, sizeof(info));
3473 info.nr_func_info = 3;
3474 info.func_info_rec_size = rec_size;
3475 info.func_info = ptr_to_u64(func_info);
3476
3477 err = bpf_obj_get_info_by_fd(prog_fd, &info, &info_len);
3478
3479 if (CHECK(err == -1, "invalid get info (2nd) errno:%d", errno)) {
3480 fprintf(stderr, "%s\n", btf_log_buf);
3481 err = -1;
3482 goto done;
3483 }
3484 if (CHECK(info.nr_func_info != 3,
3485 "incorrect info.nr_func_info (2nd) %d",
3486 info.nr_func_info)) {
3487 err = -1;
3488 goto done;
3489 }
3490 if (CHECK(info.func_info_rec_size != rec_size,
3491 "incorrect info.func_info_rec_size (2nd) %d",
3492 info.func_info_rec_size)) {
3493 err = -1;
3494 goto done;
3495 }
3496
3497 err = btf__get_from_id(info.btf_id, &btf);
3498 if (CHECK(err, "cannot get btf from kernel, err: %d", err))
3499 goto done;
3500
3501
3502 finfo = func_info;
3503 for (i = 0; i < 3; i++) {
3504 const struct btf_type *t;
3505 const char *fname;
3506
3507 t = btf__type_by_id(btf, finfo->type_id);
3508 if (CHECK(!t, "btf__type_by_id failure: id %u",
3509 finfo->type_id)) {
3510 err = -1;
3511 goto done;
3512 }
3513
3514 fname = btf__name_by_offset(btf, t->name_off);
3515 err = strcmp(fname, expected_fnames[i]);
3516
3517
3518
3519 if (i && err)
3520 err = strcmp(fname, expected_fnames[3 - i]);
3521 if (CHECK(err, "incorrect fname %s", fname ? : "")) {
3522 err = -1;
3523 goto done;
3524 }
3525
3526 finfo = (void *)finfo + rec_size;
3527 }
3528
3529skip:
3530 fprintf(stderr, "OK");
3531
3532done:
3533 free(func_info);
3534 bpf_object__close(obj);
3535 return err;
3536}
3537
3538static int test_file(void)
3539{
3540 unsigned int i;
3541 int err = 0;
3542
3543 if (args.file_test_num)
3544 return count_result(do_test_file(args.file_test_num));
3545
3546 for (i = 1; i <= ARRAY_SIZE(file_tests); i++)
3547 err |= count_result(do_test_file(i));
3548
3549 return err;
3550}
3551
3552const char *pprint_enum_str[] = {
3553 "ENUM_ZERO",
3554 "ENUM_ONE",
3555 "ENUM_TWO",
3556 "ENUM_THREE",
3557};
3558
3559struct pprint_mapv {
3560 uint32_t ui32;
3561 uint16_t ui16;
3562
3563 int32_t si32;
3564 uint32_t unused_bits2a:2,
3565 bits28:28,
3566 unused_bits2b:2;
3567 union {
3568 uint64_t ui64;
3569 uint8_t ui8a[8];
3570 };
3571 enum {
3572 ENUM_ZERO,
3573 ENUM_ONE,
3574 ENUM_TWO,
3575 ENUM_THREE,
3576 } aenum;
3577 uint32_t ui32b;
3578 uint32_t bits2c:2;
3579};
3580
3581static struct btf_raw_test pprint_test_template[] = {
3582{
3583 .raw_types = {
3584
3585 BTF_TYPE_INT_ENC(NAME_TBD, 0, 0, 8, 1),
3586
3587 BTF_TYPE_INT_ENC(NAME_TBD, 0, 0, 16, 2),
3588
3589 BTF_TYPE_INT_ENC(NAME_TBD, 0, 0, 32, 4),
3590
3591 BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),
3592
3593 BTF_TYPE_INT_ENC(NAME_TBD, 0, 0, 64, 8),
3594
3595 BTF_TYPE_INT_ENC(0, 0, 0, 2, 2),
3596
3597 BTF_TYPE_INT_ENC(0, 0, 0, 28, 4),
3598
3599 BTF_TYPE_ARRAY_ENC(9, 1, 8),
3600
3601 BTF_TYPEDEF_ENC(NAME_TBD, 1),
3602
3603 BTF_TYPEDEF_ENC(NAME_TBD, 2),
3604
3605 BTF_TYPEDEF_ENC(NAME_TBD, 3),
3606
3607 BTF_TYPEDEF_ENC(NAME_TBD, 4),
3608
3609 BTF_TYPEDEF_ENC(NAME_TBD, 5),
3610
3611 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_UNION, 0, 2), 8),
3612 BTF_MEMBER_ENC(NAME_TBD, 13, 0),
3613 BTF_MEMBER_ENC(NAME_TBD, 8, 0),
3614
3615 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_ENUM, 0, 4), 4),
3616 BTF_ENUM_ENC(NAME_TBD, 0),
3617 BTF_ENUM_ENC(NAME_TBD, 1),
3618 BTF_ENUM_ENC(NAME_TBD, 2),
3619 BTF_ENUM_ENC(NAME_TBD, 3),
3620
3621 BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 10), 40),
3622 BTF_MEMBER_ENC(NAME_TBD, 11, 0),
3623 BTF_MEMBER_ENC(NAME_TBD, 10, 32),
3624 BTF_MEMBER_ENC(NAME_TBD, 12, 64),
3625 BTF_MEMBER_ENC(NAME_TBD, 6, 96),
3626 BTF_MEMBER_ENC(NAME_TBD, 7, 98),
3627 BTF_MEMBER_ENC(NAME_TBD, 6, 126),
3628 BTF_MEMBER_ENC(0, 14, 128),
3629 BTF_MEMBER_ENC(NAME_TBD, 15, 192),
3630 BTF_MEMBER_ENC(NAME_TBD, 11, 224),
3631 BTF_MEMBER_ENC(NAME_TBD, 6, 256),
3632 BTF_END_RAW,
3633 },
3634 BTF_STR_SEC("\0unsigned char\0unsigned short\0unsigned int\0int\0unsigned long long\0uint8_t\0uint16_t\0uint32_t\0int32_t\0uint64_t\0ui64\0ui8a\0ENUM_ZERO\0ENUM_ONE\0ENUM_TWO\0ENUM_THREE\0pprint_mapv\0ui32\0ui16\0si32\0unused_bits2a\0bits28\0unused_bits2b\0aenum\0ui32b\0bits2c"),
3635 .key_size = sizeof(unsigned int),
3636 .value_size = sizeof(struct pprint_mapv),
3637 .key_type_id = 3,
3638 .value_type_id = 16,
3639 .max_entries = 128 * 1024,
3640},
3641
3642{
3643
3644
3645
3646
3647 .raw_types = {
3648
3649 BTF_TYPE_INT_ENC(NAME_TBD, 0, 0, 8, 1),
3650
3651 BTF_TYPE_INT_ENC(NAME_TBD, 0, 0, 16, 2),
3652
3653 BTF_TYPE_INT_ENC(NAME_TBD, 0, 0, 32, 4),
3654
3655 BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),
3656
3657 BTF_TYPE_INT_ENC(NAME_TBD, 0, 0, 64, 8),
3658 BTF_TYPE_INT_ENC(0, 0, 0, 32, 4),
3659 BTF_TYPE_INT_ENC(0, 0, 0, 32, 4),
3660
3661 BTF_TYPE_ARRAY_ENC(9, 1, 8),
3662
3663 BTF_TYPEDEF_ENC(NAME_TBD, 1),
3664
3665 BTF_TYPEDEF_ENC(NAME_TBD, 2),
3666
3667 BTF_TYPEDEF_ENC(NAME_TBD, 3),
3668
3669 BTF_TYPEDEF_ENC(NAME_TBD, 4),
3670
3671 BTF_TYPEDEF_ENC(NAME_TBD, 5),
3672
3673 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_UNION, 0, 2), 8),
3674 BTF_MEMBER_ENC(NAME_TBD, 13, 0),
3675 BTF_MEMBER_ENC(NAME_TBD, 8, 0),
3676
3677 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_ENUM, 0, 4), 4),
3678 BTF_ENUM_ENC(NAME_TBD, 0),
3679 BTF_ENUM_ENC(NAME_TBD, 1),
3680 BTF_ENUM_ENC(NAME_TBD, 2),
3681 BTF_ENUM_ENC(NAME_TBD, 3),
3682
3683 BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 1, 10), 40),
3684 BTF_MEMBER_ENC(NAME_TBD, 11, BTF_MEMBER_OFFSET(0, 0)),
3685 BTF_MEMBER_ENC(NAME_TBD, 10, BTF_MEMBER_OFFSET(0, 32)),
3686 BTF_MEMBER_ENC(NAME_TBD, 12, BTF_MEMBER_OFFSET(0, 64)),
3687 BTF_MEMBER_ENC(NAME_TBD, 6, BTF_MEMBER_OFFSET(2, 96)),
3688 BTF_MEMBER_ENC(NAME_TBD, 7, BTF_MEMBER_OFFSET(28, 98)),
3689 BTF_MEMBER_ENC(NAME_TBD, 6, BTF_MEMBER_OFFSET(2, 126)),
3690 BTF_MEMBER_ENC(0, 14, BTF_MEMBER_OFFSET(0, 128)),
3691 BTF_MEMBER_ENC(NAME_TBD, 15, BTF_MEMBER_OFFSET(0, 192)),
3692 BTF_MEMBER_ENC(NAME_TBD, 11, BTF_MEMBER_OFFSET(0, 224)),
3693 BTF_MEMBER_ENC(NAME_TBD, 6, BTF_MEMBER_OFFSET(2, 256)),
3694 BTF_END_RAW,
3695 },
3696 BTF_STR_SEC("\0unsigned char\0unsigned short\0unsigned int\0int\0unsigned long long\0uint8_t\0uint16_t\0uint32_t\0int32_t\0uint64_t\0ui64\0ui8a\0ENUM_ZERO\0ENUM_ONE\0ENUM_TWO\0ENUM_THREE\0pprint_mapv\0ui32\0ui16\0si32\0unused_bits2a\0bits28\0unused_bits2b\0aenum\0ui32b\0bits2c"),
3697 .key_size = sizeof(unsigned int),
3698 .value_size = sizeof(struct pprint_mapv),
3699 .key_type_id = 3,
3700 .value_type_id = 16,
3701 .max_entries = 128 * 1024,
3702},
3703
3704{
3705
3706
3707
3708
3709
3710
3711 .raw_types = {
3712
3713 BTF_TYPE_INT_ENC(NAME_TBD, 0, 0, 8, 1),
3714
3715 BTF_TYPE_INT_ENC(NAME_TBD, 0, 0, 16, 2),
3716
3717 BTF_TYPE_INT_ENC(NAME_TBD, 0, 0, 32, 4),
3718
3719 BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),
3720
3721 BTF_TYPE_INT_ENC(NAME_TBD, 0, 0, 64, 8),
3722 BTF_TYPE_INT_ENC(0, 0, 0, 32, 4),
3723 BTF_TYPE_INT_ENC(0, 0, 0, 32, 4),
3724
3725 BTF_TYPE_ARRAY_ENC(9, 1, 8),
3726
3727 BTF_TYPEDEF_ENC(NAME_TBD, 1),
3728
3729 BTF_TYPEDEF_ENC(NAME_TBD, 2),
3730
3731 BTF_TYPEDEF_ENC(NAME_TBD, 3),
3732
3733 BTF_TYPEDEF_ENC(NAME_TBD, 4),
3734
3735 BTF_TYPEDEF_ENC(NAME_TBD, 5),
3736
3737 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_UNION, 0, 2), 8),
3738 BTF_MEMBER_ENC(NAME_TBD, 13, 0),
3739 BTF_MEMBER_ENC(NAME_TBD, 8, 0),
3740
3741 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_ENUM, 0, 4), 4),
3742 BTF_ENUM_ENC(NAME_TBD, 0),
3743 BTF_ENUM_ENC(NAME_TBD, 1),
3744 BTF_ENUM_ENC(NAME_TBD, 2),
3745 BTF_ENUM_ENC(NAME_TBD, 3),
3746
3747 BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 1, 10), 40),
3748 BTF_MEMBER_ENC(NAME_TBD, 11, BTF_MEMBER_OFFSET(0, 0)),
3749 BTF_MEMBER_ENC(NAME_TBD, 10, BTF_MEMBER_OFFSET(0, 32)),
3750 BTF_MEMBER_ENC(NAME_TBD, 12, BTF_MEMBER_OFFSET(0, 64)),
3751 BTF_MEMBER_ENC(NAME_TBD, 17, BTF_MEMBER_OFFSET(2, 96)),
3752 BTF_MEMBER_ENC(NAME_TBD, 7, BTF_MEMBER_OFFSET(28, 98)),
3753 BTF_MEMBER_ENC(NAME_TBD, 19, BTF_MEMBER_OFFSET(2, 126)),
3754 BTF_MEMBER_ENC(0, 14, BTF_MEMBER_OFFSET(0, 128)),
3755 BTF_MEMBER_ENC(NAME_TBD, 15, BTF_MEMBER_OFFSET(0, 192)),
3756 BTF_MEMBER_ENC(NAME_TBD, 11, BTF_MEMBER_OFFSET(0, 224)),
3757 BTF_MEMBER_ENC(NAME_TBD, 17, BTF_MEMBER_OFFSET(2, 256)),
3758
3759 BTF_TYPEDEF_ENC(NAME_TBD, 18),
3760 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_VOLATILE, 0, 0), 6),
3761 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_CONST, 0, 0), 15),
3762 BTF_END_RAW,
3763 },
3764 BTF_STR_SEC("\0unsigned char\0unsigned short\0unsigned int\0int\0unsigned long long\0uint8_t\0uint16_t\0uint32_t\0int32_t\0uint64_t\0ui64\0ui8a\0ENUM_ZERO\0ENUM_ONE\0ENUM_TWO\0ENUM_THREE\0pprint_mapv\0ui32\0ui16\0si32\0unused_bits2a\0bits28\0unused_bits2b\0aenum\0ui32b\0bits2c\0___int"),
3765 .key_size = sizeof(unsigned int),
3766 .value_size = sizeof(struct pprint_mapv),
3767 .key_type_id = 3,
3768 .value_type_id = 16,
3769 .max_entries = 128 * 1024,
3770},
3771
3772};
3773
3774static struct btf_pprint_test_meta {
3775 const char *descr;
3776 enum bpf_map_type map_type;
3777 const char *map_name;
3778 bool ordered_map;
3779 bool lossless_map;
3780 bool percpu_map;
3781} pprint_tests_meta[] = {
3782{
3783 .descr = "BTF pretty print array",
3784 .map_type = BPF_MAP_TYPE_ARRAY,
3785 .map_name = "pprint_test_array",
3786 .ordered_map = true,
3787 .lossless_map = true,
3788 .percpu_map = false,
3789},
3790
3791{
3792 .descr = "BTF pretty print hash",
3793 .map_type = BPF_MAP_TYPE_HASH,
3794 .map_name = "pprint_test_hash",
3795 .ordered_map = false,
3796 .lossless_map = true,
3797 .percpu_map = false,
3798},
3799
3800{
3801 .descr = "BTF pretty print lru hash",
3802 .map_type = BPF_MAP_TYPE_LRU_HASH,
3803 .map_name = "pprint_test_lru_hash",
3804 .ordered_map = false,
3805 .lossless_map = false,
3806 .percpu_map = false,
3807},
3808
3809{
3810 .descr = "BTF pretty print percpu array",
3811 .map_type = BPF_MAP_TYPE_PERCPU_ARRAY,
3812 .map_name = "pprint_test_percpu_array",
3813 .ordered_map = true,
3814 .lossless_map = true,
3815 .percpu_map = true,
3816},
3817
3818{
3819 .descr = "BTF pretty print percpu hash",
3820 .map_type = BPF_MAP_TYPE_PERCPU_HASH,
3821 .map_name = "pprint_test_percpu_hash",
3822 .ordered_map = false,
3823 .lossless_map = true,
3824 .percpu_map = true,
3825},
3826
3827{
3828 .descr = "BTF pretty print lru percpu hash",
3829 .map_type = BPF_MAP_TYPE_LRU_PERCPU_HASH,
3830 .map_name = "pprint_test_lru_percpu_hash",
3831 .ordered_map = false,
3832 .lossless_map = false,
3833 .percpu_map = true,
3834},
3835
3836};
3837
3838
3839static void set_pprint_mapv(struct pprint_mapv *v, uint32_t i,
3840 int num_cpus, int rounded_value_size)
3841{
3842 int cpu;
3843
3844 for (cpu = 0; cpu < num_cpus; cpu++) {
3845 v->ui32 = i + cpu;
3846 v->si32 = -i;
3847 v->unused_bits2a = 3;
3848 v->bits28 = i;
3849 v->unused_bits2b = 3;
3850 v->ui64 = i;
3851 v->aenum = i & 0x03;
3852 v->ui32b = 4;
3853 v->bits2c = 1;
3854 v = (void *)v + rounded_value_size;
3855 }
3856}
3857
3858static int check_line(const char *expected_line, int nexpected_line,
3859 int expected_line_len, const char *line)
3860{
3861 if (CHECK(nexpected_line == expected_line_len,
3862 "expected_line is too long"))
3863 return -1;
3864
3865 if (strcmp(expected_line, line)) {
3866 fprintf(stderr, "unexpected pprint output\n");
3867 fprintf(stderr, "expected: %s", expected_line);
3868 fprintf(stderr, " read: %s", line);
3869 return -1;
3870 }
3871
3872 return 0;
3873}
3874
3875
3876static int do_test_pprint(int test_num)
3877{
3878 const struct btf_raw_test *test = &pprint_test_template[test_num];
3879 struct bpf_create_map_attr create_attr = {};
3880 bool ordered_map, lossless_map, percpu_map;
3881 int err, ret, num_cpus, rounded_value_size;
3882 struct pprint_mapv *mapv = NULL;
3883 unsigned int key, nr_read_elems;
3884 int map_fd = -1, btf_fd = -1;
3885 unsigned int raw_btf_size;
3886 char expected_line[255];
3887 FILE *pin_file = NULL;
3888 char pin_path[255];
3889 size_t line_len = 0;
3890 char *line = NULL;
3891 uint8_t *raw_btf;
3892 ssize_t nread;
3893
3894 fprintf(stderr, "%s(#%d)......", test->descr, test_num);
3895 raw_btf = btf_raw_create(&hdr_tmpl, test->raw_types,
3896 test->str_sec, test->str_sec_size,
3897 &raw_btf_size, NULL);
3898
3899 if (!raw_btf)
3900 return -1;
3901
3902 *btf_log_buf = '\0';
3903 btf_fd = bpf_load_btf(raw_btf, raw_btf_size,
3904 btf_log_buf, BTF_LOG_BUF_SIZE,
3905 args.always_log);
3906 free(raw_btf);
3907
3908 if (CHECK(btf_fd == -1, "errno:%d", errno)) {
3909 err = -1;
3910 goto done;
3911 }
3912
3913 create_attr.name = test->map_name;
3914 create_attr.map_type = test->map_type;
3915 create_attr.key_size = test->key_size;
3916 create_attr.value_size = test->value_size;
3917 create_attr.max_entries = test->max_entries;
3918 create_attr.btf_fd = btf_fd;
3919 create_attr.btf_key_type_id = test->key_type_id;
3920 create_attr.btf_value_type_id = test->value_type_id;
3921
3922 map_fd = bpf_create_map_xattr(&create_attr);
3923 if (CHECK(map_fd == -1, "errno:%d", errno)) {
3924 err = -1;
3925 goto done;
3926 }
3927
3928 ret = snprintf(pin_path, sizeof(pin_path), "%s/%s",
3929 "/sys/fs/bpf", test->map_name);
3930
3931 if (CHECK(ret == sizeof(pin_path), "pin_path %s/%s is too long",
3932 "/sys/fs/bpf", test->map_name)) {
3933 err = -1;
3934 goto done;
3935 }
3936
3937 err = bpf_obj_pin(map_fd, pin_path);
3938 if (CHECK(err, "bpf_obj_pin(%s): errno:%d.", pin_path, errno))
3939 goto done;
3940
3941 percpu_map = test->percpu_map;
3942 num_cpus = percpu_map ? bpf_num_possible_cpus() : 1;
3943 rounded_value_size = round_up(sizeof(struct pprint_mapv), 8);
3944 mapv = calloc(num_cpus, rounded_value_size);
3945 if (CHECK(!mapv, "mapv allocation failure")) {
3946 err = -1;
3947 goto done;
3948 }
3949
3950 for (key = 0; key < test->max_entries; key++) {
3951 set_pprint_mapv(mapv, key, num_cpus, rounded_value_size);
3952 bpf_map_update_elem(map_fd, &key, mapv, 0);
3953 }
3954
3955 pin_file = fopen(pin_path, "r");
3956 if (CHECK(!pin_file, "fopen(%s): errno:%d", pin_path, errno)) {
3957 err = -1;
3958 goto done;
3959 }
3960
3961
3962 while ((nread = getline(&line, &line_len, pin_file)) > 0 &&
3963 *line == '#')
3964 ;
3965
3966 if (CHECK(nread <= 0, "Unexpected EOF")) {
3967 err = -1;
3968 goto done;
3969 }
3970
3971 nr_read_elems = 0;
3972 ordered_map = test->ordered_map;
3973 lossless_map = test->lossless_map;
3974 do {
3975 struct pprint_mapv *cmapv;
3976 ssize_t nexpected_line;
3977 unsigned int next_key;
3978 int cpu;
3979
3980 next_key = ordered_map ? nr_read_elems : atoi(line);
3981 set_pprint_mapv(mapv, next_key, num_cpus, rounded_value_size);
3982 cmapv = mapv;
3983
3984 for (cpu = 0; cpu < num_cpus; cpu++) {
3985 if (percpu_map) {
3986
3987
3988
3989
3990
3991
3992
3993
3994
3995
3996 if (cpu == 0) {
3997 nexpected_line = snprintf(expected_line,
3998 sizeof(expected_line),
3999 "%u: {\n",
4000 next_key);
4001
4002 err = check_line(expected_line, nexpected_line,
4003 sizeof(expected_line), line);
4004 if (err == -1)
4005 goto done;
4006 }
4007
4008
4009 nread = getline(&line, &line_len, pin_file);
4010 if (nread < 0)
4011 break;
4012 }
4013
4014 nexpected_line = snprintf(expected_line, sizeof(expected_line),
4015 "%s%u: {%u,0,%d,0x%x,0x%x,0x%x,"
4016 "{%lu|[%u,%u,%u,%u,%u,%u,%u,%u]},%s,"
4017 "%u,0x%x}\n",
4018 percpu_map ? "\tcpu" : "",
4019 percpu_map ? cpu : next_key,
4020 cmapv->ui32, cmapv->si32,
4021 cmapv->unused_bits2a,
4022 cmapv->bits28,
4023 cmapv->unused_bits2b,
4024 cmapv->ui64,
4025 cmapv->ui8a[0], cmapv->ui8a[1],
4026 cmapv->ui8a[2], cmapv->ui8a[3],
4027 cmapv->ui8a[4], cmapv->ui8a[5],
4028 cmapv->ui8a[6], cmapv->ui8a[7],
4029 pprint_enum_str[cmapv->aenum],
4030 cmapv->ui32b,
4031 cmapv->bits2c);
4032
4033 err = check_line(expected_line, nexpected_line,
4034 sizeof(expected_line), line);
4035 if (err == -1)
4036 goto done;
4037
4038 cmapv = (void *)cmapv + rounded_value_size;
4039 }
4040
4041 if (percpu_map) {
4042
4043 nread = getline(&line, &line_len, pin_file);
4044 if (nread < 0)
4045 break;
4046 }
4047
4048 nread = getline(&line, &line_len, pin_file);
4049 } while (++nr_read_elems < test->max_entries && nread > 0);
4050
4051 if (lossless_map &&
4052 CHECK(nr_read_elems < test->max_entries,
4053 "Unexpected EOF. nr_read_elems:%u test->max_entries:%u",
4054 nr_read_elems, test->max_entries)) {
4055 err = -1;
4056 goto done;
4057 }
4058
4059 if (CHECK(nread > 0, "Unexpected extra pprint output: %s", line)) {
4060 err = -1;
4061 goto done;
4062 }
4063
4064 err = 0;
4065
4066done:
4067 if (mapv)
4068 free(mapv);
4069 if (!err)
4070 fprintf(stderr, "OK");
4071 if (*btf_log_buf && (err || args.always_log))
4072 fprintf(stderr, "\n%s", btf_log_buf);
4073 if (btf_fd != -1)
4074 close(btf_fd);
4075 if (map_fd != -1)
4076 close(map_fd);
4077 if (pin_file)
4078 fclose(pin_file);
4079 unlink(pin_path);
4080 free(line);
4081
4082 return err;
4083}
4084
4085static int test_pprint(void)
4086{
4087 unsigned int i;
4088 int err = 0;
4089
4090
4091 for (i = 0; i < ARRAY_SIZE(pprint_tests_meta); i++) {
4092 pprint_test_template[0].descr = pprint_tests_meta[i].descr;
4093 pprint_test_template[0].map_type = pprint_tests_meta[i].map_type;
4094 pprint_test_template[0].map_name = pprint_tests_meta[i].map_name;
4095 pprint_test_template[0].ordered_map = pprint_tests_meta[i].ordered_map;
4096 pprint_test_template[0].lossless_map = pprint_tests_meta[i].lossless_map;
4097 pprint_test_template[0].percpu_map = pprint_tests_meta[i].percpu_map;
4098
4099 err |= count_result(do_test_pprint(0));
4100 }
4101
4102
4103 for (i = 1; i < ARRAY_SIZE(pprint_test_template); i++) {
4104 pprint_test_template[i].descr = pprint_tests_meta[0].descr;
4105 pprint_test_template[i].map_type = pprint_tests_meta[0].map_type;
4106 pprint_test_template[i].map_name = pprint_tests_meta[0].map_name;
4107 pprint_test_template[i].ordered_map = pprint_tests_meta[0].ordered_map;
4108 pprint_test_template[i].lossless_map = pprint_tests_meta[0].lossless_map;
4109 pprint_test_template[i].percpu_map = pprint_tests_meta[0].percpu_map;
4110 err |= count_result(do_test_pprint(i));
4111 }
4112
4113 return err;
4114}
4115
4116#define BPF_LINE_INFO_ENC(insn_off, file_off, line_off, line_num, line_col) \
4117 (insn_off), (file_off), (line_off), ((line_num) << 10 | ((line_col) & 0x3ff))
4118
4119static struct prog_info_raw_test {
4120 const char *descr;
4121 const char *str_sec;
4122 const char *err_str;
4123 __u32 raw_types[MAX_NR_RAW_U32];
4124 __u32 str_sec_size;
4125 struct bpf_insn insns[MAX_INSNS];
4126 __u32 prog_type;
4127 __u32 func_info[MAX_SUBPROGS][2];
4128 __u32 func_info_rec_size;
4129 __u32 func_info_cnt;
4130 __u32 line_info[MAX_NR_RAW_U32];
4131 __u32 line_info_rec_size;
4132 __u32 nr_jited_ksyms;
4133 bool expected_prog_load_failure;
4134} info_raw_tests[] = {
4135{
4136 .descr = "func_type (main func + one sub)",
4137 .raw_types = {
4138 BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),
4139 BTF_TYPE_INT_ENC(NAME_TBD, 0, 0, 32, 4),
4140 BTF_FUNC_PROTO_ENC(1, 2),
4141 BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
4142 BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 2),
4143 BTF_FUNC_PROTO_ENC(1, 2),
4144 BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 2),
4145 BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
4146 BTF_FUNC_ENC(NAME_TBD, 3),
4147 BTF_FUNC_ENC(NAME_TBD, 4),
4148 BTF_END_RAW,
4149 },
4150 .str_sec = "\0int\0unsigned int\0a\0b\0c\0d\0funcA\0funcB",
4151 .str_sec_size = sizeof("\0int\0unsigned int\0a\0b\0c\0d\0funcA\0funcB"),
4152 .insns = {
4153 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2),
4154 BPF_MOV64_IMM(BPF_REG_0, 1),
4155 BPF_EXIT_INSN(),
4156 BPF_MOV64_IMM(BPF_REG_0, 2),
4157 BPF_EXIT_INSN(),
4158 },
4159 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
4160 .func_info = { {0, 5}, {3, 6} },
4161 .func_info_rec_size = 8,
4162 .func_info_cnt = 2,
4163 .line_info = { BTF_END_RAW },
4164},
4165
4166{
4167 .descr = "func_type (Incorrect func_info_rec_size)",
4168 .raw_types = {
4169 BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),
4170 BTF_TYPE_INT_ENC(NAME_TBD, 0, 0, 32, 4),
4171 BTF_FUNC_PROTO_ENC(1, 2),
4172 BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
4173 BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 2),
4174 BTF_FUNC_PROTO_ENC(1, 2),
4175 BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 2),
4176 BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
4177 BTF_FUNC_ENC(NAME_TBD, 3),
4178 BTF_FUNC_ENC(NAME_TBD, 4),
4179 BTF_END_RAW,
4180 },
4181 .str_sec = "\0int\0unsigned int\0a\0b\0c\0d\0funcA\0funcB",
4182 .str_sec_size = sizeof("\0int\0unsigned int\0a\0b\0c\0d\0funcA\0funcB"),
4183 .insns = {
4184 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2),
4185 BPF_MOV64_IMM(BPF_REG_0, 1),
4186 BPF_EXIT_INSN(),
4187 BPF_MOV64_IMM(BPF_REG_0, 2),
4188 BPF_EXIT_INSN(),
4189 },
4190 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
4191 .func_info = { {0, 5}, {3, 6} },
4192 .func_info_rec_size = 4,
4193 .func_info_cnt = 2,
4194 .line_info = { BTF_END_RAW },
4195 .expected_prog_load_failure = true,
4196},
4197
4198{
4199 .descr = "func_type (Incorrect func_info_cnt)",
4200 .raw_types = {
4201 BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),
4202 BTF_TYPE_INT_ENC(NAME_TBD, 0, 0, 32, 4),
4203 BTF_FUNC_PROTO_ENC(1, 2),
4204 BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
4205 BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 2),
4206 BTF_FUNC_PROTO_ENC(1, 2),
4207 BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 2),
4208 BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
4209 BTF_FUNC_ENC(NAME_TBD, 3),
4210 BTF_FUNC_ENC(NAME_TBD, 4),
4211 BTF_END_RAW,
4212 },
4213 .str_sec = "\0int\0unsigned int\0a\0b\0c\0d\0funcA\0funcB",
4214 .str_sec_size = sizeof("\0int\0unsigned int\0a\0b\0c\0d\0funcA\0funcB"),
4215 .insns = {
4216 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2),
4217 BPF_MOV64_IMM(BPF_REG_0, 1),
4218 BPF_EXIT_INSN(),
4219 BPF_MOV64_IMM(BPF_REG_0, 2),
4220 BPF_EXIT_INSN(),
4221 },
4222 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
4223 .func_info = { {0, 5}, {3, 6} },
4224 .func_info_rec_size = 8,
4225 .func_info_cnt = 1,
4226 .line_info = { BTF_END_RAW },
4227 .expected_prog_load_failure = true,
4228},
4229
4230{
4231 .descr = "func_type (Incorrect bpf_func_info.insn_off)",
4232 .raw_types = {
4233 BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),
4234 BTF_TYPE_INT_ENC(NAME_TBD, 0, 0, 32, 4),
4235 BTF_FUNC_PROTO_ENC(1, 2),
4236 BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
4237 BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 2),
4238 BTF_FUNC_PROTO_ENC(1, 2),
4239 BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 2),
4240 BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
4241 BTF_FUNC_ENC(NAME_TBD, 3),
4242 BTF_FUNC_ENC(NAME_TBD, 4),
4243 BTF_END_RAW,
4244 },
4245 .str_sec = "\0int\0unsigned int\0a\0b\0c\0d\0funcA\0funcB",
4246 .str_sec_size = sizeof("\0int\0unsigned int\0a\0b\0c\0d\0funcA\0funcB"),
4247 .insns = {
4248 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2),
4249 BPF_MOV64_IMM(BPF_REG_0, 1),
4250 BPF_EXIT_INSN(),
4251 BPF_MOV64_IMM(BPF_REG_0, 2),
4252 BPF_EXIT_INSN(),
4253 },
4254 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
4255 .func_info = { {0, 5}, {2, 6} },
4256 .func_info_rec_size = 8,
4257 .func_info_cnt = 2,
4258 .line_info = { BTF_END_RAW },
4259 .expected_prog_load_failure = true,
4260},
4261
4262{
4263 .descr = "line_info (No subprog)",
4264 .raw_types = {
4265 BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),
4266 BTF_END_RAW,
4267 },
4268 BTF_STR_SEC("\0int\0int a=1;\0int b=2;\0return a + b;\0return a + b;"),
4269 .insns = {
4270 BPF_MOV64_IMM(BPF_REG_0, 1),
4271 BPF_MOV64_IMM(BPF_REG_1, 2),
4272 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
4273 BPF_EXIT_INSN(),
4274 },
4275 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
4276 .func_info_cnt = 0,
4277 .line_info = {
4278 BPF_LINE_INFO_ENC(0, 0, NAME_TBD, 1, 10),
4279 BPF_LINE_INFO_ENC(1, 0, NAME_TBD, 2, 9),
4280 BPF_LINE_INFO_ENC(2, 0, NAME_TBD, 3, 8),
4281 BPF_LINE_INFO_ENC(3, 0, NAME_TBD, 4, 7),
4282 BTF_END_RAW,
4283 },
4284 .line_info_rec_size = sizeof(struct bpf_line_info),
4285 .nr_jited_ksyms = 1,
4286},
4287
4288{
4289 .descr = "line_info (No subprog. insn_off >= prog->len)",
4290 .raw_types = {
4291 BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),
4292 BTF_END_RAW,
4293 },
4294 BTF_STR_SEC("\0int\0int a=1;\0int b=2;\0return a + b;\0return a + b;"),
4295 .insns = {
4296 BPF_MOV64_IMM(BPF_REG_0, 1),
4297 BPF_MOV64_IMM(BPF_REG_1, 2),
4298 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
4299 BPF_EXIT_INSN(),
4300 },
4301 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
4302 .func_info_cnt = 0,
4303 .line_info = {
4304 BPF_LINE_INFO_ENC(0, 0, NAME_TBD, 1, 10),
4305 BPF_LINE_INFO_ENC(1, 0, NAME_TBD, 2, 9),
4306 BPF_LINE_INFO_ENC(2, 0, NAME_TBD, 3, 8),
4307 BPF_LINE_INFO_ENC(3, 0, NAME_TBD, 4, 7),
4308 BPF_LINE_INFO_ENC(4, 0, 0, 5, 6),
4309 BTF_END_RAW,
4310 },
4311 .line_info_rec_size = sizeof(struct bpf_line_info),
4312 .nr_jited_ksyms = 1,
4313 .err_str = "line_info[4].insn_off",
4314 .expected_prog_load_failure = true,
4315},
4316
4317{
4318 .descr = "line_info (Zero bpf insn code)",
4319 .raw_types = {
4320 BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),
4321 BTF_TYPE_INT_ENC(NAME_TBD, 0, 0, 64, 8),
4322 BTF_TYPEDEF_ENC(NAME_TBD, 2),
4323 BTF_END_RAW,
4324 },
4325 BTF_STR_SEC("\0int\0unsigned long\0u64\0u64 a=1;\0return a;"),
4326 .insns = {
4327 BPF_LD_IMM64(BPF_REG_0, 1),
4328 BPF_EXIT_INSN(),
4329 },
4330 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
4331 .func_info_cnt = 0,
4332 .line_info = {
4333 BPF_LINE_INFO_ENC(0, 0, NAME_TBD, 1, 10),
4334 BPF_LINE_INFO_ENC(1, 0, 0, 2, 9),
4335 BPF_LINE_INFO_ENC(2, 0, NAME_TBD, 3, 8),
4336 BTF_END_RAW,
4337 },
4338 .line_info_rec_size = sizeof(struct bpf_line_info),
4339 .nr_jited_ksyms = 1,
4340 .err_str = "Invalid insn code at line_info[1]",
4341 .expected_prog_load_failure = true,
4342},
4343
4344{
4345 .descr = "line_info (No subprog. zero tailing line_info",
4346 .raw_types = {
4347 BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),
4348 BTF_END_RAW,
4349 },
4350 BTF_STR_SEC("\0int\0int a=1;\0int b=2;\0return a + b;\0return a + b;"),
4351 .insns = {
4352 BPF_MOV64_IMM(BPF_REG_0, 1),
4353 BPF_MOV64_IMM(BPF_REG_1, 2),
4354 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
4355 BPF_EXIT_INSN(),
4356 },
4357 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
4358 .func_info_cnt = 0,
4359 .line_info = {
4360 BPF_LINE_INFO_ENC(0, 0, NAME_TBD, 1, 10), 0,
4361 BPF_LINE_INFO_ENC(1, 0, NAME_TBD, 2, 9), 0,
4362 BPF_LINE_INFO_ENC(2, 0, NAME_TBD, 3, 8), 0,
4363 BPF_LINE_INFO_ENC(3, 0, NAME_TBD, 4, 7), 0,
4364 BTF_END_RAW,
4365 },
4366 .line_info_rec_size = sizeof(struct bpf_line_info) + sizeof(__u32),
4367 .nr_jited_ksyms = 1,
4368},
4369
4370{
4371 .descr = "line_info (No subprog. nonzero tailing line_info)",
4372 .raw_types = {
4373 BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),
4374 BTF_END_RAW,
4375 },
4376 BTF_STR_SEC("\0int\0int a=1;\0int b=2;\0return a + b;\0return a + b;"),
4377 .insns = {
4378 BPF_MOV64_IMM(BPF_REG_0, 1),
4379 BPF_MOV64_IMM(BPF_REG_1, 2),
4380 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
4381 BPF_EXIT_INSN(),
4382 },
4383 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
4384 .func_info_cnt = 0,
4385 .line_info = {
4386 BPF_LINE_INFO_ENC(0, 0, NAME_TBD, 1, 10), 0,
4387 BPF_LINE_INFO_ENC(1, 0, NAME_TBD, 2, 9), 0,
4388 BPF_LINE_INFO_ENC(2, 0, NAME_TBD, 3, 8), 0,
4389 BPF_LINE_INFO_ENC(3, 0, NAME_TBD, 4, 7), 1,
4390 BTF_END_RAW,
4391 },
4392 .line_info_rec_size = sizeof(struct bpf_line_info) + sizeof(__u32),
4393 .nr_jited_ksyms = 1,
4394 .err_str = "nonzero tailing record in line_info",
4395 .expected_prog_load_failure = true,
4396},
4397
4398{
4399 .descr = "line_info (subprog)",
4400 .raw_types = {
4401 BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),
4402 BTF_END_RAW,
4403 },
4404 BTF_STR_SEC("\0int\0int a=1+1;\0return func(a);\0b+=1;\0return b;"),
4405 .insns = {
4406 BPF_MOV64_IMM(BPF_REG_2, 1),
4407 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, 1),
4408 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
4409 BPF_CALL_REL(1),
4410 BPF_EXIT_INSN(),
4411 BPF_MOV64_REG(BPF_REG_0, BPF_REG_1),
4412 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 1),
4413 BPF_EXIT_INSN(),
4414 },
4415 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
4416 .func_info_cnt = 0,
4417 .line_info = {
4418 BPF_LINE_INFO_ENC(0, 0, NAME_TBD, 1, 10),
4419 BPF_LINE_INFO_ENC(2, 0, NAME_TBD, 2, 9),
4420 BPF_LINE_INFO_ENC(5, 0, NAME_TBD, 3, 8),
4421 BPF_LINE_INFO_ENC(7, 0, NAME_TBD, 4, 7),
4422 BTF_END_RAW,
4423 },
4424 .line_info_rec_size = sizeof(struct bpf_line_info),
4425 .nr_jited_ksyms = 2,
4426},
4427
4428{
4429 .descr = "line_info (subprog + func_info)",
4430 .raw_types = {
4431 BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),
4432 BTF_FUNC_PROTO_ENC(1, 1),
4433 BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
4434 BTF_FUNC_ENC(NAME_TBD, 2),
4435 BTF_FUNC_ENC(NAME_TBD, 2),
4436 BTF_END_RAW,
4437 },
4438 BTF_STR_SEC("\0int\0x\0sub\0main\0int a=1+1;\0return func(a);\0b+=1;\0return b;"),
4439 .insns = {
4440 BPF_MOV64_IMM(BPF_REG_2, 1),
4441 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, 1),
4442 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
4443 BPF_CALL_REL(1),
4444 BPF_EXIT_INSN(),
4445 BPF_MOV64_REG(BPF_REG_0, BPF_REG_1),
4446 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 1),
4447 BPF_EXIT_INSN(),
4448 },
4449 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
4450 .func_info_cnt = 2,
4451 .func_info_rec_size = 8,
4452 .func_info = { {0, 4}, {5, 3} },
4453 .line_info = {
4454 BPF_LINE_INFO_ENC(0, 0, NAME_TBD, 1, 10),
4455 BPF_LINE_INFO_ENC(2, 0, NAME_TBD, 2, 9),
4456 BPF_LINE_INFO_ENC(5, 0, NAME_TBD, 3, 8),
4457 BPF_LINE_INFO_ENC(7, 0, NAME_TBD, 4, 7),
4458 BTF_END_RAW,
4459 },
4460 .line_info_rec_size = sizeof(struct bpf_line_info),
4461 .nr_jited_ksyms = 2,
4462},
4463
4464{
4465 .descr = "line_info (subprog. missing 1st func line info)",
4466 .raw_types = {
4467 BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),
4468 BTF_END_RAW,
4469 },
4470 BTF_STR_SEC("\0int\0int a=1+1;\0return func(a);\0b+=1;\0return b;"),
4471 .insns = {
4472 BPF_MOV64_IMM(BPF_REG_2, 1),
4473 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, 1),
4474 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
4475 BPF_CALL_REL(1),
4476 BPF_EXIT_INSN(),
4477 BPF_MOV64_REG(BPF_REG_0, BPF_REG_1),
4478 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 1),
4479 BPF_EXIT_INSN(),
4480 },
4481 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
4482 .func_info_cnt = 0,
4483 .line_info = {
4484 BPF_LINE_INFO_ENC(1, 0, NAME_TBD, 1, 10),
4485 BPF_LINE_INFO_ENC(2, 0, NAME_TBD, 2, 9),
4486 BPF_LINE_INFO_ENC(5, 0, NAME_TBD, 3, 8),
4487 BPF_LINE_INFO_ENC(7, 0, NAME_TBD, 4, 7),
4488 BTF_END_RAW,
4489 },
4490 .line_info_rec_size = sizeof(struct bpf_line_info),
4491 .nr_jited_ksyms = 2,
4492 .err_str = "missing bpf_line_info for func#0",
4493 .expected_prog_load_failure = true,
4494},
4495
4496{
4497 .descr = "line_info (subprog. missing 2nd func line info)",
4498 .raw_types = {
4499 BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),
4500 BTF_END_RAW,
4501 },
4502 BTF_STR_SEC("\0int\0int a=1+1;\0return func(a);\0b+=1;\0return b;"),
4503 .insns = {
4504 BPF_MOV64_IMM(BPF_REG_2, 1),
4505 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, 1),
4506 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
4507 BPF_CALL_REL(1),
4508 BPF_EXIT_INSN(),
4509 BPF_MOV64_REG(BPF_REG_0, BPF_REG_1),
4510 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 1),
4511 BPF_EXIT_INSN(),
4512 },
4513 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
4514 .func_info_cnt = 0,
4515 .line_info = {
4516 BPF_LINE_INFO_ENC(0, 0, NAME_TBD, 1, 10),
4517 BPF_LINE_INFO_ENC(2, 0, NAME_TBD, 2, 9),
4518 BPF_LINE_INFO_ENC(6, 0, NAME_TBD, 3, 8),
4519 BPF_LINE_INFO_ENC(7, 0, NAME_TBD, 4, 7),
4520 BTF_END_RAW,
4521 },
4522 .line_info_rec_size = sizeof(struct bpf_line_info),
4523 .nr_jited_ksyms = 2,
4524 .err_str = "missing bpf_line_info for func#1",
4525 .expected_prog_load_failure = true,
4526},
4527
4528{
4529 .descr = "line_info (subprog. unordered insn offset)",
4530 .raw_types = {
4531 BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),
4532 BTF_END_RAW,
4533 },
4534 BTF_STR_SEC("\0int\0int a=1+1;\0return func(a);\0b+=1;\0return b;"),
4535 .insns = {
4536 BPF_MOV64_IMM(BPF_REG_2, 1),
4537 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, 1),
4538 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
4539 BPF_CALL_REL(1),
4540 BPF_EXIT_INSN(),
4541 BPF_MOV64_REG(BPF_REG_0, BPF_REG_1),
4542 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 1),
4543 BPF_EXIT_INSN(),
4544 },
4545 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
4546 .func_info_cnt = 0,
4547 .line_info = {
4548 BPF_LINE_INFO_ENC(0, 0, NAME_TBD, 1, 10),
4549 BPF_LINE_INFO_ENC(5, 0, NAME_TBD, 2, 9),
4550 BPF_LINE_INFO_ENC(2, 0, NAME_TBD, 3, 8),
4551 BPF_LINE_INFO_ENC(7, 0, NAME_TBD, 4, 7),
4552 BTF_END_RAW,
4553 },
4554 .line_info_rec_size = sizeof(struct bpf_line_info),
4555 .nr_jited_ksyms = 2,
4556 .err_str = "Invalid line_info[2].insn_off",
4557 .expected_prog_load_failure = true,
4558},
4559
4560};
4561
4562static size_t probe_prog_length(const struct bpf_insn *fp)
4563{
4564 size_t len;
4565
4566 for (len = MAX_INSNS - 1; len > 0; --len)
4567 if (fp[len].code != 0 || fp[len].imm != 0)
4568 break;
4569 return len + 1;
4570}
4571
4572static __u32 *patch_name_tbd(const __u32 *raw_u32,
4573 const char *str, __u32 str_off,
4574 unsigned int str_sec_size,
4575 unsigned int *ret_size)
4576{
4577 int i, raw_u32_size = get_raw_sec_size(raw_u32);
4578 const char *end_str = str + str_sec_size;
4579 const char *next_str = str + str_off;
4580 __u32 *new_u32 = NULL;
4581
4582 if (raw_u32_size == -1)
4583 return ERR_PTR(-EINVAL);
4584
4585 if (!raw_u32_size) {
4586 *ret_size = 0;
4587 return NULL;
4588 }
4589
4590 new_u32 = malloc(raw_u32_size);
4591 if (!new_u32)
4592 return ERR_PTR(-ENOMEM);
4593
4594 for (i = 0; i < raw_u32_size / sizeof(raw_u32[0]); i++) {
4595 if (raw_u32[i] == NAME_TBD) {
4596 next_str = get_next_str(next_str, end_str);
4597 if (CHECK(!next_str, "Error in getting next_str\n")) {
4598 free(new_u32);
4599 return ERR_PTR(-EINVAL);
4600 }
4601 new_u32[i] = next_str - str;
4602 next_str += strlen(next_str);
4603 } else {
4604 new_u32[i] = raw_u32[i];
4605 }
4606 }
4607
4608 *ret_size = raw_u32_size;
4609 return new_u32;
4610}
4611
4612static int test_get_finfo(const struct prog_info_raw_test *test,
4613 int prog_fd)
4614{
4615 struct bpf_prog_info info = {};
4616 struct bpf_func_info *finfo;
4617 __u32 info_len, rec_size, i;
4618 void *func_info = NULL;
4619 int err;
4620
4621
4622 info_len = sizeof(struct bpf_prog_info);
4623 err = bpf_obj_get_info_by_fd(prog_fd, &info, &info_len);
4624 if (CHECK(err == -1, "invalid get info (1st) errno:%d", errno)) {
4625 fprintf(stderr, "%s\n", btf_log_buf);
4626 return -1;
4627 }
4628 if (CHECK(info.nr_func_info != test->func_info_cnt,
4629 "incorrect info.nr_func_info (1st) %d",
4630 info.nr_func_info)) {
4631 return -1;
4632 }
4633
4634 rec_size = info.func_info_rec_size;
4635 if (CHECK(rec_size != sizeof(struct bpf_func_info),
4636 "incorrect info.func_info_rec_size (1st) %d", rec_size)) {
4637 return -1;
4638 }
4639
4640 if (!info.nr_func_info)
4641 return 0;
4642
4643 func_info = malloc(info.nr_func_info * rec_size);
4644 if (CHECK(!func_info, "out of memory"))
4645 return -1;
4646
4647
4648 memset(&info, 0, sizeof(info));
4649 info.nr_func_info = test->func_info_cnt;
4650 info.func_info_rec_size = rec_size;
4651 info.func_info = ptr_to_u64(func_info);
4652 err = bpf_obj_get_info_by_fd(prog_fd, &info, &info_len);
4653 if (CHECK(err == -1, "invalid get info (2nd) errno:%d", errno)) {
4654 fprintf(stderr, "%s\n", btf_log_buf);
4655 err = -1;
4656 goto done;
4657 }
4658 if (CHECK(info.nr_func_info != test->func_info_cnt,
4659 "incorrect info.nr_func_info (2nd) %d",
4660 info.nr_func_info)) {
4661 err = -1;
4662 goto done;
4663 }
4664 if (CHECK(info.func_info_rec_size != rec_size,
4665 "incorrect info.func_info_rec_size (2nd) %d",
4666 info.func_info_rec_size)) {
4667 err = -1;
4668 goto done;
4669 }
4670
4671 finfo = func_info;
4672 for (i = 0; i < test->func_info_cnt; i++) {
4673 if (CHECK(finfo->type_id != test->func_info[i][1],
4674 "incorrect func_type %u expected %u",
4675 finfo->type_id, test->func_info[i][1])) {
4676 err = -1;
4677 goto done;
4678 }
4679 finfo = (void *)finfo + rec_size;
4680 }
4681
4682 err = 0;
4683
4684done:
4685 free(func_info);
4686 return err;
4687}
4688
4689static int test_get_linfo(const struct prog_info_raw_test *test,
4690 const void *patched_linfo,
4691 __u32 cnt, int prog_fd)
4692{
4693 __u32 i, info_len, nr_jited_ksyms, nr_jited_func_lens;
4694 __u64 *jited_linfo = NULL, *jited_ksyms = NULL;
4695 __u32 rec_size, jited_rec_size, jited_cnt;
4696 struct bpf_line_info *linfo = NULL;
4697 __u32 cur_func_len, ksyms_found;
4698 struct bpf_prog_info info = {};
4699 __u32 *jited_func_lens = NULL;
4700 __u64 cur_func_ksyms;
4701 int err;
4702
4703 jited_cnt = cnt;
4704 rec_size = sizeof(*linfo);
4705 jited_rec_size = sizeof(*jited_linfo);
4706 if (test->nr_jited_ksyms)
4707 nr_jited_ksyms = test->nr_jited_ksyms;
4708 else
4709 nr_jited_ksyms = test->func_info_cnt;
4710 nr_jited_func_lens = nr_jited_ksyms;
4711
4712 info_len = sizeof(struct bpf_prog_info);
4713 err = bpf_obj_get_info_by_fd(prog_fd, &info, &info_len);
4714 if (CHECK(err == -1, "err:%d errno:%d", err, errno)) {
4715 err = -1;
4716 goto done;
4717 }
4718
4719 if (!info.jited_prog_len) {
4720
4721 jited_cnt = 0;
4722 nr_jited_ksyms = 1;
4723 nr_jited_func_lens = 1;
4724 }
4725
4726 if (CHECK(info.nr_line_info != cnt ||
4727 info.nr_jited_line_info != jited_cnt ||
4728 info.nr_jited_ksyms != nr_jited_ksyms ||
4729 info.nr_jited_func_lens != nr_jited_func_lens ||
4730 (!info.nr_line_info && info.nr_jited_line_info),
4731 "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)",
4732 info.nr_line_info, cnt,
4733 info.nr_jited_line_info, jited_cnt,
4734 info.nr_jited_ksyms, nr_jited_ksyms,
4735 info.nr_jited_func_lens, nr_jited_func_lens)) {
4736 err = -1;
4737 goto done;
4738 }
4739
4740 if (CHECK(info.line_info_rec_size != sizeof(struct bpf_line_info) ||
4741 info.jited_line_info_rec_size != sizeof(__u64),
4742 "info: line_info_rec_size:%u(userspace expected:%u) jited_line_info_rec_size:%u(userspace expected:%u)",
4743 info.line_info_rec_size, rec_size,
4744 info.jited_line_info_rec_size, jited_rec_size)) {
4745 err = -1;
4746 goto done;
4747 }
4748
4749 if (!cnt)
4750 return 0;
4751
4752 rec_size = info.line_info_rec_size;
4753 jited_rec_size = info.jited_line_info_rec_size;
4754
4755 memset(&info, 0, sizeof(info));
4756
4757 linfo = calloc(cnt, rec_size);
4758 if (CHECK(!linfo, "!linfo")) {
4759 err = -1;
4760 goto done;
4761 }
4762 info.nr_line_info = cnt;
4763 info.line_info_rec_size = rec_size;
4764 info.line_info = ptr_to_u64(linfo);
4765
4766 if (jited_cnt) {
4767 jited_linfo = calloc(jited_cnt, jited_rec_size);
4768 jited_ksyms = calloc(nr_jited_ksyms, sizeof(*jited_ksyms));
4769 jited_func_lens = calloc(nr_jited_func_lens,
4770 sizeof(*jited_func_lens));
4771 if (CHECK(!jited_linfo || !jited_ksyms || !jited_func_lens,
4772 "jited_linfo:%p jited_ksyms:%p jited_func_lens:%p",
4773 jited_linfo, jited_ksyms, jited_func_lens)) {
4774 err = -1;
4775 goto done;
4776 }
4777
4778 info.nr_jited_line_info = jited_cnt;
4779 info.jited_line_info_rec_size = jited_rec_size;
4780 info.jited_line_info = ptr_to_u64(jited_linfo);
4781 info.nr_jited_ksyms = nr_jited_ksyms;
4782 info.jited_ksyms = ptr_to_u64(jited_ksyms);
4783 info.nr_jited_func_lens = nr_jited_func_lens;
4784 info.jited_func_lens = ptr_to_u64(jited_func_lens);
4785 }
4786
4787 err = bpf_obj_get_info_by_fd(prog_fd, &info, &info_len);
4788
4789
4790
4791
4792
4793 if (CHECK(err == -1 ||
4794 info.nr_line_info != cnt ||
4795 (jited_cnt && !info.jited_line_info) ||
4796 info.nr_jited_line_info != jited_cnt ||
4797 info.line_info_rec_size != rec_size ||
4798 info.jited_line_info_rec_size != jited_rec_size,
4799 "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",
4800 err, errno,
4801 info.nr_line_info, cnt,
4802 info.nr_jited_line_info, jited_cnt,
4803 info.line_info_rec_size, rec_size,
4804 info.jited_line_info_rec_size, jited_rec_size,
4805 (void *)(long)info.line_info,
4806 (void *)(long)info.jited_line_info)) {
4807 err = -1;
4808 goto done;
4809 }
4810
4811 CHECK(linfo[0].insn_off, "linfo[0].insn_off:%u",
4812 linfo[0].insn_off);
4813 for (i = 1; i < cnt; i++) {
4814 const struct bpf_line_info *expected_linfo;
4815
4816 expected_linfo = patched_linfo + (i * test->line_info_rec_size);
4817 if (CHECK(linfo[i].insn_off <= linfo[i - 1].insn_off,
4818 "linfo[%u].insn_off:%u <= linfo[%u].insn_off:%u",
4819 i, linfo[i].insn_off,
4820 i - 1, linfo[i - 1].insn_off)) {
4821 err = -1;
4822 goto done;
4823 }
4824 if (CHECK(linfo[i].file_name_off != expected_linfo->file_name_off ||
4825 linfo[i].line_off != expected_linfo->line_off ||
4826 linfo[i].line_col != expected_linfo->line_col,
4827 "linfo[%u] (%u, %u, %u) != (%u, %u, %u)", i,
4828 linfo[i].file_name_off,
4829 linfo[i].line_off,
4830 linfo[i].line_col,
4831 expected_linfo->file_name_off,
4832 expected_linfo->line_off,
4833 expected_linfo->line_col)) {
4834 err = -1;
4835 goto done;
4836 }
4837 }
4838
4839 if (!jited_cnt) {
4840 fprintf(stderr, "not jited. skipping jited_line_info check. ");
4841 err = 0;
4842 goto done;
4843 }
4844
4845 if (CHECK(jited_linfo[0] != jited_ksyms[0],
4846 "jited_linfo[0]:%lx != jited_ksyms[0]:%lx",
4847 (long)(jited_linfo[0]), (long)(jited_ksyms[0]))) {
4848 err = -1;
4849 goto done;
4850 }
4851
4852 ksyms_found = 1;
4853 cur_func_len = jited_func_lens[0];
4854 cur_func_ksyms = jited_ksyms[0];
4855 for (i = 1; i < jited_cnt; i++) {
4856 if (ksyms_found < nr_jited_ksyms &&
4857 jited_linfo[i] == jited_ksyms[ksyms_found]) {
4858 cur_func_ksyms = jited_ksyms[ksyms_found];
4859 cur_func_len = jited_ksyms[ksyms_found];
4860 ksyms_found++;
4861 continue;
4862 }
4863
4864 if (CHECK(jited_linfo[i] <= jited_linfo[i - 1],
4865 "jited_linfo[%u]:%lx <= jited_linfo[%u]:%lx",
4866 i, (long)jited_linfo[i],
4867 i - 1, (long)(jited_linfo[i - 1]))) {
4868 err = -1;
4869 goto done;
4870 }
4871
4872 if (CHECK(jited_linfo[i] - cur_func_ksyms > cur_func_len,
4873 "jited_linfo[%u]:%lx - %lx > %u",
4874 i, (long)jited_linfo[i], (long)cur_func_ksyms,
4875 cur_func_len)) {
4876 err = -1;
4877 goto done;
4878 }
4879 }
4880
4881 if (CHECK(ksyms_found != nr_jited_ksyms,
4882 "ksyms_found:%u != nr_jited_ksyms:%u",
4883 ksyms_found, nr_jited_ksyms)) {
4884 err = -1;
4885 goto done;
4886 }
4887
4888 err = 0;
4889
4890done:
4891 free(linfo);
4892 free(jited_linfo);
4893 free(jited_ksyms);
4894 free(jited_func_lens);
4895 return err;
4896}
4897
4898static int do_test_info_raw(unsigned int test_num)
4899{
4900 const struct prog_info_raw_test *test = &info_raw_tests[test_num - 1];
4901 unsigned int raw_btf_size, linfo_str_off, linfo_size;
4902 int btf_fd = -1, prog_fd = -1, err = 0;
4903 void *raw_btf, *patched_linfo = NULL;
4904 const char *ret_next_str;
4905 union bpf_attr attr = {};
4906
4907 fprintf(stderr, "BTF prog info raw test[%u] (%s): ", test_num, test->descr);
4908 raw_btf = btf_raw_create(&hdr_tmpl, test->raw_types,
4909 test->str_sec, test->str_sec_size,
4910 &raw_btf_size, &ret_next_str);
4911
4912 if (!raw_btf)
4913 return -1;
4914
4915 *btf_log_buf = '\0';
4916 btf_fd = bpf_load_btf(raw_btf, raw_btf_size,
4917 btf_log_buf, BTF_LOG_BUF_SIZE,
4918 args.always_log);
4919 free(raw_btf);
4920
4921 if (CHECK(btf_fd == -1, "invalid btf_fd errno:%d", errno)) {
4922 err = -1;
4923 goto done;
4924 }
4925
4926 if (*btf_log_buf && args.always_log)
4927 fprintf(stderr, "\n%s", btf_log_buf);
4928 *btf_log_buf = '\0';
4929
4930 linfo_str_off = ret_next_str - test->str_sec;
4931 patched_linfo = patch_name_tbd(test->line_info,
4932 test->str_sec, linfo_str_off,
4933 test->str_sec_size, &linfo_size);
4934 if (IS_ERR(patched_linfo)) {
4935 fprintf(stderr, "error in creating raw bpf_line_info");
4936 err = -1;
4937 goto done;
4938 }
4939
4940 attr.prog_type = test->prog_type;
4941 attr.insns = ptr_to_u64(test->insns);
4942 attr.insn_cnt = probe_prog_length(test->insns);
4943 attr.license = ptr_to_u64("GPL");
4944 attr.prog_btf_fd = btf_fd;
4945 attr.func_info_rec_size = test->func_info_rec_size;
4946 attr.func_info_cnt = test->func_info_cnt;
4947 attr.func_info = ptr_to_u64(test->func_info);
4948 attr.log_buf = ptr_to_u64(btf_log_buf);
4949 attr.log_size = BTF_LOG_BUF_SIZE;
4950 attr.log_level = 1;
4951 if (linfo_size) {
4952 attr.line_info_rec_size = test->line_info_rec_size;
4953 attr.line_info = ptr_to_u64(patched_linfo);
4954 attr.line_info_cnt = linfo_size / attr.line_info_rec_size;
4955 }
4956
4957 prog_fd = syscall(__NR_bpf, BPF_PROG_LOAD, &attr, sizeof(attr));
4958 err = ((prog_fd == -1) != test->expected_prog_load_failure);
4959 if (CHECK(err, "prog_fd:%d expected_prog_load_failure:%u errno:%d",
4960 prog_fd, test->expected_prog_load_failure, errno) ||
4961 CHECK(test->err_str && !strstr(btf_log_buf, test->err_str),
4962 "expected err_str:%s", test->err_str)) {
4963 err = -1;
4964 goto done;
4965 }
4966
4967 if (prog_fd == -1)
4968 goto done;
4969
4970 err = test_get_finfo(test, prog_fd);
4971 if (err)
4972 goto done;
4973
4974 err = test_get_linfo(test, patched_linfo, attr.line_info_cnt, prog_fd);
4975 if (err)
4976 goto done;
4977
4978done:
4979 if (!err)
4980 fprintf(stderr, "OK");
4981
4982 if (*btf_log_buf && (err || args.always_log))
4983 fprintf(stderr, "\n%s", btf_log_buf);
4984
4985 if (btf_fd != -1)
4986 close(btf_fd);
4987 if (prog_fd != -1)
4988 close(prog_fd);
4989
4990 if (!IS_ERR(patched_linfo))
4991 free(patched_linfo);
4992
4993 return err;
4994}
4995
4996static int test_info_raw(void)
4997{
4998 unsigned int i;
4999 int err = 0;
5000
5001 if (args.info_raw_test_num)
5002 return count_result(do_test_info_raw(args.info_raw_test_num));
5003
5004 for (i = 1; i <= ARRAY_SIZE(info_raw_tests); i++)
5005 err |= count_result(do_test_info_raw(i));
5006
5007 return err;
5008}
5009
5010struct btf_raw_data {
5011 __u32 raw_types[MAX_NR_RAW_U32];
5012 const char *str_sec;
5013 __u32 str_sec_size;
5014};
5015
5016struct btf_dedup_test {
5017 const char *descr;
5018 struct btf_raw_data input;
5019 struct btf_raw_data expect;
5020 struct btf_dedup_opts opts;
5021};
5022
5023const struct btf_dedup_test dedup_tests[] = {
5024
5025{
5026 .descr = "dedup: unused strings filtering",
5027 .input = {
5028 .raw_types = {
5029 BTF_TYPE_INT_ENC(NAME_NTH(2), BTF_INT_SIGNED, 0, 32, 4),
5030 BTF_TYPE_INT_ENC(NAME_NTH(5), BTF_INT_SIGNED, 0, 64, 8),
5031 BTF_END_RAW,
5032 },
5033 BTF_STR_SEC("\0unused\0int\0foo\0bar\0long"),
5034 },
5035 .expect = {
5036 .raw_types = {
5037 BTF_TYPE_INT_ENC(NAME_NTH(1), BTF_INT_SIGNED, 0, 32, 4),
5038 BTF_TYPE_INT_ENC(NAME_NTH(2), BTF_INT_SIGNED, 0, 64, 8),
5039 BTF_END_RAW,
5040 },
5041 BTF_STR_SEC("\0int\0long"),
5042 },
5043 .opts = {
5044 .dont_resolve_fwds = false,
5045 },
5046},
5047{
5048 .descr = "dedup: strings deduplication",
5049 .input = {
5050 .raw_types = {
5051 BTF_TYPE_INT_ENC(NAME_NTH(1), BTF_INT_SIGNED, 0, 32, 4),
5052 BTF_TYPE_INT_ENC(NAME_NTH(2), BTF_INT_SIGNED, 0, 64, 8),
5053 BTF_TYPE_INT_ENC(NAME_NTH(3), BTF_INT_SIGNED, 0, 32, 4),
5054 BTF_TYPE_INT_ENC(NAME_NTH(4), BTF_INT_SIGNED, 0, 64, 8),
5055 BTF_TYPE_INT_ENC(NAME_NTH(5), BTF_INT_SIGNED, 0, 32, 4),
5056 BTF_END_RAW,
5057 },
5058 BTF_STR_SEC("\0int\0long int\0int\0long int\0int"),
5059 },
5060 .expect = {
5061 .raw_types = {
5062 BTF_TYPE_INT_ENC(NAME_NTH(1), BTF_INT_SIGNED, 0, 32, 4),
5063 BTF_TYPE_INT_ENC(NAME_NTH(2), BTF_INT_SIGNED, 0, 64, 8),
5064 BTF_END_RAW,
5065 },
5066 BTF_STR_SEC("\0int\0long int"),
5067 },
5068 .opts = {
5069 .dont_resolve_fwds = false,
5070 },
5071},
5072{
5073 .descr = "dedup: struct example #1",
5074
5075
5076
5077
5078
5079
5080
5081
5082 .input = {
5083 .raw_types = {
5084
5085 BTF_TYPE_INT_ENC(NAME_NTH(1), BTF_INT_SIGNED, 0, 32, 4),
5086
5087 BTF_TYPE_ARRAY_ENC(1, 1, 16),
5088
5089 BTF_STRUCT_ENC(NAME_NTH(2), 4, 84),
5090 BTF_MEMBER_ENC(NAME_NTH(3), 4, 0),
5091 BTF_MEMBER_ENC(NAME_NTH(4), 5, 64),
5092 BTF_MEMBER_ENC(NAME_NTH(5), 2, 128),
5093 BTF_MEMBER_ENC(NAME_NTH(6), 1, 640),
5094
5095 BTF_PTR_ENC(3),
5096
5097 BTF_PTR_ENC(6),
5098
5099 BTF_CONST_ENC(1),
5100
5101
5102 BTF_TYPE_INT_ENC(NAME_NTH(1), BTF_INT_SIGNED, 0, 32, 4),
5103 BTF_TYPE_ARRAY_ENC(7, 7, 16),
5104 BTF_STRUCT_ENC(NAME_NTH(2), 4, 84),
5105 BTF_MEMBER_ENC(NAME_NTH(3), 10, 0),
5106 BTF_MEMBER_ENC(NAME_NTH(4), 11, 64),
5107 BTF_MEMBER_ENC(NAME_NTH(5), 8, 128),
5108 BTF_MEMBER_ENC(NAME_NTH(6), 7, 640),
5109 BTF_PTR_ENC(9),
5110 BTF_PTR_ENC(12),
5111 BTF_CONST_ENC(7),
5112 BTF_END_RAW,
5113 },
5114 BTF_STR_SEC("\0int\0s\0next\0a\0b\0c\0"),
5115 },
5116 .expect = {
5117 .raw_types = {
5118
5119 BTF_TYPE_INT_ENC(NAME_NTH(4), BTF_INT_SIGNED, 0, 32, 4),
5120
5121 BTF_TYPE_ARRAY_ENC(1, 1, 16),
5122
5123 BTF_STRUCT_ENC(NAME_NTH(6), 4, 84),
5124 BTF_MEMBER_ENC(NAME_NTH(5), 4, 0),
5125 BTF_MEMBER_ENC(NAME_NTH(1), 5, 64),
5126 BTF_MEMBER_ENC(NAME_NTH(2), 2, 128),
5127 BTF_MEMBER_ENC(NAME_NTH(3), 1, 640),
5128
5129 BTF_PTR_ENC(3),
5130
5131 BTF_PTR_ENC(6),
5132
5133 BTF_CONST_ENC(1),
5134 BTF_END_RAW,
5135 },
5136 BTF_STR_SEC("\0a\0b\0c\0int\0next\0s"),
5137 },
5138 .opts = {
5139 .dont_resolve_fwds = false,
5140 },
5141},
5142{
5143 .descr = "dedup: all possible kinds (no duplicates)",
5144 .input = {
5145 .raw_types = {
5146 BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 8),
5147 BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_ENUM, 0, 2), 4),
5148 BTF_ENUM_ENC(NAME_TBD, 0),
5149 BTF_ENUM_ENC(NAME_TBD, 1),
5150 BTF_FWD_ENC(NAME_TBD, 1 ),
5151 BTF_TYPE_ARRAY_ENC(2, 1, 7),
5152 BTF_STRUCT_ENC(NAME_TBD, 1, 4),
5153 BTF_MEMBER_ENC(NAME_TBD, 1, 0),
5154 BTF_UNION_ENC(NAME_TBD, 1, 4),
5155 BTF_MEMBER_ENC(NAME_TBD, 1, 0),
5156 BTF_TYPEDEF_ENC(NAME_TBD, 1),
5157 BTF_PTR_ENC(0),
5158 BTF_CONST_ENC(8),
5159 BTF_VOLATILE_ENC(8),
5160 BTF_RESTRICT_ENC(8),
5161 BTF_FUNC_PROTO_ENC(1, 2),
5162 BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
5163 BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 8),
5164 BTF_FUNC_ENC(NAME_TBD, 12),
5165 BTF_END_RAW,
5166 },
5167 BTF_STR_SEC("\0A\0B\0C\0D\0E\0F\0G\0H\0I\0J\0K\0L\0M"),
5168 },
5169 .expect = {
5170 .raw_types = {
5171 BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 8),
5172 BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_ENUM, 0, 2), 4),
5173 BTF_ENUM_ENC(NAME_TBD, 0),
5174 BTF_ENUM_ENC(NAME_TBD, 1),
5175 BTF_FWD_ENC(NAME_TBD, 1 ),
5176 BTF_TYPE_ARRAY_ENC(2, 1, 7),
5177 BTF_STRUCT_ENC(NAME_TBD, 1, 4),
5178 BTF_MEMBER_ENC(NAME_TBD, 1, 0),
5179 BTF_UNION_ENC(NAME_TBD, 1, 4),
5180 BTF_MEMBER_ENC(NAME_TBD, 1, 0),
5181 BTF_TYPEDEF_ENC(NAME_TBD, 1),
5182 BTF_PTR_ENC(0),
5183 BTF_CONST_ENC(8),
5184 BTF_VOLATILE_ENC(8),
5185 BTF_RESTRICT_ENC(8),
5186 BTF_FUNC_PROTO_ENC(1, 2),
5187 BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
5188 BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 8),
5189 BTF_FUNC_ENC(NAME_TBD, 12),
5190 BTF_END_RAW,
5191 },
5192 BTF_STR_SEC("\0A\0B\0C\0D\0E\0F\0G\0H\0I\0J\0K\0L\0M"),
5193 },
5194 .opts = {
5195 .dont_resolve_fwds = false,
5196 },
5197},
5198{
5199 .descr = "dedup: no int duplicates",
5200 .input = {
5201 .raw_types = {
5202 BTF_TYPE_INT_ENC(NAME_NTH(1), BTF_INT_SIGNED, 0, 32, 8),
5203
5204 BTF_TYPE_INT_ENC(NAME_NTH(2), BTF_INT_SIGNED, 0, 32, 8),
5205
5206 BTF_TYPE_INT_ENC(NAME_NTH(1), BTF_INT_CHAR, 0, 32, 8),
5207 BTF_TYPE_INT_ENC(NAME_NTH(1), BTF_INT_BOOL, 0, 32, 8),
5208
5209 BTF_TYPE_INT_ENC(NAME_NTH(1), BTF_INT_SIGNED, 8, 32, 8),
5210
5211 BTF_TYPE_INT_ENC(NAME_NTH(1), BTF_INT_SIGNED, 0, 27, 8),
5212
5213 BTF_TYPE_INT_ENC(NAME_NTH(1), BTF_INT_SIGNED, 0, 32, 4),
5214 BTF_END_RAW,
5215 },
5216 BTF_STR_SEC("\0int\0some other int"),
5217 },
5218 .expect = {
5219 .raw_types = {
5220 BTF_TYPE_INT_ENC(NAME_NTH(1), BTF_INT_SIGNED, 0, 32, 8),
5221
5222 BTF_TYPE_INT_ENC(NAME_NTH(2), BTF_INT_SIGNED, 0, 32, 8),
5223
5224 BTF_TYPE_INT_ENC(NAME_NTH(1), BTF_INT_CHAR, 0, 32, 8),
5225 BTF_TYPE_INT_ENC(NAME_NTH(1), BTF_INT_BOOL, 0, 32, 8),
5226
5227 BTF_TYPE_INT_ENC(NAME_NTH(1), BTF_INT_SIGNED, 8, 32, 8),
5228
5229 BTF_TYPE_INT_ENC(NAME_NTH(1), BTF_INT_SIGNED, 0, 27, 8),
5230
5231 BTF_TYPE_INT_ENC(NAME_NTH(1), BTF_INT_SIGNED, 0, 32, 4),
5232 BTF_END_RAW,
5233 },
5234 BTF_STR_SEC("\0int\0some other int"),
5235 },
5236 .opts = {
5237 .dont_resolve_fwds = false,
5238 },
5239},
5240
5241};
5242
5243static int btf_type_size(const struct btf_type *t)
5244{
5245 int base_size = sizeof(struct btf_type);
5246 __u16 vlen = BTF_INFO_VLEN(t->info);
5247 __u16 kind = BTF_INFO_KIND(t->info);
5248
5249 switch (kind) {
5250 case BTF_KIND_FWD:
5251 case BTF_KIND_CONST:
5252 case BTF_KIND_VOLATILE:
5253 case BTF_KIND_RESTRICT:
5254 case BTF_KIND_PTR:
5255 case BTF_KIND_TYPEDEF:
5256 case BTF_KIND_FUNC:
5257 return base_size;
5258 case BTF_KIND_INT:
5259 return base_size + sizeof(__u32);
5260 case BTF_KIND_ENUM:
5261 return base_size + vlen * sizeof(struct btf_enum);
5262 case BTF_KIND_ARRAY:
5263 return base_size + sizeof(struct btf_array);
5264 case BTF_KIND_STRUCT:
5265 case BTF_KIND_UNION:
5266 return base_size + vlen * sizeof(struct btf_member);
5267 case BTF_KIND_FUNC_PROTO:
5268 return base_size + vlen * sizeof(struct btf_param);
5269 default:
5270 fprintf(stderr, "Unsupported BTF_KIND:%u\n", kind);
5271 return -EINVAL;
5272 }
5273}
5274
5275static void dump_btf_strings(const char *strs, __u32 len)
5276{
5277 const char *cur = strs;
5278 int i = 0;
5279
5280 while (cur < strs + len) {
5281 fprintf(stderr, "string #%d: '%s'\n", i, cur);
5282 cur += strlen(cur) + 1;
5283 i++;
5284 }
5285}
5286
5287static int do_test_dedup(unsigned int test_num)
5288{
5289 const struct btf_dedup_test *test = &dedup_tests[test_num - 1];
5290 int err = 0, i;
5291 __u32 test_nr_types, expect_nr_types, test_str_len, expect_str_len;
5292 void *raw_btf;
5293 unsigned int raw_btf_size;
5294 struct btf *test_btf = NULL, *expect_btf = NULL;
5295 const char *ret_test_next_str, *ret_expect_next_str;
5296 const char *test_strs, *expect_strs;
5297 const char *test_str_cur, *test_str_end;
5298 const char *expect_str_cur, *expect_str_end;
5299
5300 fprintf(stderr, "BTF dedup test[%u] (%s):", test_num, test->descr);
5301
5302 raw_btf = btf_raw_create(&hdr_tmpl, test->input.raw_types,
5303 test->input.str_sec, test->input.str_sec_size,
5304 &raw_btf_size, &ret_test_next_str);
5305 if (!raw_btf)
5306 return -1;
5307 test_btf = btf__new((__u8 *)raw_btf, raw_btf_size);
5308 free(raw_btf);
5309 if (CHECK(IS_ERR(test_btf), "invalid test_btf errno:%ld",
5310 PTR_ERR(test_btf))) {
5311 err = -1;
5312 goto done;
5313 }
5314
5315 raw_btf = btf_raw_create(&hdr_tmpl, test->expect.raw_types,
5316 test->expect.str_sec,
5317 test->expect.str_sec_size,
5318 &raw_btf_size, &ret_expect_next_str);
5319 if (!raw_btf)
5320 return -1;
5321 expect_btf = btf__new((__u8 *)raw_btf, raw_btf_size);
5322 free(raw_btf);
5323 if (CHECK(IS_ERR(expect_btf), "invalid expect_btf errno:%ld",
5324 PTR_ERR(expect_btf))) {
5325 err = -1;
5326 goto done;
5327 }
5328
5329 err = btf__dedup(test_btf, NULL, &test->opts);
5330 if (CHECK(err, "btf_dedup failed errno:%d", err)) {
5331 err = -1;
5332 goto done;
5333 }
5334
5335 btf__get_strings(test_btf, &test_strs, &test_str_len);
5336 btf__get_strings(expect_btf, &expect_strs, &expect_str_len);
5337 if (CHECK(test_str_len != expect_str_len,
5338 "test_str_len:%u != expect_str_len:%u",
5339 test_str_len, expect_str_len)) {
5340 fprintf(stderr, "\ntest strings:\n");
5341 dump_btf_strings(test_strs, test_str_len);
5342 fprintf(stderr, "\nexpected strings:\n");
5343 dump_btf_strings(expect_strs, expect_str_len);
5344 err = -1;
5345 goto done;
5346 }
5347
5348 test_str_cur = test_strs;
5349 test_str_end = test_strs + test_str_len;
5350 expect_str_cur = expect_strs;
5351 expect_str_end = expect_strs + expect_str_len;
5352 while (test_str_cur < test_str_end && expect_str_cur < expect_str_end) {
5353 size_t test_len, expect_len;
5354
5355 test_len = strlen(test_str_cur);
5356 expect_len = strlen(expect_str_cur);
5357 if (CHECK(test_len != expect_len,
5358 "test_len:%zu != expect_len:%zu "
5359 "(test_str:%s, expect_str:%s)",
5360 test_len, expect_len, test_str_cur, expect_str_cur)) {
5361 err = -1;
5362 goto done;
5363 }
5364 if (CHECK(strcmp(test_str_cur, expect_str_cur),
5365 "test_str:%s != expect_str:%s",
5366 test_str_cur, expect_str_cur)) {
5367 err = -1;
5368 goto done;
5369 }
5370 test_str_cur += test_len + 1;
5371 expect_str_cur += expect_len + 1;
5372 }
5373 if (CHECK(test_str_cur != test_str_end,
5374 "test_str_cur:%p != test_str_end:%p",
5375 test_str_cur, test_str_end)) {
5376 err = -1;
5377 goto done;
5378 }
5379
5380 test_nr_types = btf__get_nr_types(test_btf);
5381 expect_nr_types = btf__get_nr_types(expect_btf);
5382 if (CHECK(test_nr_types != expect_nr_types,
5383 "test_nr_types:%u != expect_nr_types:%u",
5384 test_nr_types, expect_nr_types)) {
5385 err = -1;
5386 goto done;
5387 }
5388
5389 for (i = 1; i <= test_nr_types; i++) {
5390 const struct btf_type *test_type, *expect_type;
5391 int test_size, expect_size;
5392
5393 test_type = btf__type_by_id(test_btf, i);
5394 expect_type = btf__type_by_id(expect_btf, i);
5395 test_size = btf_type_size(test_type);
5396 expect_size = btf_type_size(expect_type);
5397
5398 if (CHECK(test_size != expect_size,
5399 "type #%d: test_size:%d != expect_size:%u",
5400 i, test_size, expect_size)) {
5401 err = -1;
5402 goto done;
5403 }
5404 if (CHECK(memcmp((void *)test_type,
5405 (void *)expect_type,
5406 test_size),
5407 "type #%d: contents differ", i)) {
5408 err = -1;
5409 goto done;
5410 }
5411 }
5412
5413done:
5414 if (!err)
5415 fprintf(stderr, "OK");
5416 if (!IS_ERR(test_btf))
5417 btf__free(test_btf);
5418 if (!IS_ERR(expect_btf))
5419 btf__free(expect_btf);
5420
5421 return err;
5422}
5423
5424static int test_dedup(void)
5425{
5426 unsigned int i;
5427 int err = 0;
5428
5429 if (args.dedup_test_num)
5430 return count_result(do_test_dedup(args.dedup_test_num));
5431
5432 for (i = 1; i <= ARRAY_SIZE(dedup_tests); i++)
5433 err |= count_result(do_test_dedup(i));
5434
5435 return err;
5436}
5437
5438static void usage(const char *cmd)
5439{
5440 fprintf(stderr, "Usage: %s [-l] [[-r btf_raw_test_num (1 - %zu)] |\n"
5441 "\t[-g btf_get_info_test_num (1 - %zu)] |\n"
5442 "\t[-f btf_file_test_num (1 - %zu)] |\n"
5443 "\t[-k btf_prog_info_raw_test_num (1 - %zu)] |\n"
5444 "\t[-p (pretty print test)] |\n"
5445 "\t[-d btf_dedup_test_num (1 - %zu)]]\n",
5446 cmd, ARRAY_SIZE(raw_tests), ARRAY_SIZE(get_info_tests),
5447 ARRAY_SIZE(file_tests), ARRAY_SIZE(info_raw_tests),
5448 ARRAY_SIZE(dedup_tests));
5449}
5450
5451static int parse_args(int argc, char **argv)
5452{
5453 const char *optstr = "hlpk:f:r:g:d:";
5454 int opt;
5455
5456 while ((opt = getopt(argc, argv, optstr)) != -1) {
5457 switch (opt) {
5458 case 'l':
5459 args.always_log = true;
5460 break;
5461 case 'f':
5462 args.file_test_num = atoi(optarg);
5463 args.file_test = true;
5464 break;
5465 case 'r':
5466 args.raw_test_num = atoi(optarg);
5467 args.raw_test = true;
5468 break;
5469 case 'g':
5470 args.get_info_test_num = atoi(optarg);
5471 args.get_info_test = true;
5472 break;
5473 case 'p':
5474 args.pprint_test = true;
5475 break;
5476 case 'k':
5477 args.info_raw_test_num = atoi(optarg);
5478 args.info_raw_test = true;
5479 break;
5480 case 'd':
5481 args.dedup_test_num = atoi(optarg);
5482 args.dedup_test = true;
5483 break;
5484 case 'h':
5485 usage(argv[0]);
5486 exit(0);
5487 default:
5488 usage(argv[0]);
5489 return -1;
5490 }
5491 }
5492
5493 if (args.raw_test_num &&
5494 (args.raw_test_num < 1 ||
5495 args.raw_test_num > ARRAY_SIZE(raw_tests))) {
5496 fprintf(stderr, "BTF raw test number must be [1 - %zu]\n",
5497 ARRAY_SIZE(raw_tests));
5498 return -1;
5499 }
5500
5501 if (args.file_test_num &&
5502 (args.file_test_num < 1 ||
5503 args.file_test_num > ARRAY_SIZE(file_tests))) {
5504 fprintf(stderr, "BTF file test number must be [1 - %zu]\n",
5505 ARRAY_SIZE(file_tests));
5506 return -1;
5507 }
5508
5509 if (args.get_info_test_num &&
5510 (args.get_info_test_num < 1 ||
5511 args.get_info_test_num > ARRAY_SIZE(get_info_tests))) {
5512 fprintf(stderr, "BTF get info test number must be [1 - %zu]\n",
5513 ARRAY_SIZE(get_info_tests));
5514 return -1;
5515 }
5516
5517 if (args.info_raw_test_num &&
5518 (args.info_raw_test_num < 1 ||
5519 args.info_raw_test_num > ARRAY_SIZE(info_raw_tests))) {
5520 fprintf(stderr, "BTF prog info raw test number must be [1 - %zu]\n",
5521 ARRAY_SIZE(info_raw_tests));
5522 return -1;
5523 }
5524
5525 if (args.dedup_test_num &&
5526 (args.dedup_test_num < 1 ||
5527 args.dedup_test_num > ARRAY_SIZE(dedup_tests))) {
5528 fprintf(stderr, "BTF dedup test number must be [1 - %zu]\n",
5529 ARRAY_SIZE(dedup_tests));
5530 return -1;
5531 }
5532
5533 return 0;
5534}
5535
5536static void print_summary(void)
5537{
5538 fprintf(stderr, "PASS:%u SKIP:%u FAIL:%u\n",
5539 pass_cnt - skip_cnt, skip_cnt, error_cnt);
5540}
5541
5542int main(int argc, char **argv)
5543{
5544 int err = 0;
5545
5546 err = parse_args(argc, argv);
5547 if (err)
5548 return err;
5549
5550 if (args.always_log)
5551 libbpf_set_print(__base_pr);
5552
5553 if (args.raw_test)
5554 err |= test_raw();
5555
5556 if (args.get_info_test)
5557 err |= test_get_info();
5558
5559 if (args.file_test)
5560 err |= test_file();
5561
5562 if (args.pprint_test)
5563 err |= test_pprint();
5564
5565 if (args.info_raw_test)
5566 err |= test_info_raw();
5567
5568 if (args.dedup_test)
5569 err |= test_dedup();
5570
5571 if (args.raw_test || args.get_info_test || args.file_test ||
5572 args.pprint_test || args.info_raw_test || args.dedup_test)
5573 goto done;
5574
5575 err |= test_raw();
5576 err |= test_get_info();
5577 err |= test_file();
5578 err |= test_info_raw();
5579 err |= test_dedup();
5580
5581done:
5582 print_summary();
5583 return err;
5584}
5585