OSDN Git Service

Merge branch 'i2c/for-current' of git://git.kernel.org/pub/scm/linux/kernel/git/wsa...
[uclinux-h8/linux.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 (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_TYPEDEF_ENC(NAME_TBD, 4),                   /* [3] */
1889                 BTF_FUNC_PROTO_ENC(0, 2),                       /* [4] */
1890                         BTF_FUNC_PROTO_ARG_ENC(0, 1),
1891                         BTF_FUNC_PROTO_ARG_ENC(0, 2),
1892                 BTF_END_RAW,
1893         },
1894         .str_sec = "\0func_typedef",
1895         .str_sec_size = sizeof("\0func_typedef"),
1896         .map_type = BPF_MAP_TYPE_ARRAY,
1897         .map_name = "func_proto_type_check_btf",
1898         .key_size = sizeof(int),
1899         .value_size = sizeof(int),
1900         .key_type_id = 1,
1901         .value_type_id = 1,
1902         .max_entries = 4,
1903 },
1904
1905 {
1906         .descr = "func proto (btf_resolve(arg))",
1907         .raw_types = {
1908                 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),  /* [1] */
1909                 /* void (*)(const void *) */
1910                 BTF_FUNC_PROTO_ENC(0, 1),                       /* [2] */
1911                         BTF_FUNC_PROTO_ARG_ENC(0, 3),
1912                 BTF_CONST_ENC(4),                               /* [3] */
1913                 BTF_PTR_ENC(0),                                 /* [4] */
1914                 BTF_END_RAW,
1915         },
1916         .str_sec = "",
1917         .str_sec_size = sizeof(""),
1918         .map_type = BPF_MAP_TYPE_ARRAY,
1919         .map_name = "func_proto_type_check_btf",
1920         .key_size = sizeof(int),
1921         .value_size = sizeof(int),
1922         .key_type_id = 1,
1923         .value_type_id = 1,
1924         .max_entries = 4,
1925 },
1926
1927 {
1928         .descr = "func proto (Not all arg has name)",
1929         .raw_types = {
1930                 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),  /* [1] */
1931                 BTF_TYPE_INT_ENC(0, 0, 0, 32, 4),               /* [2] */
1932                 /* void (*)(int, unsigned int b) */
1933                 BTF_FUNC_PROTO_ENC(0, 2),                       /* [3] */
1934                         BTF_FUNC_PROTO_ARG_ENC(0, 1),
1935                         BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 2),
1936                 BTF_END_RAW,
1937         },
1938         .str_sec = "\0b",
1939         .str_sec_size = sizeof("\0b"),
1940         .map_type = BPF_MAP_TYPE_ARRAY,
1941         .map_name = "func_proto_type_check_btf",
1942         .key_size = sizeof(int),
1943         .value_size = sizeof(int),
1944         .key_type_id = 1,
1945         .value_type_id = 1,
1946         .max_entries = 4,
1947 },
1948
1949 {
1950         .descr = "func proto (Bad arg name_off)",
1951         .raw_types = {
1952                 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),  /* [1] */
1953                 BTF_TYPE_INT_ENC(0, 0, 0, 32, 4),               /* [2] */
1954                 /* void (*)(int a, unsigned int <bad_name_off>) */
1955                 BTF_FUNC_PROTO_ENC(0, 2),                       /* [3] */
1956                         BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
1957                         BTF_FUNC_PROTO_ARG_ENC(0xffffffff, 2),
1958                 BTF_END_RAW,
1959         },
1960         .str_sec = "\0a",
1961         .str_sec_size = sizeof("\0a"),
1962         .map_type = BPF_MAP_TYPE_ARRAY,
1963         .map_name = "func_proto_type_check_btf",
1964         .key_size = sizeof(int),
1965         .value_size = sizeof(int),
1966         .key_type_id = 1,
1967         .value_type_id = 1,
1968         .max_entries = 4,
1969         .btf_load_err = true,
1970         .err_str = "Invalid arg#2",
1971 },
1972
1973 {
1974         .descr = "func proto (Bad arg name)",
1975         .raw_types = {
1976                 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),  /* [1] */
1977                 BTF_TYPE_INT_ENC(0, 0, 0, 32, 4),               /* [2] */
1978                 /* void (*)(int a, unsigned int !!!) */
1979                 BTF_FUNC_PROTO_ENC(0, 2),                       /* [3] */
1980                         BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
1981                         BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 2),
1982                 BTF_END_RAW,
1983         },
1984         .str_sec = "\0a\0!!!",
1985         .str_sec_size = sizeof("\0a\0!!!"),
1986         .map_type = BPF_MAP_TYPE_ARRAY,
1987         .map_name = "func_proto_type_check_btf",
1988         .key_size = sizeof(int),
1989         .value_size = sizeof(int),
1990         .key_type_id = 1,
1991         .value_type_id = 1,
1992         .max_entries = 4,
1993         .btf_load_err = true,
1994         .err_str = "Invalid arg#2",
1995 },
1996
1997 {
1998         .descr = "func proto (Invalid return type)",
1999         .raw_types = {
2000                 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),  /* [1] */
2001                 BTF_TYPE_INT_ENC(0, 0, 0, 32, 4),               /* [2] */
2002                 /* <bad_ret_type> (*)(int, unsigned int) */
2003                 BTF_FUNC_PROTO_ENC(100, 2),                     /* [3] */
2004                         BTF_FUNC_PROTO_ARG_ENC(0, 1),
2005                         BTF_FUNC_PROTO_ARG_ENC(0, 2),
2006                 BTF_END_RAW,
2007         },
2008         .str_sec = "",
2009         .str_sec_size = sizeof(""),
2010         .map_type = BPF_MAP_TYPE_ARRAY,
2011         .map_name = "func_proto_type_check_btf",
2012         .key_size = sizeof(int),
2013         .value_size = sizeof(int),
2014         .key_type_id = 1,
2015         .value_type_id = 1,
2016         .max_entries = 4,
2017         .btf_load_err = true,
2018         .err_str = "Invalid return type",
2019 },
2020
2021 {
2022         .descr = "func proto (with func name)",
2023         .raw_types = {
2024                 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),  /* [1] */
2025                 BTF_TYPE_INT_ENC(0, 0, 0, 32, 4),               /* [2] */
2026                 /* void func_proto(int, unsigned int) */
2027                 BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_FUNC_PROTO, 0, 2), 0),     /* [3] */
2028                         BTF_FUNC_PROTO_ARG_ENC(0, 1),
2029                         BTF_FUNC_PROTO_ARG_ENC(0, 2),
2030                 BTF_END_RAW,
2031         },
2032         .str_sec = "\0func_proto",
2033         .str_sec_size = sizeof("\0func_proto"),
2034         .map_type = BPF_MAP_TYPE_ARRAY,
2035         .map_name = "func_proto_type_check_btf",
2036         .key_size = sizeof(int),
2037         .value_size = sizeof(int),
2038         .key_type_id = 1,
2039         .value_type_id = 1,
2040         .max_entries = 4,
2041         .btf_load_err = true,
2042         .err_str = "Invalid name",
2043 },
2044
2045 {
2046         .descr = "func proto (const void arg)",
2047         .raw_types = {
2048                 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),  /* [1] */
2049                 BTF_TYPE_INT_ENC(0, 0, 0, 32, 4),               /* [2] */
2050                 /* void (*)(const void) */
2051                 BTF_FUNC_PROTO_ENC(0, 1),                       /* [3] */
2052                         BTF_FUNC_PROTO_ARG_ENC(0, 4),
2053                 BTF_CONST_ENC(0),                               /* [4] */
2054                 BTF_END_RAW,
2055         },
2056         .str_sec = "",
2057         .str_sec_size = sizeof(""),
2058         .map_type = BPF_MAP_TYPE_ARRAY,
2059         .map_name = "func_proto_type_check_btf",
2060         .key_size = sizeof(int),
2061         .value_size = sizeof(int),
2062         .key_type_id = 1,
2063         .value_type_id = 1,
2064         .max_entries = 4,
2065         .btf_load_err = true,
2066         .err_str = "Invalid arg#1",
2067 },
2068
2069 {
2070         .descr = "func (void func(int a, unsigned int b))",
2071         .raw_types = {
2072                 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),  /* [1] */
2073                 BTF_TYPE_INT_ENC(0, 0, 0, 32, 4),               /* [2] */
2074                 /* void (*)(int a, unsigned int b) */
2075                 BTF_FUNC_PROTO_ENC(0, 2),                       /* [3] */
2076                         BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
2077                         BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 2),
2078                 /* void func(int a, unsigned int b) */
2079                 BTF_FUNC_ENC(NAME_TBD, 3),                      /* [4] */
2080                 BTF_END_RAW,
2081         },
2082         .str_sec = "\0a\0b\0func",
2083         .str_sec_size = sizeof("\0a\0b\0func"),
2084         .map_type = BPF_MAP_TYPE_ARRAY,
2085         .map_name = "func_type_check_btf",
2086         .key_size = sizeof(int),
2087         .value_size = sizeof(int),
2088         .key_type_id = 1,
2089         .value_type_id = 1,
2090         .max_entries = 4,
2091 },
2092
2093 {
2094         .descr = "func (No func name)",
2095         .raw_types = {
2096                 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),  /* [1] */
2097                 BTF_TYPE_INT_ENC(0, 0, 0, 32, 4),               /* [2] */
2098                 /* void (*)(int a, unsigned int b) */
2099                 BTF_FUNC_PROTO_ENC(0, 2),                       /* [3] */
2100                         BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
2101                         BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 2),
2102                 /* void <no_name>(int a, unsigned int b) */
2103                 BTF_FUNC_ENC(0, 3),                             /* [4] */
2104                 BTF_END_RAW,
2105         },
2106         .str_sec = "\0a\0b",
2107         .str_sec_size = sizeof("\0a\0b"),
2108         .map_type = BPF_MAP_TYPE_ARRAY,
2109         .map_name = "func_type_check_btf",
2110         .key_size = sizeof(int),
2111         .value_size = sizeof(int),
2112         .key_type_id = 1,
2113         .value_type_id = 1,
2114         .max_entries = 4,
2115         .btf_load_err = true,
2116         .err_str = "Invalid name",
2117 },
2118
2119 {
2120         .descr = "func (Invalid func name)",
2121         .raw_types = {
2122                 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),  /* [1] */
2123                 BTF_TYPE_INT_ENC(0, 0, 0, 32, 4),               /* [2] */
2124                 /* void (*)(int a, unsigned int b) */
2125                 BTF_FUNC_PROTO_ENC(0, 2),                       /* [3] */
2126                         BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
2127                         BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 2),
2128                 /* void !!!(int a, unsigned int b) */
2129                 BTF_FUNC_ENC(NAME_TBD, 3),                      /* [4] */
2130                 BTF_END_RAW,
2131         },
2132         .str_sec = "\0a\0b\0!!!",
2133         .str_sec_size = sizeof("\0a\0b\0!!!"),
2134         .map_type = BPF_MAP_TYPE_ARRAY,
2135         .map_name = "func_type_check_btf",
2136         .key_size = sizeof(int),
2137         .value_size = sizeof(int),
2138         .key_type_id = 1,
2139         .value_type_id = 1,
2140         .max_entries = 4,
2141         .btf_load_err = true,
2142         .err_str = "Invalid name",
2143 },
2144
2145 {
2146         .descr = "func (Some arg has no name)",
2147         .raw_types = {
2148                 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),  /* [1] */
2149                 BTF_TYPE_INT_ENC(0, 0, 0, 32, 4),               /* [2] */
2150                 /* void (*)(int a, unsigned int) */
2151                 BTF_FUNC_PROTO_ENC(0, 2),                       /* [3] */
2152                         BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
2153                         BTF_FUNC_PROTO_ARG_ENC(0, 2),
2154                 /* void func(int a, unsigned int) */
2155                 BTF_FUNC_ENC(NAME_TBD, 3),                      /* [4] */
2156                 BTF_END_RAW,
2157         },
2158         .str_sec = "\0a\0func",
2159         .str_sec_size = sizeof("\0a\0func"),
2160         .map_type = BPF_MAP_TYPE_ARRAY,
2161         .map_name = "func_type_check_btf",
2162         .key_size = sizeof(int),
2163         .value_size = sizeof(int),
2164         .key_type_id = 1,
2165         .value_type_id = 1,
2166         .max_entries = 4,
2167         .btf_load_err = true,
2168         .err_str = "Invalid arg#2",
2169 },
2170
2171 {
2172         .descr = "func (Non zero vlen)",
2173         .raw_types = {
2174                 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),  /* [1] */
2175                 BTF_TYPE_INT_ENC(0, 0, 0, 32, 4),               /* [2] */
2176                 /* void (*)(int a, unsigned int b) */
2177                 BTF_FUNC_PROTO_ENC(0, 2),                       /* [3] */
2178                         BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
2179                         BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 2),
2180                 /* void func(int a, unsigned int b) */
2181                 BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_FUNC, 0, 2), 3),   /* [4] */
2182                 BTF_END_RAW,
2183         },
2184         .str_sec = "\0a\0b\0func",
2185         .str_sec_size = sizeof("\0a\0b\0func"),
2186         .map_type = BPF_MAP_TYPE_ARRAY,
2187         .map_name = "func_type_check_btf",
2188         .key_size = sizeof(int),
2189         .value_size = sizeof(int),
2190         .key_type_id = 1,
2191         .value_type_id = 1,
2192         .max_entries = 4,
2193         .btf_load_err = true,
2194         .err_str = "vlen != 0",
2195 },
2196
2197 {
2198         .descr = "func (Not referring to FUNC_PROTO)",
2199         .raw_types = {
2200                 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),  /* [1] */
2201                 BTF_FUNC_ENC(NAME_TBD, 1),                      /* [2] */
2202                 BTF_END_RAW,
2203         },
2204         .str_sec = "\0func",
2205         .str_sec_size = sizeof("\0func"),
2206         .map_type = BPF_MAP_TYPE_ARRAY,
2207         .map_name = "func_type_check_btf",
2208         .key_size = sizeof(int),
2209         .value_size = sizeof(int),
2210         .key_type_id = 1,
2211         .value_type_id = 1,
2212         .max_entries = 4,
2213         .btf_load_err = true,
2214         .err_str = "Invalid type_id",
2215 },
2216
2217 {
2218         .descr = "invalid int kind_flag",
2219         .raw_types = {
2220                 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),          /* [1] */
2221                 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_INT, 1, 0), 4),   /* [2] */
2222                 BTF_INT_ENC(0, 0, 32),
2223                 BTF_END_RAW,
2224         },
2225         BTF_STR_SEC(""),
2226         .map_type = BPF_MAP_TYPE_ARRAY,
2227         .map_name = "int_type_check_btf",
2228         .key_size = sizeof(int),
2229         .value_size = sizeof(int),
2230         .key_type_id = 1,
2231         .value_type_id = 1,
2232         .max_entries = 4,
2233         .btf_load_err = true,
2234         .err_str = "Invalid btf_info kind_flag",
2235 },
2236
2237 {
2238         .descr = "invalid ptr kind_flag",
2239         .raw_types = {
2240                 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),          /* [1] */
2241                 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_PTR, 1, 0), 1),   /* [2] */
2242                 BTF_END_RAW,
2243         },
2244         BTF_STR_SEC(""),
2245         .map_type = BPF_MAP_TYPE_ARRAY,
2246         .map_name = "ptr_type_check_btf",
2247         .key_size = sizeof(int),
2248         .value_size = sizeof(int),
2249         .key_type_id = 1,
2250         .value_type_id = 1,
2251         .max_entries = 4,
2252         .btf_load_err = true,
2253         .err_str = "Invalid btf_info kind_flag",
2254 },
2255
2256 {
2257         .descr = "invalid array kind_flag",
2258         .raw_types = {
2259                 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),          /* [1] */
2260                 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_ARRAY, 1, 0), 0), /* [2] */
2261                 BTF_ARRAY_ENC(1, 1, 1),
2262                 BTF_END_RAW,
2263         },
2264         BTF_STR_SEC(""),
2265         .map_type = BPF_MAP_TYPE_ARRAY,
2266         .map_name = "array_type_check_btf",
2267         .key_size = sizeof(int),
2268         .value_size = sizeof(int),
2269         .key_type_id = 1,
2270         .value_type_id = 1,
2271         .max_entries = 4,
2272         .btf_load_err = true,
2273         .err_str = "Invalid btf_info kind_flag",
2274 },
2275
2276 {
2277         .descr = "invalid enum kind_flag",
2278         .raw_types = {
2279                 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),          /* [1] */
2280                 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_ENUM, 1, 1), 4),  /* [2] */
2281                 BTF_ENUM_ENC(NAME_TBD, 0),
2282                 BTF_END_RAW,
2283         },
2284         BTF_STR_SEC("\0A"),
2285         .map_type = BPF_MAP_TYPE_ARRAY,
2286         .map_name = "enum_type_check_btf",
2287         .key_size = sizeof(int),
2288         .value_size = sizeof(int),
2289         .key_type_id = 1,
2290         .value_type_id = 1,
2291         .max_entries = 4,
2292         .btf_load_err = true,
2293         .err_str = "Invalid btf_info kind_flag",
2294 },
2295
2296 {
2297         .descr = "valid fwd kind_flag",
2298         .raw_types = {
2299                 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),          /* [1] */
2300                 BTF_TYPE_ENC(NAME_TBD,
2301                              BTF_INFO_ENC(BTF_KIND_FWD, 1, 0), 0),      /* [2] */
2302                 BTF_END_RAW,
2303         },
2304         BTF_STR_SEC("\0A"),
2305         .map_type = BPF_MAP_TYPE_ARRAY,
2306         .map_name = "fwd_type_check_btf",
2307         .key_size = sizeof(int),
2308         .value_size = sizeof(int),
2309         .key_type_id = 1,
2310         .value_type_id = 1,
2311         .max_entries = 4,
2312 },
2313
2314 {
2315         .descr = "invalid typedef kind_flag",
2316         .raw_types = {
2317                 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),          /* [1] */
2318                 BTF_TYPE_ENC(NAME_TBD,
2319                              BTF_INFO_ENC(BTF_KIND_TYPEDEF, 1, 0), 1),  /* [2] */
2320                 BTF_END_RAW,
2321         },
2322         BTF_STR_SEC("\0A"),
2323         .map_type = BPF_MAP_TYPE_ARRAY,
2324         .map_name = "typedef_type_check_btf",
2325         .key_size = sizeof(int),
2326         .value_size = sizeof(int),
2327         .key_type_id = 1,
2328         .value_type_id = 1,
2329         .max_entries = 4,
2330         .btf_load_err = true,
2331         .err_str = "Invalid btf_info kind_flag",
2332 },
2333
2334 {
2335         .descr = "invalid volatile kind_flag",
2336         .raw_types = {
2337                 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),                  /* [1] */
2338                 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_VOLATILE, 1, 0), 1),      /* [2] */
2339                 BTF_END_RAW,
2340         },
2341         BTF_STR_SEC(""),
2342         .map_type = BPF_MAP_TYPE_ARRAY,
2343         .map_name = "volatile_type_check_btf",
2344         .key_size = sizeof(int),
2345         .value_size = sizeof(int),
2346         .key_type_id = 1,
2347         .value_type_id = 1,
2348         .max_entries = 4,
2349         .btf_load_err = true,
2350         .err_str = "Invalid btf_info kind_flag",
2351 },
2352
2353 {
2354         .descr = "invalid const kind_flag",
2355         .raw_types = {
2356                 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),          /* [1] */
2357                 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_CONST, 1, 0), 1), /* [2] */
2358                 BTF_END_RAW,
2359         },
2360         BTF_STR_SEC(""),
2361         .map_type = BPF_MAP_TYPE_ARRAY,
2362         .map_name = "const_type_check_btf",
2363         .key_size = sizeof(int),
2364         .value_size = sizeof(int),
2365         .key_type_id = 1,
2366         .value_type_id = 1,
2367         .max_entries = 4,
2368         .btf_load_err = true,
2369         .err_str = "Invalid btf_info kind_flag",
2370 },
2371
2372 {
2373         .descr = "invalid restrict kind_flag",
2374         .raw_types = {
2375                 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),                  /* [1] */
2376                 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_RESTRICT, 1, 0), 1),      /* [2] */
2377                 BTF_END_RAW,
2378         },
2379         BTF_STR_SEC(""),
2380         .map_type = BPF_MAP_TYPE_ARRAY,
2381         .map_name = "restrict_type_check_btf",
2382         .key_size = sizeof(int),
2383         .value_size = sizeof(int),
2384         .key_type_id = 1,
2385         .value_type_id = 1,
2386         .max_entries = 4,
2387         .btf_load_err = true,
2388         .err_str = "Invalid btf_info kind_flag",
2389 },
2390
2391 {
2392         .descr = "invalid func kind_flag",
2393         .raw_types = {
2394                 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),                  /* [1] */
2395                 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_FUNC_PROTO, 0, 0), 0),    /* [2] */
2396                 BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_FUNC, 1, 0), 2),   /* [3] */
2397                 BTF_END_RAW,
2398         },
2399         BTF_STR_SEC("\0A"),
2400         .map_type = BPF_MAP_TYPE_ARRAY,
2401         .map_name = "func_type_check_btf",
2402         .key_size = sizeof(int),
2403         .value_size = sizeof(int),
2404         .key_type_id = 1,
2405         .value_type_id = 1,
2406         .max_entries = 4,
2407         .btf_load_err = true,
2408         .err_str = "Invalid btf_info kind_flag",
2409 },
2410
2411 {
2412         .descr = "invalid func_proto kind_flag",
2413         .raw_types = {
2414                 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),                  /* [1] */
2415                 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_FUNC_PROTO, 1, 0), 0),    /* [2] */
2416                 BTF_END_RAW,
2417         },
2418         BTF_STR_SEC(""),
2419         .map_type = BPF_MAP_TYPE_ARRAY,
2420         .map_name = "func_proto_type_check_btf",
2421         .key_size = sizeof(int),
2422         .value_size = sizeof(int),
2423         .key_type_id = 1,
2424         .value_type_id = 1,
2425         .max_entries = 4,
2426         .btf_load_err = true,
2427         .err_str = "Invalid btf_info kind_flag",
2428 },
2429
2430 {
2431         .descr = "valid struct, kind_flag, bitfield_size = 0",
2432         .raw_types = {
2433                 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),                  /* [1] */
2434                 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_STRUCT, 1, 2), 8),        /* [2] */
2435                 BTF_MEMBER_ENC(NAME_TBD, 1, BTF_MEMBER_OFFSET(0, 0)),
2436                 BTF_MEMBER_ENC(NAME_TBD, 1, BTF_MEMBER_OFFSET(0, 32)),
2437                 BTF_END_RAW,
2438         },
2439         BTF_STR_SEC("\0A\0B"),
2440         .map_type = BPF_MAP_TYPE_ARRAY,
2441         .map_name = "struct_type_check_btf",
2442         .key_size = sizeof(int),
2443         .value_size = sizeof(int),
2444         .key_type_id = 1,
2445         .value_type_id = 1,
2446         .max_entries = 4,
2447 },
2448
2449 {
2450         .descr = "valid struct, kind_flag, int member, bitfield_size != 0",
2451         .raw_types = {
2452                 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),                  /* [1] */
2453                 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_STRUCT, 1, 2), 4),        /* [2] */
2454                 BTF_MEMBER_ENC(NAME_TBD, 1, BTF_MEMBER_OFFSET(4, 0)),
2455                 BTF_MEMBER_ENC(NAME_TBD, 1, BTF_MEMBER_OFFSET(4, 4)),
2456                 BTF_END_RAW,
2457         },
2458         BTF_STR_SEC("\0A\0B"),
2459         .map_type = BPF_MAP_TYPE_ARRAY,
2460         .map_name = "struct_type_check_btf",
2461         .key_size = sizeof(int),
2462         .value_size = sizeof(int),
2463         .key_type_id = 1,
2464         .value_type_id = 1,
2465         .max_entries = 4,
2466 },
2467
2468 {
2469         .descr = "valid union, kind_flag, int member, bitfield_size != 0",
2470         .raw_types = {
2471                 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),          /* [1] */
2472                 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_UNION, 1, 2), 4), /* [2] */
2473                 BTF_MEMBER_ENC(NAME_TBD, 1, BTF_MEMBER_OFFSET(4, 0)),
2474                 BTF_MEMBER_ENC(NAME_TBD, 1, BTF_MEMBER_OFFSET(4, 0)),
2475                 BTF_END_RAW,
2476         },
2477         BTF_STR_SEC("\0A\0B"),
2478         .map_type = BPF_MAP_TYPE_ARRAY,
2479         .map_name = "union_type_check_btf",
2480         .key_size = sizeof(int),
2481         .value_size = sizeof(int),
2482         .key_type_id = 1,
2483         .value_type_id = 1,
2484         .max_entries = 4,
2485 },
2486
2487 {
2488         .descr = "valid struct, kind_flag, enum member, bitfield_size != 0",
2489         .raw_types = {
2490                 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),          /* [1] */
2491                 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_ENUM, 0, 1), 4),  /* [2] */
2492                 BTF_ENUM_ENC(NAME_TBD, 0),
2493                 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_STRUCT, 1, 2), 4),/* [3] */
2494                 BTF_MEMBER_ENC(NAME_TBD, 2, BTF_MEMBER_OFFSET(4, 0)),
2495                 BTF_MEMBER_ENC(NAME_TBD, 2, BTF_MEMBER_OFFSET(4, 4)),
2496                 BTF_END_RAW,
2497         },
2498         BTF_STR_SEC("\0A\0B\0C"),
2499         .map_type = BPF_MAP_TYPE_ARRAY,
2500         .map_name = "struct_type_check_btf",
2501         .key_size = sizeof(int),
2502         .value_size = sizeof(int),
2503         .key_type_id = 1,
2504         .value_type_id = 1,
2505         .max_entries = 4,
2506 },
2507
2508 {
2509         .descr = "valid union, kind_flag, enum member, bitfield_size != 0",
2510         .raw_types = {
2511                 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),          /* [1] */
2512                 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_ENUM, 0, 1), 4),  /* [2] */
2513                 BTF_ENUM_ENC(NAME_TBD, 0),
2514                 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_UNION, 1, 2), 4), /* [3] */
2515                 BTF_MEMBER_ENC(NAME_TBD, 2, BTF_MEMBER_OFFSET(4, 0)),
2516                 BTF_MEMBER_ENC(NAME_TBD, 2, BTF_MEMBER_OFFSET(4, 0)),
2517                 BTF_END_RAW,
2518         },
2519         BTF_STR_SEC("\0A\0B\0C"),
2520         .map_type = BPF_MAP_TYPE_ARRAY,
2521         .map_name = "union_type_check_btf",
2522         .key_size = sizeof(int),
2523         .value_size = sizeof(int),
2524         .key_type_id = 1,
2525         .value_type_id = 1,
2526         .max_entries = 4,
2527 },
2528
2529 {
2530         .descr = "valid struct, kind_flag, typedef member, bitfield_size != 0",
2531         .raw_types = {
2532                 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),          /* [1] */
2533                 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_ENUM, 0, 1), 4),  /* [2] */
2534                 BTF_ENUM_ENC(NAME_TBD, 0),
2535                 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_STRUCT, 1, 2), 4),/* [3] */
2536                 BTF_MEMBER_ENC(NAME_TBD, 4, BTF_MEMBER_OFFSET(4, 0)),
2537                 BTF_MEMBER_ENC(NAME_TBD, 5, BTF_MEMBER_OFFSET(4, 4)),
2538                 BTF_TYPEDEF_ENC(NAME_TBD, 1),                           /* [4] */
2539                 BTF_TYPEDEF_ENC(NAME_TBD, 2),                           /* [5] */
2540                 BTF_END_RAW,
2541         },
2542         BTF_STR_SEC("\0A\0B\0C\0D\0E"),
2543         .map_type = BPF_MAP_TYPE_ARRAY,
2544         .map_name = "struct_type_check_btf",
2545         .key_size = sizeof(int),
2546         .value_size = sizeof(int),
2547         .key_type_id = 1,
2548         .value_type_id = 1,
2549         .max_entries = 4,
2550 },
2551
2552 {
2553         .descr = "valid union, kind_flag, typedef member, bitfield_size != 0",
2554         .raw_types = {
2555                 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),          /* [1] */
2556                 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_ENUM, 0, 1), 4),  /* [2] */
2557                 BTF_ENUM_ENC(NAME_TBD, 0),
2558                 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_UNION, 1, 2), 4), /* [3] */
2559                 BTF_MEMBER_ENC(NAME_TBD, 4, BTF_MEMBER_OFFSET(4, 0)),
2560                 BTF_MEMBER_ENC(NAME_TBD, 5, BTF_MEMBER_OFFSET(4, 0)),
2561                 BTF_TYPEDEF_ENC(NAME_TBD, 1),                           /* [4] */
2562                 BTF_TYPEDEF_ENC(NAME_TBD, 2),                           /* [5] */
2563                 BTF_END_RAW,
2564         },
2565         BTF_STR_SEC("\0A\0B\0C\0D\0E"),
2566         .map_type = BPF_MAP_TYPE_ARRAY,
2567         .map_name = "union_type_check_btf",
2568         .key_size = sizeof(int),
2569         .value_size = sizeof(int),
2570         .key_type_id = 1,
2571         .value_type_id = 1,
2572         .max_entries = 4,
2573 },
2574
2575 {
2576         .descr = "invalid struct, kind_flag, bitfield_size greater than struct size",
2577         .raw_types = {
2578                 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),                  /* [1] */
2579                 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_STRUCT, 1, 2), 4),        /* [2] */
2580                 BTF_MEMBER_ENC(NAME_TBD, 1, BTF_MEMBER_OFFSET(20, 0)),
2581                 BTF_MEMBER_ENC(NAME_TBD, 1, BTF_MEMBER_OFFSET(20, 20)),
2582                 BTF_END_RAW,
2583         },
2584         BTF_STR_SEC("\0A\0B"),
2585         .map_type = BPF_MAP_TYPE_ARRAY,
2586         .map_name = "struct_type_check_btf",
2587         .key_size = sizeof(int),
2588         .value_size = sizeof(int),
2589         .key_type_id = 1,
2590         .value_type_id = 1,
2591         .max_entries = 4,
2592         .btf_load_err = true,
2593         .err_str = "Member exceeds struct_size",
2594 },
2595
2596 {
2597         .descr = "invalid struct, kind_flag, bitfield base_type int not regular",
2598         .raw_types = {
2599                 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),                  /* [1] */
2600                 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 20, 4),                  /* [2] */
2601                 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_STRUCT, 1, 2), 4),        /* [3] */
2602                 BTF_MEMBER_ENC(NAME_TBD, 2, BTF_MEMBER_OFFSET(20, 0)),
2603                 BTF_MEMBER_ENC(NAME_TBD, 2, BTF_MEMBER_OFFSET(20, 20)),
2604                 BTF_END_RAW,
2605         },
2606         BTF_STR_SEC("\0A\0B"),
2607         .map_type = BPF_MAP_TYPE_ARRAY,
2608         .map_name = "struct_type_check_btf",
2609         .key_size = sizeof(int),
2610         .value_size = sizeof(int),
2611         .key_type_id = 1,
2612         .value_type_id = 1,
2613         .max_entries = 4,
2614         .btf_load_err = true,
2615         .err_str = "Invalid member base type",
2616 },
2617
2618 {
2619         .descr = "invalid struct, kind_flag, base_type int not regular",
2620         .raw_types = {
2621                 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),                  /* [1] */
2622                 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 12, 4),                  /* [2] */
2623                 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_STRUCT, 1, 2), 4),        /* [3] */
2624                 BTF_MEMBER_ENC(NAME_TBD, 2, BTF_MEMBER_OFFSET(8, 0)),
2625                 BTF_MEMBER_ENC(NAME_TBD, 2, BTF_MEMBER_OFFSET(8, 8)),
2626                 BTF_END_RAW,
2627         },
2628         BTF_STR_SEC("\0A\0B"),
2629         .map_type = BPF_MAP_TYPE_ARRAY,
2630         .map_name = "struct_type_check_btf",
2631         .key_size = sizeof(int),
2632         .value_size = sizeof(int),
2633         .key_type_id = 1,
2634         .value_type_id = 1,
2635         .max_entries = 4,
2636         .btf_load_err = true,
2637         .err_str = "Invalid member base type",
2638 },
2639
2640 {
2641         .descr = "invalid union, kind_flag, bitfield_size greater than struct size",
2642         .raw_types = {
2643                 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),          /* [1] */
2644                 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_UNION, 1, 2), 2), /* [2] */
2645                 BTF_MEMBER_ENC(NAME_TBD, 1, BTF_MEMBER_OFFSET(8, 0)),
2646                 BTF_MEMBER_ENC(NAME_TBD, 1, BTF_MEMBER_OFFSET(20, 0)),
2647                 BTF_END_RAW,
2648         },
2649         BTF_STR_SEC("\0A\0B"),
2650         .map_type = BPF_MAP_TYPE_ARRAY,
2651         .map_name = "union_type_check_btf",
2652         .key_size = sizeof(int),
2653         .value_size = sizeof(int),
2654         .key_type_id = 1,
2655         .value_type_id = 1,
2656         .max_entries = 4,
2657         .btf_load_err = true,
2658         .err_str = "Member exceeds struct_size",
2659 },
2660
2661 {
2662         .descr = "invalid struct, kind_flag, int member, bitfield_size = 0, wrong byte alignment",
2663         .raw_types = {
2664                 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),                  /* [1] */
2665                 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),                  /* [2] */
2666                 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_STRUCT, 1, 2), 12),       /* [3] */
2667                 BTF_MEMBER_ENC(NAME_TBD, 2, BTF_MEMBER_OFFSET(0, 0)),
2668                 BTF_MEMBER_ENC(NAME_TBD, 2, BTF_MEMBER_OFFSET(0, 36)),
2669                 BTF_END_RAW,
2670         },
2671         BTF_STR_SEC("\0A\0B"),
2672         .map_type = BPF_MAP_TYPE_ARRAY,
2673         .map_name = "struct_type_check_btf",
2674         .key_size = sizeof(int),
2675         .value_size = sizeof(int),
2676         .key_type_id = 1,
2677         .value_type_id = 1,
2678         .max_entries = 4,
2679         .btf_load_err = true,
2680         .err_str = "Invalid member offset",
2681 },
2682
2683 {
2684         .descr = "invalid struct, kind_flag, enum member, bitfield_size = 0, wrong byte alignment",
2685         .raw_types = {
2686                 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),                  /* [1] */
2687                 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),                  /* [2] */
2688                 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_ENUM, 0, 1), 4),  /* [2] */
2689                 BTF_ENUM_ENC(NAME_TBD, 0),
2690                 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_STRUCT, 1, 2), 12),       /* [3] */
2691                 BTF_MEMBER_ENC(NAME_TBD, 2, BTF_MEMBER_OFFSET(0, 0)),
2692                 BTF_MEMBER_ENC(NAME_TBD, 2, BTF_MEMBER_OFFSET(0, 36)),
2693                 BTF_END_RAW,
2694         },
2695         BTF_STR_SEC("\0A\0B\0C"),
2696         .map_type = BPF_MAP_TYPE_ARRAY,
2697         .map_name = "struct_type_check_btf",
2698         .key_size = sizeof(int),
2699         .value_size = sizeof(int),
2700         .key_type_id = 1,
2701         .value_type_id = 1,
2702         .max_entries = 4,
2703         .btf_load_err = true,
2704         .err_str = "Invalid member offset",
2705 },
2706
2707 }; /* struct btf_raw_test raw_tests[] */
2708
2709 static const char *get_next_str(const char *start, const char *end)
2710 {
2711         return start < end - 1 ? start + 1 : NULL;
2712 }
2713
2714 static int get_raw_sec_size(const __u32 *raw_types)
2715 {
2716         int i;
2717
2718         for (i = MAX_NR_RAW_U32 - 1;
2719              i >= 0 && raw_types[i] != BTF_END_RAW;
2720              i--)
2721                 ;
2722
2723         return i < 0 ? i : i * sizeof(raw_types[0]);
2724 }
2725
2726 static void *btf_raw_create(const struct btf_header *hdr,
2727                             const __u32 *raw_types,
2728                             const char *str,
2729                             unsigned int str_sec_size,
2730                             unsigned int *btf_size,
2731                             const char **ret_next_str)
2732 {
2733         const char *next_str = str, *end_str = str + str_sec_size;
2734         unsigned int size_needed, offset;
2735         struct btf_header *ret_hdr;
2736         int i, type_sec_size;
2737         uint32_t *ret_types;
2738         void *raw_btf;
2739
2740         type_sec_size = get_raw_sec_size(raw_types);
2741         if (CHECK(type_sec_size < 0, "Cannot get nr_raw_types"))
2742                 return NULL;
2743
2744         size_needed = sizeof(*hdr) + type_sec_size + str_sec_size;
2745         raw_btf = malloc(size_needed);
2746         if (CHECK(!raw_btf, "Cannot allocate memory for raw_btf"))
2747                 return NULL;
2748
2749         /* Copy header */
2750         memcpy(raw_btf, hdr, sizeof(*hdr));
2751         offset = sizeof(*hdr);
2752
2753         /* Copy type section */
2754         ret_types = raw_btf + offset;
2755         for (i = 0; i < type_sec_size / sizeof(raw_types[0]); i++) {
2756                 if (raw_types[i] == NAME_TBD) {
2757                         next_str = get_next_str(next_str, end_str);
2758                         if (CHECK(!next_str, "Error in getting next_str")) {
2759                                 free(raw_btf);
2760                                 return NULL;
2761                         }
2762                         ret_types[i] = next_str - str;
2763                         next_str += strlen(next_str);
2764                 } else {
2765                         ret_types[i] = raw_types[i];
2766                 }
2767         }
2768         offset += type_sec_size;
2769
2770         /* Copy string section */
2771         memcpy(raw_btf + offset, str, str_sec_size);
2772
2773         ret_hdr = (struct btf_header *)raw_btf;
2774         ret_hdr->type_len = type_sec_size;
2775         ret_hdr->str_off = type_sec_size;
2776         ret_hdr->str_len = str_sec_size;
2777
2778         *btf_size = size_needed;
2779         if (ret_next_str)
2780                 *ret_next_str = next_str;
2781
2782         return raw_btf;
2783 }
2784
2785 static int do_test_raw(unsigned int test_num)
2786 {
2787         struct btf_raw_test *test = &raw_tests[test_num - 1];
2788         struct bpf_create_map_attr create_attr = {};
2789         int map_fd = -1, btf_fd = -1;
2790         unsigned int raw_btf_size;
2791         struct btf_header *hdr;
2792         void *raw_btf;
2793         int err;
2794
2795         fprintf(stderr, "BTF raw test[%u] (%s): ", test_num, test->descr);
2796         raw_btf = btf_raw_create(&hdr_tmpl,
2797                                  test->raw_types,
2798                                  test->str_sec,
2799                                  test->str_sec_size,
2800                                  &raw_btf_size, NULL);
2801
2802         if (!raw_btf)
2803                 return -1;
2804
2805         hdr = raw_btf;
2806
2807         hdr->hdr_len = (int)hdr->hdr_len + test->hdr_len_delta;
2808         hdr->type_off = (int)hdr->type_off + test->type_off_delta;
2809         hdr->str_off = (int)hdr->str_off + test->str_off_delta;
2810         hdr->str_len = (int)hdr->str_len + test->str_len_delta;
2811
2812         *btf_log_buf = '\0';
2813         btf_fd = bpf_load_btf(raw_btf, raw_btf_size,
2814                               btf_log_buf, BTF_LOG_BUF_SIZE,
2815                               args.always_log);
2816         free(raw_btf);
2817
2818         err = ((btf_fd == -1) != test->btf_load_err);
2819         if (CHECK(err, "btf_fd:%d test->btf_load_err:%u",
2820                   btf_fd, test->btf_load_err) ||
2821             CHECK(test->err_str && !strstr(btf_log_buf, test->err_str),
2822                   "expected err_str:%s", test->err_str)) {
2823                 err = -1;
2824                 goto done;
2825         }
2826
2827         if (err || btf_fd == -1)
2828                 goto done;
2829
2830         create_attr.name = test->map_name;
2831         create_attr.map_type = test->map_type;
2832         create_attr.key_size = test->key_size;
2833         create_attr.value_size = test->value_size;
2834         create_attr.max_entries = test->max_entries;
2835         create_attr.btf_fd = btf_fd;
2836         create_attr.btf_key_type_id = test->key_type_id;
2837         create_attr.btf_value_type_id = test->value_type_id;
2838
2839         map_fd = bpf_create_map_xattr(&create_attr);
2840
2841         err = ((map_fd == -1) != test->map_create_err);
2842         CHECK(err, "map_fd:%d test->map_create_err:%u",
2843               map_fd, test->map_create_err);
2844
2845 done:
2846         if (!err)
2847                 fprintf(stderr, "OK");
2848
2849         if (*btf_log_buf && (err || args.always_log))
2850                 fprintf(stderr, "\n%s", btf_log_buf);
2851
2852         if (btf_fd != -1)
2853                 close(btf_fd);
2854         if (map_fd != -1)
2855                 close(map_fd);
2856
2857         return err;
2858 }
2859
2860 static int test_raw(void)
2861 {
2862         unsigned int i;
2863         int err = 0;
2864
2865         if (args.raw_test_num)
2866                 return count_result(do_test_raw(args.raw_test_num));
2867
2868         for (i = 1; i <= ARRAY_SIZE(raw_tests); i++)
2869                 err |= count_result(do_test_raw(i));
2870
2871         return err;
2872 }
2873
2874 struct btf_get_info_test {
2875         const char *descr;
2876         const char *str_sec;
2877         __u32 raw_types[MAX_NR_RAW_U32];
2878         __u32 str_sec_size;
2879         int btf_size_delta;
2880         int (*special_test)(unsigned int test_num);
2881 };
2882
2883 static int test_big_btf_info(unsigned int test_num);
2884 static int test_btf_id(unsigned int test_num);
2885
2886 const struct btf_get_info_test get_info_tests[] = {
2887 {
2888         .descr = "== raw_btf_size+1",
2889         .raw_types = {
2890                 /* int */                               /* [1] */
2891                 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
2892                 BTF_END_RAW,
2893         },
2894         .str_sec = "",
2895         .str_sec_size = sizeof(""),
2896         .btf_size_delta = 1,
2897 },
2898 {
2899         .descr = "== raw_btf_size-3",
2900         .raw_types = {
2901                 /* int */                               /* [1] */
2902                 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
2903                 BTF_END_RAW,
2904         },
2905         .str_sec = "",
2906         .str_sec_size = sizeof(""),
2907         .btf_size_delta = -3,
2908 },
2909 {
2910         .descr = "Large bpf_btf_info",
2911         .raw_types = {
2912                 /* int */                               /* [1] */
2913                 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
2914                 BTF_END_RAW,
2915         },
2916         .str_sec = "",
2917         .str_sec_size = sizeof(""),
2918         .special_test = test_big_btf_info,
2919 },
2920 {
2921         .descr = "BTF ID",
2922         .raw_types = {
2923                 /* int */                               /* [1] */
2924                 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
2925                 /* unsigned int */                      /* [2] */
2926                 BTF_TYPE_INT_ENC(0, 0, 0, 32, 4),
2927                 BTF_END_RAW,
2928         },
2929         .str_sec = "",
2930         .str_sec_size = sizeof(""),
2931         .special_test = test_btf_id,
2932 },
2933 };
2934
2935 static inline __u64 ptr_to_u64(const void *ptr)
2936 {
2937         return (__u64)(unsigned long)ptr;
2938 }
2939
2940 static int test_big_btf_info(unsigned int test_num)
2941 {
2942         const struct btf_get_info_test *test = &get_info_tests[test_num - 1];
2943         uint8_t *raw_btf = NULL, *user_btf = NULL;
2944         unsigned int raw_btf_size;
2945         struct {
2946                 struct bpf_btf_info info;
2947                 uint64_t garbage;
2948         } info_garbage;
2949         struct bpf_btf_info *info;
2950         int btf_fd = -1, err;
2951         uint32_t info_len;
2952
2953         raw_btf = btf_raw_create(&hdr_tmpl,
2954                                  test->raw_types,
2955                                  test->str_sec,
2956                                  test->str_sec_size,
2957                                  &raw_btf_size, NULL);
2958
2959         if (!raw_btf)
2960                 return -1;
2961
2962         *btf_log_buf = '\0';
2963
2964         user_btf = malloc(raw_btf_size);
2965         if (CHECK(!user_btf, "!user_btf")) {
2966                 err = -1;
2967                 goto done;
2968         }
2969
2970         btf_fd = bpf_load_btf(raw_btf, raw_btf_size,
2971                               btf_log_buf, BTF_LOG_BUF_SIZE,
2972                               args.always_log);
2973         if (CHECK(btf_fd == -1, "errno:%d", errno)) {
2974                 err = -1;
2975                 goto done;
2976         }
2977
2978         /*
2979          * GET_INFO should error out if the userspace info
2980          * has non zero tailing bytes.
2981          */
2982         info = &info_garbage.info;
2983         memset(info, 0, sizeof(*info));
2984         info_garbage.garbage = 0xdeadbeef;
2985         info_len = sizeof(info_garbage);
2986         info->btf = ptr_to_u64(user_btf);
2987         info->btf_size = raw_btf_size;
2988
2989         err = bpf_obj_get_info_by_fd(btf_fd, info, &info_len);
2990         if (CHECK(!err, "!err")) {
2991                 err = -1;
2992                 goto done;
2993         }
2994
2995         /*
2996          * GET_INFO should succeed even info_len is larger than
2997          * the kernel supported as long as tailing bytes are zero.
2998          * The kernel supported info len should also be returned
2999          * to userspace.
3000          */
3001         info_garbage.garbage = 0;
3002         err = bpf_obj_get_info_by_fd(btf_fd, info, &info_len);
3003         if (CHECK(err || info_len != sizeof(*info),
3004                   "err:%d errno:%d info_len:%u sizeof(*info):%lu",
3005                   err, errno, info_len, sizeof(*info))) {
3006                 err = -1;
3007                 goto done;
3008         }
3009
3010         fprintf(stderr, "OK");
3011
3012 done:
3013         if (*btf_log_buf && (err || args.always_log))
3014                 fprintf(stderr, "\n%s", btf_log_buf);
3015
3016         free(raw_btf);
3017         free(user_btf);
3018
3019         if (btf_fd != -1)
3020                 close(btf_fd);
3021
3022         return err;
3023 }
3024
3025 static int test_btf_id(unsigned int test_num)
3026 {
3027         const struct btf_get_info_test *test = &get_info_tests[test_num - 1];
3028         struct bpf_create_map_attr create_attr = {};
3029         uint8_t *raw_btf = NULL, *user_btf[2] = {};
3030         int btf_fd[2] = {-1, -1}, map_fd = -1;
3031         struct bpf_map_info map_info = {};
3032         struct bpf_btf_info info[2] = {};
3033         unsigned int raw_btf_size;
3034         uint32_t info_len;
3035         int err, i, ret;
3036
3037         raw_btf = btf_raw_create(&hdr_tmpl,
3038                                  test->raw_types,
3039                                  test->str_sec,
3040                                  test->str_sec_size,
3041                                  &raw_btf_size, NULL);
3042
3043         if (!raw_btf)
3044                 return -1;
3045
3046         *btf_log_buf = '\0';
3047
3048         for (i = 0; i < 2; i++) {
3049                 user_btf[i] = malloc(raw_btf_size);
3050                 if (CHECK(!user_btf[i], "!user_btf[%d]", i)) {
3051                         err = -1;
3052                         goto done;
3053                 }
3054                 info[i].btf = ptr_to_u64(user_btf[i]);
3055                 info[i].btf_size = raw_btf_size;
3056         }
3057
3058         btf_fd[0] = bpf_load_btf(raw_btf, raw_btf_size,
3059                                  btf_log_buf, BTF_LOG_BUF_SIZE,
3060                                  args.always_log);
3061         if (CHECK(btf_fd[0] == -1, "errno:%d", errno)) {
3062                 err = -1;
3063                 goto done;
3064         }
3065
3066         /* Test BPF_OBJ_GET_INFO_BY_ID on btf_id */
3067         info_len = sizeof(info[0]);
3068         err = bpf_obj_get_info_by_fd(btf_fd[0], &info[0], &info_len);
3069         if (CHECK(err, "errno:%d", errno)) {
3070                 err = -1;
3071                 goto done;
3072         }
3073
3074         btf_fd[1] = bpf_btf_get_fd_by_id(info[0].id);
3075         if (CHECK(btf_fd[1] == -1, "errno:%d", errno)) {
3076                 err = -1;
3077                 goto done;
3078         }
3079
3080         ret = 0;
3081         err = bpf_obj_get_info_by_fd(btf_fd[1], &info[1], &info_len);
3082         if (CHECK(err || info[0].id != info[1].id ||
3083                   info[0].btf_size != info[1].btf_size ||
3084                   (ret = memcmp(user_btf[0], user_btf[1], info[0].btf_size)),
3085                   "err:%d errno:%d id0:%u id1:%u btf_size0:%u btf_size1:%u memcmp:%d",
3086                   err, errno, info[0].id, info[1].id,
3087                   info[0].btf_size, info[1].btf_size, ret)) {
3088                 err = -1;
3089                 goto done;
3090         }
3091
3092         /* Test btf members in struct bpf_map_info */
3093         create_attr.name = "test_btf_id";
3094         create_attr.map_type = BPF_MAP_TYPE_ARRAY;
3095         create_attr.key_size = sizeof(int);
3096         create_attr.value_size = sizeof(unsigned int);
3097         create_attr.max_entries = 4;
3098         create_attr.btf_fd = btf_fd[0];
3099         create_attr.btf_key_type_id = 1;
3100         create_attr.btf_value_type_id = 2;
3101
3102         map_fd = bpf_create_map_xattr(&create_attr);
3103         if (CHECK(map_fd == -1, "errno:%d", errno)) {
3104                 err = -1;
3105                 goto done;
3106         }
3107
3108         info_len = sizeof(map_info);
3109         err = bpf_obj_get_info_by_fd(map_fd, &map_info, &info_len);
3110         if (CHECK(err || map_info.btf_id != info[0].id ||
3111                   map_info.btf_key_type_id != 1 || map_info.btf_value_type_id != 2,
3112                   "err:%d errno:%d info.id:%u btf_id:%u btf_key_type_id:%u btf_value_type_id:%u",
3113                   err, errno, info[0].id, map_info.btf_id, map_info.btf_key_type_id,
3114                   map_info.btf_value_type_id)) {
3115                 err = -1;
3116                 goto done;
3117         }
3118
3119         for (i = 0; i < 2; i++) {
3120                 close(btf_fd[i]);
3121                 btf_fd[i] = -1;
3122         }
3123
3124         /* Test BTF ID is removed from the kernel */
3125         btf_fd[0] = bpf_btf_get_fd_by_id(map_info.btf_id);
3126         if (CHECK(btf_fd[0] == -1, "errno:%d", errno)) {
3127                 err = -1;
3128                 goto done;
3129         }
3130         close(btf_fd[0]);
3131         btf_fd[0] = -1;
3132
3133         /* The map holds the last ref to BTF and its btf_id */
3134         close(map_fd);
3135         map_fd = -1;
3136         btf_fd[0] = bpf_btf_get_fd_by_id(map_info.btf_id);
3137         if (CHECK(btf_fd[0] != -1, "BTF lingers")) {
3138                 err = -1;
3139                 goto done;
3140         }
3141
3142         fprintf(stderr, "OK");
3143
3144 done:
3145         if (*btf_log_buf && (err || args.always_log))
3146                 fprintf(stderr, "\n%s", btf_log_buf);
3147
3148         free(raw_btf);
3149         if (map_fd != -1)
3150                 close(map_fd);
3151         for (i = 0; i < 2; i++) {
3152                 free(user_btf[i]);
3153                 if (btf_fd[i] != -1)
3154                         close(btf_fd[i]);
3155         }
3156
3157         return err;
3158 }
3159
3160 static int do_test_get_info(unsigned int test_num)
3161 {
3162         const struct btf_get_info_test *test = &get_info_tests[test_num - 1];
3163         unsigned int raw_btf_size, user_btf_size, expected_nbytes;
3164         uint8_t *raw_btf = NULL, *user_btf = NULL;
3165         struct bpf_btf_info info = {};
3166         int btf_fd = -1, err, ret;
3167         uint32_t info_len;
3168
3169         fprintf(stderr, "BTF GET_INFO test[%u] (%s): ",
3170                 test_num, test->descr);
3171
3172         if (test->special_test)
3173                 return test->special_test(test_num);
3174
3175         raw_btf = btf_raw_create(&hdr_tmpl,
3176                                  test->raw_types,
3177                                  test->str_sec,
3178                                  test->str_sec_size,
3179                                  &raw_btf_size, NULL);
3180
3181         if (!raw_btf)
3182                 return -1;
3183
3184         *btf_log_buf = '\0';
3185
3186         user_btf = malloc(raw_btf_size);
3187         if (CHECK(!user_btf, "!user_btf")) {
3188                 err = -1;
3189                 goto done;
3190         }
3191
3192         btf_fd = bpf_load_btf(raw_btf, raw_btf_size,
3193                               btf_log_buf, BTF_LOG_BUF_SIZE,
3194                               args.always_log);
3195         if (CHECK(btf_fd == -1, "errno:%d", errno)) {
3196                 err = -1;
3197                 goto done;
3198         }
3199
3200         user_btf_size = (int)raw_btf_size + test->btf_size_delta;
3201         expected_nbytes = min(raw_btf_size, user_btf_size);
3202         if (raw_btf_size > expected_nbytes)
3203                 memset(user_btf + expected_nbytes, 0xff,
3204                        raw_btf_size - expected_nbytes);
3205
3206         info_len = sizeof(info);
3207         info.btf = ptr_to_u64(user_btf);
3208         info.btf_size = user_btf_size;
3209
3210         ret = 0;
3211         err = bpf_obj_get_info_by_fd(btf_fd, &info, &info_len);
3212         if (CHECK(err || !info.id || info_len != sizeof(info) ||
3213                   info.btf_size != raw_btf_size ||
3214                   (ret = memcmp(raw_btf, user_btf, expected_nbytes)),
3215                   "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",
3216                   err, errno, info.id, info_len, sizeof(info),
3217                   raw_btf_size, info.btf_size, expected_nbytes, ret)) {
3218                 err = -1;
3219                 goto done;
3220         }
3221
3222         while (expected_nbytes < raw_btf_size) {
3223                 fprintf(stderr, "%u...", expected_nbytes);
3224                 if (CHECK(user_btf[expected_nbytes++] != 0xff,
3225                           "user_btf[%u]:%x != 0xff", expected_nbytes - 1,
3226                           user_btf[expected_nbytes - 1])) {
3227                         err = -1;
3228                         goto done;
3229                 }
3230         }
3231
3232         fprintf(stderr, "OK");
3233
3234 done:
3235         if (*btf_log_buf && (err || args.always_log))
3236                 fprintf(stderr, "\n%s", btf_log_buf);
3237
3238         free(raw_btf);
3239         free(user_btf);
3240
3241         if (btf_fd != -1)
3242                 close(btf_fd);
3243
3244         return err;
3245 }
3246
3247 static int test_get_info(void)
3248 {
3249         unsigned int i;
3250         int err = 0;
3251
3252         if (args.get_info_test_num)
3253                 return count_result(do_test_get_info(args.get_info_test_num));
3254
3255         for (i = 1; i <= ARRAY_SIZE(get_info_tests); i++)
3256                 err |= count_result(do_test_get_info(i));
3257
3258         return err;
3259 }
3260
3261 struct btf_file_test {
3262         const char *file;
3263         bool btf_kv_notfound;
3264 };
3265
3266 static struct btf_file_test file_tests[] = {
3267 {
3268         .file = "test_btf_haskv.o",
3269 },
3270 {
3271         .file = "test_btf_nokv.o",
3272         .btf_kv_notfound = true,
3273 },
3274 };
3275
3276 static int file_has_btf_elf(const char *fn, bool *has_btf_ext)
3277 {
3278         Elf_Scn *scn = NULL;
3279         GElf_Ehdr ehdr;
3280         int ret = 0;
3281         int elf_fd;
3282         Elf *elf;
3283
3284         if (CHECK(elf_version(EV_CURRENT) == EV_NONE,
3285                   "elf_version(EV_CURRENT) == EV_NONE"))
3286                 return -1;
3287
3288         elf_fd = open(fn, O_RDONLY);
3289         if (CHECK(elf_fd == -1, "open(%s): errno:%d", fn, errno))
3290                 return -1;
3291
3292         elf = elf_begin(elf_fd, ELF_C_READ, NULL);
3293         if (CHECK(!elf, "elf_begin(%s): %s", fn, elf_errmsg(elf_errno()))) {
3294                 ret = -1;
3295                 goto done;
3296         }
3297
3298         if (CHECK(!gelf_getehdr(elf, &ehdr), "!gelf_getehdr(%s)", fn)) {
3299                 ret = -1;
3300                 goto done;
3301         }
3302
3303         while ((scn = elf_nextscn(elf, scn))) {
3304                 const char *sh_name;
3305                 GElf_Shdr sh;
3306
3307                 if (CHECK(gelf_getshdr(scn, &sh) != &sh,
3308                           "file:%s gelf_getshdr != &sh", fn)) {
3309                         ret = -1;
3310                         goto done;
3311                 }
3312
3313                 sh_name = elf_strptr(elf, ehdr.e_shstrndx, sh.sh_name);
3314                 if (!strcmp(sh_name, BTF_ELF_SEC))
3315                         ret = 1;
3316                 if (!strcmp(sh_name, BTF_EXT_ELF_SEC))
3317                         *has_btf_ext = true;
3318         }
3319
3320 done:
3321         close(elf_fd);
3322         elf_end(elf);
3323         return ret;
3324 }
3325
3326 static int do_test_file(unsigned int test_num)
3327 {
3328         const struct btf_file_test *test = &file_tests[test_num - 1];
3329         const char *expected_fnames[] = {"_dummy_tracepoint",
3330                                          "test_long_fname_1",
3331                                          "test_long_fname_2"};
3332         struct bpf_prog_info info = {};
3333         struct bpf_object *obj = NULL;
3334         struct bpf_func_info *finfo;
3335         struct bpf_program *prog;
3336         __u32 info_len, rec_size;
3337         bool has_btf_ext = false;
3338         struct btf *btf = NULL;
3339         void *func_info = NULL;
3340         struct bpf_map *map;
3341         int i, err, prog_fd;
3342
3343         fprintf(stderr, "BTF libbpf test[%u] (%s): ", test_num,
3344                 test->file);
3345
3346         err = file_has_btf_elf(test->file, &has_btf_ext);
3347         if (err == -1)
3348                 return err;
3349
3350         if (err == 0) {
3351                 fprintf(stderr, "SKIP. No ELF %s found", BTF_ELF_SEC);
3352                 skip_cnt++;
3353                 return 0;
3354         }
3355
3356         obj = bpf_object__open(test->file);
3357         if (CHECK(IS_ERR(obj), "obj: %ld", PTR_ERR(obj)))
3358                 return PTR_ERR(obj);
3359
3360         err = bpf_object__btf_fd(obj);
3361         if (CHECK(err == -1, "bpf_object__btf_fd: -1"))
3362                 goto done;
3363
3364         prog = bpf_program__next(NULL, obj);
3365         if (CHECK(!prog, "Cannot find bpf_prog")) {
3366                 err = -1;
3367                 goto done;
3368         }
3369
3370         bpf_program__set_type(prog, BPF_PROG_TYPE_TRACEPOINT);
3371         err = bpf_object__load(obj);
3372         if (CHECK(err < 0, "bpf_object__load: %d", err))
3373                 goto done;
3374         prog_fd = bpf_program__fd(prog);
3375
3376         map = bpf_object__find_map_by_name(obj, "btf_map");
3377         if (CHECK(!map, "btf_map not found")) {
3378                 err = -1;
3379                 goto done;
3380         }
3381
3382         err = (bpf_map__btf_key_type_id(map) == 0 || bpf_map__btf_value_type_id(map) == 0)
3383                 != test->btf_kv_notfound;
3384         if (CHECK(err, "btf_key_type_id:%u btf_value_type_id:%u test->btf_kv_notfound:%u",
3385                   bpf_map__btf_key_type_id(map), bpf_map__btf_value_type_id(map),
3386                   test->btf_kv_notfound))
3387                 goto done;
3388
3389         if (!has_btf_ext)
3390                 goto skip;
3391
3392         /* get necessary program info */
3393         info_len = sizeof(struct bpf_prog_info);
3394         err = bpf_obj_get_info_by_fd(prog_fd, &info, &info_len);
3395
3396         if (CHECK(err == -1, "invalid get info (1st) errno:%d", errno)) {
3397                 fprintf(stderr, "%s\n", btf_log_buf);
3398                 err = -1;
3399                 goto done;
3400         }
3401         if (CHECK(info.nr_func_info != 3,
3402                   "incorrect info.nr_func_info (1st) %d",
3403                   info.nr_func_info)) {
3404                 err = -1;
3405                 goto done;
3406         }
3407         rec_size = info.func_info_rec_size;
3408         if (CHECK(rec_size != sizeof(struct bpf_func_info),
3409                   "incorrect info.func_info_rec_size (1st) %d\n", rec_size)) {
3410                 err = -1;
3411                 goto done;
3412         }
3413
3414         func_info = malloc(info.nr_func_info * rec_size);
3415         if (CHECK(!func_info, "out of memory")) {
3416                 err = -1;
3417                 goto done;
3418         }
3419
3420         /* reset info to only retrieve func_info related data */
3421         memset(&info, 0, sizeof(info));
3422         info.nr_func_info = 3;
3423         info.func_info_rec_size = rec_size;
3424         info.func_info = ptr_to_u64(func_info);
3425
3426         err = bpf_obj_get_info_by_fd(prog_fd, &info, &info_len);
3427
3428         if (CHECK(err == -1, "invalid get info (2nd) errno:%d", errno)) {
3429                 fprintf(stderr, "%s\n", btf_log_buf);
3430                 err = -1;
3431                 goto done;
3432         }
3433         if (CHECK(info.nr_func_info != 3,
3434                   "incorrect info.nr_func_info (2nd) %d",
3435                   info.nr_func_info)) {
3436                 err = -1;
3437                 goto done;
3438         }
3439         if (CHECK(info.func_info_rec_size != rec_size,
3440                   "incorrect info.func_info_rec_size (2nd) %d",
3441                   info.func_info_rec_size)) {
3442                 err = -1;
3443                 goto done;
3444         }
3445
3446         err = btf__get_from_id(info.btf_id, &btf);
3447         if (CHECK(err, "cannot get btf from kernel, err: %d", err))
3448                 goto done;
3449
3450         /* check three functions */
3451         finfo = func_info;
3452         for (i = 0; i < 3; i++) {
3453                 const struct btf_type *t;
3454                 const char *fname;
3455
3456                 t = btf__type_by_id(btf, finfo->type_id);
3457                 if (CHECK(!t, "btf__type_by_id failure: id %u",
3458                           finfo->type_id)) {
3459                         err = -1;
3460                         goto done;
3461                 }
3462
3463                 fname = btf__name_by_offset(btf, t->name_off);
3464                 err = strcmp(fname, expected_fnames[i]);
3465                 /* for the second and third functions in .text section,
3466                  * the compiler may order them either way.
3467                  */
3468                 if (i && err)
3469                         err = strcmp(fname, expected_fnames[3 - i]);
3470                 if (CHECK(err, "incorrect fname %s", fname ? : "")) {
3471                         err = -1;
3472                         goto done;
3473                 }
3474
3475                 finfo = (void *)finfo + rec_size;
3476         }
3477
3478 skip:
3479         fprintf(stderr, "OK");
3480
3481 done:
3482         free(func_info);
3483         bpf_object__close(obj);
3484         return err;
3485 }
3486
3487 static int test_file(void)
3488 {
3489         unsigned int i;
3490         int err = 0;
3491
3492         if (args.file_test_num)
3493                 return count_result(do_test_file(args.file_test_num));
3494
3495         for (i = 1; i <= ARRAY_SIZE(file_tests); i++)
3496                 err |= count_result(do_test_file(i));
3497
3498         return err;
3499 }
3500
3501 const char *pprint_enum_str[] = {
3502         "ENUM_ZERO",
3503         "ENUM_ONE",
3504         "ENUM_TWO",
3505         "ENUM_THREE",
3506 };
3507
3508 struct pprint_mapv {
3509         uint32_t ui32;
3510         uint16_t ui16;
3511         /* 2 bytes hole */
3512         int32_t si32;
3513         uint32_t unused_bits2a:2,
3514                 bits28:28,
3515                 unused_bits2b:2;
3516         union {
3517                 uint64_t ui64;
3518                 uint8_t ui8a[8];
3519         };
3520         enum {
3521                 ENUM_ZERO,
3522                 ENUM_ONE,
3523                 ENUM_TWO,
3524                 ENUM_THREE,
3525         } aenum;
3526         uint32_t ui32b;
3527         uint32_t bits2c:2;
3528 };
3529
3530 static struct btf_raw_test pprint_test_template[] = {
3531 {
3532         .raw_types = {
3533                 /* unsighed char */                     /* [1] */
3534                 BTF_TYPE_INT_ENC(NAME_TBD, 0, 0, 8, 1),
3535                 /* unsigned short */                    /* [2] */
3536                 BTF_TYPE_INT_ENC(NAME_TBD, 0, 0, 16, 2),
3537                 /* unsigned int */                      /* [3] */
3538                 BTF_TYPE_INT_ENC(NAME_TBD, 0, 0, 32, 4),
3539                 /* int */                               /* [4] */
3540                 BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),
3541                 /* unsigned long long */                /* [5] */
3542                 BTF_TYPE_INT_ENC(NAME_TBD, 0, 0, 64, 8),
3543                 /* 2 bits */                            /* [6] */
3544                 BTF_TYPE_INT_ENC(0, 0, 0, 2, 2),
3545                 /* 28 bits */                           /* [7] */
3546                 BTF_TYPE_INT_ENC(0, 0, 0, 28, 4),
3547                 /* uint8_t[8] */                        /* [8] */
3548                 BTF_TYPE_ARRAY_ENC(9, 1, 8),
3549                 /* typedef unsigned char uint8_t */     /* [9] */
3550                 BTF_TYPEDEF_ENC(NAME_TBD, 1),
3551                 /* typedef unsigned short uint16_t */   /* [10] */
3552                 BTF_TYPEDEF_ENC(NAME_TBD, 2),
3553                 /* typedef unsigned int uint32_t */     /* [11] */
3554                 BTF_TYPEDEF_ENC(NAME_TBD, 3),
3555                 /* typedef int int32_t */               /* [12] */
3556                 BTF_TYPEDEF_ENC(NAME_TBD, 4),
3557                 /* typedef unsigned long long uint64_t *//* [13] */
3558                 BTF_TYPEDEF_ENC(NAME_TBD, 5),
3559                 /* union (anon) */                      /* [14] */
3560                 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_UNION, 0, 2), 8),
3561                 BTF_MEMBER_ENC(NAME_TBD, 13, 0),/* uint64_t ui64; */
3562                 BTF_MEMBER_ENC(NAME_TBD, 8, 0), /* uint8_t ui8a[8]; */
3563                 /* enum (anon) */                       /* [15] */
3564                 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_ENUM, 0, 4), 4),
3565                 BTF_ENUM_ENC(NAME_TBD, 0),
3566                 BTF_ENUM_ENC(NAME_TBD, 1),
3567                 BTF_ENUM_ENC(NAME_TBD, 2),
3568                 BTF_ENUM_ENC(NAME_TBD, 3),
3569                 /* struct pprint_mapv */                /* [16] */
3570                 BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 10), 40),
3571                 BTF_MEMBER_ENC(NAME_TBD, 11, 0),        /* uint32_t ui32 */
3572                 BTF_MEMBER_ENC(NAME_TBD, 10, 32),       /* uint16_t ui16 */
3573                 BTF_MEMBER_ENC(NAME_TBD, 12, 64),       /* int32_t si32 */
3574                 BTF_MEMBER_ENC(NAME_TBD, 6, 96),        /* unused_bits2a */
3575                 BTF_MEMBER_ENC(NAME_TBD, 7, 98),        /* bits28 */
3576                 BTF_MEMBER_ENC(NAME_TBD, 6, 126),       /* unused_bits2b */
3577                 BTF_MEMBER_ENC(0, 14, 128),             /* union (anon) */
3578                 BTF_MEMBER_ENC(NAME_TBD, 15, 192),      /* aenum */
3579                 BTF_MEMBER_ENC(NAME_TBD, 11, 224),      /* uint32_t ui32b */
3580                 BTF_MEMBER_ENC(NAME_TBD, 6, 256),       /* bits2c */
3581                 BTF_END_RAW,
3582         },
3583         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"),
3584         .key_size = sizeof(unsigned int),
3585         .value_size = sizeof(struct pprint_mapv),
3586         .key_type_id = 3,       /* unsigned int */
3587         .value_type_id = 16,    /* struct pprint_mapv */
3588         .max_entries = 128 * 1024,
3589 },
3590
3591 {
3592         /* this type will have the same type as the
3593          * first .raw_types definition, but struct type will
3594          * be encoded with kind_flag set.
3595          */
3596         .raw_types = {
3597                 /* unsighed char */                     /* [1] */
3598                 BTF_TYPE_INT_ENC(NAME_TBD, 0, 0, 8, 1),
3599                 /* unsigned short */                    /* [2] */
3600                 BTF_TYPE_INT_ENC(NAME_TBD, 0, 0, 16, 2),
3601                 /* unsigned int */                      /* [3] */
3602                 BTF_TYPE_INT_ENC(NAME_TBD, 0, 0, 32, 4),
3603                 /* int */                               /* [4] */
3604                 BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),
3605                 /* unsigned long long */                /* [5] */
3606                 BTF_TYPE_INT_ENC(NAME_TBD, 0, 0, 64, 8),
3607                 BTF_TYPE_INT_ENC(0, 0, 0, 32, 4),       /* [6] */
3608                 BTF_TYPE_INT_ENC(0, 0, 0, 32, 4),       /* [7] */
3609                 /* uint8_t[8] */                        /* [8] */
3610                 BTF_TYPE_ARRAY_ENC(9, 1, 8),
3611                 /* typedef unsigned char uint8_t */     /* [9] */
3612                 BTF_TYPEDEF_ENC(NAME_TBD, 1),
3613                 /* typedef unsigned short uint16_t */   /* [10] */
3614                 BTF_TYPEDEF_ENC(NAME_TBD, 2),
3615                 /* typedef unsigned int uint32_t */     /* [11] */
3616                 BTF_TYPEDEF_ENC(NAME_TBD, 3),
3617                 /* typedef int int32_t */               /* [12] */
3618                 BTF_TYPEDEF_ENC(NAME_TBD, 4),
3619                 /* typedef unsigned long long uint64_t *//* [13] */
3620                 BTF_TYPEDEF_ENC(NAME_TBD, 5),
3621                 /* union (anon) */                      /* [14] */
3622                 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_UNION, 0, 2), 8),
3623                 BTF_MEMBER_ENC(NAME_TBD, 13, 0),/* uint64_t ui64; */
3624                 BTF_MEMBER_ENC(NAME_TBD, 8, 0), /* uint8_t ui8a[8]; */
3625                 /* enum (anon) */                       /* [15] */
3626                 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_ENUM, 0, 4), 4),
3627                 BTF_ENUM_ENC(NAME_TBD, 0),
3628                 BTF_ENUM_ENC(NAME_TBD, 1),
3629                 BTF_ENUM_ENC(NAME_TBD, 2),
3630                 BTF_ENUM_ENC(NAME_TBD, 3),
3631                 /* struct pprint_mapv */                /* [16] */
3632                 BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 1, 10), 40),
3633                 BTF_MEMBER_ENC(NAME_TBD, 11, BTF_MEMBER_OFFSET(0, 0)),  /* uint32_t ui32 */
3634                 BTF_MEMBER_ENC(NAME_TBD, 10, BTF_MEMBER_OFFSET(0, 32)), /* uint16_t ui16 */
3635                 BTF_MEMBER_ENC(NAME_TBD, 12, BTF_MEMBER_OFFSET(0, 64)), /* int32_t si32 */
3636                 BTF_MEMBER_ENC(NAME_TBD, 6, BTF_MEMBER_OFFSET(2, 96)),  /* unused_bits2a */
3637                 BTF_MEMBER_ENC(NAME_TBD, 7, BTF_MEMBER_OFFSET(28, 98)), /* bits28 */
3638                 BTF_MEMBER_ENC(NAME_TBD, 6, BTF_MEMBER_OFFSET(2, 126)), /* unused_bits2b */
3639                 BTF_MEMBER_ENC(0, 14, BTF_MEMBER_OFFSET(0, 128)),       /* union (anon) */
3640                 BTF_MEMBER_ENC(NAME_TBD, 15, BTF_MEMBER_OFFSET(0, 192)),        /* aenum */
3641                 BTF_MEMBER_ENC(NAME_TBD, 11, BTF_MEMBER_OFFSET(0, 224)),        /* uint32_t ui32b */
3642                 BTF_MEMBER_ENC(NAME_TBD, 6, BTF_MEMBER_OFFSET(2, 256)), /* bits2c */
3643                 BTF_END_RAW,
3644         },
3645         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"),
3646         .key_size = sizeof(unsigned int),
3647         .value_size = sizeof(struct pprint_mapv),
3648         .key_type_id = 3,       /* unsigned int */
3649         .value_type_id = 16,    /* struct pprint_mapv */
3650         .max_entries = 128 * 1024,
3651 },
3652
3653 {
3654         /* this type will have the same layout as the
3655          * first .raw_types definition. The struct type will
3656          * be encoded with kind_flag set, bitfield members
3657          * are added typedef/const/volatile, and bitfield members
3658          * will have both int and enum types.
3659          */
3660         .raw_types = {
3661                 /* unsighed char */                     /* [1] */
3662                 BTF_TYPE_INT_ENC(NAME_TBD, 0, 0, 8, 1),
3663                 /* unsigned short */                    /* [2] */
3664                 BTF_TYPE_INT_ENC(NAME_TBD, 0, 0, 16, 2),
3665                 /* unsigned int */                      /* [3] */
3666                 BTF_TYPE_INT_ENC(NAME_TBD, 0, 0, 32, 4),
3667                 /* int */                               /* [4] */
3668                 BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),
3669                 /* unsigned long long */                /* [5] */
3670                 BTF_TYPE_INT_ENC(NAME_TBD, 0, 0, 64, 8),
3671                 BTF_TYPE_INT_ENC(0, 0, 0, 32, 4),       /* [6] */
3672                 BTF_TYPE_INT_ENC(0, 0, 0, 32, 4),       /* [7] */
3673                 /* uint8_t[8] */                        /* [8] */
3674                 BTF_TYPE_ARRAY_ENC(9, 1, 8),
3675                 /* typedef unsigned char uint8_t */     /* [9] */
3676                 BTF_TYPEDEF_ENC(NAME_TBD, 1),
3677                 /* typedef unsigned short uint16_t */   /* [10] */
3678                 BTF_TYPEDEF_ENC(NAME_TBD, 2),
3679                 /* typedef unsigned int uint32_t */     /* [11] */
3680                 BTF_TYPEDEF_ENC(NAME_TBD, 3),
3681                 /* typedef int int32_t */               /* [12] */
3682                 BTF_TYPEDEF_ENC(NAME_TBD, 4),
3683                 /* typedef unsigned long long uint64_t *//* [13] */
3684                 BTF_TYPEDEF_ENC(NAME_TBD, 5),
3685                 /* union (anon) */                      /* [14] */
3686                 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_UNION, 0, 2), 8),
3687                 BTF_MEMBER_ENC(NAME_TBD, 13, 0),/* uint64_t ui64; */
3688                 BTF_MEMBER_ENC(NAME_TBD, 8, 0), /* uint8_t ui8a[8]; */
3689                 /* enum (anon) */                       /* [15] */
3690                 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_ENUM, 0, 4), 4),
3691                 BTF_ENUM_ENC(NAME_TBD, 0),
3692                 BTF_ENUM_ENC(NAME_TBD, 1),
3693                 BTF_ENUM_ENC(NAME_TBD, 2),
3694                 BTF_ENUM_ENC(NAME_TBD, 3),
3695                 /* struct pprint_mapv */                /* [16] */
3696                 BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 1, 10), 40),
3697                 BTF_MEMBER_ENC(NAME_TBD, 11, BTF_MEMBER_OFFSET(0, 0)),  /* uint32_t ui32 */
3698                 BTF_MEMBER_ENC(NAME_TBD, 10, BTF_MEMBER_OFFSET(0, 32)), /* uint16_t ui16 */
3699                 BTF_MEMBER_ENC(NAME_TBD, 12, BTF_MEMBER_OFFSET(0, 64)), /* int32_t si32 */
3700                 BTF_MEMBER_ENC(NAME_TBD, 17, BTF_MEMBER_OFFSET(2, 96)), /* unused_bits2a */
3701                 BTF_MEMBER_ENC(NAME_TBD, 7, BTF_MEMBER_OFFSET(28, 98)), /* bits28 */
3702                 BTF_MEMBER_ENC(NAME_TBD, 19, BTF_MEMBER_OFFSET(2, 126)),/* unused_bits2b */
3703                 BTF_MEMBER_ENC(0, 14, BTF_MEMBER_OFFSET(0, 128)),       /* union (anon) */
3704                 BTF_MEMBER_ENC(NAME_TBD, 15, BTF_MEMBER_OFFSET(0, 192)),        /* aenum */
3705                 BTF_MEMBER_ENC(NAME_TBD, 11, BTF_MEMBER_OFFSET(0, 224)),        /* uint32_t ui32b */
3706                 BTF_MEMBER_ENC(NAME_TBD, 17, BTF_MEMBER_OFFSET(2, 256)),        /* bits2c */
3707                 /* typedef unsigned int ___int */       /* [17] */
3708                 BTF_TYPEDEF_ENC(NAME_TBD, 18),
3709                 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_VOLATILE, 0, 0), 6),      /* [18] */
3710                 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_CONST, 0, 0), 15),        /* [19] */
3711                 BTF_END_RAW,
3712         },
3713         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"),
3714         .key_size = sizeof(unsigned int),
3715         .value_size = sizeof(struct pprint_mapv),
3716         .key_type_id = 3,       /* unsigned int */
3717         .value_type_id = 16,    /* struct pprint_mapv */
3718         .max_entries = 128 * 1024,
3719 },
3720
3721 };
3722
3723 static struct btf_pprint_test_meta {
3724         const char *descr;
3725         enum bpf_map_type map_type;
3726         const char *map_name;
3727         bool ordered_map;
3728         bool lossless_map;
3729         bool percpu_map;
3730 } pprint_tests_meta[] = {
3731 {
3732         .descr = "BTF pretty print array",
3733         .map_type = BPF_MAP_TYPE_ARRAY,
3734         .map_name = "pprint_test_array",
3735         .ordered_map = true,
3736         .lossless_map = true,
3737         .percpu_map = false,
3738 },
3739
3740 {
3741         .descr = "BTF pretty print hash",
3742         .map_type = BPF_MAP_TYPE_HASH,
3743         .map_name = "pprint_test_hash",
3744         .ordered_map = false,
3745         .lossless_map = true,
3746         .percpu_map = false,
3747 },
3748
3749 {
3750         .descr = "BTF pretty print lru hash",
3751         .map_type = BPF_MAP_TYPE_LRU_HASH,
3752         .map_name = "pprint_test_lru_hash",
3753         .ordered_map = false,
3754         .lossless_map = false,
3755         .percpu_map = false,
3756 },
3757
3758 {
3759         .descr = "BTF pretty print percpu array",
3760         .map_type = BPF_MAP_TYPE_PERCPU_ARRAY,
3761         .map_name = "pprint_test_percpu_array",
3762         .ordered_map = true,
3763         .lossless_map = true,
3764         .percpu_map = true,
3765 },
3766
3767 {
3768         .descr = "BTF pretty print percpu hash",
3769         .map_type = BPF_MAP_TYPE_PERCPU_HASH,
3770         .map_name = "pprint_test_percpu_hash",
3771         .ordered_map = false,
3772         .lossless_map = true,
3773         .percpu_map = true,
3774 },
3775
3776 {
3777         .descr = "BTF pretty print lru percpu hash",
3778         .map_type = BPF_MAP_TYPE_LRU_PERCPU_HASH,
3779         .map_name = "pprint_test_lru_percpu_hash",
3780         .ordered_map = false,
3781         .lossless_map = false,
3782         .percpu_map = true,
3783 },
3784
3785 };
3786
3787
3788 static void set_pprint_mapv(struct pprint_mapv *v, uint32_t i,
3789                             int num_cpus, int rounded_value_size)
3790 {
3791         int cpu;
3792
3793         for (cpu = 0; cpu < num_cpus; cpu++) {
3794                 v->ui32 = i + cpu;
3795                 v->si32 = -i;
3796                 v->unused_bits2a = 3;
3797                 v->bits28 = i;
3798                 v->unused_bits2b = 3;
3799                 v->ui64 = i;
3800                 v->aenum = i & 0x03;
3801                 v->ui32b = 4;
3802                 v->bits2c = 1;
3803                 v = (void *)v + rounded_value_size;
3804         }
3805 }
3806
3807 static int check_line(const char *expected_line, int nexpected_line,
3808                       int expected_line_len, const char *line)
3809 {
3810         if (CHECK(nexpected_line == expected_line_len,
3811                   "expected_line is too long"))
3812                 return -1;
3813
3814         if (strcmp(expected_line, line)) {
3815                 fprintf(stderr, "unexpected pprint output\n");
3816                 fprintf(stderr, "expected: %s", expected_line);
3817                 fprintf(stderr, "    read: %s", line);
3818                 return -1;
3819         }
3820
3821         return 0;
3822 }
3823
3824
3825 static int do_test_pprint(int test_num)
3826 {
3827         const struct btf_raw_test *test = &pprint_test_template[test_num];
3828         struct bpf_create_map_attr create_attr = {};
3829         bool ordered_map, lossless_map, percpu_map;
3830         int err, ret, num_cpus, rounded_value_size;
3831         struct pprint_mapv *mapv = NULL;
3832         unsigned int key, nr_read_elems;
3833         int map_fd = -1, btf_fd = -1;
3834         unsigned int raw_btf_size;
3835         char expected_line[255];
3836         FILE *pin_file = NULL;
3837         char pin_path[255];
3838         size_t line_len = 0;
3839         char *line = NULL;
3840         uint8_t *raw_btf;
3841         ssize_t nread;
3842
3843         fprintf(stderr, "%s(#%d)......", test->descr, test_num);
3844         raw_btf = btf_raw_create(&hdr_tmpl, test->raw_types,
3845                                  test->str_sec, test->str_sec_size,
3846                                  &raw_btf_size, NULL);
3847
3848         if (!raw_btf)
3849                 return -1;
3850
3851         *btf_log_buf = '\0';
3852         btf_fd = bpf_load_btf(raw_btf, raw_btf_size,
3853                               btf_log_buf, BTF_LOG_BUF_SIZE,
3854                               args.always_log);
3855         free(raw_btf);
3856
3857         if (CHECK(btf_fd == -1, "errno:%d", errno)) {
3858                 err = -1;
3859                 goto done;
3860         }
3861
3862         create_attr.name = test->map_name;
3863         create_attr.map_type = test->map_type;
3864         create_attr.key_size = test->key_size;
3865         create_attr.value_size = test->value_size;
3866         create_attr.max_entries = test->max_entries;
3867         create_attr.btf_fd = btf_fd;
3868         create_attr.btf_key_type_id = test->key_type_id;
3869         create_attr.btf_value_type_id = test->value_type_id;
3870
3871         map_fd = bpf_create_map_xattr(&create_attr);
3872         if (CHECK(map_fd == -1, "errno:%d", errno)) {
3873                 err = -1;
3874                 goto done;
3875         }
3876
3877         ret = snprintf(pin_path, sizeof(pin_path), "%s/%s",
3878                        "/sys/fs/bpf", test->map_name);
3879
3880         if (CHECK(ret == sizeof(pin_path), "pin_path %s/%s is too long",
3881                   "/sys/fs/bpf", test->map_name)) {
3882                 err = -1;
3883                 goto done;
3884         }
3885
3886         err = bpf_obj_pin(map_fd, pin_path);
3887         if (CHECK(err, "bpf_obj_pin(%s): errno:%d.", pin_path, errno))
3888                 goto done;
3889
3890         percpu_map = test->percpu_map;
3891         num_cpus = percpu_map ? bpf_num_possible_cpus() : 1;
3892         rounded_value_size = round_up(sizeof(struct pprint_mapv), 8);
3893         mapv = calloc(num_cpus, rounded_value_size);
3894         if (CHECK(!mapv, "mapv allocation failure")) {
3895                 err = -1;
3896                 goto done;
3897         }
3898
3899         for (key = 0; key < test->max_entries; key++) {
3900                 set_pprint_mapv(mapv, key, num_cpus, rounded_value_size);
3901                 bpf_map_update_elem(map_fd, &key, mapv, 0);
3902         }
3903
3904         pin_file = fopen(pin_path, "r");
3905         if (CHECK(!pin_file, "fopen(%s): errno:%d", pin_path, errno)) {
3906                 err = -1;
3907                 goto done;
3908         }
3909
3910         /* Skip lines start with '#' */
3911         while ((nread = getline(&line, &line_len, pin_file)) > 0 &&
3912                *line == '#')
3913                 ;
3914
3915         if (CHECK(nread <= 0, "Unexpected EOF")) {
3916                 err = -1;
3917                 goto done;
3918         }
3919
3920         nr_read_elems = 0;
3921         ordered_map = test->ordered_map;
3922         lossless_map = test->lossless_map;
3923         do {
3924                 struct pprint_mapv *cmapv;
3925                 ssize_t nexpected_line;
3926                 unsigned int next_key;
3927                 int cpu;
3928
3929                 next_key = ordered_map ? nr_read_elems : atoi(line);
3930                 set_pprint_mapv(mapv, next_key, num_cpus, rounded_value_size);
3931                 cmapv = mapv;
3932
3933                 for (cpu = 0; cpu < num_cpus; cpu++) {
3934                         if (percpu_map) {
3935                                 /* for percpu map, the format looks like:
3936                                  * <key>: {
3937                                  *      cpu0: <value_on_cpu0>
3938                                  *      cpu1: <value_on_cpu1>
3939                                  *      ...
3940                                  *      cpun: <value_on_cpun>
3941                                  * }
3942                                  *
3943                                  * let us verify the line containing the key here.
3944                                  */
3945                                 if (cpu == 0) {
3946                                         nexpected_line = snprintf(expected_line,
3947                                                                   sizeof(expected_line),
3948                                                                   "%u: {\n",
3949                                                                   next_key);
3950
3951                                         err = check_line(expected_line, nexpected_line,
3952                                                          sizeof(expected_line), line);
3953                                         if (err == -1)
3954                                                 goto done;
3955                                 }
3956
3957                                 /* read value@cpu */
3958                                 nread = getline(&line, &line_len, pin_file);
3959                                 if (nread < 0)
3960                                         break;
3961                         }
3962
3963                         nexpected_line = snprintf(expected_line, sizeof(expected_line),
3964                                                   "%s%u: {%u,0,%d,0x%x,0x%x,0x%x,"
3965                                                   "{%lu|[%u,%u,%u,%u,%u,%u,%u,%u]},%s,"
3966                                                   "%u,0x%x}\n",
3967                                                   percpu_map ? "\tcpu" : "",
3968                                                   percpu_map ? cpu : next_key,
3969                                                   cmapv->ui32, cmapv->si32,
3970                                                   cmapv->unused_bits2a,
3971                                                   cmapv->bits28,
3972                                                   cmapv->unused_bits2b,
3973                                                   cmapv->ui64,
3974                                                   cmapv->ui8a[0], cmapv->ui8a[1],
3975                                                   cmapv->ui8a[2], cmapv->ui8a[3],
3976                                                   cmapv->ui8a[4], cmapv->ui8a[5],
3977                                                   cmapv->ui8a[6], cmapv->ui8a[7],
3978                                                   pprint_enum_str[cmapv->aenum],
3979                                                   cmapv->ui32b,
3980                                                   cmapv->bits2c);
3981
3982                         err = check_line(expected_line, nexpected_line,
3983                                          sizeof(expected_line), line);
3984                         if (err == -1)
3985                                 goto done;
3986
3987                         cmapv = (void *)cmapv + rounded_value_size;
3988                 }
3989
3990                 if (percpu_map) {
3991                         /* skip the last bracket for the percpu map */
3992                         nread = getline(&line, &line_len, pin_file);
3993                         if (nread < 0)
3994                                 break;
3995                 }
3996
3997                 nread = getline(&line, &line_len, pin_file);
3998         } while (++nr_read_elems < test->max_entries && nread > 0);
3999
4000         if (lossless_map &&
4001             CHECK(nr_read_elems < test->max_entries,
4002                   "Unexpected EOF. nr_read_elems:%u test->max_entries:%u",
4003                   nr_read_elems, test->max_entries)) {
4004                 err = -1;
4005                 goto done;
4006         }
4007
4008         if (CHECK(nread > 0, "Unexpected extra pprint output: %s", line)) {
4009                 err = -1;
4010                 goto done;
4011         }
4012
4013         err = 0;
4014
4015 done:
4016         if (mapv)
4017                 free(mapv);
4018         if (!err)
4019                 fprintf(stderr, "OK");
4020         if (*btf_log_buf && (err || args.always_log))
4021                 fprintf(stderr, "\n%s", btf_log_buf);
4022         if (btf_fd != -1)
4023                 close(btf_fd);
4024         if (map_fd != -1)
4025                 close(map_fd);
4026         if (pin_file)
4027                 fclose(pin_file);
4028         unlink(pin_path);
4029         free(line);
4030
4031         return err;
4032 }
4033
4034 static int test_pprint(void)
4035 {
4036         unsigned int i;
4037         int err = 0;
4038
4039         /* test various maps with the first test template */
4040         for (i = 0; i < ARRAY_SIZE(pprint_tests_meta); i++) {
4041                 pprint_test_template[0].descr = pprint_tests_meta[i].descr;
4042                 pprint_test_template[0].map_type = pprint_tests_meta[i].map_type;
4043                 pprint_test_template[0].map_name = pprint_tests_meta[i].map_name;
4044                 pprint_test_template[0].ordered_map = pprint_tests_meta[i].ordered_map;
4045                 pprint_test_template[0].lossless_map = pprint_tests_meta[i].lossless_map;
4046                 pprint_test_template[0].percpu_map = pprint_tests_meta[i].percpu_map;
4047
4048                 err |= count_result(do_test_pprint(0));
4049         }
4050
4051         /* test rest test templates with the first map */
4052         for (i = 1; i < ARRAY_SIZE(pprint_test_template); i++) {
4053                 pprint_test_template[i].descr = pprint_tests_meta[0].descr;
4054                 pprint_test_template[i].map_type = pprint_tests_meta[0].map_type;
4055                 pprint_test_template[i].map_name = pprint_tests_meta[0].map_name;
4056                 pprint_test_template[i].ordered_map = pprint_tests_meta[0].ordered_map;
4057                 pprint_test_template[i].lossless_map = pprint_tests_meta[0].lossless_map;
4058                 pprint_test_template[i].percpu_map = pprint_tests_meta[0].percpu_map;
4059                 err |= count_result(do_test_pprint(i));
4060         }
4061
4062         return err;
4063 }
4064
4065 #define BPF_LINE_INFO_ENC(insn_off, file_off, line_off, line_num, line_col) \
4066         (insn_off), (file_off), (line_off), ((line_num) << 10 | ((line_col) & 0x3ff))
4067
4068 static struct prog_info_raw_test {
4069         const char *descr;
4070         const char *str_sec;
4071         const char *err_str;
4072         __u32 raw_types[MAX_NR_RAW_U32];
4073         __u32 str_sec_size;
4074         struct bpf_insn insns[MAX_INSNS];
4075         __u32 prog_type;
4076         __u32 func_info[MAX_SUBPROGS][2];
4077         __u32 func_info_rec_size;
4078         __u32 func_info_cnt;
4079         __u32 line_info[MAX_NR_RAW_U32];
4080         __u32 line_info_rec_size;
4081         __u32 nr_jited_ksyms;
4082         bool expected_prog_load_failure;
4083 } info_raw_tests[] = {
4084 {
4085         .descr = "func_type (main func + one sub)",
4086         .raw_types = {
4087                 BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),   /* [1] */
4088                 BTF_TYPE_INT_ENC(NAME_TBD, 0, 0, 32, 4),        /* [2] */
4089                 BTF_FUNC_PROTO_ENC(1, 2),                       /* [3] */
4090                         BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
4091                         BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 2),
4092                 BTF_FUNC_PROTO_ENC(1, 2),                       /* [4] */
4093                         BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 2),
4094                         BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
4095                 BTF_FUNC_ENC(NAME_TBD, 3),                      /* [5] */
4096                 BTF_FUNC_ENC(NAME_TBD, 4),                      /* [6] */
4097                 BTF_END_RAW,
4098         },
4099         .str_sec = "\0int\0unsigned int\0a\0b\0c\0d\0funcA\0funcB",
4100         .str_sec_size = sizeof("\0int\0unsigned int\0a\0b\0c\0d\0funcA\0funcB"),
4101         .insns = {
4102                 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2),
4103                 BPF_MOV64_IMM(BPF_REG_0, 1),
4104                 BPF_EXIT_INSN(),
4105                 BPF_MOV64_IMM(BPF_REG_0, 2),
4106                 BPF_EXIT_INSN(),
4107         },
4108         .prog_type = BPF_PROG_TYPE_TRACEPOINT,
4109         .func_info = { {0, 5}, {3, 6} },
4110         .func_info_rec_size = 8,
4111         .func_info_cnt = 2,
4112         .line_info = { BTF_END_RAW },
4113 },
4114
4115 {
4116         .descr = "func_type (Incorrect func_info_rec_size)",
4117         .raw_types = {
4118                 BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),   /* [1] */
4119                 BTF_TYPE_INT_ENC(NAME_TBD, 0, 0, 32, 4),        /* [2] */
4120                 BTF_FUNC_PROTO_ENC(1, 2),                       /* [3] */
4121                         BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
4122                         BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 2),
4123                 BTF_FUNC_PROTO_ENC(1, 2),                       /* [4] */
4124                         BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 2),
4125                         BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
4126                 BTF_FUNC_ENC(NAME_TBD, 3),                      /* [5] */
4127                 BTF_FUNC_ENC(NAME_TBD, 4),                      /* [6] */
4128                 BTF_END_RAW,
4129         },
4130         .str_sec = "\0int\0unsigned int\0a\0b\0c\0d\0funcA\0funcB",
4131         .str_sec_size = sizeof("\0int\0unsigned int\0a\0b\0c\0d\0funcA\0funcB"),
4132         .insns = {
4133                 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2),
4134                 BPF_MOV64_IMM(BPF_REG_0, 1),
4135                 BPF_EXIT_INSN(),
4136                 BPF_MOV64_IMM(BPF_REG_0, 2),
4137                 BPF_EXIT_INSN(),
4138         },
4139         .prog_type = BPF_PROG_TYPE_TRACEPOINT,
4140         .func_info = { {0, 5}, {3, 6} },
4141         .func_info_rec_size = 4,
4142         .func_info_cnt = 2,
4143         .line_info = { BTF_END_RAW },
4144         .expected_prog_load_failure = true,
4145 },
4146
4147 {
4148         .descr = "func_type (Incorrect func_info_cnt)",
4149         .raw_types = {
4150                 BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),   /* [1] */
4151                 BTF_TYPE_INT_ENC(NAME_TBD, 0, 0, 32, 4),        /* [2] */
4152                 BTF_FUNC_PROTO_ENC(1, 2),                       /* [3] */
4153                         BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
4154                         BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 2),
4155                 BTF_FUNC_PROTO_ENC(1, 2),                       /* [4] */
4156                         BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 2),
4157                         BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
4158                 BTF_FUNC_ENC(NAME_TBD, 3),                      /* [5] */
4159                 BTF_FUNC_ENC(NAME_TBD, 4),                      /* [6] */
4160                 BTF_END_RAW,
4161         },
4162         .str_sec = "\0int\0unsigned int\0a\0b\0c\0d\0funcA\0funcB",
4163         .str_sec_size = sizeof("\0int\0unsigned int\0a\0b\0c\0d\0funcA\0funcB"),
4164         .insns = {
4165                 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2),
4166                 BPF_MOV64_IMM(BPF_REG_0, 1),
4167                 BPF_EXIT_INSN(),
4168                 BPF_MOV64_IMM(BPF_REG_0, 2),
4169                 BPF_EXIT_INSN(),
4170         },
4171         .prog_type = BPF_PROG_TYPE_TRACEPOINT,
4172         .func_info = { {0, 5}, {3, 6} },
4173         .func_info_rec_size = 8,
4174         .func_info_cnt = 1,
4175         .line_info = { BTF_END_RAW },
4176         .expected_prog_load_failure = true,
4177 },
4178
4179 {
4180         .descr = "func_type (Incorrect bpf_func_info.insn_off)",
4181         .raw_types = {
4182                 BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),   /* [1] */
4183                 BTF_TYPE_INT_ENC(NAME_TBD, 0, 0, 32, 4),        /* [2] */
4184                 BTF_FUNC_PROTO_ENC(1, 2),                       /* [3] */
4185                         BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
4186                         BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 2),
4187                 BTF_FUNC_PROTO_ENC(1, 2),                       /* [4] */
4188                         BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 2),
4189                         BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
4190                 BTF_FUNC_ENC(NAME_TBD, 3),                      /* [5] */
4191                 BTF_FUNC_ENC(NAME_TBD, 4),                      /* [6] */
4192                 BTF_END_RAW,
4193         },
4194         .str_sec = "\0int\0unsigned int\0a\0b\0c\0d\0funcA\0funcB",
4195         .str_sec_size = sizeof("\0int\0unsigned int\0a\0b\0c\0d\0funcA\0funcB"),
4196         .insns = {
4197                 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2),
4198                 BPF_MOV64_IMM(BPF_REG_0, 1),
4199                 BPF_EXIT_INSN(),
4200                 BPF_MOV64_IMM(BPF_REG_0, 2),
4201                 BPF_EXIT_INSN(),
4202         },
4203         .prog_type = BPF_PROG_TYPE_TRACEPOINT,
4204         .func_info = { {0, 5}, {2, 6} },
4205         .func_info_rec_size = 8,
4206         .func_info_cnt = 2,
4207         .line_info = { BTF_END_RAW },
4208         .expected_prog_load_failure = true,
4209 },
4210
4211 {
4212         .descr = "line_info (No subprog)",
4213         .raw_types = {
4214                 BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),   /* [1] */
4215                 BTF_END_RAW,
4216         },
4217         BTF_STR_SEC("\0int\0int a=1;\0int b=2;\0return a + b;\0return a + b;"),
4218         .insns = {
4219                 BPF_MOV64_IMM(BPF_REG_0, 1),
4220                 BPF_MOV64_IMM(BPF_REG_1, 2),
4221                 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
4222                 BPF_EXIT_INSN(),
4223         },
4224         .prog_type = BPF_PROG_TYPE_TRACEPOINT,
4225         .func_info_cnt = 0,
4226         .line_info = {
4227                 BPF_LINE_INFO_ENC(0, 0, NAME_TBD, 1, 10),
4228                 BPF_LINE_INFO_ENC(1, 0, NAME_TBD, 2, 9),
4229                 BPF_LINE_INFO_ENC(2, 0, NAME_TBD, 3, 8),
4230                 BPF_LINE_INFO_ENC(3, 0, NAME_TBD, 4, 7),
4231                 BTF_END_RAW,
4232         },
4233         .line_info_rec_size = sizeof(struct bpf_line_info),
4234         .nr_jited_ksyms = 1,
4235 },
4236
4237 {
4238         .descr = "line_info (No subprog. insn_off >= prog->len)",
4239         .raw_types = {
4240                 BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),   /* [1] */
4241                 BTF_END_RAW,
4242         },
4243         BTF_STR_SEC("\0int\0int a=1;\0int b=2;\0return a + b;\0return a + b;"),
4244         .insns = {
4245                 BPF_MOV64_IMM(BPF_REG_0, 1),
4246                 BPF_MOV64_IMM(BPF_REG_1, 2),
4247                 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
4248                 BPF_EXIT_INSN(),
4249         },
4250         .prog_type = BPF_PROG_TYPE_TRACEPOINT,
4251         .func_info_cnt = 0,
4252         .line_info = {
4253                 BPF_LINE_INFO_ENC(0, 0, NAME_TBD, 1, 10),
4254                 BPF_LINE_INFO_ENC(1, 0, NAME_TBD, 2, 9),
4255                 BPF_LINE_INFO_ENC(2, 0, NAME_TBD, 3, 8),
4256                 BPF_LINE_INFO_ENC(3, 0, NAME_TBD, 4, 7),
4257                 BPF_LINE_INFO_ENC(4, 0, 0, 5, 6),
4258                 BTF_END_RAW,
4259         },
4260         .line_info_rec_size = sizeof(struct bpf_line_info),
4261         .nr_jited_ksyms = 1,
4262         .err_str = "line_info[4].insn_off",
4263         .expected_prog_load_failure = true,
4264 },
4265
4266 {
4267         .descr = "line_info (Zero bpf insn code)",
4268         .raw_types = {
4269                 BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),   /* [1] */
4270                 BTF_TYPE_INT_ENC(NAME_TBD, 0, 0, 64, 8),        /* [2] */
4271                 BTF_TYPEDEF_ENC(NAME_TBD, 2),                   /* [3] */
4272                 BTF_END_RAW,
4273         },
4274         BTF_STR_SEC("\0int\0unsigned long\0u64\0u64 a=1;\0return a;"),
4275         .insns = {
4276                 BPF_LD_IMM64(BPF_REG_0, 1),
4277                 BPF_EXIT_INSN(),
4278         },
4279         .prog_type = BPF_PROG_TYPE_TRACEPOINT,
4280         .func_info_cnt = 0,
4281         .line_info = {
4282                 BPF_LINE_INFO_ENC(0, 0, NAME_TBD, 1, 10),
4283                 BPF_LINE_INFO_ENC(1, 0, 0, 2, 9),
4284                 BPF_LINE_INFO_ENC(2, 0, NAME_TBD, 3, 8),
4285                 BTF_END_RAW,
4286         },
4287         .line_info_rec_size = sizeof(struct bpf_line_info),
4288         .nr_jited_ksyms = 1,
4289         .err_str = "Invalid insn code at line_info[1]",
4290         .expected_prog_load_failure = true,
4291 },
4292
4293 {
4294         .descr = "line_info (No subprog. zero tailing line_info",
4295         .raw_types = {
4296                 BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),   /* [1] */
4297                 BTF_END_RAW,
4298         },
4299         BTF_STR_SEC("\0int\0int a=1;\0int b=2;\0return a + b;\0return a + b;"),
4300         .insns = {
4301                 BPF_MOV64_IMM(BPF_REG_0, 1),
4302                 BPF_MOV64_IMM(BPF_REG_1, 2),
4303                 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
4304                 BPF_EXIT_INSN(),
4305         },
4306         .prog_type = BPF_PROG_TYPE_TRACEPOINT,
4307         .func_info_cnt = 0,
4308         .line_info = {
4309                 BPF_LINE_INFO_ENC(0, 0, NAME_TBD, 1, 10), 0,
4310                 BPF_LINE_INFO_ENC(1, 0, NAME_TBD, 2, 9), 0,
4311                 BPF_LINE_INFO_ENC(2, 0, NAME_TBD, 3, 8), 0,
4312                 BPF_LINE_INFO_ENC(3, 0, NAME_TBD, 4, 7), 0,
4313                 BTF_END_RAW,
4314         },
4315         .line_info_rec_size = sizeof(struct bpf_line_info) + sizeof(__u32),
4316         .nr_jited_ksyms = 1,
4317 },
4318
4319 {
4320         .descr = "line_info (No subprog. nonzero tailing line_info)",
4321         .raw_types = {
4322                 BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),   /* [1] */
4323                 BTF_END_RAW,
4324         },
4325         BTF_STR_SEC("\0int\0int a=1;\0int b=2;\0return a + b;\0return a + b;"),
4326         .insns = {
4327                 BPF_MOV64_IMM(BPF_REG_0, 1),
4328                 BPF_MOV64_IMM(BPF_REG_1, 2),
4329                 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
4330                 BPF_EXIT_INSN(),
4331         },
4332         .prog_type = BPF_PROG_TYPE_TRACEPOINT,
4333         .func_info_cnt = 0,
4334         .line_info = {
4335                 BPF_LINE_INFO_ENC(0, 0, NAME_TBD, 1, 10), 0,
4336                 BPF_LINE_INFO_ENC(1, 0, NAME_TBD, 2, 9), 0,
4337                 BPF_LINE_INFO_ENC(2, 0, NAME_TBD, 3, 8), 0,
4338                 BPF_LINE_INFO_ENC(3, 0, NAME_TBD, 4, 7), 1,
4339                 BTF_END_RAW,
4340         },
4341         .line_info_rec_size = sizeof(struct bpf_line_info) + sizeof(__u32),
4342         .nr_jited_ksyms = 1,
4343         .err_str = "nonzero tailing record in line_info",
4344         .expected_prog_load_failure = true,
4345 },
4346
4347 {
4348         .descr = "line_info (subprog)",
4349         .raw_types = {
4350                 BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),   /* [1] */
4351                 BTF_END_RAW,
4352         },
4353         BTF_STR_SEC("\0int\0int a=1+1;\0return func(a);\0b+=1;\0return b;"),
4354         .insns = {
4355                 BPF_MOV64_IMM(BPF_REG_2, 1),
4356                 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, 1),
4357                 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
4358                 BPF_CALL_REL(1),
4359                 BPF_EXIT_INSN(),
4360                 BPF_MOV64_REG(BPF_REG_0, BPF_REG_1),
4361                 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 1),
4362                 BPF_EXIT_INSN(),
4363         },
4364         .prog_type = BPF_PROG_TYPE_TRACEPOINT,
4365         .func_info_cnt = 0,
4366         .line_info = {
4367                 BPF_LINE_INFO_ENC(0, 0, NAME_TBD, 1, 10),
4368                 BPF_LINE_INFO_ENC(2, 0, NAME_TBD, 2, 9),
4369                 BPF_LINE_INFO_ENC(5, 0, NAME_TBD, 3, 8),
4370                 BPF_LINE_INFO_ENC(7, 0, NAME_TBD, 4, 7),
4371                 BTF_END_RAW,
4372         },
4373         .line_info_rec_size = sizeof(struct bpf_line_info),
4374         .nr_jited_ksyms = 2,
4375 },
4376
4377 {
4378         .descr = "line_info (subprog + func_info)",
4379         .raw_types = {
4380                 BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),   /* [1] */
4381                 BTF_FUNC_PROTO_ENC(1, 1),                       /* [2] */
4382                         BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
4383                 BTF_FUNC_ENC(NAME_TBD, 2),                      /* [3] */
4384                 BTF_FUNC_ENC(NAME_TBD, 2),                      /* [4] */
4385                 BTF_END_RAW,
4386         },
4387         BTF_STR_SEC("\0int\0x\0sub\0main\0int a=1+1;\0return func(a);\0b+=1;\0return b;"),
4388         .insns = {
4389                 BPF_MOV64_IMM(BPF_REG_2, 1),
4390                 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, 1),
4391                 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
4392                 BPF_CALL_REL(1),
4393                 BPF_EXIT_INSN(),
4394                 BPF_MOV64_REG(BPF_REG_0, BPF_REG_1),
4395                 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 1),
4396                 BPF_EXIT_INSN(),
4397         },
4398         .prog_type = BPF_PROG_TYPE_TRACEPOINT,
4399         .func_info_cnt = 2,
4400         .func_info_rec_size = 8,
4401         .func_info = { {0, 4}, {5, 3} },
4402         .line_info = {
4403                 BPF_LINE_INFO_ENC(0, 0, NAME_TBD, 1, 10),
4404                 BPF_LINE_INFO_ENC(2, 0, NAME_TBD, 2, 9),
4405                 BPF_LINE_INFO_ENC(5, 0, NAME_TBD, 3, 8),
4406                 BPF_LINE_INFO_ENC(7, 0, NAME_TBD, 4, 7),
4407                 BTF_END_RAW,
4408         },
4409         .line_info_rec_size = sizeof(struct bpf_line_info),
4410         .nr_jited_ksyms = 2,
4411 },
4412
4413 {
4414         .descr = "line_info (subprog. missing 1st func line info)",
4415         .raw_types = {
4416                 BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),   /* [1] */
4417                 BTF_END_RAW,
4418         },
4419         BTF_STR_SEC("\0int\0int a=1+1;\0return func(a);\0b+=1;\0return b;"),
4420         .insns = {
4421                 BPF_MOV64_IMM(BPF_REG_2, 1),
4422                 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, 1),
4423                 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
4424                 BPF_CALL_REL(1),
4425                 BPF_EXIT_INSN(),
4426                 BPF_MOV64_REG(BPF_REG_0, BPF_REG_1),
4427                 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 1),
4428                 BPF_EXIT_INSN(),
4429         },
4430         .prog_type = BPF_PROG_TYPE_TRACEPOINT,
4431         .func_info_cnt = 0,
4432         .line_info = {
4433                 BPF_LINE_INFO_ENC(1, 0, NAME_TBD, 1, 10),
4434                 BPF_LINE_INFO_ENC(2, 0, NAME_TBD, 2, 9),
4435                 BPF_LINE_INFO_ENC(5, 0, NAME_TBD, 3, 8),
4436                 BPF_LINE_INFO_ENC(7, 0, NAME_TBD, 4, 7),
4437                 BTF_END_RAW,
4438         },
4439         .line_info_rec_size = sizeof(struct bpf_line_info),
4440         .nr_jited_ksyms = 2,
4441         .err_str = "missing bpf_line_info for func#0",
4442         .expected_prog_load_failure = true,
4443 },
4444
4445 {
4446         .descr = "line_info (subprog. missing 2nd func line info)",
4447         .raw_types = {
4448                 BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),   /* [1] */
4449                 BTF_END_RAW,
4450         },
4451         BTF_STR_SEC("\0int\0int a=1+1;\0return func(a);\0b+=1;\0return b;"),
4452         .insns = {
4453                 BPF_MOV64_IMM(BPF_REG_2, 1),
4454                 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, 1),
4455                 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
4456                 BPF_CALL_REL(1),
4457                 BPF_EXIT_INSN(),
4458                 BPF_MOV64_REG(BPF_REG_0, BPF_REG_1),
4459                 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 1),
4460                 BPF_EXIT_INSN(),
4461         },
4462         .prog_type = BPF_PROG_TYPE_TRACEPOINT,
4463         .func_info_cnt = 0,
4464         .line_info = {
4465                 BPF_LINE_INFO_ENC(0, 0, NAME_TBD, 1, 10),
4466                 BPF_LINE_INFO_ENC(2, 0, NAME_TBD, 2, 9),
4467                 BPF_LINE_INFO_ENC(6, 0, NAME_TBD, 3, 8),
4468                 BPF_LINE_INFO_ENC(7, 0, NAME_TBD, 4, 7),
4469                 BTF_END_RAW,
4470         },
4471         .line_info_rec_size = sizeof(struct bpf_line_info),
4472         .nr_jited_ksyms = 2,
4473         .err_str = "missing bpf_line_info for func#1",
4474         .expected_prog_load_failure = true,
4475 },
4476
4477 {
4478         .descr = "line_info (subprog. unordered insn offset)",
4479         .raw_types = {
4480                 BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),   /* [1] */
4481                 BTF_END_RAW,
4482         },
4483         BTF_STR_SEC("\0int\0int a=1+1;\0return func(a);\0b+=1;\0return b;"),
4484         .insns = {
4485                 BPF_MOV64_IMM(BPF_REG_2, 1),
4486                 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, 1),
4487                 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
4488                 BPF_CALL_REL(1),
4489                 BPF_EXIT_INSN(),
4490                 BPF_MOV64_REG(BPF_REG_0, BPF_REG_1),
4491                 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 1),
4492                 BPF_EXIT_INSN(),
4493         },
4494         .prog_type = BPF_PROG_TYPE_TRACEPOINT,
4495         .func_info_cnt = 0,
4496         .line_info = {
4497                 BPF_LINE_INFO_ENC(0, 0, NAME_TBD, 1, 10),
4498                 BPF_LINE_INFO_ENC(5, 0, NAME_TBD, 2, 9),
4499                 BPF_LINE_INFO_ENC(2, 0, NAME_TBD, 3, 8),
4500                 BPF_LINE_INFO_ENC(7, 0, NAME_TBD, 4, 7),
4501                 BTF_END_RAW,
4502         },
4503         .line_info_rec_size = sizeof(struct bpf_line_info),
4504         .nr_jited_ksyms = 2,
4505         .err_str = "Invalid line_info[2].insn_off",
4506         .expected_prog_load_failure = true,
4507 },
4508
4509 };
4510
4511 static size_t probe_prog_length(const struct bpf_insn *fp)
4512 {
4513         size_t len;
4514
4515         for (len = MAX_INSNS - 1; len > 0; --len)
4516                 if (fp[len].code != 0 || fp[len].imm != 0)
4517                         break;
4518         return len + 1;
4519 }
4520
4521 static __u32 *patch_name_tbd(const __u32 *raw_u32,
4522                              const char *str, __u32 str_off,
4523                              unsigned int str_sec_size,
4524                              unsigned int *ret_size)
4525 {
4526         int i, raw_u32_size = get_raw_sec_size(raw_u32);
4527         const char *end_str = str + str_sec_size;
4528         const char *next_str = str + str_off;
4529         __u32 *new_u32 = NULL;
4530
4531         if (raw_u32_size == -1)
4532                 return ERR_PTR(-EINVAL);
4533
4534         if (!raw_u32_size) {
4535                 *ret_size = 0;
4536                 return NULL;
4537         }
4538
4539         new_u32 = malloc(raw_u32_size);
4540         if (!new_u32)
4541                 return ERR_PTR(-ENOMEM);
4542
4543         for (i = 0; i < raw_u32_size / sizeof(raw_u32[0]); i++) {
4544                 if (raw_u32[i] == NAME_TBD) {
4545                         next_str = get_next_str(next_str, end_str);
4546                         if (CHECK(!next_str, "Error in getting next_str\n")) {
4547                                 free(new_u32);
4548                                 return ERR_PTR(-EINVAL);
4549                         }
4550                         new_u32[i] = next_str - str;
4551                         next_str += strlen(next_str);
4552                 } else {
4553                         new_u32[i] = raw_u32[i];
4554                 }
4555         }
4556
4557         *ret_size = raw_u32_size;
4558         return new_u32;
4559 }
4560
4561 static int test_get_finfo(const struct prog_info_raw_test *test,
4562                           int prog_fd)
4563 {
4564         struct bpf_prog_info info = {};
4565         struct bpf_func_info *finfo;
4566         __u32 info_len, rec_size, i;
4567         void *func_info = NULL;
4568         int err;
4569
4570         /* get necessary lens */
4571         info_len = sizeof(struct bpf_prog_info);
4572         err = bpf_obj_get_info_by_fd(prog_fd, &info, &info_len);
4573         if (CHECK(err == -1, "invalid get info (1st) errno:%d", errno)) {
4574                 fprintf(stderr, "%s\n", btf_log_buf);
4575                 return -1;
4576         }
4577         if (CHECK(info.nr_func_info != test->func_info_cnt,
4578                   "incorrect info.nr_func_info (1st) %d",
4579                   info.nr_func_info)) {
4580                 return -1;
4581         }
4582
4583         rec_size = info.func_info_rec_size;
4584         if (CHECK(rec_size != sizeof(struct bpf_func_info),
4585                   "incorrect info.func_info_rec_size (1st) %d", rec_size)) {
4586                 return -1;
4587         }
4588
4589         if (!info.nr_func_info)
4590                 return 0;
4591
4592         func_info = malloc(info.nr_func_info * rec_size);
4593         if (CHECK(!func_info, "out of memory"))
4594                 return -1;
4595
4596         /* reset info to only retrieve func_info related data */
4597         memset(&info, 0, sizeof(info));
4598         info.nr_func_info = test->func_info_cnt;
4599         info.func_info_rec_size = rec_size;
4600         info.func_info = ptr_to_u64(func_info);
4601         err = bpf_obj_get_info_by_fd(prog_fd, &info, &info_len);
4602         if (CHECK(err == -1, "invalid get info (2nd) errno:%d", errno)) {
4603                 fprintf(stderr, "%s\n", btf_log_buf);
4604                 err = -1;
4605                 goto done;
4606         }
4607         if (CHECK(info.nr_func_info != test->func_info_cnt,
4608                   "incorrect info.nr_func_info (2nd) %d",
4609                   info.nr_func_info)) {
4610                 err = -1;
4611                 goto done;
4612         }
4613         if (CHECK(info.func_info_rec_size != rec_size,
4614                   "incorrect info.func_info_rec_size (2nd) %d",
4615                   info.func_info_rec_size)) {
4616                 err = -1;
4617                 goto done;
4618         }
4619
4620         finfo = func_info;
4621         for (i = 0; i < test->func_info_cnt; i++) {
4622                 if (CHECK(finfo->type_id != test->func_info[i][1],
4623                           "incorrect func_type %u expected %u",
4624                           finfo->type_id, test->func_info[i][1])) {
4625                         err = -1;
4626                         goto done;
4627                 }
4628                 finfo = (void *)finfo + rec_size;
4629         }
4630
4631         err = 0;
4632
4633 done:
4634         free(func_info);
4635         return err;
4636 }
4637
4638 static int test_get_linfo(const struct prog_info_raw_test *test,
4639                           const void *patched_linfo,
4640                           __u32 cnt, int prog_fd)
4641 {
4642         __u32 i, info_len, nr_jited_ksyms, nr_jited_func_lens;
4643         __u64 *jited_linfo = NULL, *jited_ksyms = NULL;
4644         __u32 rec_size, jited_rec_size, jited_cnt;
4645         struct bpf_line_info *linfo = NULL;
4646         __u32 cur_func_len, ksyms_found;
4647         struct bpf_prog_info info = {};
4648         __u32 *jited_func_lens = NULL;
4649         __u64 cur_func_ksyms;
4650         int err;
4651
4652         jited_cnt = cnt;
4653         rec_size = sizeof(*linfo);
4654         jited_rec_size = sizeof(*jited_linfo);
4655         if (test->nr_jited_ksyms)
4656                 nr_jited_ksyms = test->nr_jited_ksyms;
4657         else
4658                 nr_jited_ksyms = test->func_info_cnt;
4659         nr_jited_func_lens = nr_jited_ksyms;
4660
4661         info_len = sizeof(struct bpf_prog_info);
4662         err = bpf_obj_get_info_by_fd(prog_fd, &info, &info_len);
4663         if (CHECK(err == -1, "err:%d errno:%d", err, errno)) {
4664                 err = -1;
4665                 goto done;
4666         }
4667
4668         if (!info.jited_prog_len) {
4669                 /* prog is not jited */
4670                 jited_cnt = 0;
4671                 nr_jited_ksyms = 1;
4672                 nr_jited_func_lens = 1;
4673         }
4674
4675         if (CHECK(info.nr_line_info != cnt ||
4676                   info.nr_jited_line_info != jited_cnt ||
4677                   info.nr_jited_ksyms != nr_jited_ksyms ||
4678                   info.nr_jited_func_lens != nr_jited_func_lens ||
4679                   (!info.nr_line_info && info.nr_jited_line_info),
4680                   "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)",
4681                   info.nr_line_info, cnt,
4682                   info.nr_jited_line_info, jited_cnt,
4683                   info.nr_jited_ksyms, nr_jited_ksyms,
4684                   info.nr_jited_func_lens, nr_jited_func_lens)) {
4685                 err = -1;
4686                 goto done;
4687         }
4688
4689         if (CHECK(info.line_info_rec_size != sizeof(struct bpf_line_info) ||
4690                   info.jited_line_info_rec_size != sizeof(__u64),
4691                   "info: line_info_rec_size:%u(userspace expected:%u) jited_line_info_rec_size:%u(userspace expected:%u)",
4692                   info.line_info_rec_size, rec_size,
4693                   info.jited_line_info_rec_size, jited_rec_size)) {
4694                 err = -1;
4695                 goto done;
4696         }
4697
4698         if (!cnt)
4699                 return 0;
4700
4701         rec_size = info.line_info_rec_size;
4702         jited_rec_size = info.jited_line_info_rec_size;
4703
4704         memset(&info, 0, sizeof(info));
4705
4706         linfo = calloc(cnt, rec_size);
4707         if (CHECK(!linfo, "!linfo")) {
4708                 err = -1;
4709                 goto done;
4710         }
4711         info.nr_line_info = cnt;
4712         info.line_info_rec_size = rec_size;
4713         info.line_info = ptr_to_u64(linfo);
4714
4715         if (jited_cnt) {
4716                 jited_linfo = calloc(jited_cnt, jited_rec_size);
4717                 jited_ksyms = calloc(nr_jited_ksyms, sizeof(*jited_ksyms));
4718                 jited_func_lens = calloc(nr_jited_func_lens,
4719                                          sizeof(*jited_func_lens));
4720                 if (CHECK(!jited_linfo || !jited_ksyms || !jited_func_lens,
4721                           "jited_linfo:%p jited_ksyms:%p jited_func_lens:%p",
4722                           jited_linfo, jited_ksyms, jited_func_lens)) {
4723                         err = -1;
4724                         goto done;
4725                 }
4726
4727                 info.nr_jited_line_info = jited_cnt;
4728                 info.jited_line_info_rec_size = jited_rec_size;
4729                 info.jited_line_info = ptr_to_u64(jited_linfo);
4730                 info.nr_jited_ksyms = nr_jited_ksyms;
4731                 info.jited_ksyms = ptr_to_u64(jited_ksyms);
4732                 info.nr_jited_func_lens = nr_jited_func_lens;
4733                 info.jited_func_lens = ptr_to_u64(jited_func_lens);
4734         }
4735
4736         err = bpf_obj_get_info_by_fd(prog_fd, &info, &info_len);
4737
4738         /*
4739          * Only recheck the info.*line_info* fields.
4740          * Other fields are not the concern of this test.
4741          */
4742         if (CHECK(err == -1 ||
4743                   info.nr_line_info != cnt ||
4744                   (jited_cnt && !info.jited_line_info) ||
4745                   info.nr_jited_line_info != jited_cnt ||
4746                   info.line_info_rec_size != rec_size ||
4747                   info.jited_line_info_rec_size != jited_rec_size,
4748                   "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",
4749                   err, errno,
4750                   info.nr_line_info, cnt,
4751                   info.nr_jited_line_info, jited_cnt,
4752                   info.line_info_rec_size, rec_size,
4753                   info.jited_line_info_rec_size, jited_rec_size,
4754                   (void *)(long)info.line_info,
4755                   (void *)(long)info.jited_line_info)) {
4756                 err = -1;
4757                 goto done;
4758         }
4759
4760         CHECK(linfo[0].insn_off, "linfo[0].insn_off:%u",
4761               linfo[0].insn_off);
4762         for (i = 1; i < cnt; i++) {
4763                 const struct bpf_line_info *expected_linfo;
4764
4765                 expected_linfo = patched_linfo + (i * test->line_info_rec_size);
4766                 if (CHECK(linfo[i].insn_off <= linfo[i - 1].insn_off,
4767                           "linfo[%u].insn_off:%u <= linfo[%u].insn_off:%u",
4768                           i, linfo[i].insn_off,
4769                           i - 1, linfo[i - 1].insn_off)) {
4770                         err = -1;
4771                         goto done;
4772                 }
4773                 if (CHECK(linfo[i].file_name_off != expected_linfo->file_name_off ||
4774                           linfo[i].line_off != expected_linfo->line_off ||
4775                           linfo[i].line_col != expected_linfo->line_col,
4776                           "linfo[%u] (%u, %u, %u) != (%u, %u, %u)", i,
4777                           linfo[i].file_name_off,
4778                           linfo[i].line_off,
4779                           linfo[i].line_col,
4780                           expected_linfo->file_name_off,
4781                           expected_linfo->line_off,
4782                           expected_linfo->line_col)) {
4783                         err = -1;
4784                         goto done;
4785                 }
4786         }
4787
4788         if (!jited_cnt) {
4789                 fprintf(stderr, "not jited. skipping jited_line_info check. ");
4790                 err = 0;
4791                 goto done;
4792         }
4793
4794         if (CHECK(jited_linfo[0] != jited_ksyms[0],
4795                   "jited_linfo[0]:%lx != jited_ksyms[0]:%lx",
4796                   (long)(jited_linfo[0]), (long)(jited_ksyms[0]))) {
4797                 err = -1;
4798                 goto done;
4799         }
4800
4801         ksyms_found = 1;
4802         cur_func_len = jited_func_lens[0];
4803         cur_func_ksyms = jited_ksyms[0];
4804         for (i = 1; i < jited_cnt; i++) {
4805                 if (ksyms_found < nr_jited_ksyms &&
4806                     jited_linfo[i] == jited_ksyms[ksyms_found]) {
4807                         cur_func_ksyms = jited_ksyms[ksyms_found];
4808                         cur_func_len = jited_ksyms[ksyms_found];
4809                         ksyms_found++;
4810                         continue;
4811                 }
4812
4813                 if (CHECK(jited_linfo[i] <= jited_linfo[i - 1],
4814                           "jited_linfo[%u]:%lx <= jited_linfo[%u]:%lx",
4815                           i, (long)jited_linfo[i],
4816                           i - 1, (long)(jited_linfo[i - 1]))) {
4817                         err = -1;
4818                         goto done;
4819                 }
4820
4821                 if (CHECK(jited_linfo[i] - cur_func_ksyms > cur_func_len,
4822                           "jited_linfo[%u]:%lx - %lx > %u",
4823                           i, (long)jited_linfo[i], (long)cur_func_ksyms,
4824                           cur_func_len)) {
4825                         err = -1;
4826                         goto done;
4827                 }
4828         }
4829
4830         if (CHECK(ksyms_found != nr_jited_ksyms,
4831                   "ksyms_found:%u != nr_jited_ksyms:%u",
4832                   ksyms_found, nr_jited_ksyms)) {
4833                 err = -1;
4834                 goto done;
4835         }
4836
4837         err = 0;
4838
4839 done:
4840         free(linfo);
4841         free(jited_linfo);
4842         free(jited_ksyms);
4843         free(jited_func_lens);
4844         return err;
4845 }
4846
4847 static int do_test_info_raw(unsigned int test_num)
4848 {
4849         const struct prog_info_raw_test *test = &info_raw_tests[test_num - 1];
4850         unsigned int raw_btf_size, linfo_str_off, linfo_size;
4851         int btf_fd = -1, prog_fd = -1, err = 0;
4852         void *raw_btf, *patched_linfo = NULL;
4853         const char *ret_next_str;
4854         union bpf_attr attr = {};
4855
4856         fprintf(stderr, "BTF prog info raw test[%u] (%s): ", test_num, test->descr);
4857         raw_btf = btf_raw_create(&hdr_tmpl, test->raw_types,
4858                                  test->str_sec, test->str_sec_size,
4859                                  &raw_btf_size, &ret_next_str);
4860
4861         if (!raw_btf)
4862                 return -1;
4863
4864         *btf_log_buf = '\0';
4865         btf_fd = bpf_load_btf(raw_btf, raw_btf_size,
4866                               btf_log_buf, BTF_LOG_BUF_SIZE,
4867                               args.always_log);
4868         free(raw_btf);
4869
4870         if (CHECK(btf_fd == -1, "invalid btf_fd errno:%d", errno)) {
4871                 err = -1;
4872                 goto done;
4873         }
4874
4875         if (*btf_log_buf && args.always_log)
4876                 fprintf(stderr, "\n%s", btf_log_buf);
4877         *btf_log_buf = '\0';
4878
4879         linfo_str_off = ret_next_str - test->str_sec;
4880         patched_linfo = patch_name_tbd(test->line_info,
4881                                        test->str_sec, linfo_str_off,
4882                                        test->str_sec_size, &linfo_size);
4883         if (IS_ERR(patched_linfo)) {
4884                 fprintf(stderr, "error in creating raw bpf_line_info");
4885                 err = -1;
4886                 goto done;
4887         }
4888
4889         attr.prog_type = test->prog_type;
4890         attr.insns = ptr_to_u64(test->insns);
4891         attr.insn_cnt = probe_prog_length(test->insns);
4892         attr.license = ptr_to_u64("GPL");
4893         attr.prog_btf_fd = btf_fd;
4894         attr.func_info_rec_size = test->func_info_rec_size;
4895         attr.func_info_cnt = test->func_info_cnt;
4896         attr.func_info = ptr_to_u64(test->func_info);
4897         attr.log_buf = ptr_to_u64(btf_log_buf);
4898         attr.log_size = BTF_LOG_BUF_SIZE;
4899         attr.log_level = 1;
4900         if (linfo_size) {
4901                 attr.line_info_rec_size = test->line_info_rec_size;
4902                 attr.line_info = ptr_to_u64(patched_linfo);
4903                 attr.line_info_cnt = linfo_size / attr.line_info_rec_size;
4904         }
4905
4906         prog_fd = syscall(__NR_bpf, BPF_PROG_LOAD, &attr, sizeof(attr));
4907         err = ((prog_fd == -1) != test->expected_prog_load_failure);
4908         if (CHECK(err, "prog_fd:%d expected_prog_load_failure:%u errno:%d",
4909                   prog_fd, test->expected_prog_load_failure, errno) ||
4910             CHECK(test->err_str && !strstr(btf_log_buf, test->err_str),
4911                   "expected err_str:%s", test->err_str)) {
4912                 err = -1;
4913                 goto done;
4914         }
4915
4916         if (prog_fd == -1)
4917                 goto done;
4918
4919         err = test_get_finfo(test, prog_fd);
4920         if (err)
4921                 goto done;
4922
4923         err = test_get_linfo(test, patched_linfo, attr.line_info_cnt, prog_fd);
4924         if (err)
4925                 goto done;
4926
4927 done:
4928         if (!err)
4929                 fprintf(stderr, "OK");
4930
4931         if (*btf_log_buf && (err || args.always_log))
4932                 fprintf(stderr, "\n%s", btf_log_buf);
4933
4934         if (btf_fd != -1)
4935                 close(btf_fd);
4936         if (prog_fd != -1)
4937                 close(prog_fd);
4938
4939         if (!IS_ERR(patched_linfo))
4940                 free(patched_linfo);
4941
4942         return err;
4943 }
4944
4945 static int test_info_raw(void)
4946 {
4947         unsigned int i;
4948         int err = 0;
4949
4950         if (args.info_raw_test_num)
4951                 return count_result(do_test_info_raw(args.info_raw_test_num));
4952
4953         for (i = 1; i <= ARRAY_SIZE(info_raw_tests); i++)
4954                 err |= count_result(do_test_info_raw(i));
4955
4956         return err;
4957 }
4958
4959 static void usage(const char *cmd)
4960 {
4961         fprintf(stderr, "Usage: %s [-l] [[-r btf_raw_test_num (1 - %zu)] |\n"
4962                         "\t[-g btf_get_info_test_num (1 - %zu)] |\n"
4963                         "\t[-f btf_file_test_num (1 - %zu)] |\n"
4964                         "\t[-k btf_prog_info_raw_test_num (1 - %zu)] |\n"
4965                         "\t[-p (pretty print test)]]\n",
4966                 cmd, ARRAY_SIZE(raw_tests), ARRAY_SIZE(get_info_tests),
4967                 ARRAY_SIZE(file_tests), ARRAY_SIZE(info_raw_tests));
4968 }
4969
4970 static int parse_args(int argc, char **argv)
4971 {
4972         const char *optstr = "lpk:f:r:g:";
4973         int opt;
4974
4975         while ((opt = getopt(argc, argv, optstr)) != -1) {
4976                 switch (opt) {
4977                 case 'l':
4978                         args.always_log = true;
4979                         break;
4980                 case 'f':
4981                         args.file_test_num = atoi(optarg);
4982                         args.file_test = true;
4983                         break;
4984                 case 'r':
4985                         args.raw_test_num = atoi(optarg);
4986                         args.raw_test = true;
4987                         break;
4988                 case 'g':
4989                         args.get_info_test_num = atoi(optarg);
4990                         args.get_info_test = true;
4991                         break;
4992                 case 'p':
4993                         args.pprint_test = true;
4994                         break;
4995                 case 'k':
4996                         args.info_raw_test_num = atoi(optarg);
4997                         args.info_raw_test = true;
4998                         break;
4999                 case 'h':
5000                         usage(argv[0]);
5001                         exit(0);
5002                 default:
5003                                 usage(argv[0]);
5004                                 return -1;
5005                 }
5006         }
5007
5008         if (args.raw_test_num &&
5009             (args.raw_test_num < 1 ||
5010              args.raw_test_num > ARRAY_SIZE(raw_tests))) {
5011                 fprintf(stderr, "BTF raw test number must be [1 - %zu]\n",
5012                         ARRAY_SIZE(raw_tests));
5013                 return -1;
5014         }
5015
5016         if (args.file_test_num &&
5017             (args.file_test_num < 1 ||
5018              args.file_test_num > ARRAY_SIZE(file_tests))) {
5019                 fprintf(stderr, "BTF file test number must be [1 - %zu]\n",
5020                         ARRAY_SIZE(file_tests));
5021                 return -1;
5022         }
5023
5024         if (args.get_info_test_num &&
5025             (args.get_info_test_num < 1 ||
5026              args.get_info_test_num > ARRAY_SIZE(get_info_tests))) {
5027                 fprintf(stderr, "BTF get info test number must be [1 - %zu]\n",
5028                         ARRAY_SIZE(get_info_tests));
5029                 return -1;
5030         }
5031
5032         if (args.info_raw_test_num &&
5033             (args.info_raw_test_num < 1 ||
5034              args.info_raw_test_num > ARRAY_SIZE(info_raw_tests))) {
5035                 fprintf(stderr, "BTF prog info raw test number must be [1 - %zu]\n",
5036                         ARRAY_SIZE(info_raw_tests));
5037                 return -1;
5038         }
5039
5040         return 0;
5041 }
5042
5043 static void print_summary(void)
5044 {
5045         fprintf(stderr, "PASS:%u SKIP:%u FAIL:%u\n",
5046                 pass_cnt - skip_cnt, skip_cnt, error_cnt);
5047 }
5048
5049 int main(int argc, char **argv)
5050 {
5051         int err = 0;
5052
5053         err = parse_args(argc, argv);
5054         if (err)
5055                 return err;
5056
5057         if (args.always_log)
5058                 libbpf_set_print(__base_pr, __base_pr, __base_pr);
5059
5060         if (args.raw_test)
5061                 err |= test_raw();
5062
5063         if (args.get_info_test)
5064                 err |= test_get_info();
5065
5066         if (args.file_test)
5067                 err |= test_file();
5068
5069         if (args.pprint_test)
5070                 err |= test_pprint();
5071
5072         if (args.info_raw_test)
5073                 err |= test_info_raw();
5074
5075         if (args.raw_test || args.get_info_test || args.file_test ||
5076             args.pprint_test || args.info_raw_test)
5077                 goto done;
5078
5079         err |= test_raw();
5080         err |= test_get_info();
5081         err |= test_file();
5082         err |= test_info_raw();
5083
5084 done:
5085         print_summary();
5086         return err;
5087 }