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