tools/bpf: extends test_btf to test load/retrieve func_type info
[linux-2.6-block.git] / tools / testing / selftests / bpf / test_btf.c
1 /* SPDX-License-Identifier: GPL-2.0 */
2 /* Copyright (c) 2018 Facebook */
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 <bpf/bpf.h>
10 #include <sys/resource.h>
11 #include <libelf.h>
12 #include <gelf.h>
13 #include <string.h>
14 #include <stdlib.h>
15 #include <stdio.h>
16 #include <stdarg.h>
17 #include <unistd.h>
18 #include <fcntl.h>
19 #include <errno.h>
20 #include <bpf/libbpf.h>
21 #include <bpf/btf.h>
22
23 #include "bpf_rlimit.h"
24 #include "bpf_util.h"
25
26 #define MAX_INSNS       512
27 #define MAX_SUBPROGS    16
28
29 static uint32_t pass_cnt;
30 static uint32_t error_cnt;
31 static uint32_t skip_cnt;
32 static bool jit_enabled;
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
43 static 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
54 #define __printf(a, b)  __attribute__((format(printf, a, b)))
55
56 __printf(1, 2)
57 static int __base_pr(const char *format, ...)
58 {
59         va_list args;
60         int err;
61
62         va_start(args, format);
63         err = vfprintf(stderr, format, args);
64         va_end(args);
65         return err;
66 }
67
68 static bool is_jit_enabled(void)
69 {
70         const char *jit_sysctl = "/proc/sys/net/core/bpf_jit_enable";
71         bool enabled = false;
72         int sysctl_fd;
73
74         sysctl_fd = open(jit_sysctl, 0, O_RDONLY);
75         if (sysctl_fd != -1) {
76                 char tmpc;
77
78                 if (read(sysctl_fd, &tmpc, sizeof(tmpc)) == 1)
79                         enabled = (tmpc != '0');
80                 close(sysctl_fd);
81         }
82
83         return enabled;
84 }
85
86 #define BTF_INFO_ENC(kind, root, vlen)                  \
87         ((!!(root) << 31) | ((kind) << 24) | ((vlen) & BTF_MAX_VLEN))
88
89 #define BTF_TYPE_ENC(name, info, size_or_type)  \
90         (name), (info), (size_or_type)
91
92 #define BTF_INT_ENC(encoding, bits_offset, nr_bits)     \
93         ((encoding) << 24 | (bits_offset) << 16 | (nr_bits))
94 #define BTF_TYPE_INT_ENC(name, encoding, bits_offset, bits, sz) \
95         BTF_TYPE_ENC(name, BTF_INFO_ENC(BTF_KIND_INT, 0, 0), sz),       \
96         BTF_INT_ENC(encoding, bits_offset, bits)
97
98 #define BTF_ARRAY_ENC(type, index_type, nr_elems)       \
99         (type), (index_type), (nr_elems)
100 #define BTF_TYPE_ARRAY_ENC(type, index_type, nr_elems) \
101         BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_ARRAY, 0, 0), 0), \
102         BTF_ARRAY_ENC(type, index_type, nr_elems)
103
104 #define BTF_MEMBER_ENC(name, type, bits_offset) \
105         (name), (type), (bits_offset)
106 #define BTF_ENUM_ENC(name, val) (name), (val)
107
108 #define BTF_TYPEDEF_ENC(name, type) \
109         BTF_TYPE_ENC(name, BTF_INFO_ENC(BTF_KIND_TYPEDEF, 0, 0), type)
110
111 #define BTF_PTR_ENC(type) \
112         BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_PTR, 0, 0), type)
113
114 #define BTF_CONST_ENC(type) \
115         BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_CONST, 0, 0), type)
116
117 #define BTF_FUNC_PROTO_ENC(ret_type, nargs) \
118         BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_FUNC_PROTO, 0, nargs), ret_type)
119
120 #define BTF_FUNC_PROTO_ARG_ENC(name, type) \
121         (name), (type)
122
123 #define BTF_FUNC_ENC(name, func_proto) \
124         BTF_TYPE_ENC(name, BTF_INFO_ENC(BTF_KIND_FUNC, 0, 0), func_proto)
125
126 #define BTF_END_RAW 0xdeadbeef
127 #define NAME_TBD 0xdeadb33f
128
129 #define MAX_NR_RAW_TYPES 1024
130 #define BTF_LOG_BUF_SIZE 65535
131
132 static struct args {
133         unsigned int raw_test_num;
134         unsigned int file_test_num;
135         unsigned int get_info_test_num;
136         bool raw_test;
137         bool file_test;
138         bool get_info_test;
139         bool pprint_test;
140         bool always_log;
141         bool func_type_test;
142 } args;
143
144 static char btf_log_buf[BTF_LOG_BUF_SIZE];
145
146 static struct btf_header hdr_tmpl = {
147         .magic = BTF_MAGIC,
148         .version = BTF_VERSION,
149         .hdr_len = sizeof(struct btf_header),
150 };
151
152 struct btf_raw_test {
153         const char *descr;
154         const char *str_sec;
155         const char *map_name;
156         const char *err_str;
157         __u32 raw_types[MAX_NR_RAW_TYPES];
158         __u32 str_sec_size;
159         enum bpf_map_type map_type;
160         __u32 key_size;
161         __u32 value_size;
162         __u32 key_type_id;
163         __u32 value_type_id;
164         __u32 max_entries;
165         bool btf_load_err;
166         bool map_create_err;
167         bool ordered_map;
168         bool lossless_map;
169         bool percpu_map;
170         int hdr_len_delta;
171         int type_off_delta;
172         int str_off_delta;
173         int str_len_delta;
174 };
175
176 static struct btf_raw_test raw_tests[] = {
177 /* enum E {
178  *     E0,
179  *     E1,
180  * };
181  *
182  * struct A {
183  *      unsigned long long m;
184  *      int n;
185  *      char o;
186  *      [3 bytes hole]
187  *      int p[8];
188  *      int q[4][8];
189  *      enum E r;
190  * };
191  */
192 {
193         .descr = "struct test #1",
194         .raw_types = {
195                 /* int */
196                 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),  /* [1] */
197                 /* unsigned long long */
198                 BTF_TYPE_INT_ENC(0, 0, 0, 64, 8),               /* [2] */
199                 /* char */
200                 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 8, 1),   /* [3] */
201                 /* int[8] */
202                 BTF_TYPE_ARRAY_ENC(1, 1, 8),                    /* [4] */
203                 /* struct A { */                                /* [5] */
204                 BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 6), 180),
205                 BTF_MEMBER_ENC(NAME_TBD, 2, 0), /* unsigned long long m;*/
206                 BTF_MEMBER_ENC(NAME_TBD, 1, 64),/* int n;               */
207                 BTF_MEMBER_ENC(NAME_TBD, 3, 96),/* char o;              */
208                 BTF_MEMBER_ENC(NAME_TBD, 4, 128),/* int p[8]            */
209                 BTF_MEMBER_ENC(NAME_TBD, 6, 384),/* int q[4][8]         */
210                 BTF_MEMBER_ENC(NAME_TBD, 7, 1408), /* enum E r          */
211                 /* } */
212                 /* int[4][8] */
213                 BTF_TYPE_ARRAY_ENC(4, 1, 4),                    /* [6] */
214                 /* enum E */                                    /* [7] */
215                 BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_ENUM, 0, 2), sizeof(int)),
216                 BTF_ENUM_ENC(NAME_TBD, 0),
217                 BTF_ENUM_ENC(NAME_TBD, 1),
218                 BTF_END_RAW,
219         },
220         .str_sec = "\0A\0m\0n\0o\0p\0q\0r\0E\0E0\0E1",
221         .str_sec_size = sizeof("\0A\0m\0n\0o\0p\0q\0r\0E\0E0\0E1"),
222         .map_type = BPF_MAP_TYPE_ARRAY,
223         .map_name = "struct_test1_map",
224         .key_size = sizeof(int),
225         .value_size = 180,
226         .key_type_id = 1,
227         .value_type_id = 5,
228         .max_entries = 4,
229 },
230
231 /* typedef struct b Struct_B;
232  *
233  * struct A {
234  *     int m;
235  *     struct b n[4];
236  *     const Struct_B o[4];
237  * };
238  *
239  * struct B {
240  *     int m;
241  *     int n;
242  * };
243  */
244 {
245         .descr = "struct test #2",
246         .raw_types = {
247                 /* int */                                       /* [1] */
248                 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
249                 /* struct b [4] */                              /* [2] */
250                 BTF_TYPE_ARRAY_ENC(4, 1, 4),
251
252                 /* struct A { */                                /* [3] */
253                 BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 3), 68),
254                 BTF_MEMBER_ENC(NAME_TBD, 1, 0), /* int m;               */
255                 BTF_MEMBER_ENC(NAME_TBD, 2, 32),/* struct B n[4]        */
256                 BTF_MEMBER_ENC(NAME_TBD, 8, 288),/* const Struct_B o[4];*/
257                 /* } */
258
259                 /* struct B { */                                /* [4] */
260                 BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 2), 8),
261                 BTF_MEMBER_ENC(NAME_TBD, 1, 0), /* int m; */
262                 BTF_MEMBER_ENC(NAME_TBD, 1, 32),/* int n; */
263                 /* } */
264
265                 /* const int */                                 /* [5] */
266                 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_CONST, 0, 0), 1),
267                 /* typedef struct b Struct_B */ /* [6] */
268                 BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_TYPEDEF, 0, 0), 4),
269                 /* const Struct_B */                            /* [7] */
270                 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_CONST, 0, 0), 6),
271                 /* const Struct_B [4] */                        /* [8] */
272                 BTF_TYPE_ARRAY_ENC(7, 1, 4),
273                 BTF_END_RAW,
274         },
275         .str_sec = "\0A\0m\0n\0o\0B\0m\0n\0Struct_B",
276         .str_sec_size = sizeof("\0A\0m\0n\0o\0B\0m\0n\0Struct_B"),
277         .map_type = BPF_MAP_TYPE_ARRAY,
278         .map_name = "struct_test2_map",
279         .key_size = sizeof(int),
280         .value_size = 68,
281         .key_type_id = 1,
282         .value_type_id = 3,
283         .max_entries = 4,
284 },
285
286 {
287         .descr = "struct test #3 Invalid member offset",
288         .raw_types = {
289                 /* int */                                       /* [1] */
290                 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
291                 /* int64 */                                     /* [2] */
292                 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 64, 8),
293
294                 /* struct A { */                                /* [3] */
295                 BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 2), 16),
296                 BTF_MEMBER_ENC(NAME_TBD, 1, 64),        /* int m;               */
297                 BTF_MEMBER_ENC(NAME_TBD, 2, 0),         /* int64 n; */
298                 /* } */
299                 BTF_END_RAW,
300         },
301         .str_sec = "\0A\0m\0n\0",
302         .str_sec_size = sizeof("\0A\0m\0n\0"),
303         .map_type = BPF_MAP_TYPE_ARRAY,
304         .map_name = "struct_test3_map",
305         .key_size = sizeof(int),
306         .value_size = 16,
307         .key_type_id = 1,
308         .value_type_id = 3,
309         .max_entries = 4,
310         .btf_load_err = true,
311         .err_str = "Invalid member bits_offset",
312 },
313
314 /* Test member exceeds the size of struct.
315  *
316  * struct A {
317  *     int m;
318  *     int n;
319  * };
320  */
321 {
322         .descr = "size check test #1",
323         .raw_types = {
324                 /* int */                                       /* [1] */
325                 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
326                 /* struct A { */                                /* [2] */
327                 BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 2), sizeof(int) * 2 -  1),
328                 BTF_MEMBER_ENC(NAME_TBD, 1, 0), /* int m; */
329                 BTF_MEMBER_ENC(NAME_TBD, 1, 32),/* int n; */
330                 /* } */
331                 BTF_END_RAW,
332         },
333         .str_sec = "\0A\0m\0n",
334         .str_sec_size = sizeof("\0A\0m\0n"),
335         .map_type = BPF_MAP_TYPE_ARRAY,
336         .map_name = "size_check1_map",
337         .key_size = sizeof(int),
338         .value_size = 1,
339         .key_type_id = 1,
340         .value_type_id = 2,
341         .max_entries = 4,
342         .btf_load_err = true,
343         .err_str = "Member exceeds struct_size",
344 },
345
346 /* Test member exeeds the size of struct
347  *
348  * struct A {
349  *     int m;
350  *     int n[2];
351  * };
352  */
353 {
354         .descr = "size check test #2",
355         .raw_types = {
356                 /* int */                                       /* [1] */
357                 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, sizeof(int)),
358                 /* int[2] */                                    /* [2] */
359                 BTF_TYPE_ARRAY_ENC(1, 1, 2),
360                 /* struct A { */                                /* [3] */
361                 BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 2), sizeof(int) * 3 - 1),
362                 BTF_MEMBER_ENC(NAME_TBD, 1, 0), /* int m; */
363                 BTF_MEMBER_ENC(NAME_TBD, 2, 32),/* int n[2]; */
364                 /* } */
365                 BTF_END_RAW,
366         },
367         .str_sec = "\0A\0m\0n",
368         .str_sec_size = sizeof("\0A\0m\0n"),
369         .map_type = BPF_MAP_TYPE_ARRAY,
370         .map_name = "size_check2_map",
371         .key_size = sizeof(int),
372         .value_size = 1,
373         .key_type_id = 1,
374         .value_type_id = 3,
375         .max_entries = 4,
376         .btf_load_err = true,
377         .err_str = "Member exceeds struct_size",
378 },
379
380 /* Test member exeeds the size of struct
381  *
382  * struct A {
383  *     int m;
384  *     void *n;
385  * };
386  */
387 {
388         .descr = "size check test #3",
389         .raw_types = {
390                 /* int */                                       /* [1] */
391                 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, sizeof(int)),
392                 /* void* */                                     /* [2] */
393                 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_PTR, 0, 0), 0),
394                 /* struct A { */                                /* [3] */
395                 BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 2), sizeof(int) + sizeof(void *) - 1),
396                 BTF_MEMBER_ENC(NAME_TBD, 1, 0), /* int m; */
397                 BTF_MEMBER_ENC(NAME_TBD, 2, 32),/* void *n; */
398                 /* } */
399                 BTF_END_RAW,
400         },
401         .str_sec = "\0A\0m\0n",
402         .str_sec_size = sizeof("\0A\0m\0n"),
403         .map_type = BPF_MAP_TYPE_ARRAY,
404         .map_name = "size_check3_map",
405         .key_size = sizeof(int),
406         .value_size = 1,
407         .key_type_id = 1,
408         .value_type_id = 3,
409         .max_entries = 4,
410         .btf_load_err = true,
411         .err_str = "Member exceeds struct_size",
412 },
413
414 /* Test member exceeds the size of struct
415  *
416  * enum E {
417  *     E0,
418  *     E1,
419  * };
420  *
421  * struct A {
422  *     int m;
423  *     enum E n;
424  * };
425  */
426 {
427         .descr = "size check test #4",
428         .raw_types = {
429                 /* int */                       /* [1] */
430                 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, sizeof(int)),
431                 /* enum E { */                  /* [2] */
432                 BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_ENUM, 0, 2), sizeof(int)),
433                 BTF_ENUM_ENC(NAME_TBD, 0),
434                 BTF_ENUM_ENC(NAME_TBD, 1),
435                 /* } */
436                 /* struct A { */                /* [3] */
437                 BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 2), sizeof(int) * 2 - 1),
438                 BTF_MEMBER_ENC(NAME_TBD, 1, 0), /* int m; */
439                 BTF_MEMBER_ENC(NAME_TBD, 2, 32),/* enum E n; */
440                 /* } */
441                 BTF_END_RAW,
442         },
443         .str_sec = "\0E\0E0\0E1\0A\0m\0n",
444         .str_sec_size = sizeof("\0E\0E0\0E1\0A\0m\0n"),
445         .map_type = BPF_MAP_TYPE_ARRAY,
446         .map_name = "size_check4_map",
447         .key_size = sizeof(int),
448         .value_size = 1,
449         .key_type_id = 1,
450         .value_type_id = 3,
451         .max_entries = 4,
452         .btf_load_err = true,
453         .err_str = "Member exceeds struct_size",
454 },
455
456 /* typedef const void * const_void_ptr;
457  * struct A {
458  *      const_void_ptr m;
459  * };
460  */
461 {
462         .descr = "void test #1",
463         .raw_types = {
464                 /* int */               /* [1] */
465                 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
466                 /* const void */        /* [2] */
467                 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_CONST, 0, 0), 0),
468                 /* const void* */       /* [3] */
469                 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_PTR, 0, 0), 2),
470                 /* typedef const void * const_void_ptr */
471                 BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_PTR, 0, 0), 3),
472                 /* struct A { */        /* [4] */
473                 BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 1), sizeof(void *)),
474                 /* const_void_ptr m; */
475                 BTF_MEMBER_ENC(NAME_TBD, 3, 0),
476                 /* } */
477                 BTF_END_RAW,
478         },
479         .str_sec = "\0const_void_ptr\0A\0m",
480         .str_sec_size = sizeof("\0const_void_ptr\0A\0m"),
481         .map_type = BPF_MAP_TYPE_ARRAY,
482         .map_name = "void_test1_map",
483         .key_size = sizeof(int),
484         .value_size = sizeof(void *),
485         .key_type_id = 1,
486         .value_type_id = 4,
487         .max_entries = 4,
488 },
489
490 /* struct A {
491  *     const void m;
492  * };
493  */
494 {
495         .descr = "void test #2",
496         .raw_types = {
497                 /* int */               /* [1] */
498                 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
499                 /* const void */        /* [2] */
500                 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_CONST, 0, 0), 0),
501                 /* struct A { */        /* [3] */
502                 BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 1), 8),
503                 /* const void m; */
504                 BTF_MEMBER_ENC(NAME_TBD, 2, 0),
505                 /* } */
506                 BTF_END_RAW,
507         },
508         .str_sec = "\0A\0m",
509         .str_sec_size = sizeof("\0A\0m"),
510         .map_type = BPF_MAP_TYPE_ARRAY,
511         .map_name = "void_test2_map",
512         .key_size = sizeof(int),
513         .value_size = sizeof(void *),
514         .key_type_id = 1,
515         .value_type_id = 3,
516         .max_entries = 4,
517         .btf_load_err = true,
518         .err_str = "Invalid member",
519 },
520
521 /* typedef const void * const_void_ptr;
522  * const_void_ptr[4]
523  */
524 {
525         .descr = "void test #3",
526         .raw_types = {
527                 /* int */               /* [1] */
528                 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
529                 /* const void */        /* [2] */
530                 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_CONST, 0, 0), 0),
531                 /* const void* */       /* [3] */
532                 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_PTR, 0, 0), 2),
533                 /* typedef const void * const_void_ptr */       /* [4] */
534                 BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_PTR, 0, 0), 3),
535                 /* const_void_ptr[4] */ /* [5] */
536                 BTF_TYPE_ARRAY_ENC(3, 1, 4),
537                 BTF_END_RAW,
538         },
539         .str_sec = "\0const_void_ptr",
540         .str_sec_size = sizeof("\0const_void_ptr"),
541         .map_type = BPF_MAP_TYPE_ARRAY,
542         .map_name = "void_test3_map",
543         .key_size = sizeof(int),
544         .value_size = sizeof(void *) * 4,
545         .key_type_id = 1,
546         .value_type_id = 5,
547         .max_entries = 4,
548 },
549
550 /* const void[4]  */
551 {
552         .descr = "void test #4",
553         .raw_types = {
554                 /* int */               /* [1] */
555                 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
556                 /* const void */        /* [2] */
557                 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_CONST, 0, 0), 0),
558                 /* const void[4] */     /* [3] */
559                 BTF_TYPE_ARRAY_ENC(2, 1, 4),
560                 BTF_END_RAW,
561         },
562         .str_sec = "\0A\0m",
563         .str_sec_size = sizeof("\0A\0m"),
564         .map_type = BPF_MAP_TYPE_ARRAY,
565         .map_name = "void_test4_map",
566         .key_size = sizeof(int),
567         .value_size = sizeof(void *) * 4,
568         .key_type_id = 1,
569         .value_type_id = 3,
570         .max_entries = 4,
571         .btf_load_err = true,
572         .err_str = "Invalid elem",
573 },
574
575 /* Array_A  <------------------+
576  *     elem_type == Array_B    |
577  *                    |        |
578  *                    |        |
579  * Array_B  <-------- +        |
580  *      elem_type == Array A --+
581  */
582 {
583         .descr = "loop test #1",
584         .raw_types = {
585                 /* int */                       /* [1] */
586                 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
587                 /* Array_A */                   /* [2] */
588                 BTF_TYPE_ARRAY_ENC(3, 1, 8),
589                 /* Array_B */                   /* [3] */
590                 BTF_TYPE_ARRAY_ENC(2, 1, 8),
591                 BTF_END_RAW,
592         },
593         .str_sec = "",
594         .str_sec_size = sizeof(""),
595         .map_type = BPF_MAP_TYPE_ARRAY,
596         .map_name = "loop_test1_map",
597         .key_size = sizeof(int),
598         .value_size = sizeof(sizeof(int) * 8),
599         .key_type_id = 1,
600         .value_type_id = 2,
601         .max_entries = 4,
602         .btf_load_err = true,
603         .err_str = "Loop detected",
604 },
605
606 /* typedef is _before_ the BTF type of Array_A and Array_B
607  *
608  * typedef Array_B int_array;
609  *
610  * Array_A  <------------------+
611  *     elem_type == int_array  |
612  *                    |        |
613  *                    |        |
614  * Array_B  <-------- +        |
615  *      elem_type == Array_A --+
616  */
617 {
618         .descr = "loop test #2",
619         .raw_types = {
620                 /* int */
621                 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),  /* [1] */
622                 /* typedef Array_B int_array */
623                 BTF_TYPEDEF_ENC(1, 4),                          /* [2] */
624                 /* Array_A */
625                 BTF_TYPE_ARRAY_ENC(2, 1, 8),                    /* [3] */
626                 /* Array_B */
627                 BTF_TYPE_ARRAY_ENC(3, 1, 8),                    /* [4] */
628                 BTF_END_RAW,
629         },
630         .str_sec = "\0int_array\0",
631         .str_sec_size = sizeof("\0int_array"),
632         .map_type = BPF_MAP_TYPE_ARRAY,
633         .map_name = "loop_test2_map",
634         .key_size = sizeof(int),
635         .value_size = sizeof(sizeof(int) * 8),
636         .key_type_id = 1,
637         .value_type_id = 2,
638         .max_entries = 4,
639         .btf_load_err = true,
640         .err_str = "Loop detected",
641 },
642
643 /* Array_A  <------------------+
644  *     elem_type == Array_B    |
645  *                    |        |
646  *                    |        |
647  * Array_B  <-------- +        |
648  *      elem_type == Array_A --+
649  */
650 {
651         .descr = "loop test #3",
652         .raw_types = {
653                 /* int */                               /* [1] */
654                 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
655                 /* Array_A */                           /* [2] */
656                 BTF_TYPE_ARRAY_ENC(3, 1, 8),
657                 /* Array_B */                           /* [3] */
658                 BTF_TYPE_ARRAY_ENC(2, 1, 8),
659                 BTF_END_RAW,
660         },
661         .str_sec = "",
662         .str_sec_size = sizeof(""),
663         .map_type = BPF_MAP_TYPE_ARRAY,
664         .map_name = "loop_test3_map",
665         .key_size = sizeof(int),
666         .value_size = sizeof(sizeof(int) * 8),
667         .key_type_id = 1,
668         .value_type_id = 2,
669         .max_entries = 4,
670         .btf_load_err = true,
671         .err_str = "Loop detected",
672 },
673
674 /* typedef is _between_ the BTF type of Array_A and Array_B
675  *
676  * typedef Array_B int_array;
677  *
678  * Array_A  <------------------+
679  *     elem_type == int_array  |
680  *                    |        |
681  *                    |        |
682  * Array_B  <-------- +        |
683  *      elem_type == Array_A --+
684  */
685 {
686         .descr = "loop test #4",
687         .raw_types = {
688                 /* int */                               /* [1] */
689                 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
690                 /* Array_A */                           /* [2] */
691                 BTF_TYPE_ARRAY_ENC(3, 1, 8),
692                 /* typedef Array_B int_array */         /* [3] */
693                 BTF_TYPEDEF_ENC(NAME_TBD, 4),
694                 /* Array_B */                           /* [4] */
695                 BTF_TYPE_ARRAY_ENC(2, 1, 8),
696                 BTF_END_RAW,
697         },
698         .str_sec = "\0int_array\0",
699         .str_sec_size = sizeof("\0int_array"),
700         .map_type = BPF_MAP_TYPE_ARRAY,
701         .map_name = "loop_test4_map",
702         .key_size = sizeof(int),
703         .value_size = sizeof(sizeof(int) * 8),
704         .key_type_id = 1,
705         .value_type_id = 2,
706         .max_entries = 4,
707         .btf_load_err = true,
708         .err_str = "Loop detected",
709 },
710
711 /* typedef struct B Struct_B
712  *
713  * struct A {
714  *     int x;
715  *     Struct_B y;
716  * };
717  *
718  * struct B {
719  *     int x;
720  *     struct A y;
721  * };
722  */
723 {
724         .descr = "loop test #5",
725         .raw_types = {
726                 /* int */
727                 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),  /* [1] */
728                 /* struct A */                                  /* [2] */
729                 BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 2), 8),
730                 BTF_MEMBER_ENC(NAME_TBD, 1, 0), /* int x;       */
731                 BTF_MEMBER_ENC(NAME_TBD, 3, 32),/* Struct_B y;  */
732                 /* typedef struct B Struct_B */
733                 BTF_TYPEDEF_ENC(NAME_TBD, 4),                   /* [3] */
734                 /* struct B */                                  /* [4] */
735                 BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 2), 8),
736                 BTF_MEMBER_ENC(NAME_TBD, 1, 0), /* int x;       */
737                 BTF_MEMBER_ENC(NAME_TBD, 2, 32),/* struct A y;  */
738                 BTF_END_RAW,
739         },
740         .str_sec = "\0A\0x\0y\0Struct_B\0B\0x\0y",
741         .str_sec_size = sizeof("\0A\0x\0y\0Struct_B\0B\0x\0y"),
742         .map_type = BPF_MAP_TYPE_ARRAY,
743         .map_name = "loop_test5_map",
744         .key_size = sizeof(int),
745         .value_size = 8,
746         .key_type_id = 1,
747         .value_type_id = 2,
748         .max_entries = 4,
749         .btf_load_err = true,
750         .err_str = "Loop detected",
751 },
752
753 /* struct A {
754  *     int x;
755  *     struct A array_a[4];
756  * };
757  */
758 {
759         .descr = "loop test #6",
760         .raw_types = {
761                 /* int */
762                 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),  /* [1] */
763                 BTF_TYPE_ARRAY_ENC(3, 1, 4),                    /* [2] */
764                 /* struct A */                                  /* [3] */
765                 BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 2), 8),
766                 BTF_MEMBER_ENC(NAME_TBD, 1, 0), /* int x;               */
767                 BTF_MEMBER_ENC(NAME_TBD, 2, 32),/* struct A array_a[4]; */
768                 BTF_END_RAW,
769         },
770         .str_sec = "\0A\0x\0y",
771         .str_sec_size = sizeof("\0A\0x\0y"),
772         .map_type = BPF_MAP_TYPE_ARRAY,
773         .map_name = "loop_test6_map",
774         .key_size = sizeof(int),
775         .value_size = 8,
776         .key_type_id = 1,
777         .value_type_id = 2,
778         .max_entries = 4,
779         .btf_load_err = true,
780         .err_str = "Loop detected",
781 },
782
783 {
784         .descr = "loop test #7",
785         .raw_types = {
786                 /* int */                               /* [1] */
787                 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
788                 /* struct A { */                        /* [2] */
789                 BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 1), sizeof(void *)),
790                 /*     const void *m;   */
791                 BTF_MEMBER_ENC(NAME_TBD, 3, 0),
792                 /* CONST type_id=3      */              /* [3] */
793                 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_CONST, 0, 0), 4),
794                 /* PTR type_id=2        */              /* [4] */
795                 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_PTR, 0, 0), 3),
796                 BTF_END_RAW,
797         },
798         .str_sec = "\0A\0m",
799         .str_sec_size = sizeof("\0A\0m"),
800         .map_type = BPF_MAP_TYPE_ARRAY,
801         .map_name = "loop_test7_map",
802         .key_size = sizeof(int),
803         .value_size = sizeof(void *),
804         .key_type_id = 1,
805         .value_type_id = 2,
806         .max_entries = 4,
807         .btf_load_err = true,
808         .err_str = "Loop detected",
809 },
810
811 {
812         .descr = "loop test #8",
813         .raw_types = {
814                 /* int */                               /* [1] */
815                 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
816                 /* struct A { */                        /* [2] */
817                 BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 1), sizeof(void *)),
818                 /*     const void *m;   */
819                 BTF_MEMBER_ENC(NAME_TBD, 4, 0),
820                 /* struct B { */                        /* [3] */
821                 BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 1), sizeof(void *)),
822                 /*     const void *n;   */
823                 BTF_MEMBER_ENC(NAME_TBD, 6, 0),
824                 /* CONST type_id=5      */              /* [4] */
825                 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_CONST, 0, 0), 5),
826                 /* PTR type_id=6        */              /* [5] */
827                 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_PTR, 0, 0), 6),
828                 /* CONST type_id=7      */              /* [6] */
829                 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_CONST, 0, 0), 7),
830                 /* PTR type_id=4        */              /* [7] */
831                 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_PTR, 0, 0), 4),
832                 BTF_END_RAW,
833         },
834         .str_sec = "\0A\0m\0B\0n",
835         .str_sec_size = sizeof("\0A\0m\0B\0n"),
836         .map_type = BPF_MAP_TYPE_ARRAY,
837         .map_name = "loop_test8_map",
838         .key_size = sizeof(int),
839         .value_size = sizeof(void *),
840         .key_type_id = 1,
841         .value_type_id = 2,
842         .max_entries = 4,
843         .btf_load_err = true,
844         .err_str = "Loop detected",
845 },
846
847 {
848         .descr = "string section does not end with null",
849         .raw_types = {
850                 /* int */                               /* [1] */
851                 BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),
852                 BTF_END_RAW,
853         },
854         .str_sec = "\0int",
855         .str_sec_size = sizeof("\0int") - 1,
856         .map_type = BPF_MAP_TYPE_ARRAY,
857         .map_name = "hdr_test_map",
858         .key_size = sizeof(int),
859         .value_size = sizeof(int),
860         .key_type_id = 1,
861         .value_type_id = 1,
862         .max_entries = 4,
863         .btf_load_err = true,
864         .err_str = "Invalid string section",
865 },
866
867 {
868         .descr = "empty string section",
869         .raw_types = {
870                 /* int */                               /* [1] */
871                 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
872                 BTF_END_RAW,
873         },
874         .str_sec = "",
875         .str_sec_size = 0,
876         .map_type = BPF_MAP_TYPE_ARRAY,
877         .map_name = "hdr_test_map",
878         .key_size = sizeof(int),
879         .value_size = sizeof(int),
880         .key_type_id = 1,
881         .value_type_id = 1,
882         .max_entries = 4,
883         .btf_load_err = true,
884         .err_str = "Invalid string section",
885 },
886
887 {
888         .descr = "empty type section",
889         .raw_types = {
890                 BTF_END_RAW,
891         },
892         .str_sec = "\0int",
893         .str_sec_size = sizeof("\0int"),
894         .map_type = BPF_MAP_TYPE_ARRAY,
895         .map_name = "hdr_test_map",
896         .key_size = sizeof(int),
897         .value_size = sizeof(int),
898         .key_type_id = 1,
899         .value_type_id = 1,
900         .max_entries = 4,
901         .btf_load_err = true,
902         .err_str = "No type found",
903 },
904
905 {
906         .descr = "btf_header test. Longer hdr_len",
907         .raw_types = {
908                 /* int */                               /* [1] */
909                 BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),
910                 BTF_END_RAW,
911         },
912         .str_sec = "\0int",
913         .str_sec_size = sizeof("\0int"),
914         .map_type = BPF_MAP_TYPE_ARRAY,
915         .map_name = "hdr_test_map",
916         .key_size = sizeof(int),
917         .value_size = sizeof(int),
918         .key_type_id = 1,
919         .value_type_id = 1,
920         .max_entries = 4,
921         .btf_load_err = true,
922         .hdr_len_delta = 4,
923         .err_str = "Unsupported btf_header",
924 },
925
926 {
927         .descr = "btf_header test. Gap between hdr and type",
928         .raw_types = {
929                 /* int */                               /* [1] */
930                 BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),
931                 BTF_END_RAW,
932         },
933         .str_sec = "\0int",
934         .str_sec_size = sizeof("\0int"),
935         .map_type = BPF_MAP_TYPE_ARRAY,
936         .map_name = "hdr_test_map",
937         .key_size = sizeof(int),
938         .value_size = sizeof(int),
939         .key_type_id = 1,
940         .value_type_id = 1,
941         .max_entries = 4,
942         .btf_load_err = true,
943         .type_off_delta = 4,
944         .err_str = "Unsupported section found",
945 },
946
947 {
948         .descr = "btf_header test. Gap between type and str",
949         .raw_types = {
950                 /* int */                               /* [1] */
951                 BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),
952                 BTF_END_RAW,
953         },
954         .str_sec = "\0int",
955         .str_sec_size = sizeof("\0int"),
956         .map_type = BPF_MAP_TYPE_ARRAY,
957         .map_name = "hdr_test_map",
958         .key_size = sizeof(int),
959         .value_size = sizeof(int),
960         .key_type_id = 1,
961         .value_type_id = 1,
962         .max_entries = 4,
963         .btf_load_err = true,
964         .str_off_delta = 4,
965         .err_str = "Unsupported section found",
966 },
967
968 {
969         .descr = "btf_header test. Overlap between type and str",
970         .raw_types = {
971                 /* int */                               /* [1] */
972                 BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),
973                 BTF_END_RAW,
974         },
975         .str_sec = "\0int",
976         .str_sec_size = sizeof("\0int"),
977         .map_type = BPF_MAP_TYPE_ARRAY,
978         .map_name = "hdr_test_map",
979         .key_size = sizeof(int),
980         .value_size = sizeof(int),
981         .key_type_id = 1,
982         .value_type_id = 1,
983         .max_entries = 4,
984         .btf_load_err = true,
985         .str_off_delta = -4,
986         .err_str = "Section overlap found",
987 },
988
989 {
990         .descr = "btf_header test. Larger BTF size",
991         .raw_types = {
992                 /* int */                               /* [1] */
993                 BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),
994                 BTF_END_RAW,
995         },
996         .str_sec = "\0int",
997         .str_sec_size = sizeof("\0int"),
998         .map_type = BPF_MAP_TYPE_ARRAY,
999         .map_name = "hdr_test_map",
1000         .key_size = sizeof(int),
1001         .value_size = sizeof(int),
1002         .key_type_id = 1,
1003         .value_type_id = 1,
1004         .max_entries = 4,
1005         .btf_load_err = true,
1006         .str_len_delta = -4,
1007         .err_str = "Unsupported section found",
1008 },
1009
1010 {
1011         .descr = "btf_header test. Smaller BTF size",
1012         .raw_types = {
1013                 /* int */                               /* [1] */
1014                 BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),
1015                 BTF_END_RAW,
1016         },
1017         .str_sec = "\0int",
1018         .str_sec_size = sizeof("\0int"),
1019         .map_type = BPF_MAP_TYPE_ARRAY,
1020         .map_name = "hdr_test_map",
1021         .key_size = sizeof(int),
1022         .value_size = sizeof(int),
1023         .key_type_id = 1,
1024         .value_type_id = 1,
1025         .max_entries = 4,
1026         .btf_load_err = true,
1027         .str_len_delta = 4,
1028         .err_str = "Total section length too long",
1029 },
1030
1031 {
1032         .descr = "array test. index_type/elem_type \"int\"",
1033         .raw_types = {
1034                 /* int */                               /* [1] */
1035                 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
1036                 /* int[16] */                           /* [2] */
1037                 BTF_TYPE_ARRAY_ENC(1, 1, 16),
1038                 BTF_END_RAW,
1039         },
1040         .str_sec = "",
1041         .str_sec_size = sizeof(""),
1042         .map_type = BPF_MAP_TYPE_ARRAY,
1043         .map_name = "array_test_map",
1044         .key_size = sizeof(int),
1045         .value_size = sizeof(int),
1046         .key_type_id = 1,
1047         .value_type_id = 1,
1048         .max_entries = 4,
1049 },
1050
1051 {
1052         .descr = "array test. index_type/elem_type \"const int\"",
1053         .raw_types = {
1054                 /* int */                               /* [1] */
1055                 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
1056                 /* int[16] */                           /* [2] */
1057                 BTF_TYPE_ARRAY_ENC(3, 3, 16),
1058                 /* CONST type_id=1 */                   /* [3] */
1059                 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_CONST, 0, 0), 1),
1060                 BTF_END_RAW,
1061         },
1062         .str_sec = "",
1063         .str_sec_size = sizeof(""),
1064         .map_type = BPF_MAP_TYPE_ARRAY,
1065         .map_name = "array_test_map",
1066         .key_size = sizeof(int),
1067         .value_size = sizeof(int),
1068         .key_type_id = 1,
1069         .value_type_id = 1,
1070         .max_entries = 4,
1071 },
1072
1073 {
1074         .descr = "array test. index_type \"const int:31\"",
1075         .raw_types = {
1076                 /* int */                               /* [1] */
1077                 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
1078                 /* int:31 */                            /* [2] */
1079                 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 31, 4),
1080                 /* int[16] */                           /* [3] */
1081                 BTF_TYPE_ARRAY_ENC(1, 4, 16),
1082                 /* CONST type_id=2 */                   /* [4] */
1083                 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_CONST, 0, 0), 2),
1084                 BTF_END_RAW,
1085         },
1086         .str_sec = "",
1087         .str_sec_size = sizeof(""),
1088         .map_type = BPF_MAP_TYPE_ARRAY,
1089         .map_name = "array_test_map",
1090         .key_size = sizeof(int),
1091         .value_size = sizeof(int),
1092         .key_type_id = 1,
1093         .value_type_id = 1,
1094         .max_entries = 4,
1095         .btf_load_err = true,
1096         .err_str = "Invalid index",
1097 },
1098
1099 {
1100         .descr = "array test. elem_type \"const int:31\"",
1101         .raw_types = {
1102                 /* int */                               /* [1] */
1103                 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
1104                 /* int:31 */                            /* [2] */
1105                 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 31, 4),
1106                 /* int[16] */                           /* [3] */
1107                 BTF_TYPE_ARRAY_ENC(4, 1, 16),
1108                 /* CONST type_id=2 */                   /* [4] */
1109                 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_CONST, 0, 0), 2),
1110                 BTF_END_RAW,
1111         },
1112         .str_sec = "",
1113         .str_sec_size = sizeof(""),
1114         .map_type = BPF_MAP_TYPE_ARRAY,
1115         .map_name = "array_test_map",
1116         .key_size = sizeof(int),
1117         .value_size = sizeof(int),
1118         .key_type_id = 1,
1119         .value_type_id = 1,
1120         .max_entries = 4,
1121         .btf_load_err = true,
1122         .err_str = "Invalid array of int",
1123 },
1124
1125 {
1126         .descr = "array test. index_type \"void\"",
1127         .raw_types = {
1128                 /* int */                               /* [1] */
1129                 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
1130                 /* int[16] */                           /* [2] */
1131                 BTF_TYPE_ARRAY_ENC(1, 0, 16),
1132                 BTF_END_RAW,
1133         },
1134         .str_sec = "",
1135         .str_sec_size = sizeof(""),
1136         .map_type = BPF_MAP_TYPE_ARRAY,
1137         .map_name = "array_test_map",
1138         .key_size = sizeof(int),
1139         .value_size = sizeof(int),
1140         .key_type_id = 1,
1141         .value_type_id = 1,
1142         .max_entries = 4,
1143         .btf_load_err = true,
1144         .err_str = "Invalid index",
1145 },
1146
1147 {
1148         .descr = "array test. index_type \"const void\"",
1149         .raw_types = {
1150                 /* int */                               /* [1] */
1151                 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
1152                 /* int[16] */                           /* [2] */
1153                 BTF_TYPE_ARRAY_ENC(1, 3, 16),
1154                 /* CONST type_id=0 (void) */            /* [3] */
1155                 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_CONST, 0, 0), 0),
1156                 BTF_END_RAW,
1157         },
1158         .str_sec = "",
1159         .str_sec_size = sizeof(""),
1160         .map_type = BPF_MAP_TYPE_ARRAY,
1161         .map_name = "array_test_map",
1162         .key_size = sizeof(int),
1163         .value_size = sizeof(int),
1164         .key_type_id = 1,
1165         .value_type_id = 1,
1166         .max_entries = 4,
1167         .btf_load_err = true,
1168         .err_str = "Invalid index",
1169 },
1170
1171 {
1172         .descr = "array test. elem_type \"const void\"",
1173         .raw_types = {
1174                 /* int */                               /* [1] */
1175                 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
1176                 /* int[16] */                           /* [2] */
1177                 BTF_TYPE_ARRAY_ENC(3, 1, 16),
1178                 /* CONST type_id=0 (void) */            /* [3] */
1179                 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_CONST, 0, 0), 0),
1180                 BTF_END_RAW,
1181         },
1182         .str_sec = "",
1183         .str_sec_size = sizeof(""),
1184         .map_type = BPF_MAP_TYPE_ARRAY,
1185         .map_name = "array_test_map",
1186         .key_size = sizeof(int),
1187         .value_size = sizeof(int),
1188         .key_type_id = 1,
1189         .value_type_id = 1,
1190         .max_entries = 4,
1191         .btf_load_err = true,
1192         .err_str = "Invalid elem",
1193 },
1194
1195 {
1196         .descr = "array test. elem_type \"const void *\"",
1197         .raw_types = {
1198                 /* int */                               /* [1] */
1199                 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
1200                 /* const void *[16] */                  /* [2] */
1201                 BTF_TYPE_ARRAY_ENC(3, 1, 16),
1202                 /* CONST type_id=4 */                   /* [3] */
1203                 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_CONST, 0, 0), 4),
1204                 /* void* */                             /* [4] */
1205                 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_PTR, 0, 0), 0),
1206                 BTF_END_RAW,
1207         },
1208         .str_sec = "",
1209         .str_sec_size = sizeof(""),
1210         .map_type = BPF_MAP_TYPE_ARRAY,
1211         .map_name = "array_test_map",
1212         .key_size = sizeof(int),
1213         .value_size = sizeof(int),
1214         .key_type_id = 1,
1215         .value_type_id = 1,
1216         .max_entries = 4,
1217 },
1218
1219 {
1220         .descr = "array test. index_type \"const void *\"",
1221         .raw_types = {
1222                 /* int */                               /* [1] */
1223                 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
1224                 /* const void *[16] */                  /* [2] */
1225                 BTF_TYPE_ARRAY_ENC(3, 3, 16),
1226                 /* CONST type_id=4 */                   /* [3] */
1227                 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_CONST, 0, 0), 4),
1228                 /* void* */                             /* [4] */
1229                 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_PTR, 0, 0), 0),
1230                 BTF_END_RAW,
1231         },
1232         .str_sec = "",
1233         .str_sec_size = sizeof(""),
1234         .map_type = BPF_MAP_TYPE_ARRAY,
1235         .map_name = "array_test_map",
1236         .key_size = sizeof(int),
1237         .value_size = sizeof(int),
1238         .key_type_id = 1,
1239         .value_type_id = 1,
1240         .max_entries = 4,
1241         .btf_load_err = true,
1242         .err_str = "Invalid index",
1243 },
1244
1245 {
1246         .descr = "array test. t->size != 0\"",
1247         .raw_types = {
1248                 /* int */                               /* [1] */
1249                 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
1250                 /* int[16] */                           /* [2] */
1251                 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_ARRAY, 0, 0), 1),
1252                 BTF_ARRAY_ENC(1, 1, 16),
1253                 BTF_END_RAW,
1254         },
1255         .str_sec = "",
1256         .str_sec_size = sizeof(""),
1257         .map_type = BPF_MAP_TYPE_ARRAY,
1258         .map_name = "array_test_map",
1259         .key_size = sizeof(int),
1260         .value_size = sizeof(int),
1261         .key_type_id = 1,
1262         .value_type_id = 1,
1263         .max_entries = 4,
1264         .btf_load_err = true,
1265         .err_str = "size != 0",
1266 },
1267
1268 {
1269         .descr = "int test. invalid int_data",
1270         .raw_types = {
1271                 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_INT, 0, 0), 4),
1272                 0x10000000,
1273                 BTF_END_RAW,
1274         },
1275         .str_sec = "",
1276         .str_sec_size = sizeof(""),
1277         .map_type = BPF_MAP_TYPE_ARRAY,
1278         .map_name = "array_test_map",
1279         .key_size = sizeof(int),
1280         .value_size = sizeof(int),
1281         .key_type_id = 1,
1282         .value_type_id = 1,
1283         .max_entries = 4,
1284         .btf_load_err = true,
1285         .err_str = "Invalid int_data",
1286 },
1287
1288 {
1289         .descr = "invalid BTF_INFO",
1290         .raw_types = {
1291                 /* int */                               /* [1] */
1292                 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
1293                 BTF_TYPE_ENC(0, 0x10000000, 4),
1294                 BTF_END_RAW,
1295         },
1296         .str_sec = "",
1297         .str_sec_size = sizeof(""),
1298         .map_type = BPF_MAP_TYPE_ARRAY,
1299         .map_name = "array_test_map",
1300         .key_size = sizeof(int),
1301         .value_size = sizeof(int),
1302         .key_type_id = 1,
1303         .value_type_id = 1,
1304         .max_entries = 4,
1305         .btf_load_err = true,
1306         .err_str = "Invalid btf_info",
1307 },
1308
1309 {
1310         .descr = "fwd test. t->type != 0\"",
1311         .raw_types = {
1312                 /* int */                               /* [1] */
1313                 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
1314                 /* fwd type */                          /* [2] */
1315                 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_FWD, 0, 0), 1),
1316                 BTF_END_RAW,
1317         },
1318         .str_sec = "",
1319         .str_sec_size = sizeof(""),
1320         .map_type = BPF_MAP_TYPE_ARRAY,
1321         .map_name = "fwd_test_map",
1322         .key_size = sizeof(int),
1323         .value_size = sizeof(int),
1324         .key_type_id = 1,
1325         .value_type_id = 1,
1326         .max_entries = 4,
1327         .btf_load_err = true,
1328         .err_str = "type != 0",
1329 },
1330
1331 {
1332         .descr = "arraymap invalid btf key (a bit field)",
1333         .raw_types = {
1334                 /* int */                               /* [1] */
1335                 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
1336                 /* 32 bit int with 32 bit offset */     /* [2] */
1337                 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 32, 32, 8),
1338                 BTF_END_RAW,
1339         },
1340         .str_sec = "",
1341         .str_sec_size = sizeof(""),
1342         .map_type = BPF_MAP_TYPE_ARRAY,
1343         .map_name = "array_map_check_btf",
1344         .key_size = sizeof(int),
1345         .value_size = sizeof(int),
1346         .key_type_id = 2,
1347         .value_type_id = 1,
1348         .max_entries = 4,
1349         .map_create_err = true,
1350 },
1351
1352 {
1353         .descr = "arraymap invalid btf key (!= 32 bits)",
1354         .raw_types = {
1355                 /* int */                               /* [1] */
1356                 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
1357                 /* 16 bit int with 0 bit offset */      /* [2] */
1358                 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 16, 2),
1359                 BTF_END_RAW,
1360         },
1361         .str_sec = "",
1362         .str_sec_size = sizeof(""),
1363         .map_type = BPF_MAP_TYPE_ARRAY,
1364         .map_name = "array_map_check_btf",
1365         .key_size = sizeof(int),
1366         .value_size = sizeof(int),
1367         .key_type_id = 2,
1368         .value_type_id = 1,
1369         .max_entries = 4,
1370         .map_create_err = true,
1371 },
1372
1373 {
1374         .descr = "arraymap invalid btf value (too small)",
1375         .raw_types = {
1376                 /* int */                               /* [1] */
1377                 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
1378                 BTF_END_RAW,
1379         },
1380         .str_sec = "",
1381         .str_sec_size = sizeof(""),
1382         .map_type = BPF_MAP_TYPE_ARRAY,
1383         .map_name = "array_map_check_btf",
1384         .key_size = sizeof(int),
1385         /* btf_value_size < map->value_size */
1386         .value_size = sizeof(__u64),
1387         .key_type_id = 1,
1388         .value_type_id = 1,
1389         .max_entries = 4,
1390         .map_create_err = true,
1391 },
1392
1393 {
1394         .descr = "arraymap invalid btf value (too big)",
1395         .raw_types = {
1396                 /* int */                               /* [1] */
1397                 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
1398                 BTF_END_RAW,
1399         },
1400         .str_sec = "",
1401         .str_sec_size = sizeof(""),
1402         .map_type = BPF_MAP_TYPE_ARRAY,
1403         .map_name = "array_map_check_btf",
1404         .key_size = sizeof(int),
1405         /* btf_value_size > map->value_size */
1406         .value_size = sizeof(__u16),
1407         .key_type_id = 1,
1408         .value_type_id = 1,
1409         .max_entries = 4,
1410         .map_create_err = true,
1411 },
1412
1413 {
1414         .descr = "func proto (int (*)(int, unsigned int))",
1415         .raw_types = {
1416                 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
1417                 BTF_TYPE_INT_ENC(0, 0, 0, 32, 4),               /* [2] */
1418                 /* int (*)(int, unsigned int) */
1419                 BTF_FUNC_PROTO_ENC(1, 2),                       /* [3] */
1420                         BTF_FUNC_PROTO_ARG_ENC(0, 1),
1421                         BTF_FUNC_PROTO_ARG_ENC(0, 2),
1422                 BTF_END_RAW,
1423         },
1424         .str_sec = "",
1425         .str_sec_size = sizeof(""),
1426         .map_type = BPF_MAP_TYPE_ARRAY,
1427         .map_name = "func_proto_type_check_btf",
1428         .key_size = sizeof(int),
1429         .value_size = sizeof(int),
1430         .key_type_id = 1,
1431         .value_type_id = 1,
1432         .max_entries = 4,
1433 },
1434
1435 {
1436         .descr = "func proto (vararg)",
1437         .raw_types = {
1438                 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),  /* [1] */
1439                 BTF_TYPE_INT_ENC(0, 0, 0, 32, 4),               /* [2] */
1440                 /* void (*)(int, unsigned int, ...) */
1441                 BTF_FUNC_PROTO_ENC(0, 3),                       /* [3] */
1442                         BTF_FUNC_PROTO_ARG_ENC(0, 1),
1443                         BTF_FUNC_PROTO_ARG_ENC(0, 2),
1444                         BTF_FUNC_PROTO_ARG_ENC(0, 0),
1445                 BTF_END_RAW,
1446         },
1447         .str_sec = "",
1448         .str_sec_size = sizeof(""),
1449         .map_type = BPF_MAP_TYPE_ARRAY,
1450         .map_name = "func_proto_type_check_btf",
1451         .key_size = sizeof(int),
1452         .value_size = sizeof(int),
1453         .key_type_id = 1,
1454         .value_type_id = 1,
1455         .max_entries = 4,
1456 },
1457
1458 {
1459         .descr = "func proto (vararg with name)",
1460         .raw_types = {
1461                 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),  /* [1] */
1462                 BTF_TYPE_INT_ENC(0, 0, 0, 32, 4),               /* [2] */
1463                 /* void (*)(int a, unsigned int b, ... c) */
1464                 BTF_FUNC_PROTO_ENC(0, 3),                       /* [3] */
1465                         BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
1466                         BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 2),
1467                         BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 0),
1468                 BTF_END_RAW,
1469         },
1470         .str_sec = "\0a\0b\0c",
1471         .str_sec_size = sizeof("\0a\0b\0c"),
1472         .map_type = BPF_MAP_TYPE_ARRAY,
1473         .map_name = "func_proto_type_check_btf",
1474         .key_size = sizeof(int),
1475         .value_size = sizeof(int),
1476         .key_type_id = 1,
1477         .value_type_id = 1,
1478         .max_entries = 4,
1479         .btf_load_err = true,
1480         .err_str = "Invalid arg#3",
1481 },
1482
1483 {
1484         .descr = "func proto (arg after vararg)",
1485         .raw_types = {
1486                 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),  /* [1] */
1487                 BTF_TYPE_INT_ENC(0, 0, 0, 32, 4),               /* [2] */
1488                 /* void (*)(int a, ..., unsigned int b) */
1489                 BTF_FUNC_PROTO_ENC(0, 3),                       /* [3] */
1490                         BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
1491                         BTF_FUNC_PROTO_ARG_ENC(0, 0),
1492                         BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 2),
1493                 BTF_END_RAW,
1494         },
1495         .str_sec = "\0a\0b",
1496         .str_sec_size = sizeof("\0a\0b"),
1497         .map_type = BPF_MAP_TYPE_ARRAY,
1498         .map_name = "func_proto_type_check_btf",
1499         .key_size = sizeof(int),
1500         .value_size = sizeof(int),
1501         .key_type_id = 1,
1502         .value_type_id = 1,
1503         .max_entries = 4,
1504         .btf_load_err = true,
1505         .err_str = "Invalid arg#2",
1506 },
1507
1508 {
1509         .descr = "func proto (CONST=>TYPEDEF=>PTR=>FUNC_PROTO)",
1510         .raw_types = {
1511                 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),  /* [1] */
1512                 BTF_TYPE_INT_ENC(0, 0, 0, 32, 4),               /* [2] */
1513                 /* typedef void (*func_ptr)(int, unsigned int) */
1514                 BTF_TYPEDEF_ENC(NAME_TBD, 5),                   /* [3] */
1515                 /* const func_ptr */
1516                 BTF_CONST_ENC(3),                               /* [4] */
1517                 BTF_PTR_ENC(6),                                 /* [5] */
1518                 BTF_FUNC_PROTO_ENC(0, 2),                       /* [6] */
1519                         BTF_FUNC_PROTO_ARG_ENC(0, 1),
1520                         BTF_FUNC_PROTO_ARG_ENC(0, 2),
1521                 BTF_END_RAW,
1522         },
1523         .str_sec = "\0func_ptr",
1524         .str_sec_size = sizeof("\0func_ptr"),
1525         .map_type = BPF_MAP_TYPE_ARRAY,
1526         .map_name = "func_proto_type_check_btf",
1527         .key_size = sizeof(int),
1528         .value_size = sizeof(int),
1529         .key_type_id = 1,
1530         .value_type_id = 1,
1531         .max_entries = 4,
1532 },
1533
1534 {
1535         .descr = "func proto (CONST=>TYPEDEF=>FUNC_PROTO)",
1536         .raw_types = {
1537                 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),  /* [1] */
1538                 BTF_TYPE_INT_ENC(0, 0, 0, 32, 4),               /* [2] */
1539                 BTF_CONST_ENC(4),                               /* [3] */
1540                 BTF_TYPEDEF_ENC(NAME_TBD, 5),                   /* [4] */
1541                 BTF_FUNC_PROTO_ENC(0, 2),                       /* [5] */
1542                         BTF_FUNC_PROTO_ARG_ENC(0, 1),
1543                         BTF_FUNC_PROTO_ARG_ENC(0, 2),
1544                 BTF_END_RAW,
1545         },
1546         .str_sec = "\0func_typedef",
1547         .str_sec_size = sizeof("\0func_typedef"),
1548         .map_type = BPF_MAP_TYPE_ARRAY,
1549         .map_name = "func_proto_type_check_btf",
1550         .key_size = sizeof(int),
1551         .value_size = sizeof(int),
1552         .key_type_id = 1,
1553         .value_type_id = 1,
1554         .max_entries = 4,
1555         .btf_load_err = true,
1556         .err_str = "Invalid type_id",
1557 },
1558
1559 {
1560         .descr = "func proto (btf_resolve(arg))",
1561         .raw_types = {
1562                 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),  /* [1] */
1563                 /* void (*)(const void *) */
1564                 BTF_FUNC_PROTO_ENC(0, 1),                       /* [2] */
1565                         BTF_FUNC_PROTO_ARG_ENC(0, 3),
1566                 BTF_CONST_ENC(4),                               /* [3] */
1567                 BTF_PTR_ENC(0),                                 /* [4] */
1568                 BTF_END_RAW,
1569         },
1570         .str_sec = "",
1571         .str_sec_size = sizeof(""),
1572         .map_type = BPF_MAP_TYPE_ARRAY,
1573         .map_name = "func_proto_type_check_btf",
1574         .key_size = sizeof(int),
1575         .value_size = sizeof(int),
1576         .key_type_id = 1,
1577         .value_type_id = 1,
1578         .max_entries = 4,
1579 },
1580
1581 {
1582         .descr = "func proto (Not all arg has name)",
1583         .raw_types = {
1584                 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),  /* [1] */
1585                 BTF_TYPE_INT_ENC(0, 0, 0, 32, 4),               /* [2] */
1586                 /* void (*)(int, unsigned int b) */
1587                 BTF_FUNC_PROTO_ENC(0, 2),                       /* [3] */
1588                         BTF_FUNC_PROTO_ARG_ENC(0, 1),
1589                         BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 2),
1590                 BTF_END_RAW,
1591         },
1592         .str_sec = "\0b",
1593         .str_sec_size = sizeof("\0b"),
1594         .map_type = BPF_MAP_TYPE_ARRAY,
1595         .map_name = "func_proto_type_check_btf",
1596         .key_size = sizeof(int),
1597         .value_size = sizeof(int),
1598         .key_type_id = 1,
1599         .value_type_id = 1,
1600         .max_entries = 4,
1601 },
1602
1603 {
1604         .descr = "func proto (Bad arg name_off)",
1605         .raw_types = {
1606                 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),  /* [1] */
1607                 BTF_TYPE_INT_ENC(0, 0, 0, 32, 4),               /* [2] */
1608                 /* void (*)(int a, unsigned int <bad_name_off>) */
1609                 BTF_FUNC_PROTO_ENC(0, 2),                       /* [3] */
1610                         BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
1611                         BTF_FUNC_PROTO_ARG_ENC(0xffffffff, 2),
1612                 BTF_END_RAW,
1613         },
1614         .str_sec = "\0a",
1615         .str_sec_size = sizeof("\0a"),
1616         .map_type = BPF_MAP_TYPE_ARRAY,
1617         .map_name = "func_proto_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         .btf_load_err = true,
1624         .err_str = "Invalid arg#2",
1625 },
1626
1627 {
1628         .descr = "func proto (Bad arg name)",
1629         .raw_types = {
1630                 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),  /* [1] */
1631                 BTF_TYPE_INT_ENC(0, 0, 0, 32, 4),               /* [2] */
1632                 /* void (*)(int a, unsigned int !!!) */
1633                 BTF_FUNC_PROTO_ENC(0, 2),                       /* [3] */
1634                         BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
1635                         BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 2),
1636                 BTF_END_RAW,
1637         },
1638         .str_sec = "\0a\0!!!",
1639         .str_sec_size = sizeof("\0a\0!!!"),
1640         .map_type = BPF_MAP_TYPE_ARRAY,
1641         .map_name = "func_proto_type_check_btf",
1642         .key_size = sizeof(int),
1643         .value_size = sizeof(int),
1644         .key_type_id = 1,
1645         .value_type_id = 1,
1646         .max_entries = 4,
1647         .btf_load_err = true,
1648         .err_str = "Invalid arg#2",
1649 },
1650
1651 {
1652         .descr = "func proto (Invalid return type)",
1653         .raw_types = {
1654                 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),  /* [1] */
1655                 BTF_TYPE_INT_ENC(0, 0, 0, 32, 4),               /* [2] */
1656                 /* <bad_ret_type> (*)(int, unsigned int) */
1657                 BTF_FUNC_PROTO_ENC(100, 2),                     /* [3] */
1658                         BTF_FUNC_PROTO_ARG_ENC(0, 1),
1659                         BTF_FUNC_PROTO_ARG_ENC(0, 2),
1660                 BTF_END_RAW,
1661         },
1662         .str_sec = "",
1663         .str_sec_size = sizeof(""),
1664         .map_type = BPF_MAP_TYPE_ARRAY,
1665         .map_name = "func_proto_type_check_btf",
1666         .key_size = sizeof(int),
1667         .value_size = sizeof(int),
1668         .key_type_id = 1,
1669         .value_type_id = 1,
1670         .max_entries = 4,
1671         .btf_load_err = true,
1672         .err_str = "Invalid return type",
1673 },
1674
1675 {
1676         .descr = "func proto (with func name)",
1677         .raw_types = {
1678                 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),  /* [1] */
1679                 BTF_TYPE_INT_ENC(0, 0, 0, 32, 4),               /* [2] */
1680                 /* void func_proto(int, unsigned int) */
1681                 BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_FUNC_PROTO, 0, 2), 0),     /* [3] */
1682                         BTF_FUNC_PROTO_ARG_ENC(0, 1),
1683                         BTF_FUNC_PROTO_ARG_ENC(0, 2),
1684                 BTF_END_RAW,
1685         },
1686         .str_sec = "\0func_proto",
1687         .str_sec_size = sizeof("\0func_proto"),
1688         .map_type = BPF_MAP_TYPE_ARRAY,
1689         .map_name = "func_proto_type_check_btf",
1690         .key_size = sizeof(int),
1691         .value_size = sizeof(int),
1692         .key_type_id = 1,
1693         .value_type_id = 1,
1694         .max_entries = 4,
1695         .btf_load_err = true,
1696         .err_str = "Invalid name",
1697 },
1698
1699 {
1700         .descr = "func proto (const void arg)",
1701         .raw_types = {
1702                 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),  /* [1] */
1703                 BTF_TYPE_INT_ENC(0, 0, 0, 32, 4),               /* [2] */
1704                 /* void (*)(const void) */
1705                 BTF_FUNC_PROTO_ENC(0, 1),                       /* [3] */
1706                         BTF_FUNC_PROTO_ARG_ENC(0, 4),
1707                 BTF_CONST_ENC(0),                               /* [4] */
1708                 BTF_END_RAW,
1709         },
1710         .str_sec = "",
1711         .str_sec_size = sizeof(""),
1712         .map_type = BPF_MAP_TYPE_ARRAY,
1713         .map_name = "func_proto_type_check_btf",
1714         .key_size = sizeof(int),
1715         .value_size = sizeof(int),
1716         .key_type_id = 1,
1717         .value_type_id = 1,
1718         .max_entries = 4,
1719         .btf_load_err = true,
1720         .err_str = "Invalid arg#1",
1721 },
1722
1723 {
1724         .descr = "func (void func(int a, unsigned int b))",
1725         .raw_types = {
1726                 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),  /* [1] */
1727                 BTF_TYPE_INT_ENC(0, 0, 0, 32, 4),               /* [2] */
1728                 /* void (*)(int a, unsigned int b) */
1729                 BTF_FUNC_PROTO_ENC(0, 2),                       /* [3] */
1730                         BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
1731                         BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 2),
1732                 /* void func(int a, unsigned int b) */
1733                 BTF_FUNC_ENC(NAME_TBD, 3),                      /* [4] */
1734                 BTF_END_RAW,
1735         },
1736         .str_sec = "\0a\0b\0func",
1737         .str_sec_size = sizeof("\0a\0b\0func"),
1738         .map_type = BPF_MAP_TYPE_ARRAY,
1739         .map_name = "func_type_check_btf",
1740         .key_size = sizeof(int),
1741         .value_size = sizeof(int),
1742         .key_type_id = 1,
1743         .value_type_id = 1,
1744         .max_entries = 4,
1745 },
1746
1747 {
1748         .descr = "func (No func name)",
1749         .raw_types = {
1750                 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),  /* [1] */
1751                 BTF_TYPE_INT_ENC(0, 0, 0, 32, 4),               /* [2] */
1752                 /* void (*)(int a, unsigned int b) */
1753                 BTF_FUNC_PROTO_ENC(0, 2),                       /* [3] */
1754                         BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
1755                         BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 2),
1756                 /* void <no_name>(int a, unsigned int b) */
1757                 BTF_FUNC_ENC(0, 3),                             /* [4] */
1758                 BTF_END_RAW,
1759         },
1760         .str_sec = "\0a\0b",
1761         .str_sec_size = sizeof("\0a\0b"),
1762         .map_type = BPF_MAP_TYPE_ARRAY,
1763         .map_name = "func_type_check_btf",
1764         .key_size = sizeof(int),
1765         .value_size = sizeof(int),
1766         .key_type_id = 1,
1767         .value_type_id = 1,
1768         .max_entries = 4,
1769         .btf_load_err = true,
1770         .err_str = "Invalid name",
1771 },
1772
1773 {
1774         .descr = "func (Invalid func name)",
1775         .raw_types = {
1776                 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),  /* [1] */
1777                 BTF_TYPE_INT_ENC(0, 0, 0, 32, 4),               /* [2] */
1778                 /* void (*)(int a, unsigned int b) */
1779                 BTF_FUNC_PROTO_ENC(0, 2),                       /* [3] */
1780                         BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
1781                         BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 2),
1782                 /* void !!!(int a, unsigned int b) */
1783                 BTF_FUNC_ENC(NAME_TBD, 3),                      /* [4] */
1784                 BTF_END_RAW,
1785         },
1786         .str_sec = "\0a\0b\0!!!",
1787         .str_sec_size = sizeof("\0a\0b\0!!!"),
1788         .map_type = BPF_MAP_TYPE_ARRAY,
1789         .map_name = "func_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         .btf_load_err = true,
1796         .err_str = "Invalid name",
1797 },
1798
1799 {
1800         .descr = "func (Some arg has no name)",
1801         .raw_types = {
1802                 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),  /* [1] */
1803                 BTF_TYPE_INT_ENC(0, 0, 0, 32, 4),               /* [2] */
1804                 /* void (*)(int a, unsigned int) */
1805                 BTF_FUNC_PROTO_ENC(0, 2),                       /* [3] */
1806                         BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
1807                         BTF_FUNC_PROTO_ARG_ENC(0, 2),
1808                 /* void func(int a, unsigned int) */
1809                 BTF_FUNC_ENC(NAME_TBD, 3),                      /* [4] */
1810                 BTF_END_RAW,
1811         },
1812         .str_sec = "\0a\0func",
1813         .str_sec_size = sizeof("\0a\0func"),
1814         .map_type = BPF_MAP_TYPE_ARRAY,
1815         .map_name = "func_type_check_btf",
1816         .key_size = sizeof(int),
1817         .value_size = sizeof(int),
1818         .key_type_id = 1,
1819         .value_type_id = 1,
1820         .max_entries = 4,
1821         .btf_load_err = true,
1822         .err_str = "Invalid arg#2",
1823 },
1824
1825 {
1826         .descr = "func (Non zero vlen)",
1827         .raw_types = {
1828                 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),  /* [1] */
1829                 BTF_TYPE_INT_ENC(0, 0, 0, 32, 4),               /* [2] */
1830                 /* void (*)(int a, unsigned int b) */
1831                 BTF_FUNC_PROTO_ENC(0, 2),                       /* [3] */
1832                         BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
1833                         BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 2),
1834                 /* void func(int a, unsigned int b) */
1835                 BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_FUNC, 0, 2), 3),   /* [4] */
1836                 BTF_END_RAW,
1837         },
1838         .str_sec = "\0a\0b\0func",
1839         .str_sec_size = sizeof("\0a\0b\0func"),
1840         .map_type = BPF_MAP_TYPE_ARRAY,
1841         .map_name = "func_type_check_btf",
1842         .key_size = sizeof(int),
1843         .value_size = sizeof(int),
1844         .key_type_id = 1,
1845         .value_type_id = 1,
1846         .max_entries = 4,
1847         .btf_load_err = true,
1848         .err_str = "vlen != 0",
1849 },
1850
1851 {
1852         .descr = "func (Not referring to FUNC_PROTO)",
1853         .raw_types = {
1854                 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),  /* [1] */
1855                 BTF_FUNC_ENC(NAME_TBD, 1),                      /* [2] */
1856                 BTF_END_RAW,
1857         },
1858         .str_sec = "\0func",
1859         .str_sec_size = sizeof("\0func"),
1860         .map_type = BPF_MAP_TYPE_ARRAY,
1861         .map_name = "func_type_check_btf",
1862         .key_size = sizeof(int),
1863         .value_size = sizeof(int),
1864         .key_type_id = 1,
1865         .value_type_id = 1,
1866         .max_entries = 4,
1867         .btf_load_err = true,
1868         .err_str = "Invalid type_id",
1869 },
1870
1871 }; /* struct btf_raw_test raw_tests[] */
1872
1873 static const char *get_next_str(const char *start, const char *end)
1874 {
1875         return start < end - 1 ? start + 1 : NULL;
1876 }
1877
1878 static int get_type_sec_size(const __u32 *raw_types)
1879 {
1880         int i;
1881
1882         for (i = MAX_NR_RAW_TYPES - 1;
1883              i >= 0 && raw_types[i] != BTF_END_RAW;
1884              i--)
1885                 ;
1886
1887         return i < 0 ? i : i * sizeof(raw_types[0]);
1888 }
1889
1890 static void *btf_raw_create(const struct btf_header *hdr,
1891                             const __u32 *raw_types,
1892                             const char *str,
1893                             unsigned int str_sec_size,
1894                             unsigned int *btf_size)
1895 {
1896         const char *next_str = str, *end_str = str + str_sec_size;
1897         unsigned int size_needed, offset;
1898         struct btf_header *ret_hdr;
1899         int i, type_sec_size;
1900         uint32_t *ret_types;
1901         void *raw_btf;
1902
1903         type_sec_size = get_type_sec_size(raw_types);
1904         if (CHECK(type_sec_size < 0, "Cannot get nr_raw_types"))
1905                 return NULL;
1906
1907         size_needed = sizeof(*hdr) + type_sec_size + str_sec_size;
1908         raw_btf = malloc(size_needed);
1909         if (CHECK(!raw_btf, "Cannot allocate memory for raw_btf"))
1910                 return NULL;
1911
1912         /* Copy header */
1913         memcpy(raw_btf, hdr, sizeof(*hdr));
1914         offset = sizeof(*hdr);
1915
1916         /* Copy type section */
1917         ret_types = raw_btf + offset;
1918         for (i = 0; i < type_sec_size / sizeof(raw_types[0]); i++) {
1919                 if (raw_types[i] == NAME_TBD) {
1920                         next_str = get_next_str(next_str, end_str);
1921                         if (CHECK(!next_str, "Error in getting next_str")) {
1922                                 free(raw_btf);
1923                                 return NULL;
1924                         }
1925                         ret_types[i] = next_str - str;
1926                         next_str += strlen(next_str);
1927                 } else {
1928                         ret_types[i] = raw_types[i];
1929                 }
1930         }
1931         offset += type_sec_size;
1932
1933         /* Copy string section */
1934         memcpy(raw_btf + offset, str, str_sec_size);
1935
1936         ret_hdr = (struct btf_header *)raw_btf;
1937         ret_hdr->type_len = type_sec_size;
1938         ret_hdr->str_off = type_sec_size;
1939         ret_hdr->str_len = str_sec_size;
1940
1941         *btf_size = size_needed;
1942
1943         return raw_btf;
1944 }
1945
1946 static int do_test_raw(unsigned int test_num)
1947 {
1948         struct btf_raw_test *test = &raw_tests[test_num - 1];
1949         struct bpf_create_map_attr create_attr = {};
1950         int map_fd = -1, btf_fd = -1;
1951         unsigned int raw_btf_size;
1952         struct btf_header *hdr;
1953         void *raw_btf;
1954         int err;
1955
1956         fprintf(stderr, "BTF raw test[%u] (%s): ", test_num, test->descr);
1957         raw_btf = btf_raw_create(&hdr_tmpl,
1958                                  test->raw_types,
1959                                  test->str_sec,
1960                                  test->str_sec_size,
1961                                  &raw_btf_size);
1962
1963         if (!raw_btf)
1964                 return -1;
1965
1966         hdr = raw_btf;
1967
1968         hdr->hdr_len = (int)hdr->hdr_len + test->hdr_len_delta;
1969         hdr->type_off = (int)hdr->type_off + test->type_off_delta;
1970         hdr->str_off = (int)hdr->str_off + test->str_off_delta;
1971         hdr->str_len = (int)hdr->str_len + test->str_len_delta;
1972
1973         *btf_log_buf = '\0';
1974         btf_fd = bpf_load_btf(raw_btf, raw_btf_size,
1975                               btf_log_buf, BTF_LOG_BUF_SIZE,
1976                               args.always_log);
1977         free(raw_btf);
1978
1979         err = ((btf_fd == -1) != test->btf_load_err);
1980         if (CHECK(err, "btf_fd:%d test->btf_load_err:%u",
1981                   btf_fd, test->btf_load_err) ||
1982             CHECK(test->err_str && !strstr(btf_log_buf, test->err_str),
1983                   "expected err_str:%s", test->err_str)) {
1984                 err = -1;
1985                 goto done;
1986         }
1987
1988         if (err || btf_fd == -1)
1989                 goto done;
1990
1991         create_attr.name = test->map_name;
1992         create_attr.map_type = test->map_type;
1993         create_attr.key_size = test->key_size;
1994         create_attr.value_size = test->value_size;
1995         create_attr.max_entries = test->max_entries;
1996         create_attr.btf_fd = btf_fd;
1997         create_attr.btf_key_type_id = test->key_type_id;
1998         create_attr.btf_value_type_id = test->value_type_id;
1999
2000         map_fd = bpf_create_map_xattr(&create_attr);
2001
2002         err = ((map_fd == -1) != test->map_create_err);
2003         CHECK(err, "map_fd:%d test->map_create_err:%u",
2004               map_fd, test->map_create_err);
2005
2006 done:
2007         if (!err)
2008                 fprintf(stderr, "OK");
2009
2010         if (*btf_log_buf && (err || args.always_log))
2011                 fprintf(stderr, "\n%s", btf_log_buf);
2012
2013         if (btf_fd != -1)
2014                 close(btf_fd);
2015         if (map_fd != -1)
2016                 close(map_fd);
2017
2018         return err;
2019 }
2020
2021 static int test_raw(void)
2022 {
2023         unsigned int i;
2024         int err = 0;
2025
2026         if (args.raw_test_num)
2027                 return count_result(do_test_raw(args.raw_test_num));
2028
2029         for (i = 1; i <= ARRAY_SIZE(raw_tests); i++)
2030                 err |= count_result(do_test_raw(i));
2031
2032         return err;
2033 }
2034
2035 struct btf_get_info_test {
2036         const char *descr;
2037         const char *str_sec;
2038         __u32 raw_types[MAX_NR_RAW_TYPES];
2039         __u32 str_sec_size;
2040         int btf_size_delta;
2041         int (*special_test)(unsigned int test_num);
2042 };
2043
2044 static int test_big_btf_info(unsigned int test_num);
2045 static int test_btf_id(unsigned int test_num);
2046
2047 const struct btf_get_info_test get_info_tests[] = {
2048 {
2049         .descr = "== raw_btf_size+1",
2050         .raw_types = {
2051                 /* int */                               /* [1] */
2052                 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
2053                 BTF_END_RAW,
2054         },
2055         .str_sec = "",
2056         .str_sec_size = sizeof(""),
2057         .btf_size_delta = 1,
2058 },
2059 {
2060         .descr = "== raw_btf_size-3",
2061         .raw_types = {
2062                 /* int */                               /* [1] */
2063                 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
2064                 BTF_END_RAW,
2065         },
2066         .str_sec = "",
2067         .str_sec_size = sizeof(""),
2068         .btf_size_delta = -3,
2069 },
2070 {
2071         .descr = "Large bpf_btf_info",
2072         .raw_types = {
2073                 /* int */                               /* [1] */
2074                 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
2075                 BTF_END_RAW,
2076         },
2077         .str_sec = "",
2078         .str_sec_size = sizeof(""),
2079         .special_test = test_big_btf_info,
2080 },
2081 {
2082         .descr = "BTF ID",
2083         .raw_types = {
2084                 /* int */                               /* [1] */
2085                 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
2086                 /* unsigned int */                      /* [2] */
2087                 BTF_TYPE_INT_ENC(0, 0, 0, 32, 4),
2088                 BTF_END_RAW,
2089         },
2090         .str_sec = "",
2091         .str_sec_size = sizeof(""),
2092         .special_test = test_btf_id,
2093 },
2094 };
2095
2096 static inline __u64 ptr_to_u64(const void *ptr)
2097 {
2098         return (__u64)(unsigned long)ptr;
2099 }
2100
2101 static int test_big_btf_info(unsigned int test_num)
2102 {
2103         const struct btf_get_info_test *test = &get_info_tests[test_num - 1];
2104         uint8_t *raw_btf = NULL, *user_btf = NULL;
2105         unsigned int raw_btf_size;
2106         struct {
2107                 struct bpf_btf_info info;
2108                 uint64_t garbage;
2109         } info_garbage;
2110         struct bpf_btf_info *info;
2111         int btf_fd = -1, err;
2112         uint32_t info_len;
2113
2114         raw_btf = btf_raw_create(&hdr_tmpl,
2115                                  test->raw_types,
2116                                  test->str_sec,
2117                                  test->str_sec_size,
2118                                  &raw_btf_size);
2119
2120         if (!raw_btf)
2121                 return -1;
2122
2123         *btf_log_buf = '\0';
2124
2125         user_btf = malloc(raw_btf_size);
2126         if (CHECK(!user_btf, "!user_btf")) {
2127                 err = -1;
2128                 goto done;
2129         }
2130
2131         btf_fd = bpf_load_btf(raw_btf, raw_btf_size,
2132                               btf_log_buf, BTF_LOG_BUF_SIZE,
2133                               args.always_log);
2134         if (CHECK(btf_fd == -1, "errno:%d", errno)) {
2135                 err = -1;
2136                 goto done;
2137         }
2138
2139         /*
2140          * GET_INFO should error out if the userspace info
2141          * has non zero tailing bytes.
2142          */
2143         info = &info_garbage.info;
2144         memset(info, 0, sizeof(*info));
2145         info_garbage.garbage = 0xdeadbeef;
2146         info_len = sizeof(info_garbage);
2147         info->btf = ptr_to_u64(user_btf);
2148         info->btf_size = raw_btf_size;
2149
2150         err = bpf_obj_get_info_by_fd(btf_fd, info, &info_len);
2151         if (CHECK(!err, "!err")) {
2152                 err = -1;
2153                 goto done;
2154         }
2155
2156         /*
2157          * GET_INFO should succeed even info_len is larger than
2158          * the kernel supported as long as tailing bytes are zero.
2159          * The kernel supported info len should also be returned
2160          * to userspace.
2161          */
2162         info_garbage.garbage = 0;
2163         err = bpf_obj_get_info_by_fd(btf_fd, info, &info_len);
2164         if (CHECK(err || info_len != sizeof(*info),
2165                   "err:%d errno:%d info_len:%u sizeof(*info):%lu",
2166                   err, errno, info_len, sizeof(*info))) {
2167                 err = -1;
2168                 goto done;
2169         }
2170
2171         fprintf(stderr, "OK");
2172
2173 done:
2174         if (*btf_log_buf && (err || args.always_log))
2175                 fprintf(stderr, "\n%s", btf_log_buf);
2176
2177         free(raw_btf);
2178         free(user_btf);
2179
2180         if (btf_fd != -1)
2181                 close(btf_fd);
2182
2183         return err;
2184 }
2185
2186 static int test_btf_id(unsigned int test_num)
2187 {
2188         const struct btf_get_info_test *test = &get_info_tests[test_num - 1];
2189         struct bpf_create_map_attr create_attr = {};
2190         uint8_t *raw_btf = NULL, *user_btf[2] = {};
2191         int btf_fd[2] = {-1, -1}, map_fd = -1;
2192         struct bpf_map_info map_info = {};
2193         struct bpf_btf_info info[2] = {};
2194         unsigned int raw_btf_size;
2195         uint32_t info_len;
2196         int err, i, ret;
2197
2198         raw_btf = btf_raw_create(&hdr_tmpl,
2199                                  test->raw_types,
2200                                  test->str_sec,
2201                                  test->str_sec_size,
2202                                  &raw_btf_size);
2203
2204         if (!raw_btf)
2205                 return -1;
2206
2207         *btf_log_buf = '\0';
2208
2209         for (i = 0; i < 2; i++) {
2210                 user_btf[i] = malloc(raw_btf_size);
2211                 if (CHECK(!user_btf[i], "!user_btf[%d]", i)) {
2212                         err = -1;
2213                         goto done;
2214                 }
2215                 info[i].btf = ptr_to_u64(user_btf[i]);
2216                 info[i].btf_size = raw_btf_size;
2217         }
2218
2219         btf_fd[0] = bpf_load_btf(raw_btf, raw_btf_size,
2220                                  btf_log_buf, BTF_LOG_BUF_SIZE,
2221                                  args.always_log);
2222         if (CHECK(btf_fd[0] == -1, "errno:%d", errno)) {
2223                 err = -1;
2224                 goto done;
2225         }
2226
2227         /* Test BPF_OBJ_GET_INFO_BY_ID on btf_id */
2228         info_len = sizeof(info[0]);
2229         err = bpf_obj_get_info_by_fd(btf_fd[0], &info[0], &info_len);
2230         if (CHECK(err, "errno:%d", errno)) {
2231                 err = -1;
2232                 goto done;
2233         }
2234
2235         btf_fd[1] = bpf_btf_get_fd_by_id(info[0].id);
2236         if (CHECK(btf_fd[1] == -1, "errno:%d", errno)) {
2237                 err = -1;
2238                 goto done;
2239         }
2240
2241         ret = 0;
2242         err = bpf_obj_get_info_by_fd(btf_fd[1], &info[1], &info_len);
2243         if (CHECK(err || info[0].id != info[1].id ||
2244                   info[0].btf_size != info[1].btf_size ||
2245                   (ret = memcmp(user_btf[0], user_btf[1], info[0].btf_size)),
2246                   "err:%d errno:%d id0:%u id1:%u btf_size0:%u btf_size1:%u memcmp:%d",
2247                   err, errno, info[0].id, info[1].id,
2248                   info[0].btf_size, info[1].btf_size, ret)) {
2249                 err = -1;
2250                 goto done;
2251         }
2252
2253         /* Test btf members in struct bpf_map_info */
2254         create_attr.name = "test_btf_id";
2255         create_attr.map_type = BPF_MAP_TYPE_ARRAY;
2256         create_attr.key_size = sizeof(int);
2257         create_attr.value_size = sizeof(unsigned int);
2258         create_attr.max_entries = 4;
2259         create_attr.btf_fd = btf_fd[0];
2260         create_attr.btf_key_type_id = 1;
2261         create_attr.btf_value_type_id = 2;
2262
2263         map_fd = bpf_create_map_xattr(&create_attr);
2264         if (CHECK(map_fd == -1, "errno:%d", errno)) {
2265                 err = -1;
2266                 goto done;
2267         }
2268
2269         info_len = sizeof(map_info);
2270         err = bpf_obj_get_info_by_fd(map_fd, &map_info, &info_len);
2271         if (CHECK(err || map_info.btf_id != info[0].id ||
2272                   map_info.btf_key_type_id != 1 || map_info.btf_value_type_id != 2,
2273                   "err:%d errno:%d info.id:%u btf_id:%u btf_key_type_id:%u btf_value_type_id:%u",
2274                   err, errno, info[0].id, map_info.btf_id, map_info.btf_key_type_id,
2275                   map_info.btf_value_type_id)) {
2276                 err = -1;
2277                 goto done;
2278         }
2279
2280         for (i = 0; i < 2; i++) {
2281                 close(btf_fd[i]);
2282                 btf_fd[i] = -1;
2283         }
2284
2285         /* Test BTF ID is removed from the kernel */
2286         btf_fd[0] = bpf_btf_get_fd_by_id(map_info.btf_id);
2287         if (CHECK(btf_fd[0] == -1, "errno:%d", errno)) {
2288                 err = -1;
2289                 goto done;
2290         }
2291         close(btf_fd[0]);
2292         btf_fd[0] = -1;
2293
2294         /* The map holds the last ref to BTF and its btf_id */
2295         close(map_fd);
2296         map_fd = -1;
2297         btf_fd[0] = bpf_btf_get_fd_by_id(map_info.btf_id);
2298         if (CHECK(btf_fd[0] != -1, "BTF lingers")) {
2299                 err = -1;
2300                 goto done;
2301         }
2302
2303         fprintf(stderr, "OK");
2304
2305 done:
2306         if (*btf_log_buf && (err || args.always_log))
2307                 fprintf(stderr, "\n%s", btf_log_buf);
2308
2309         free(raw_btf);
2310         if (map_fd != -1)
2311                 close(map_fd);
2312         for (i = 0; i < 2; i++) {
2313                 free(user_btf[i]);
2314                 if (btf_fd[i] != -1)
2315                         close(btf_fd[i]);
2316         }
2317
2318         return err;
2319 }
2320
2321 static int do_test_get_info(unsigned int test_num)
2322 {
2323         const struct btf_get_info_test *test = &get_info_tests[test_num - 1];
2324         unsigned int raw_btf_size, user_btf_size, expected_nbytes;
2325         uint8_t *raw_btf = NULL, *user_btf = NULL;
2326         struct bpf_btf_info info = {};
2327         int btf_fd = -1, err, ret;
2328         uint32_t info_len;
2329
2330         fprintf(stderr, "BTF GET_INFO test[%u] (%s): ",
2331                 test_num, test->descr);
2332
2333         if (test->special_test)
2334                 return test->special_test(test_num);
2335
2336         raw_btf = btf_raw_create(&hdr_tmpl,
2337                                  test->raw_types,
2338                                  test->str_sec,
2339                                  test->str_sec_size,
2340                                  &raw_btf_size);
2341
2342         if (!raw_btf)
2343                 return -1;
2344
2345         *btf_log_buf = '\0';
2346
2347         user_btf = malloc(raw_btf_size);
2348         if (CHECK(!user_btf, "!user_btf")) {
2349                 err = -1;
2350                 goto done;
2351         }
2352
2353         btf_fd = bpf_load_btf(raw_btf, raw_btf_size,
2354                               btf_log_buf, BTF_LOG_BUF_SIZE,
2355                               args.always_log);
2356         if (CHECK(btf_fd == -1, "errno:%d", errno)) {
2357                 err = -1;
2358                 goto done;
2359         }
2360
2361         user_btf_size = (int)raw_btf_size + test->btf_size_delta;
2362         expected_nbytes = min(raw_btf_size, user_btf_size);
2363         if (raw_btf_size > expected_nbytes)
2364                 memset(user_btf + expected_nbytes, 0xff,
2365                        raw_btf_size - expected_nbytes);
2366
2367         info_len = sizeof(info);
2368         info.btf = ptr_to_u64(user_btf);
2369         info.btf_size = user_btf_size;
2370
2371         ret = 0;
2372         err = bpf_obj_get_info_by_fd(btf_fd, &info, &info_len);
2373         if (CHECK(err || !info.id || info_len != sizeof(info) ||
2374                   info.btf_size != raw_btf_size ||
2375                   (ret = memcmp(raw_btf, user_btf, expected_nbytes)),
2376                   "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",
2377                   err, errno, info.id, info_len, sizeof(info),
2378                   raw_btf_size, info.btf_size, expected_nbytes, ret)) {
2379                 err = -1;
2380                 goto done;
2381         }
2382
2383         while (expected_nbytes < raw_btf_size) {
2384                 fprintf(stderr, "%u...", expected_nbytes);
2385                 if (CHECK(user_btf[expected_nbytes++] != 0xff,
2386                           "user_btf[%u]:%x != 0xff", expected_nbytes - 1,
2387                           user_btf[expected_nbytes - 1])) {
2388                         err = -1;
2389                         goto done;
2390                 }
2391         }
2392
2393         fprintf(stderr, "OK");
2394
2395 done:
2396         if (*btf_log_buf && (err || args.always_log))
2397                 fprintf(stderr, "\n%s", btf_log_buf);
2398
2399         free(raw_btf);
2400         free(user_btf);
2401
2402         if (btf_fd != -1)
2403                 close(btf_fd);
2404
2405         return err;
2406 }
2407
2408 static int test_get_info(void)
2409 {
2410         unsigned int i;
2411         int err = 0;
2412
2413         if (args.get_info_test_num)
2414                 return count_result(do_test_get_info(args.get_info_test_num));
2415
2416         for (i = 1; i <= ARRAY_SIZE(get_info_tests); i++)
2417                 err |= count_result(do_test_get_info(i));
2418
2419         return err;
2420 }
2421
2422 struct btf_file_test {
2423         const char *file;
2424         bool btf_kv_notfound;
2425 };
2426
2427 static struct btf_file_test file_tests[] = {
2428 {
2429         .file = "test_btf_haskv.o",
2430 },
2431 {
2432         .file = "test_btf_nokv.o",
2433         .btf_kv_notfound = true,
2434 },
2435 };
2436
2437 static int file_has_btf_elf(const char *fn)
2438 {
2439         Elf_Scn *scn = NULL;
2440         GElf_Ehdr ehdr;
2441         int elf_fd;
2442         Elf *elf;
2443         int ret;
2444
2445         if (CHECK(elf_version(EV_CURRENT) == EV_NONE,
2446                   "elf_version(EV_CURRENT) == EV_NONE"))
2447                 return -1;
2448
2449         elf_fd = open(fn, O_RDONLY);
2450         if (CHECK(elf_fd == -1, "open(%s): errno:%d", fn, errno))
2451                 return -1;
2452
2453         elf = elf_begin(elf_fd, ELF_C_READ, NULL);
2454         if (CHECK(!elf, "elf_begin(%s): %s", fn, elf_errmsg(elf_errno()))) {
2455                 ret = -1;
2456                 goto done;
2457         }
2458
2459         if (CHECK(!gelf_getehdr(elf, &ehdr), "!gelf_getehdr(%s)", fn)) {
2460                 ret = -1;
2461                 goto done;
2462         }
2463
2464         while ((scn = elf_nextscn(elf, scn))) {
2465                 const char *sh_name;
2466                 GElf_Shdr sh;
2467
2468                 if (CHECK(gelf_getshdr(scn, &sh) != &sh,
2469                           "file:%s gelf_getshdr != &sh", fn)) {
2470                         ret = -1;
2471                         goto done;
2472                 }
2473
2474                 sh_name = elf_strptr(elf, ehdr.e_shstrndx, sh.sh_name);
2475                 if (!strcmp(sh_name, BTF_ELF_SEC)) {
2476                         ret = 1;
2477                         goto done;
2478                 }
2479         }
2480
2481         ret = 0;
2482
2483 done:
2484         close(elf_fd);
2485         elf_end(elf);
2486         return ret;
2487 }
2488
2489 static int do_test_file(unsigned int test_num)
2490 {
2491         const struct btf_file_test *test = &file_tests[test_num - 1];
2492         struct bpf_object *obj = NULL;
2493         struct bpf_program *prog;
2494         struct bpf_map *map;
2495         int err;
2496
2497         fprintf(stderr, "BTF libbpf test[%u] (%s): ", test_num,
2498                 test->file);
2499
2500         err = file_has_btf_elf(test->file);
2501         if (err == -1)
2502                 return err;
2503
2504         if (err == 0) {
2505                 fprintf(stderr, "SKIP. No ELF %s found", BTF_ELF_SEC);
2506                 skip_cnt++;
2507                 return 0;
2508         }
2509
2510         obj = bpf_object__open(test->file);
2511         if (CHECK(IS_ERR(obj), "obj: %ld", PTR_ERR(obj)))
2512                 return PTR_ERR(obj);
2513
2514         err = bpf_object__btf_fd(obj);
2515         if (CHECK(err == -1, "bpf_object__btf_fd: -1"))
2516                 goto done;
2517
2518         prog = bpf_program__next(NULL, obj);
2519         if (CHECK(!prog, "Cannot find bpf_prog")) {
2520                 err = -1;
2521                 goto done;
2522         }
2523
2524         bpf_program__set_type(prog, BPF_PROG_TYPE_TRACEPOINT);
2525         err = bpf_object__load(obj);
2526         if (CHECK(err < 0, "bpf_object__load: %d", err))
2527                 goto done;
2528
2529         map = bpf_object__find_map_by_name(obj, "btf_map");
2530         if (CHECK(!map, "btf_map not found")) {
2531                 err = -1;
2532                 goto done;
2533         }
2534
2535         err = (bpf_map__btf_key_type_id(map) == 0 || bpf_map__btf_value_type_id(map) == 0)
2536                 != test->btf_kv_notfound;
2537         if (CHECK(err, "btf_key_type_id:%u btf_value_type_id:%u test->btf_kv_notfound:%u",
2538                   bpf_map__btf_key_type_id(map), bpf_map__btf_value_type_id(map),
2539                   test->btf_kv_notfound))
2540                 goto done;
2541
2542         fprintf(stderr, "OK");
2543
2544 done:
2545         bpf_object__close(obj);
2546         return err;
2547 }
2548
2549 static int test_file(void)
2550 {
2551         unsigned int i;
2552         int err = 0;
2553
2554         if (args.file_test_num)
2555                 return count_result(do_test_file(args.file_test_num));
2556
2557         for (i = 1; i <= ARRAY_SIZE(file_tests); i++)
2558                 err |= count_result(do_test_file(i));
2559
2560         return err;
2561 }
2562
2563 const char *pprint_enum_str[] = {
2564         "ENUM_ZERO",
2565         "ENUM_ONE",
2566         "ENUM_TWO",
2567         "ENUM_THREE",
2568 };
2569
2570 struct pprint_mapv {
2571         uint32_t ui32;
2572         uint16_t ui16;
2573         /* 2 bytes hole */
2574         int32_t si32;
2575         uint32_t unused_bits2a:2,
2576                 bits28:28,
2577                 unused_bits2b:2;
2578         union {
2579                 uint64_t ui64;
2580                 uint8_t ui8a[8];
2581         };
2582         enum {
2583                 ENUM_ZERO,
2584                 ENUM_ONE,
2585                 ENUM_TWO,
2586                 ENUM_THREE,
2587         } aenum;
2588 };
2589
2590 static struct btf_raw_test pprint_test_template = {
2591         .raw_types = {
2592                 /* unsighed char */                     /* [1] */
2593                 BTF_TYPE_INT_ENC(NAME_TBD, 0, 0, 8, 1),
2594                 /* unsigned short */                    /* [2] */
2595                 BTF_TYPE_INT_ENC(NAME_TBD, 0, 0, 16, 2),
2596                 /* unsigned int */                      /* [3] */
2597                 BTF_TYPE_INT_ENC(NAME_TBD, 0, 0, 32, 4),
2598                 /* int */                               /* [4] */
2599                 BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),
2600                 /* unsigned long long */                /* [5] */
2601                 BTF_TYPE_INT_ENC(NAME_TBD, 0, 0, 64, 8),
2602                 /* 2 bits */                            /* [6] */
2603                 BTF_TYPE_INT_ENC(0, 0, 0, 2, 2),
2604                 /* 28 bits */                           /* [7] */
2605                 BTF_TYPE_INT_ENC(0, 0, 0, 28, 4),
2606                 /* uint8_t[8] */                        /* [8] */
2607                 BTF_TYPE_ARRAY_ENC(9, 1, 8),
2608                 /* typedef unsigned char uint8_t */     /* [9] */
2609                 BTF_TYPEDEF_ENC(NAME_TBD, 1),
2610                 /* typedef unsigned short uint16_t */   /* [10] */
2611                 BTF_TYPEDEF_ENC(NAME_TBD, 2),
2612                 /* typedef unsigned int uint32_t */     /* [11] */
2613                 BTF_TYPEDEF_ENC(NAME_TBD, 3),
2614                 /* typedef int int32_t */               /* [12] */
2615                 BTF_TYPEDEF_ENC(NAME_TBD, 4),
2616                 /* typedef unsigned long long uint64_t *//* [13] */
2617                 BTF_TYPEDEF_ENC(NAME_TBD, 5),
2618                 /* union (anon) */                      /* [14] */
2619                 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_UNION, 0, 2), 8),
2620                 BTF_MEMBER_ENC(NAME_TBD, 13, 0),/* uint64_t ui64; */
2621                 BTF_MEMBER_ENC(NAME_TBD, 8, 0), /* uint8_t ui8a[8]; */
2622                 /* enum (anon) */                       /* [15] */
2623                 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_ENUM, 0, 4), 4),
2624                 BTF_ENUM_ENC(NAME_TBD, 0),
2625                 BTF_ENUM_ENC(NAME_TBD, 1),
2626                 BTF_ENUM_ENC(NAME_TBD, 2),
2627                 BTF_ENUM_ENC(NAME_TBD, 3),
2628                 /* struct pprint_mapv */                /* [16] */
2629                 BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 8), 32),
2630                 BTF_MEMBER_ENC(NAME_TBD, 11, 0),        /* uint32_t ui32 */
2631                 BTF_MEMBER_ENC(NAME_TBD, 10, 32),       /* uint16_t ui16 */
2632                 BTF_MEMBER_ENC(NAME_TBD, 12, 64),       /* int32_t si32 */
2633                 BTF_MEMBER_ENC(NAME_TBD, 6, 96),        /* unused_bits2a */
2634                 BTF_MEMBER_ENC(NAME_TBD, 7, 98),        /* bits28 */
2635                 BTF_MEMBER_ENC(NAME_TBD, 6, 126),       /* unused_bits2b */
2636                 BTF_MEMBER_ENC(0, 14, 128),             /* union (anon) */
2637                 BTF_MEMBER_ENC(NAME_TBD, 15, 192),      /* aenum */
2638                 BTF_END_RAW,
2639         },
2640         .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",
2641         .str_sec_size = sizeof("\0unsigned char\0unsigned short\0unsigned int\0int\0unsigned long long\0uint8_t\0uint16_t\0uint32_t\0int32_t\0uint64_t\0ui64\0ui8a\0ENUM_ZERO\0ENUM_ONE\0ENUM_TWO\0ENUM_THREE\0pprint_mapv\0ui32\0ui16\0si32\0unused_bits2a\0bits28\0unused_bits2b\0aenum"),
2642         .key_size = sizeof(unsigned int),
2643         .value_size = sizeof(struct pprint_mapv),
2644         .key_type_id = 3,       /* unsigned int */
2645         .value_type_id = 16,    /* struct pprint_mapv */
2646         .max_entries = 128 * 1024,
2647 };
2648
2649 static struct btf_pprint_test_meta {
2650         const char *descr;
2651         enum bpf_map_type map_type;
2652         const char *map_name;
2653         bool ordered_map;
2654         bool lossless_map;
2655         bool percpu_map;
2656 } pprint_tests_meta[] = {
2657 {
2658         .descr = "BTF pretty print array",
2659         .map_type = BPF_MAP_TYPE_ARRAY,
2660         .map_name = "pprint_test_array",
2661         .ordered_map = true,
2662         .lossless_map = true,
2663         .percpu_map = false,
2664 },
2665
2666 {
2667         .descr = "BTF pretty print hash",
2668         .map_type = BPF_MAP_TYPE_HASH,
2669         .map_name = "pprint_test_hash",
2670         .ordered_map = false,
2671         .lossless_map = true,
2672         .percpu_map = false,
2673 },
2674
2675 {
2676         .descr = "BTF pretty print lru hash",
2677         .map_type = BPF_MAP_TYPE_LRU_HASH,
2678         .map_name = "pprint_test_lru_hash",
2679         .ordered_map = false,
2680         .lossless_map = false,
2681         .percpu_map = false,
2682 },
2683
2684 {
2685         .descr = "BTF pretty print percpu array",
2686         .map_type = BPF_MAP_TYPE_PERCPU_ARRAY,
2687         .map_name = "pprint_test_percpu_array",
2688         .ordered_map = true,
2689         .lossless_map = true,
2690         .percpu_map = true,
2691 },
2692
2693 {
2694         .descr = "BTF pretty print percpu hash",
2695         .map_type = BPF_MAP_TYPE_PERCPU_HASH,
2696         .map_name = "pprint_test_percpu_hash",
2697         .ordered_map = false,
2698         .lossless_map = true,
2699         .percpu_map = true,
2700 },
2701
2702 {
2703         .descr = "BTF pretty print lru percpu hash",
2704         .map_type = BPF_MAP_TYPE_LRU_PERCPU_HASH,
2705         .map_name = "pprint_test_lru_percpu_hash",
2706         .ordered_map = false,
2707         .lossless_map = false,
2708         .percpu_map = true,
2709 },
2710
2711 };
2712
2713
2714 static void set_pprint_mapv(struct pprint_mapv *v, uint32_t i,
2715                             int num_cpus, int rounded_value_size)
2716 {
2717         int cpu;
2718
2719         for (cpu = 0; cpu < num_cpus; cpu++) {
2720                 v->ui32 = i + cpu;
2721                 v->si32 = -i;
2722                 v->unused_bits2a = 3;
2723                 v->bits28 = i;
2724                 v->unused_bits2b = 3;
2725                 v->ui64 = i;
2726                 v->aenum = i & 0x03;
2727                 v = (void *)v + rounded_value_size;
2728         }
2729 }
2730
2731 static int check_line(const char *expected_line, int nexpected_line,
2732                       int expected_line_len, const char *line)
2733 {
2734         if (CHECK(nexpected_line == expected_line_len,
2735                   "expected_line is too long"))
2736                 return -1;
2737
2738         if (strcmp(expected_line, line)) {
2739                 fprintf(stderr, "unexpected pprint output\n");
2740                 fprintf(stderr, "expected: %s", expected_line);
2741                 fprintf(stderr, "    read: %s", line);
2742                 return -1;
2743         }
2744
2745         return 0;
2746 }
2747
2748
2749 static int do_test_pprint(void)
2750 {
2751         const struct btf_raw_test *test = &pprint_test_template;
2752         struct bpf_create_map_attr create_attr = {};
2753         bool ordered_map, lossless_map, percpu_map;
2754         int err, ret, num_cpus, rounded_value_size;
2755         struct pprint_mapv *mapv = NULL;
2756         unsigned int key, nr_read_elems;
2757         int map_fd = -1, btf_fd = -1;
2758         unsigned int raw_btf_size;
2759         char expected_line[255];
2760         FILE *pin_file = NULL;
2761         char pin_path[255];
2762         size_t line_len = 0;
2763         char *line = NULL;
2764         uint8_t *raw_btf;
2765         ssize_t nread;
2766
2767         fprintf(stderr, "%s......", test->descr);
2768         raw_btf = btf_raw_create(&hdr_tmpl, test->raw_types,
2769                                  test->str_sec, test->str_sec_size,
2770                                  &raw_btf_size);
2771
2772         if (!raw_btf)
2773                 return -1;
2774
2775         *btf_log_buf = '\0';
2776         btf_fd = bpf_load_btf(raw_btf, raw_btf_size,
2777                               btf_log_buf, BTF_LOG_BUF_SIZE,
2778                               args.always_log);
2779         free(raw_btf);
2780
2781         if (CHECK(btf_fd == -1, "errno:%d", errno)) {
2782                 err = -1;
2783                 goto done;
2784         }
2785
2786         create_attr.name = test->map_name;
2787         create_attr.map_type = test->map_type;
2788         create_attr.key_size = test->key_size;
2789         create_attr.value_size = test->value_size;
2790         create_attr.max_entries = test->max_entries;
2791         create_attr.btf_fd = btf_fd;
2792         create_attr.btf_key_type_id = test->key_type_id;
2793         create_attr.btf_value_type_id = test->value_type_id;
2794
2795         map_fd = bpf_create_map_xattr(&create_attr);
2796         if (CHECK(map_fd == -1, "errno:%d", errno)) {
2797                 err = -1;
2798                 goto done;
2799         }
2800
2801         ret = snprintf(pin_path, sizeof(pin_path), "%s/%s",
2802                        "/sys/fs/bpf", test->map_name);
2803
2804         if (CHECK(ret == sizeof(pin_path), "pin_path %s/%s is too long",
2805                   "/sys/fs/bpf", test->map_name)) {
2806                 err = -1;
2807                 goto done;
2808         }
2809
2810         err = bpf_obj_pin(map_fd, pin_path);
2811         if (CHECK(err, "bpf_obj_pin(%s): errno:%d.", pin_path, errno))
2812                 goto done;
2813
2814         percpu_map = test->percpu_map;
2815         num_cpus = percpu_map ? bpf_num_possible_cpus() : 1;
2816         rounded_value_size = round_up(sizeof(struct pprint_mapv), 8);
2817         mapv = calloc(num_cpus, rounded_value_size);
2818         if (CHECK(!mapv, "mapv allocation failure")) {
2819                 err = -1;
2820                 goto done;
2821         }
2822
2823         for (key = 0; key < test->max_entries; key++) {
2824                 set_pprint_mapv(mapv, key, num_cpus, rounded_value_size);
2825                 bpf_map_update_elem(map_fd, &key, mapv, 0);
2826         }
2827
2828         pin_file = fopen(pin_path, "r");
2829         if (CHECK(!pin_file, "fopen(%s): errno:%d", pin_path, errno)) {
2830                 err = -1;
2831                 goto done;
2832         }
2833
2834         /* Skip lines start with '#' */
2835         while ((nread = getline(&line, &line_len, pin_file)) > 0 &&
2836                *line == '#')
2837                 ;
2838
2839         if (CHECK(nread <= 0, "Unexpected EOF")) {
2840                 err = -1;
2841                 goto done;
2842         }
2843
2844         nr_read_elems = 0;
2845         ordered_map = test->ordered_map;
2846         lossless_map = test->lossless_map;
2847         do {
2848                 struct pprint_mapv *cmapv;
2849                 ssize_t nexpected_line;
2850                 unsigned int next_key;
2851                 int cpu;
2852
2853                 next_key = ordered_map ? nr_read_elems : atoi(line);
2854                 set_pprint_mapv(mapv, next_key, num_cpus, rounded_value_size);
2855                 cmapv = mapv;
2856
2857                 for (cpu = 0; cpu < num_cpus; cpu++) {
2858                         if (percpu_map) {
2859                                 /* for percpu map, the format looks like:
2860                                  * <key>: {
2861                                  *      cpu0: <value_on_cpu0>
2862                                  *      cpu1: <value_on_cpu1>
2863                                  *      ...
2864                                  *      cpun: <value_on_cpun>
2865                                  * }
2866                                  *
2867                                  * let us verify the line containing the key here.
2868                                  */
2869                                 if (cpu == 0) {
2870                                         nexpected_line = snprintf(expected_line,
2871                                                                   sizeof(expected_line),
2872                                                                   "%u: {\n",
2873                                                                   next_key);
2874
2875                                         err = check_line(expected_line, nexpected_line,
2876                                                          sizeof(expected_line), line);
2877                                         if (err == -1)
2878                                                 goto done;
2879                                 }
2880
2881                                 /* read value@cpu */
2882                                 nread = getline(&line, &line_len, pin_file);
2883                                 if (nread < 0)
2884                                         break;
2885                         }
2886
2887                         nexpected_line = snprintf(expected_line, sizeof(expected_line),
2888                                                   "%s%u: {%u,0,%d,0x%x,0x%x,0x%x,"
2889                                                   "{%lu|[%u,%u,%u,%u,%u,%u,%u,%u]},%s}\n",
2890                                                   percpu_map ? "\tcpu" : "",
2891                                                   percpu_map ? cpu : next_key,
2892                                                   cmapv->ui32, cmapv->si32,
2893                                                   cmapv->unused_bits2a,
2894                                                   cmapv->bits28,
2895                                                   cmapv->unused_bits2b,
2896                                                   cmapv->ui64,
2897                                                   cmapv->ui8a[0], cmapv->ui8a[1],
2898                                                   cmapv->ui8a[2], cmapv->ui8a[3],
2899                                                   cmapv->ui8a[4], cmapv->ui8a[5],
2900                                                   cmapv->ui8a[6], cmapv->ui8a[7],
2901                                                   pprint_enum_str[cmapv->aenum]);
2902
2903                         err = check_line(expected_line, nexpected_line,
2904                                          sizeof(expected_line), line);
2905                         if (err == -1)
2906                                 goto done;
2907
2908                         cmapv = (void *)cmapv + rounded_value_size;
2909                 }
2910
2911                 if (percpu_map) {
2912                         /* skip the last bracket for the percpu map */
2913                         nread = getline(&line, &line_len, pin_file);
2914                         if (nread < 0)
2915                                 break;
2916                 }
2917
2918                 nread = getline(&line, &line_len, pin_file);
2919         } while (++nr_read_elems < test->max_entries && nread > 0);
2920
2921         if (lossless_map &&
2922             CHECK(nr_read_elems < test->max_entries,
2923                   "Unexpected EOF. nr_read_elems:%u test->max_entries:%u",
2924                   nr_read_elems, test->max_entries)) {
2925                 err = -1;
2926                 goto done;
2927         }
2928
2929         if (CHECK(nread > 0, "Unexpected extra pprint output: %s", line)) {
2930                 err = -1;
2931                 goto done;
2932         }
2933
2934         err = 0;
2935
2936 done:
2937         if (mapv)
2938                 free(mapv);
2939         if (!err)
2940                 fprintf(stderr, "OK");
2941         if (*btf_log_buf && (err || args.always_log))
2942                 fprintf(stderr, "\n%s", btf_log_buf);
2943         if (btf_fd != -1)
2944                 close(btf_fd);
2945         if (map_fd != -1)
2946                 close(map_fd);
2947         if (pin_file)
2948                 fclose(pin_file);
2949         unlink(pin_path);
2950         free(line);
2951
2952         return err;
2953 }
2954
2955 static int test_pprint(void)
2956 {
2957         unsigned int i;
2958         int err = 0;
2959
2960         for (i = 0; i < ARRAY_SIZE(pprint_tests_meta); i++) {
2961                 pprint_test_template.descr = pprint_tests_meta[i].descr;
2962                 pprint_test_template.map_type = pprint_tests_meta[i].map_type;
2963                 pprint_test_template.map_name = pprint_tests_meta[i].map_name;
2964                 pprint_test_template.ordered_map = pprint_tests_meta[i].ordered_map;
2965                 pprint_test_template.lossless_map = pprint_tests_meta[i].lossless_map;
2966                 pprint_test_template.percpu_map = pprint_tests_meta[i].percpu_map;
2967
2968                 err |= count_result(do_test_pprint());
2969         }
2970
2971         return err;
2972 }
2973
2974 static struct btf_func_type_test {
2975         const char *descr;
2976         const char *str_sec;
2977         __u32 raw_types[MAX_NR_RAW_TYPES];
2978         __u32 str_sec_size;
2979         struct bpf_insn insns[MAX_INSNS];
2980         __u32 prog_type;
2981         __u32 func_info[MAX_SUBPROGS][2];
2982         __u32 func_info_rec_size;
2983         __u32 func_info_cnt;
2984         bool expected_prog_load_failure;
2985 } func_type_test[] = {
2986 {
2987         .descr = "func_type (main func + one sub)",
2988         .raw_types = {
2989                 BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),   /* [1] */
2990                 BTF_TYPE_INT_ENC(NAME_TBD, 0, 0, 32, 4),        /* [2] */
2991                 BTF_FUNC_PROTO_ENC(1, 2),                       /* [3] */
2992                         BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
2993                         BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 2),
2994                 BTF_FUNC_PROTO_ENC(1, 2),                       /* [4] */
2995                         BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 2),
2996                         BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
2997                 BTF_FUNC_ENC(NAME_TBD, 3),                      /* [5] */
2998                 BTF_FUNC_ENC(NAME_TBD, 4),                      /* [6] */
2999                 BTF_END_RAW,
3000         },
3001         .str_sec = "\0int\0unsigned int\0a\0b\0c\0d\0funcA\0funcB",
3002         .str_sec_size = sizeof("\0int\0unsigned int\0a\0b\0c\0d\0funcA\0funcB"),
3003         .insns = {
3004                 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2),
3005                 BPF_MOV64_IMM(BPF_REG_0, 1),
3006                 BPF_EXIT_INSN(),
3007                 BPF_MOV64_IMM(BPF_REG_0, 2),
3008                 BPF_EXIT_INSN(),
3009         },
3010         .prog_type = BPF_PROG_TYPE_TRACEPOINT,
3011         .func_info = { {0, 5}, {3, 6} },
3012         .func_info_rec_size = 8,
3013         .func_info_cnt = 2,
3014 },
3015
3016 {
3017         .descr = "func_type (Incorrect func_info_rec_size)",
3018         .raw_types = {
3019                 BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),   /* [1] */
3020                 BTF_TYPE_INT_ENC(NAME_TBD, 0, 0, 32, 4),        /* [2] */
3021                 BTF_FUNC_PROTO_ENC(1, 2),                       /* [3] */
3022                         BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
3023                         BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 2),
3024                 BTF_FUNC_PROTO_ENC(1, 2),                       /* [4] */
3025                         BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 2),
3026                         BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
3027                 BTF_FUNC_ENC(NAME_TBD, 3),                      /* [5] */
3028                 BTF_FUNC_ENC(NAME_TBD, 4),                      /* [6] */
3029                 BTF_END_RAW,
3030         },
3031         .str_sec = "\0int\0unsigned int\0a\0b\0c\0d\0funcA\0funcB",
3032         .str_sec_size = sizeof("\0int\0unsigned int\0a\0b\0c\0d\0funcA\0funcB"),
3033         .insns = {
3034                 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2),
3035                 BPF_MOV64_IMM(BPF_REG_0, 1),
3036                 BPF_EXIT_INSN(),
3037                 BPF_MOV64_IMM(BPF_REG_0, 2),
3038                 BPF_EXIT_INSN(),
3039         },
3040         .prog_type = BPF_PROG_TYPE_TRACEPOINT,
3041         .func_info = { {0, 5}, {3, 6} },
3042         .func_info_rec_size = 4,
3043         .func_info_cnt = 2,
3044         .expected_prog_load_failure = true,
3045 },
3046
3047 {
3048         .descr = "func_type (Incorrect func_info_cnt)",
3049         .raw_types = {
3050                 BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),   /* [1] */
3051                 BTF_TYPE_INT_ENC(NAME_TBD, 0, 0, 32, 4),        /* [2] */
3052                 BTF_FUNC_PROTO_ENC(1, 2),                       /* [3] */
3053                         BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
3054                         BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 2),
3055                 BTF_FUNC_PROTO_ENC(1, 2),                       /* [4] */
3056                         BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 2),
3057                         BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
3058                 BTF_FUNC_ENC(NAME_TBD, 3),                      /* [5] */
3059                 BTF_FUNC_ENC(NAME_TBD, 4),                      /* [6] */
3060                 BTF_END_RAW,
3061         },
3062         .str_sec = "\0int\0unsigned int\0a\0b\0c\0d\0funcA\0funcB",
3063         .str_sec_size = sizeof("\0int\0unsigned int\0a\0b\0c\0d\0funcA\0funcB"),
3064         .insns = {
3065                 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2),
3066                 BPF_MOV64_IMM(BPF_REG_0, 1),
3067                 BPF_EXIT_INSN(),
3068                 BPF_MOV64_IMM(BPF_REG_0, 2),
3069                 BPF_EXIT_INSN(),
3070         },
3071         .prog_type = BPF_PROG_TYPE_TRACEPOINT,
3072         .func_info = { {0, 5}, {3, 6} },
3073         .func_info_rec_size = 8,
3074         .func_info_cnt = 1,
3075         .expected_prog_load_failure = true,
3076 },
3077
3078 {
3079         .descr = "func_type (Incorrect bpf_func_info.insn_offset)",
3080         .raw_types = {
3081                 BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),   /* [1] */
3082                 BTF_TYPE_INT_ENC(NAME_TBD, 0, 0, 32, 4),        /* [2] */
3083                 BTF_FUNC_PROTO_ENC(1, 2),                       /* [3] */
3084                         BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
3085                         BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 2),
3086                 BTF_FUNC_PROTO_ENC(1, 2),                       /* [4] */
3087                         BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 2),
3088                         BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
3089                 BTF_FUNC_ENC(NAME_TBD, 3),                      /* [5] */
3090                 BTF_FUNC_ENC(NAME_TBD, 4),                      /* [6] */
3091                 BTF_END_RAW,
3092         },
3093         .str_sec = "\0int\0unsigned int\0a\0b\0c\0d\0funcA\0funcB",
3094         .str_sec_size = sizeof("\0int\0unsigned int\0a\0b\0c\0d\0funcA\0funcB"),
3095         .insns = {
3096                 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2),
3097                 BPF_MOV64_IMM(BPF_REG_0, 1),
3098                 BPF_EXIT_INSN(),
3099                 BPF_MOV64_IMM(BPF_REG_0, 2),
3100                 BPF_EXIT_INSN(),
3101         },
3102         .prog_type = BPF_PROG_TYPE_TRACEPOINT,
3103         .func_info = { {0, 5}, {2, 6} },
3104         .func_info_rec_size = 8,
3105         .func_info_cnt = 2,
3106         .expected_prog_load_failure = true,
3107 },
3108
3109 };
3110
3111 static size_t probe_prog_length(const struct bpf_insn *fp)
3112 {
3113         size_t len;
3114
3115         for (len = MAX_INSNS - 1; len > 0; --len)
3116                 if (fp[len].code != 0 || fp[len].imm != 0)
3117                         break;
3118         return len + 1;
3119 }
3120
3121 static int do_test_func_type(int test_num)
3122 {
3123         const struct btf_func_type_test *test = &func_type_test[test_num];
3124         unsigned int raw_btf_size, info_len, rec_size;
3125         int i, btf_fd = -1, prog_fd = -1, err = 0;
3126         struct bpf_load_program_attr attr = {};
3127         void *raw_btf, *func_info = NULL;
3128         struct bpf_prog_info info = {};
3129         struct bpf_func_info *finfo;
3130
3131         fprintf(stderr, "%s......", test->descr);
3132         raw_btf = btf_raw_create(&hdr_tmpl, test->raw_types,
3133                                  test->str_sec, test->str_sec_size,
3134                                  &raw_btf_size);
3135
3136         if (!raw_btf)
3137                 return -1;
3138
3139         *btf_log_buf = '\0';
3140         btf_fd = bpf_load_btf(raw_btf, raw_btf_size,
3141                               btf_log_buf, BTF_LOG_BUF_SIZE,
3142                               args.always_log);
3143         free(raw_btf);
3144
3145         if (CHECK(btf_fd == -1, "invalid btf_fd errno:%d", errno)) {
3146                 err = -1;
3147                 goto done;
3148         }
3149
3150         if (*btf_log_buf && args.always_log)
3151                 fprintf(stderr, "\n%s", btf_log_buf);
3152
3153         attr.prog_type = test->prog_type;
3154         attr.insns = test->insns;
3155         attr.insns_cnt = probe_prog_length(attr.insns);
3156         attr.license = "GPL";
3157         attr.prog_btf_fd = btf_fd;
3158         attr.func_info_rec_size = test->func_info_rec_size;
3159         attr.func_info_cnt = test->func_info_cnt;
3160         attr.func_info = test->func_info;
3161
3162         *btf_log_buf = '\0';
3163         prog_fd = bpf_load_program_xattr(&attr, btf_log_buf,
3164                                          BTF_LOG_BUF_SIZE);
3165         if (test->expected_prog_load_failure && prog_fd == -1) {
3166                 err = 0;
3167                 goto done;
3168         }
3169         if (CHECK(prog_fd == -1, "invalid prog_id errno:%d", errno)) {
3170                 fprintf(stderr, "%s\n", btf_log_buf);
3171                 err = -1;
3172                 goto done;
3173         }
3174         if (!jit_enabled) {
3175                 skip_cnt++;
3176                 fprintf(stderr, "SKIPPED, please enable sysctl bpf_jit_enable\n");
3177                 err = 0;
3178                 goto done;
3179         }
3180
3181         /* get necessary lens */
3182         info_len = sizeof(struct bpf_prog_info);
3183         err = bpf_obj_get_info_by_fd(prog_fd, &info, &info_len);
3184         if (CHECK(err == -1, "invalid get info (1st) errno:%d", errno)) {
3185                 fprintf(stderr, "%s\n", btf_log_buf);
3186                 err = -1;
3187                 goto done;
3188         }
3189         if (CHECK(info.func_info_cnt != 2,
3190                   "incorrect info.func_info_cnt (1st) %d\n",
3191                   info.func_info_cnt)) {
3192                 err = -1;
3193                 goto done;
3194         }
3195         rec_size = info.func_info_rec_size;
3196         if (CHECK(rec_size < 4,
3197                   "incorrect info.func_info_rec_size (1st) %d\n", rec_size)) {
3198                 err = -1;
3199                 goto done;
3200         }
3201
3202         func_info = malloc(info.func_info_cnt * rec_size);
3203         if (CHECK(!func_info, "out of memeory")) {
3204                 err = -1;
3205                 goto done;
3206         }
3207
3208         /* reset info to only retrieve func_info related data */
3209         memset(&info, 0, sizeof(info));
3210         info.func_info_cnt = 2;
3211         info.func_info_rec_size = rec_size;
3212         info.func_info = ptr_to_u64(func_info);
3213         err = bpf_obj_get_info_by_fd(prog_fd, &info, &info_len);
3214         if (CHECK(err == -1, "invalid get info (2nd) errno:%d", errno)) {
3215                 fprintf(stderr, "%s\n", btf_log_buf);
3216                 err = -1;
3217                 goto done;
3218         }
3219         if (CHECK(info.func_info_cnt != 2,
3220                   "incorrect info.func_info_cnt (2nd) %d\n",
3221                   info.func_info_cnt)) {
3222                 err = -1;
3223                 goto done;
3224         }
3225         if (CHECK(info.func_info_rec_size != rec_size,
3226                   "incorrect info.func_info_rec_size (2nd) %d\n",
3227                   info.func_info_rec_size)) {
3228                 err = -1;
3229                 goto done;
3230         }
3231
3232         finfo = func_info;
3233         for (i = 0; i < 2; i++) {
3234                 if (CHECK(finfo->type_id != test->func_info[i][1],
3235                           "incorrect func_type %u expected %u",
3236                           finfo->type_id, test->func_info[i][1])) {
3237                         err = -1;
3238                         goto done;
3239                 }
3240                 finfo = (void *)finfo + rec_size;
3241         }
3242
3243 done:
3244         if (*btf_log_buf && (err || args.always_log))
3245                 fprintf(stderr, "\n%s", btf_log_buf);
3246
3247         if (btf_fd != -1)
3248                 close(btf_fd);
3249         if (prog_fd != -1)
3250                 close(prog_fd);
3251         free(func_info);
3252         return err;
3253 }
3254
3255 static int test_func_type(void)
3256 {
3257         unsigned int i;
3258         int err = 0;
3259
3260         for (i = 0; i < ARRAY_SIZE(func_type_test); i++)
3261                 err |= count_result(do_test_func_type(i));
3262
3263         return err;
3264 }
3265
3266 static void usage(const char *cmd)
3267 {
3268         fprintf(stderr, "Usage: %s [-l] [[-r test_num (1 - %zu)] |"
3269                         " [-g test_num (1 - %zu)] |"
3270                         " [-f test_num (1 - %zu)] | [-p] | [-k] ]\n",
3271                 cmd, ARRAY_SIZE(raw_tests), ARRAY_SIZE(get_info_tests),
3272                 ARRAY_SIZE(file_tests));
3273 }
3274
3275 static int parse_args(int argc, char **argv)
3276 {
3277         const char *optstr = "lpkf:r:g:";
3278         int opt;
3279
3280         while ((opt = getopt(argc, argv, optstr)) != -1) {
3281                 switch (opt) {
3282                 case 'l':
3283                         args.always_log = true;
3284                         break;
3285                 case 'f':
3286                         args.file_test_num = atoi(optarg);
3287                         args.file_test = true;
3288                         break;
3289                 case 'r':
3290                         args.raw_test_num = atoi(optarg);
3291                         args.raw_test = true;
3292                         break;
3293                 case 'g':
3294                         args.get_info_test_num = atoi(optarg);
3295                         args.get_info_test = true;
3296                         break;
3297                 case 'p':
3298                         args.pprint_test = true;
3299                         break;
3300                 case 'k':
3301                         args.func_type_test = true;
3302                         break;
3303                 case 'h':
3304                         usage(argv[0]);
3305                         exit(0);
3306                 default:
3307                                 usage(argv[0]);
3308                                 return -1;
3309                 }
3310         }
3311
3312         if (args.raw_test_num &&
3313             (args.raw_test_num < 1 ||
3314              args.raw_test_num > ARRAY_SIZE(raw_tests))) {
3315                 fprintf(stderr, "BTF raw test number must be [1 - %zu]\n",
3316                         ARRAY_SIZE(raw_tests));
3317                 return -1;
3318         }
3319
3320         if (args.file_test_num &&
3321             (args.file_test_num < 1 ||
3322              args.file_test_num > ARRAY_SIZE(file_tests))) {
3323                 fprintf(stderr, "BTF file test number must be [1 - %zu]\n",
3324                         ARRAY_SIZE(file_tests));
3325                 return -1;
3326         }
3327
3328         if (args.get_info_test_num &&
3329             (args.get_info_test_num < 1 ||
3330              args.get_info_test_num > ARRAY_SIZE(get_info_tests))) {
3331                 fprintf(stderr, "BTF get info test number must be [1 - %zu]\n",
3332                         ARRAY_SIZE(get_info_tests));
3333                 return -1;
3334         }
3335
3336         return 0;
3337 }
3338
3339 static void print_summary(void)
3340 {
3341         fprintf(stderr, "PASS:%u SKIP:%u FAIL:%u\n",
3342                 pass_cnt - skip_cnt, skip_cnt, error_cnt);
3343 }
3344
3345 int main(int argc, char **argv)
3346 {
3347         int err = 0;
3348
3349         err = parse_args(argc, argv);
3350         if (err)
3351                 return err;
3352
3353         if (args.always_log)
3354                 libbpf_set_print(__base_pr, __base_pr, __base_pr);
3355
3356         jit_enabled = is_jit_enabled();
3357
3358         if (args.raw_test)
3359                 err |= test_raw();
3360
3361         if (args.get_info_test)
3362                 err |= test_get_info();
3363
3364         if (args.file_test)
3365                 err |= test_file();
3366
3367         if (args.pprint_test)
3368                 err |= test_pprint();
3369
3370         if (args.func_type_test)
3371                 err |= test_func_type();
3372
3373         if (args.raw_test || args.get_info_test || args.file_test ||
3374             args.pprint_test || args.func_type_test)
3375                 goto done;
3376
3377         err |= test_raw();
3378         err |= test_get_info();
3379         err |= test_file();
3380
3381 done:
3382         print_summary();
3383         return err;
3384 }