Merge git://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf-next
[sfrench/cifs-2.6.git] / tools / testing / selftests / bpf / test_btf.c
1 /* SPDX-License-Identifier: GPL-2.0 */
2 /* Copyright (c) 2018 Facebook */
3
4 #include <linux/bpf.h>
5 #include <linux/btf.h>
6 #include <linux/err.h>
7 #include <linux/kernel.h>
8 #include <linux/filter.h>
9 #include <linux/unistd.h>
10 #include <bpf/bpf.h>
11 #include <sys/resource.h>
12 #include <libelf.h>
13 #include <gelf.h>
14 #include <string.h>
15 #include <stdlib.h>
16 #include <stdio.h>
17 #include <stdarg.h>
18 #include <unistd.h>
19 #include <fcntl.h>
20 #include <errno.h>
21 #include <assert.h>
22 #include <bpf/libbpf.h>
23 #include <bpf/btf.h>
24
25 #include "bpf_rlimit.h"
26 #include "bpf_util.h"
27 #include "test_btf.h"
28
29 #define MAX_INSNS       512
30 #define MAX_SUBPROGS    16
31
32 static uint32_t pass_cnt;
33 static uint32_t error_cnt;
34 static uint32_t skip_cnt;
35
36 #define CHECK(condition, format...) ({                                  \
37         int __ret = !!(condition);                                      \
38         if (__ret) {                                                    \
39                 fprintf(stderr, "%s:%d:FAIL ", __func__, __LINE__);     \
40                 fprintf(stderr, format);                                \
41         }                                                               \
42         __ret;                                                          \
43 })
44
45 static int count_result(int err)
46 {
47         if (err)
48                 error_cnt++;
49         else
50                 pass_cnt++;
51
52         fprintf(stderr, "\n");
53         return err;
54 }
55
56 static int __base_pr(enum libbpf_print_level level __attribute__((unused)),
57                      const char *format, va_list args)
58 {
59         return vfprintf(stderr, format, args);
60 }
61
62 #define BTF_END_RAW 0xdeadbeef
63 #define NAME_TBD 0xdeadb33f
64
65 #define NAME_NTH(N) (0xffff0000 | N)
66 #define IS_NAME_NTH(X) ((X & 0xffff0000) == 0xffff0000)
67 #define GET_NAME_NTH_IDX(X) (X & 0x0000ffff)
68
69 #define MAX_NR_RAW_U32 1024
70 #define BTF_LOG_BUF_SIZE 65535
71
72 static struct args {
73         unsigned int raw_test_num;
74         unsigned int file_test_num;
75         unsigned int get_info_test_num;
76         unsigned int info_raw_test_num;
77         unsigned int dedup_test_num;
78         bool raw_test;
79         bool file_test;
80         bool get_info_test;
81         bool pprint_test;
82         bool always_log;
83         bool info_raw_test;
84         bool dedup_test;
85 } args;
86
87 static char btf_log_buf[BTF_LOG_BUF_SIZE];
88
89 static struct btf_header hdr_tmpl = {
90         .magic = BTF_MAGIC,
91         .version = BTF_VERSION,
92         .hdr_len = sizeof(struct btf_header),
93 };
94
95 /* several different mapv kinds(types) supported by pprint */
96 enum pprint_mapv_kind_t {
97         PPRINT_MAPV_KIND_BASIC = 0,
98         PPRINT_MAPV_KIND_INT128,
99 };
100
101 struct btf_raw_test {
102         const char *descr;
103         const char *str_sec;
104         const char *map_name;
105         const char *err_str;
106         __u32 raw_types[MAX_NR_RAW_U32];
107         __u32 str_sec_size;
108         enum bpf_map_type map_type;
109         __u32 key_size;
110         __u32 value_size;
111         __u32 key_type_id;
112         __u32 value_type_id;
113         __u32 max_entries;
114         bool btf_load_err;
115         bool map_create_err;
116         bool ordered_map;
117         bool lossless_map;
118         bool percpu_map;
119         int hdr_len_delta;
120         int type_off_delta;
121         int str_off_delta;
122         int str_len_delta;
123         enum pprint_mapv_kind_t mapv_kind;
124 };
125
126 #define BTF_STR_SEC(str) \
127         .str_sec = str, .str_sec_size = sizeof(str)
128
129 static struct btf_raw_test raw_tests[] = {
130 /* enum E {
131  *     E0,
132  *     E1,
133  * };
134  *
135  * struct A {
136  *      unsigned long long m;
137  *      int n;
138  *      char o;
139  *      [3 bytes hole]
140  *      int p[8];
141  *      int q[4][8];
142  *      enum E r;
143  * };
144  */
145 {
146         .descr = "struct test #1",
147         .raw_types = {
148                 /* int */
149                 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),  /* [1] */
150                 /* unsigned long long */
151                 BTF_TYPE_INT_ENC(0, 0, 0, 64, 8),               /* [2] */
152                 /* char */
153                 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 8, 1),   /* [3] */
154                 /* int[8] */
155                 BTF_TYPE_ARRAY_ENC(1, 1, 8),                    /* [4] */
156                 /* struct A { */                                /* [5] */
157                 BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 6), 180),
158                 BTF_MEMBER_ENC(NAME_TBD, 2, 0), /* unsigned long long m;*/
159                 BTF_MEMBER_ENC(NAME_TBD, 1, 64),/* int n;               */
160                 BTF_MEMBER_ENC(NAME_TBD, 3, 96),/* char o;              */
161                 BTF_MEMBER_ENC(NAME_TBD, 4, 128),/* int p[8]            */
162                 BTF_MEMBER_ENC(NAME_TBD, 6, 384),/* int q[4][8]         */
163                 BTF_MEMBER_ENC(NAME_TBD, 7, 1408), /* enum E r          */
164                 /* } */
165                 /* int[4][8] */
166                 BTF_TYPE_ARRAY_ENC(4, 1, 4),                    /* [6] */
167                 /* enum E */                                    /* [7] */
168                 BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_ENUM, 0, 2), sizeof(int)),
169                 BTF_ENUM_ENC(NAME_TBD, 0),
170                 BTF_ENUM_ENC(NAME_TBD, 1),
171                 BTF_END_RAW,
172         },
173         .str_sec = "\0A\0m\0n\0o\0p\0q\0r\0E\0E0\0E1",
174         .str_sec_size = sizeof("\0A\0m\0n\0o\0p\0q\0r\0E\0E0\0E1"),
175         .map_type = BPF_MAP_TYPE_ARRAY,
176         .map_name = "struct_test1_map",
177         .key_size = sizeof(int),
178         .value_size = 180,
179         .key_type_id = 1,
180         .value_type_id = 5,
181         .max_entries = 4,
182 },
183
184 /* typedef struct b Struct_B;
185  *
186  * struct A {
187  *     int m;
188  *     struct b n[4];
189  *     const Struct_B o[4];
190  * };
191  *
192  * struct B {
193  *     int m;
194  *     int n;
195  * };
196  */
197 {
198         .descr = "struct test #2",
199         .raw_types = {
200                 /* int */                                       /* [1] */
201                 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
202                 /* struct b [4] */                              /* [2] */
203                 BTF_TYPE_ARRAY_ENC(4, 1, 4),
204
205                 /* struct A { */                                /* [3] */
206                 BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 3), 68),
207                 BTF_MEMBER_ENC(NAME_TBD, 1, 0), /* int m;               */
208                 BTF_MEMBER_ENC(NAME_TBD, 2, 32),/* struct B n[4]        */
209                 BTF_MEMBER_ENC(NAME_TBD, 8, 288),/* const Struct_B o[4];*/
210                 /* } */
211
212                 /* struct B { */                                /* [4] */
213                 BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 2), 8),
214                 BTF_MEMBER_ENC(NAME_TBD, 1, 0), /* int m; */
215                 BTF_MEMBER_ENC(NAME_TBD, 1, 32),/* int n; */
216                 /* } */
217
218                 /* const int */                                 /* [5] */
219                 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_CONST, 0, 0), 1),
220                 /* typedef struct b Struct_B */ /* [6] */
221                 BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_TYPEDEF, 0, 0), 4),
222                 /* const Struct_B */                            /* [7] */
223                 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_CONST, 0, 0), 6),
224                 /* const Struct_B [4] */                        /* [8] */
225                 BTF_TYPE_ARRAY_ENC(7, 1, 4),
226                 BTF_END_RAW,
227         },
228         .str_sec = "\0A\0m\0n\0o\0B\0m\0n\0Struct_B",
229         .str_sec_size = sizeof("\0A\0m\0n\0o\0B\0m\0n\0Struct_B"),
230         .map_type = BPF_MAP_TYPE_ARRAY,
231         .map_name = "struct_test2_map",
232         .key_size = sizeof(int),
233         .value_size = 68,
234         .key_type_id = 1,
235         .value_type_id = 3,
236         .max_entries = 4,
237 },
238 {
239         .descr = "struct test #3 Invalid member offset",
240         .raw_types = {
241                 /* int */                                       /* [1] */
242                 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
243                 /* int64 */                                     /* [2] */
244                 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 64, 8),
245
246                 /* struct A { */                                /* [3] */
247                 BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 2), 16),
248                 BTF_MEMBER_ENC(NAME_TBD, 1, 64),        /* int m;               */
249                 BTF_MEMBER_ENC(NAME_TBD, 2, 0),         /* int64 n; */
250                 /* } */
251                 BTF_END_RAW,
252         },
253         .str_sec = "\0A\0m\0n\0",
254         .str_sec_size = sizeof("\0A\0m\0n\0"),
255         .map_type = BPF_MAP_TYPE_ARRAY,
256         .map_name = "struct_test3_map",
257         .key_size = sizeof(int),
258         .value_size = 16,
259         .key_type_id = 1,
260         .value_type_id = 3,
261         .max_entries = 4,
262         .btf_load_err = true,
263         .err_str = "Invalid member bits_offset",
264 },
265 /*
266  * struct A {
267  *      unsigned long long m;
268  *      int n;
269  *      char o;
270  *      [3 bytes hole]
271  *      int p[8];
272  * };
273  */
274 {
275         .descr = "global data test #1",
276         .raw_types = {
277                 /* int */
278                 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),  /* [1] */
279                 /* unsigned long long */
280                 BTF_TYPE_INT_ENC(0, 0, 0, 64, 8),               /* [2] */
281                 /* char */
282                 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 8, 1),   /* [3] */
283                 /* int[8] */
284                 BTF_TYPE_ARRAY_ENC(1, 1, 8),                    /* [4] */
285                 /* struct A { */                                /* [5] */
286                 BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 4), 48),
287                 BTF_MEMBER_ENC(NAME_TBD, 2, 0), /* unsigned long long m;*/
288                 BTF_MEMBER_ENC(NAME_TBD, 1, 64),/* int n;               */
289                 BTF_MEMBER_ENC(NAME_TBD, 3, 96),/* char o;              */
290                 BTF_MEMBER_ENC(NAME_TBD, 4, 128),/* int p[8]            */
291                 /* } */
292                 BTF_END_RAW,
293         },
294         .str_sec = "\0A\0m\0n\0o\0p",
295         .str_sec_size = sizeof("\0A\0m\0n\0o\0p"),
296         .map_type = BPF_MAP_TYPE_ARRAY,
297         .map_name = "struct_test1_map",
298         .key_size = sizeof(int),
299         .value_size = 48,
300         .key_type_id = 1,
301         .value_type_id = 5,
302         .max_entries = 4,
303 },
304 /*
305  * struct A {
306  *      unsigned long long m;
307  *      int n;
308  *      char o;
309  *      [3 bytes hole]
310  *      int p[8];
311  * };
312  * static struct A t; <- in .bss
313  */
314 {
315         .descr = "global data test #2",
316         .raw_types = {
317                 /* int */
318                 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),  /* [1] */
319                 /* unsigned long long */
320                 BTF_TYPE_INT_ENC(0, 0, 0, 64, 8),               /* [2] */
321                 /* char */
322                 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 8, 1),   /* [3] */
323                 /* int[8] */
324                 BTF_TYPE_ARRAY_ENC(1, 1, 8),                    /* [4] */
325                 /* struct A { */                                /* [5] */
326                 BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 4), 48),
327                 BTF_MEMBER_ENC(NAME_TBD, 2, 0), /* unsigned long long m;*/
328                 BTF_MEMBER_ENC(NAME_TBD, 1, 64),/* int n;               */
329                 BTF_MEMBER_ENC(NAME_TBD, 3, 96),/* char o;              */
330                 BTF_MEMBER_ENC(NAME_TBD, 4, 128),/* int p[8]            */
331                 /* } */
332                 /* static struct A t */
333                 BTF_VAR_ENC(NAME_TBD, 5, 0),                    /* [6] */
334                 /* .bss section */                              /* [7] */
335                 BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_DATASEC, 0, 1), 48),
336                 BTF_VAR_SECINFO_ENC(6, 0, 48),
337                 BTF_END_RAW,
338         },
339         .str_sec = "\0A\0m\0n\0o\0p\0t\0.bss",
340         .str_sec_size = sizeof("\0A\0m\0n\0o\0p\0t\0.bss"),
341         .map_type = BPF_MAP_TYPE_ARRAY,
342         .map_name = ".bss",
343         .key_size = sizeof(int),
344         .value_size = 48,
345         .key_type_id = 0,
346         .value_type_id = 7,
347         .max_entries = 1,
348 },
349 {
350         .descr = "global data test #3",
351         .raw_types = {
352                 /* int */
353                 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),  /* [1] */
354                 /* static int t */
355                 BTF_VAR_ENC(NAME_TBD, 1, 0),                    /* [2] */
356                 /* .bss section */                              /* [3] */
357                 BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_DATASEC, 0, 1), 4),
358                 BTF_VAR_SECINFO_ENC(2, 0, 4),
359                 BTF_END_RAW,
360         },
361         .str_sec = "\0t\0.bss",
362         .str_sec_size = sizeof("\0t\0.bss"),
363         .map_type = BPF_MAP_TYPE_ARRAY,
364         .map_name = ".bss",
365         .key_size = sizeof(int),
366         .value_size = 4,
367         .key_type_id = 0,
368         .value_type_id = 3,
369         .max_entries = 1,
370 },
371 {
372         .descr = "global data test #4, unsupported linkage",
373         .raw_types = {
374                 /* int */
375                 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),  /* [1] */
376                 /* static int t */
377                 BTF_VAR_ENC(NAME_TBD, 1, 2),                    /* [2] */
378                 /* .bss section */                              /* [3] */
379                 BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_DATASEC, 0, 1), 4),
380                 BTF_VAR_SECINFO_ENC(2, 0, 4),
381                 BTF_END_RAW,
382         },
383         .str_sec = "\0t\0.bss",
384         .str_sec_size = sizeof("\0t\0.bss"),
385         .map_type = BPF_MAP_TYPE_ARRAY,
386         .map_name = ".bss",
387         .key_size = sizeof(int),
388         .value_size = 4,
389         .key_type_id = 0,
390         .value_type_id = 3,
391         .max_entries = 1,
392         .btf_load_err = true,
393         .err_str = "Linkage not supported",
394 },
395 {
396         .descr = "global data test #5, invalid var type",
397         .raw_types = {
398                 /* static void t */
399                 BTF_VAR_ENC(NAME_TBD, 0, 0),                    /* [1] */
400                 /* .bss section */                              /* [2] */
401                 BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_DATASEC, 0, 1), 4),
402                 BTF_VAR_SECINFO_ENC(1, 0, 4),
403                 BTF_END_RAW,
404         },
405         .str_sec = "\0t\0.bss",
406         .str_sec_size = sizeof("\0t\0.bss"),
407         .map_type = BPF_MAP_TYPE_ARRAY,
408         .map_name = ".bss",
409         .key_size = sizeof(int),
410         .value_size = 4,
411         .key_type_id = 0,
412         .value_type_id = 2,
413         .max_entries = 1,
414         .btf_load_err = true,
415         .err_str = "Invalid type_id",
416 },
417 {
418         .descr = "global data test #6, invalid var type (fwd type)",
419         .raw_types = {
420                 /* union A */
421                 BTF_TYPE_ENC(NAME_TBD,
422                              BTF_INFO_ENC(BTF_KIND_FWD, 1, 0), 0), /* [1] */
423                 /* static union A t */
424                 BTF_VAR_ENC(NAME_TBD, 1, 0),                    /* [2] */
425                 /* .bss section */                              /* [3] */
426                 BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_DATASEC, 0, 1), 4),
427                 BTF_VAR_SECINFO_ENC(2, 0, 4),
428                 BTF_END_RAW,
429         },
430         .str_sec = "\0A\0t\0.bss",
431         .str_sec_size = sizeof("\0A\0t\0.bss"),
432         .map_type = BPF_MAP_TYPE_ARRAY,
433         .map_name = ".bss",
434         .key_size = sizeof(int),
435         .value_size = 4,
436         .key_type_id = 0,
437         .value_type_id = 2,
438         .max_entries = 1,
439         .btf_load_err = true,
440         .err_str = "Invalid type",
441 },
442 {
443         .descr = "global data test #7, invalid var type (fwd type)",
444         .raw_types = {
445                 /* union A */
446                 BTF_TYPE_ENC(NAME_TBD,
447                              BTF_INFO_ENC(BTF_KIND_FWD, 1, 0), 0), /* [1] */
448                 /* static union A t */
449                 BTF_VAR_ENC(NAME_TBD, 1, 0),                    /* [2] */
450                 /* .bss section */                              /* [3] */
451                 BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_DATASEC, 0, 1), 4),
452                 BTF_VAR_SECINFO_ENC(1, 0, 4),
453                 BTF_END_RAW,
454         },
455         .str_sec = "\0A\0t\0.bss",
456         .str_sec_size = sizeof("\0A\0t\0.bss"),
457         .map_type = BPF_MAP_TYPE_ARRAY,
458         .map_name = ".bss",
459         .key_size = sizeof(int),
460         .value_size = 4,
461         .key_type_id = 0,
462         .value_type_id = 2,
463         .max_entries = 1,
464         .btf_load_err = true,
465         .err_str = "Invalid type",
466 },
467 {
468         .descr = "global data test #8, invalid var size",
469         .raw_types = {
470                 /* int */
471                 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),  /* [1] */
472                 /* unsigned long long */
473                 BTF_TYPE_INT_ENC(0, 0, 0, 64, 8),               /* [2] */
474                 /* char */
475                 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 8, 1),   /* [3] */
476                 /* int[8] */
477                 BTF_TYPE_ARRAY_ENC(1, 1, 8),                    /* [4] */
478                 /* struct A { */                                /* [5] */
479                 BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 4), 48),
480                 BTF_MEMBER_ENC(NAME_TBD, 2, 0), /* unsigned long long m;*/
481                 BTF_MEMBER_ENC(NAME_TBD, 1, 64),/* int n;               */
482                 BTF_MEMBER_ENC(NAME_TBD, 3, 96),/* char o;              */
483                 BTF_MEMBER_ENC(NAME_TBD, 4, 128),/* int p[8]            */
484                 /* } */
485                 /* static struct A t */
486                 BTF_VAR_ENC(NAME_TBD, 5, 0),                    /* [6] */
487                 /* .bss section */                              /* [7] */
488                 BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_DATASEC, 0, 1), 48),
489                 BTF_VAR_SECINFO_ENC(6, 0, 47),
490                 BTF_END_RAW,
491         },
492         .str_sec = "\0A\0m\0n\0o\0p\0t\0.bss",
493         .str_sec_size = sizeof("\0A\0m\0n\0o\0p\0t\0.bss"),
494         .map_type = BPF_MAP_TYPE_ARRAY,
495         .map_name = ".bss",
496         .key_size = sizeof(int),
497         .value_size = 48,
498         .key_type_id = 0,
499         .value_type_id = 7,
500         .max_entries = 1,
501         .btf_load_err = true,
502         .err_str = "Invalid size",
503 },
504 {
505         .descr = "global data test #9, invalid var size",
506         .raw_types = {
507                 /* int */
508                 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),  /* [1] */
509                 /* unsigned long long */
510                 BTF_TYPE_INT_ENC(0, 0, 0, 64, 8),               /* [2] */
511                 /* char */
512                 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 8, 1),   /* [3] */
513                 /* int[8] */
514                 BTF_TYPE_ARRAY_ENC(1, 1, 8),                    /* [4] */
515                 /* struct A { */                                /* [5] */
516                 BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 4), 48),
517                 BTF_MEMBER_ENC(NAME_TBD, 2, 0), /* unsigned long long m;*/
518                 BTF_MEMBER_ENC(NAME_TBD, 1, 64),/* int n;               */
519                 BTF_MEMBER_ENC(NAME_TBD, 3, 96),/* char o;              */
520                 BTF_MEMBER_ENC(NAME_TBD, 4, 128),/* int p[8]            */
521                 /* } */
522                 /* static struct A t */
523                 BTF_VAR_ENC(NAME_TBD, 5, 0),                    /* [6] */
524                 /* .bss section */                              /* [7] */
525                 BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_DATASEC, 0, 1), 46),
526                 BTF_VAR_SECINFO_ENC(6, 0, 48),
527                 BTF_END_RAW,
528         },
529         .str_sec = "\0A\0m\0n\0o\0p\0t\0.bss",
530         .str_sec_size = sizeof("\0A\0m\0n\0o\0p\0t\0.bss"),
531         .map_type = BPF_MAP_TYPE_ARRAY,
532         .map_name = ".bss",
533         .key_size = sizeof(int),
534         .value_size = 48,
535         .key_type_id = 0,
536         .value_type_id = 7,
537         .max_entries = 1,
538         .btf_load_err = true,
539         .err_str = "Invalid size",
540 },
541 {
542         .descr = "global data test #10, invalid var size",
543         .raw_types = {
544                 /* int */
545                 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),  /* [1] */
546                 /* unsigned long long */
547                 BTF_TYPE_INT_ENC(0, 0, 0, 64, 8),               /* [2] */
548                 /* char */
549                 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 8, 1),   /* [3] */
550                 /* int[8] */
551                 BTF_TYPE_ARRAY_ENC(1, 1, 8),                    /* [4] */
552                 /* struct A { */                                /* [5] */
553                 BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 4), 48),
554                 BTF_MEMBER_ENC(NAME_TBD, 2, 0), /* unsigned long long m;*/
555                 BTF_MEMBER_ENC(NAME_TBD, 1, 64),/* int n;               */
556                 BTF_MEMBER_ENC(NAME_TBD, 3, 96),/* char o;              */
557                 BTF_MEMBER_ENC(NAME_TBD, 4, 128),/* int p[8]            */
558                 /* } */
559                 /* static struct A t */
560                 BTF_VAR_ENC(NAME_TBD, 5, 0),                    /* [6] */
561                 /* .bss section */                              /* [7] */
562                 BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_DATASEC, 0, 1), 46),
563                 BTF_VAR_SECINFO_ENC(6, 0, 46),
564                 BTF_END_RAW,
565         },
566         .str_sec = "\0A\0m\0n\0o\0p\0t\0.bss",
567         .str_sec_size = sizeof("\0A\0m\0n\0o\0p\0t\0.bss"),
568         .map_type = BPF_MAP_TYPE_ARRAY,
569         .map_name = ".bss",
570         .key_size = sizeof(int),
571         .value_size = 48,
572         .key_type_id = 0,
573         .value_type_id = 7,
574         .max_entries = 1,
575         .btf_load_err = true,
576         .err_str = "Invalid size",
577 },
578 {
579         .descr = "global data test #11, multiple section members",
580         .raw_types = {
581                 /* int */
582                 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),  /* [1] */
583                 /* unsigned long long */
584                 BTF_TYPE_INT_ENC(0, 0, 0, 64, 8),               /* [2] */
585                 /* char */
586                 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 8, 1),   /* [3] */
587                 /* int[8] */
588                 BTF_TYPE_ARRAY_ENC(1, 1, 8),                    /* [4] */
589                 /* struct A { */                                /* [5] */
590                 BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 4), 48),
591                 BTF_MEMBER_ENC(NAME_TBD, 2, 0), /* unsigned long long m;*/
592                 BTF_MEMBER_ENC(NAME_TBD, 1, 64),/* int n;               */
593                 BTF_MEMBER_ENC(NAME_TBD, 3, 96),/* char o;              */
594                 BTF_MEMBER_ENC(NAME_TBD, 4, 128),/* int p[8]            */
595                 /* } */
596                 /* static struct A t */
597                 BTF_VAR_ENC(NAME_TBD, 5, 0),                    /* [6] */
598                 /* static int u */
599                 BTF_VAR_ENC(NAME_TBD, 1, 0),                    /* [7] */
600                 /* .bss section */                              /* [8] */
601                 BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_DATASEC, 0, 2), 62),
602                 BTF_VAR_SECINFO_ENC(6, 10, 48),
603                 BTF_VAR_SECINFO_ENC(7, 58, 4),
604                 BTF_END_RAW,
605         },
606         .str_sec = "\0A\0m\0n\0o\0p\0t\0u\0.bss",
607         .str_sec_size = sizeof("\0A\0m\0n\0o\0p\0t\0u\0.bss"),
608         .map_type = BPF_MAP_TYPE_ARRAY,
609         .map_name = ".bss",
610         .key_size = sizeof(int),
611         .value_size = 62,
612         .key_type_id = 0,
613         .value_type_id = 8,
614         .max_entries = 1,
615 },
616 {
617         .descr = "global data test #12, invalid offset",
618         .raw_types = {
619                 /* int */
620                 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),  /* [1] */
621                 /* unsigned long long */
622                 BTF_TYPE_INT_ENC(0, 0, 0, 64, 8),               /* [2] */
623                 /* char */
624                 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 8, 1),   /* [3] */
625                 /* int[8] */
626                 BTF_TYPE_ARRAY_ENC(1, 1, 8),                    /* [4] */
627                 /* struct A { */                                /* [5] */
628                 BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 4), 48),
629                 BTF_MEMBER_ENC(NAME_TBD, 2, 0), /* unsigned long long m;*/
630                 BTF_MEMBER_ENC(NAME_TBD, 1, 64),/* int n;               */
631                 BTF_MEMBER_ENC(NAME_TBD, 3, 96),/* char o;              */
632                 BTF_MEMBER_ENC(NAME_TBD, 4, 128),/* int p[8]            */
633                 /* } */
634                 /* static struct A t */
635                 BTF_VAR_ENC(NAME_TBD, 5, 0),                    /* [6] */
636                 /* static int u */
637                 BTF_VAR_ENC(NAME_TBD, 1, 0),                    /* [7] */
638                 /* .bss section */                              /* [8] */
639                 BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_DATASEC, 0, 2), 62),
640                 BTF_VAR_SECINFO_ENC(6, 10, 48),
641                 BTF_VAR_SECINFO_ENC(7, 60, 4),
642                 BTF_END_RAW,
643         },
644         .str_sec = "\0A\0m\0n\0o\0p\0t\0u\0.bss",
645         .str_sec_size = sizeof("\0A\0m\0n\0o\0p\0t\0u\0.bss"),
646         .map_type = BPF_MAP_TYPE_ARRAY,
647         .map_name = ".bss",
648         .key_size = sizeof(int),
649         .value_size = 62,
650         .key_type_id = 0,
651         .value_type_id = 8,
652         .max_entries = 1,
653         .btf_load_err = true,
654         .err_str = "Invalid offset+size",
655 },
656 {
657         .descr = "global data test #13, invalid offset",
658         .raw_types = {
659                 /* int */
660                 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),  /* [1] */
661                 /* unsigned long long */
662                 BTF_TYPE_INT_ENC(0, 0, 0, 64, 8),               /* [2] */
663                 /* char */
664                 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 8, 1),   /* [3] */
665                 /* int[8] */
666                 BTF_TYPE_ARRAY_ENC(1, 1, 8),                    /* [4] */
667                 /* struct A { */                                /* [5] */
668                 BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 4), 48),
669                 BTF_MEMBER_ENC(NAME_TBD, 2, 0), /* unsigned long long m;*/
670                 BTF_MEMBER_ENC(NAME_TBD, 1, 64),/* int n;               */
671                 BTF_MEMBER_ENC(NAME_TBD, 3, 96),/* char o;              */
672                 BTF_MEMBER_ENC(NAME_TBD, 4, 128),/* int p[8]            */
673                 /* } */
674                 /* static struct A t */
675                 BTF_VAR_ENC(NAME_TBD, 5, 0),                    /* [6] */
676                 /* static int u */
677                 BTF_VAR_ENC(NAME_TBD, 1, 0),                    /* [7] */
678                 /* .bss section */                              /* [8] */
679                 BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_DATASEC, 0, 2), 62),
680                 BTF_VAR_SECINFO_ENC(6, 10, 48),
681                 BTF_VAR_SECINFO_ENC(7, 12, 4),
682                 BTF_END_RAW,
683         },
684         .str_sec = "\0A\0m\0n\0o\0p\0t\0u\0.bss",
685         .str_sec_size = sizeof("\0A\0m\0n\0o\0p\0t\0u\0.bss"),
686         .map_type = BPF_MAP_TYPE_ARRAY,
687         .map_name = ".bss",
688         .key_size = sizeof(int),
689         .value_size = 62,
690         .key_type_id = 0,
691         .value_type_id = 8,
692         .max_entries = 1,
693         .btf_load_err = true,
694         .err_str = "Invalid offset",
695 },
696 {
697         .descr = "global data test #14, invalid offset",
698         .raw_types = {
699                 /* int */
700                 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),  /* [1] */
701                 /* unsigned long long */
702                 BTF_TYPE_INT_ENC(0, 0, 0, 64, 8),               /* [2] */
703                 /* char */
704                 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 8, 1),   /* [3] */
705                 /* int[8] */
706                 BTF_TYPE_ARRAY_ENC(1, 1, 8),                    /* [4] */
707                 /* struct A { */                                /* [5] */
708                 BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 4), 48),
709                 BTF_MEMBER_ENC(NAME_TBD, 2, 0), /* unsigned long long m;*/
710                 BTF_MEMBER_ENC(NAME_TBD, 1, 64),/* int n;               */
711                 BTF_MEMBER_ENC(NAME_TBD, 3, 96),/* char o;              */
712                 BTF_MEMBER_ENC(NAME_TBD, 4, 128),/* int p[8]            */
713                 /* } */
714                 /* static struct A t */
715                 BTF_VAR_ENC(NAME_TBD, 5, 0),                    /* [6] */
716                 /* static int u */
717                 BTF_VAR_ENC(NAME_TBD, 1, 0),                    /* [7] */
718                 /* .bss section */                              /* [8] */
719                 BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_DATASEC, 0, 2), 62),
720                 BTF_VAR_SECINFO_ENC(7, 58, 4),
721                 BTF_VAR_SECINFO_ENC(6, 10, 48),
722                 BTF_END_RAW,
723         },
724         .str_sec = "\0A\0m\0n\0o\0p\0t\0u\0.bss",
725         .str_sec_size = sizeof("\0A\0m\0n\0o\0p\0t\0u\0.bss"),
726         .map_type = BPF_MAP_TYPE_ARRAY,
727         .map_name = ".bss",
728         .key_size = sizeof(int),
729         .value_size = 62,
730         .key_type_id = 0,
731         .value_type_id = 8,
732         .max_entries = 1,
733         .btf_load_err = true,
734         .err_str = "Invalid offset",
735 },
736 {
737         .descr = "global data test #15, not var kind",
738         .raw_types = {
739                 /* int */
740                 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),  /* [1] */
741                 BTF_VAR_ENC(NAME_TBD, 1, 0),                    /* [2] */
742                 /* .bss section */                              /* [3] */
743                 BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_DATASEC, 0, 1), 4),
744                 BTF_VAR_SECINFO_ENC(1, 0, 4),
745                 BTF_END_RAW,
746         },
747         .str_sec = "\0A\0t\0.bss",
748         .str_sec_size = sizeof("\0A\0t\0.bss"),
749         .map_type = BPF_MAP_TYPE_ARRAY,
750         .map_name = ".bss",
751         .key_size = sizeof(int),
752         .value_size = 4,
753         .key_type_id = 0,
754         .value_type_id = 3,
755         .max_entries = 1,
756         .btf_load_err = true,
757         .err_str = "Not a VAR kind member",
758 },
759 {
760         .descr = "global data test #16, invalid var referencing sec",
761         .raw_types = {
762                 /* int */
763                 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),  /* [1] */
764                 BTF_VAR_ENC(NAME_TBD, 5, 0),                    /* [2] */
765                 BTF_VAR_ENC(NAME_TBD, 2, 0),                    /* [3] */
766                 /* a section */                                 /* [4] */
767                 BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_DATASEC, 0, 1), 4),
768                 BTF_VAR_SECINFO_ENC(3, 0, 4),
769                 /* a section */                                 /* [5] */
770                 BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_DATASEC, 0, 1), 4),
771                 BTF_VAR_SECINFO_ENC(6, 0, 4),
772                 BTF_VAR_ENC(NAME_TBD, 1, 0),                    /* [6] */
773                 BTF_END_RAW,
774         },
775         .str_sec = "\0A\0t\0s\0a\0a",
776         .str_sec_size = sizeof("\0A\0t\0s\0a\0a"),
777         .map_type = BPF_MAP_TYPE_ARRAY,
778         .map_name = ".bss",
779         .key_size = sizeof(int),
780         .value_size = 4,
781         .key_type_id = 0,
782         .value_type_id = 4,
783         .max_entries = 1,
784         .btf_load_err = true,
785         .err_str = "Invalid type_id",
786 },
787 {
788         .descr = "global data test #17, invalid var referencing var",
789         .raw_types = {
790                 /* int */
791                 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),  /* [1] */
792                 BTF_VAR_ENC(NAME_TBD, 1, 0),                    /* [2] */
793                 BTF_VAR_ENC(NAME_TBD, 2, 0),                    /* [3] */
794                 /* a section */                                 /* [4] */
795                 BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_DATASEC, 0, 1), 4),
796                 BTF_VAR_SECINFO_ENC(3, 0, 4),
797                 BTF_END_RAW,
798         },
799         .str_sec = "\0A\0t\0s\0a\0a",
800         .str_sec_size = sizeof("\0A\0t\0s\0a\0a"),
801         .map_type = BPF_MAP_TYPE_ARRAY,
802         .map_name = ".bss",
803         .key_size = sizeof(int),
804         .value_size = 4,
805         .key_type_id = 0,
806         .value_type_id = 4,
807         .max_entries = 1,
808         .btf_load_err = true,
809         .err_str = "Invalid type_id",
810 },
811 {
812         .descr = "global data test #18, invalid var loop",
813         .raw_types = {
814                 /* int */
815                 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),  /* [1] */
816                 BTF_VAR_ENC(NAME_TBD, 2, 0),                    /* [2] */
817                 /* .bss section */                              /* [3] */
818                 BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_DATASEC, 0, 1), 4),
819                 BTF_VAR_SECINFO_ENC(2, 0, 4),
820                 BTF_END_RAW,
821         },
822         .str_sec = "\0A\0t\0aaa",
823         .str_sec_size = sizeof("\0A\0t\0aaa"),
824         .map_type = BPF_MAP_TYPE_ARRAY,
825         .map_name = ".bss",
826         .key_size = sizeof(int),
827         .value_size = 4,
828         .key_type_id = 0,
829         .value_type_id = 4,
830         .max_entries = 1,
831         .btf_load_err = true,
832         .err_str = "Invalid type_id",
833 },
834 {
835         .descr = "global data test #19, invalid var referencing var",
836         .raw_types = {
837                 /* int */
838                 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),  /* [1] */
839                 BTF_VAR_ENC(NAME_TBD, 3, 0),                    /* [2] */
840                 BTF_VAR_ENC(NAME_TBD, 1, 0),                    /* [3] */
841                 BTF_END_RAW,
842         },
843         .str_sec = "\0A\0t\0s\0a\0a",
844         .str_sec_size = sizeof("\0A\0t\0s\0a\0a"),
845         .map_type = BPF_MAP_TYPE_ARRAY,
846         .map_name = ".bss",
847         .key_size = sizeof(int),
848         .value_size = 4,
849         .key_type_id = 0,
850         .value_type_id = 4,
851         .max_entries = 1,
852         .btf_load_err = true,
853         .err_str = "Invalid type_id",
854 },
855 {
856         .descr = "global data test #20, invalid ptr referencing var",
857         .raw_types = {
858                 /* int */
859                 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),  /* [1] */
860                 /* PTR type_id=3        */                      /* [2] */
861                 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_PTR, 0, 0), 3),
862                 BTF_VAR_ENC(NAME_TBD, 1, 0),                    /* [3] */
863                 BTF_END_RAW,
864         },
865         .str_sec = "\0A\0t\0s\0a\0a",
866         .str_sec_size = sizeof("\0A\0t\0s\0a\0a"),
867         .map_type = BPF_MAP_TYPE_ARRAY,
868         .map_name = ".bss",
869         .key_size = sizeof(int),
870         .value_size = 4,
871         .key_type_id = 0,
872         .value_type_id = 4,
873         .max_entries = 1,
874         .btf_load_err = true,
875         .err_str = "Invalid type_id",
876 },
877 {
878         .descr = "global data test #21, var included in struct",
879         .raw_types = {
880                 /* int */
881                 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),  /* [1] */
882                 /* struct A { */                                /* [2] */
883                 BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 2), sizeof(int) * 2),
884                 BTF_MEMBER_ENC(NAME_TBD, 1, 0), /* int m; */
885                 BTF_MEMBER_ENC(NAME_TBD, 3, 32),/* VAR type_id=3; */
886                 /* } */
887                 BTF_VAR_ENC(NAME_TBD, 1, 0),                    /* [3] */
888                 BTF_END_RAW,
889         },
890         .str_sec = "\0A\0t\0s\0a\0a",
891         .str_sec_size = sizeof("\0A\0t\0s\0a\0a"),
892         .map_type = BPF_MAP_TYPE_ARRAY,
893         .map_name = ".bss",
894         .key_size = sizeof(int),
895         .value_size = 4,
896         .key_type_id = 0,
897         .value_type_id = 4,
898         .max_entries = 1,
899         .btf_load_err = true,
900         .err_str = "Invalid member",
901 },
902 {
903         .descr = "global data test #22, array of var",
904         .raw_types = {
905                 /* int */
906                 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),  /* [1] */
907                 BTF_TYPE_ARRAY_ENC(3, 1, 4),                    /* [2] */
908                 BTF_VAR_ENC(NAME_TBD, 1, 0),                    /* [3] */
909                 BTF_END_RAW,
910         },
911         .str_sec = "\0A\0t\0s\0a\0a",
912         .str_sec_size = sizeof("\0A\0t\0s\0a\0a"),
913         .map_type = BPF_MAP_TYPE_ARRAY,
914         .map_name = ".bss",
915         .key_size = sizeof(int),
916         .value_size = 4,
917         .key_type_id = 0,
918         .value_type_id = 4,
919         .max_entries = 1,
920         .btf_load_err = true,
921         .err_str = "Invalid elem",
922 },
923 /* Test member exceeds the size of struct.
924  *
925  * struct A {
926  *     int m;
927  *     int n;
928  * };
929  */
930 {
931         .descr = "size check test #1",
932         .raw_types = {
933                 /* int */                                       /* [1] */
934                 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
935                 /* struct A { */                                /* [2] */
936                 BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 2), sizeof(int) * 2 -  1),
937                 BTF_MEMBER_ENC(NAME_TBD, 1, 0), /* int m; */
938                 BTF_MEMBER_ENC(NAME_TBD, 1, 32),/* int n; */
939                 /* } */
940                 BTF_END_RAW,
941         },
942         .str_sec = "\0A\0m\0n",
943         .str_sec_size = sizeof("\0A\0m\0n"),
944         .map_type = BPF_MAP_TYPE_ARRAY,
945         .map_name = "size_check1_map",
946         .key_size = sizeof(int),
947         .value_size = 1,
948         .key_type_id = 1,
949         .value_type_id = 2,
950         .max_entries = 4,
951         .btf_load_err = true,
952         .err_str = "Member exceeds struct_size",
953 },
954
955 /* Test member exeeds the size of struct
956  *
957  * struct A {
958  *     int m;
959  *     int n[2];
960  * };
961  */
962 {
963         .descr = "size check test #2",
964         .raw_types = {
965                 /* int */                                       /* [1] */
966                 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, sizeof(int)),
967                 /* int[2] */                                    /* [2] */
968                 BTF_TYPE_ARRAY_ENC(1, 1, 2),
969                 /* struct A { */                                /* [3] */
970                 BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 2), sizeof(int) * 3 - 1),
971                 BTF_MEMBER_ENC(NAME_TBD, 1, 0), /* int m; */
972                 BTF_MEMBER_ENC(NAME_TBD, 2, 32),/* int n[2]; */
973                 /* } */
974                 BTF_END_RAW,
975         },
976         .str_sec = "\0A\0m\0n",
977         .str_sec_size = sizeof("\0A\0m\0n"),
978         .map_type = BPF_MAP_TYPE_ARRAY,
979         .map_name = "size_check2_map",
980         .key_size = sizeof(int),
981         .value_size = 1,
982         .key_type_id = 1,
983         .value_type_id = 3,
984         .max_entries = 4,
985         .btf_load_err = true,
986         .err_str = "Member exceeds struct_size",
987 },
988
989 /* Test member exeeds the size of struct
990  *
991  * struct A {
992  *     int m;
993  *     void *n;
994  * };
995  */
996 {
997         .descr = "size check test #3",
998         .raw_types = {
999                 /* int */                                       /* [1] */
1000                 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, sizeof(int)),
1001                 /* void* */                                     /* [2] */
1002                 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_PTR, 0, 0), 0),
1003                 /* struct A { */                                /* [3] */
1004                 BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 2), sizeof(int) + sizeof(void *) - 1),
1005                 BTF_MEMBER_ENC(NAME_TBD, 1, 0), /* int m; */
1006                 BTF_MEMBER_ENC(NAME_TBD, 2, 32),/* void *n; */
1007                 /* } */
1008                 BTF_END_RAW,
1009         },
1010         .str_sec = "\0A\0m\0n",
1011         .str_sec_size = sizeof("\0A\0m\0n"),
1012         .map_type = BPF_MAP_TYPE_ARRAY,
1013         .map_name = "size_check3_map",
1014         .key_size = sizeof(int),
1015         .value_size = 1,
1016         .key_type_id = 1,
1017         .value_type_id = 3,
1018         .max_entries = 4,
1019         .btf_load_err = true,
1020         .err_str = "Member exceeds struct_size",
1021 },
1022
1023 /* Test member exceeds the size of struct
1024  *
1025  * enum E {
1026  *     E0,
1027  *     E1,
1028  * };
1029  *
1030  * struct A {
1031  *     int m;
1032  *     enum E n;
1033  * };
1034  */
1035 {
1036         .descr = "size check test #4",
1037         .raw_types = {
1038                 /* int */                       /* [1] */
1039                 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, sizeof(int)),
1040                 /* enum E { */                  /* [2] */
1041                 BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_ENUM, 0, 2), sizeof(int)),
1042                 BTF_ENUM_ENC(NAME_TBD, 0),
1043                 BTF_ENUM_ENC(NAME_TBD, 1),
1044                 /* } */
1045                 /* struct A { */                /* [3] */
1046                 BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 2), sizeof(int) * 2 - 1),
1047                 BTF_MEMBER_ENC(NAME_TBD, 1, 0), /* int m; */
1048                 BTF_MEMBER_ENC(NAME_TBD, 2, 32),/* enum E n; */
1049                 /* } */
1050                 BTF_END_RAW,
1051         },
1052         .str_sec = "\0E\0E0\0E1\0A\0m\0n",
1053         .str_sec_size = sizeof("\0E\0E0\0E1\0A\0m\0n"),
1054         .map_type = BPF_MAP_TYPE_ARRAY,
1055         .map_name = "size_check4_map",
1056         .key_size = sizeof(int),
1057         .value_size = 1,
1058         .key_type_id = 1,
1059         .value_type_id = 3,
1060         .max_entries = 4,
1061         .btf_load_err = true,
1062         .err_str = "Member exceeds struct_size",
1063 },
1064
1065 /* typedef const void * const_void_ptr;
1066  * struct A {
1067  *      const_void_ptr m;
1068  * };
1069  */
1070 {
1071         .descr = "void test #1",
1072         .raw_types = {
1073                 /* int */               /* [1] */
1074                 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
1075                 /* const void */        /* [2] */
1076                 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_CONST, 0, 0), 0),
1077                 /* const void* */       /* [3] */
1078                 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_PTR, 0, 0), 2),
1079                 /* typedef const void * const_void_ptr */
1080                 BTF_TYPEDEF_ENC(NAME_TBD, 3),   /* [4] */
1081                 /* struct A { */        /* [5] */
1082                 BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 1), sizeof(void *)),
1083                 /* const_void_ptr m; */
1084                 BTF_MEMBER_ENC(NAME_TBD, 4, 0),
1085                 /* } */
1086                 BTF_END_RAW,
1087         },
1088         .str_sec = "\0const_void_ptr\0A\0m",
1089         .str_sec_size = sizeof("\0const_void_ptr\0A\0m"),
1090         .map_type = BPF_MAP_TYPE_ARRAY,
1091         .map_name = "void_test1_map",
1092         .key_size = sizeof(int),
1093         .value_size = sizeof(void *),
1094         .key_type_id = 1,
1095         .value_type_id = 4,
1096         .max_entries = 4,
1097 },
1098
1099 /* struct A {
1100  *     const void m;
1101  * };
1102  */
1103 {
1104         .descr = "void test #2",
1105         .raw_types = {
1106                 /* int */               /* [1] */
1107                 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
1108                 /* const void */        /* [2] */
1109                 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_CONST, 0, 0), 0),
1110                 /* struct A { */        /* [3] */
1111                 BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 1), 8),
1112                 /* const void m; */
1113                 BTF_MEMBER_ENC(NAME_TBD, 2, 0),
1114                 /* } */
1115                 BTF_END_RAW,
1116         },
1117         .str_sec = "\0A\0m",
1118         .str_sec_size = sizeof("\0A\0m"),
1119         .map_type = BPF_MAP_TYPE_ARRAY,
1120         .map_name = "void_test2_map",
1121         .key_size = sizeof(int),
1122         .value_size = sizeof(void *),
1123         .key_type_id = 1,
1124         .value_type_id = 3,
1125         .max_entries = 4,
1126         .btf_load_err = true,
1127         .err_str = "Invalid member",
1128 },
1129
1130 /* typedef const void * const_void_ptr;
1131  * const_void_ptr[4]
1132  */
1133 {
1134         .descr = "void test #3",
1135         .raw_types = {
1136                 /* int */               /* [1] */
1137                 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
1138                 /* const void */        /* [2] */
1139                 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_CONST, 0, 0), 0),
1140                 /* const void* */       /* [3] */
1141                 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_PTR, 0, 0), 2),
1142                 /* typedef const void * const_void_ptr */
1143                 BTF_TYPEDEF_ENC(NAME_TBD, 3),   /* [4] */
1144                 /* const_void_ptr[4] */
1145                 BTF_TYPE_ARRAY_ENC(4, 1, 4),    /* [5] */
1146                 BTF_END_RAW,
1147         },
1148         .str_sec = "\0const_void_ptr",
1149         .str_sec_size = sizeof("\0const_void_ptr"),
1150         .map_type = BPF_MAP_TYPE_ARRAY,
1151         .map_name = "void_test3_map",
1152         .key_size = sizeof(int),
1153         .value_size = sizeof(void *) * 4,
1154         .key_type_id = 1,
1155         .value_type_id = 5,
1156         .max_entries = 4,
1157 },
1158
1159 /* const void[4]  */
1160 {
1161         .descr = "void test #4",
1162         .raw_types = {
1163                 /* int */               /* [1] */
1164                 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
1165                 /* const void */        /* [2] */
1166                 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_CONST, 0, 0), 0),
1167                 /* const void[4] */     /* [3] */
1168                 BTF_TYPE_ARRAY_ENC(2, 1, 4),
1169                 BTF_END_RAW,
1170         },
1171         .str_sec = "\0A\0m",
1172         .str_sec_size = sizeof("\0A\0m"),
1173         .map_type = BPF_MAP_TYPE_ARRAY,
1174         .map_name = "void_test4_map",
1175         .key_size = sizeof(int),
1176         .value_size = sizeof(void *) * 4,
1177         .key_type_id = 1,
1178         .value_type_id = 3,
1179         .max_entries = 4,
1180         .btf_load_err = true,
1181         .err_str = "Invalid elem",
1182 },
1183
1184 /* Array_A  <------------------+
1185  *     elem_type == Array_B    |
1186  *                    |        |
1187  *                    |        |
1188  * Array_B  <-------- +        |
1189  *      elem_type == Array A --+
1190  */
1191 {
1192         .descr = "loop test #1",
1193         .raw_types = {
1194                 /* int */                       /* [1] */
1195                 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
1196                 /* Array_A */                   /* [2] */
1197                 BTF_TYPE_ARRAY_ENC(3, 1, 8),
1198                 /* Array_B */                   /* [3] */
1199                 BTF_TYPE_ARRAY_ENC(2, 1, 8),
1200                 BTF_END_RAW,
1201         },
1202         .str_sec = "",
1203         .str_sec_size = sizeof(""),
1204         .map_type = BPF_MAP_TYPE_ARRAY,
1205         .map_name = "loop_test1_map",
1206         .key_size = sizeof(int),
1207         .value_size = sizeof(sizeof(int) * 8),
1208         .key_type_id = 1,
1209         .value_type_id = 2,
1210         .max_entries = 4,
1211         .btf_load_err = true,
1212         .err_str = "Loop detected",
1213 },
1214
1215 /* typedef is _before_ the BTF type of Array_A and Array_B
1216  *
1217  * typedef Array_B int_array;
1218  *
1219  * Array_A  <------------------+
1220  *     elem_type == int_array  |
1221  *                    |        |
1222  *                    |        |
1223  * Array_B  <-------- +        |
1224  *      elem_type == Array_A --+
1225  */
1226 {
1227         .descr = "loop test #2",
1228         .raw_types = {
1229                 /* int */
1230                 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),  /* [1] */
1231                 /* typedef Array_B int_array */
1232                 BTF_TYPEDEF_ENC(1, 4),                          /* [2] */
1233                 /* Array_A */
1234                 BTF_TYPE_ARRAY_ENC(2, 1, 8),                    /* [3] */
1235                 /* Array_B */
1236                 BTF_TYPE_ARRAY_ENC(3, 1, 8),                    /* [4] */
1237                 BTF_END_RAW,
1238         },
1239         .str_sec = "\0int_array\0",
1240         .str_sec_size = sizeof("\0int_array"),
1241         .map_type = BPF_MAP_TYPE_ARRAY,
1242         .map_name = "loop_test2_map",
1243         .key_size = sizeof(int),
1244         .value_size = sizeof(sizeof(int) * 8),
1245         .key_type_id = 1,
1246         .value_type_id = 2,
1247         .max_entries = 4,
1248         .btf_load_err = true,
1249         .err_str = "Loop detected",
1250 },
1251
1252 /* Array_A  <------------------+
1253  *     elem_type == Array_B    |
1254  *                    |        |
1255  *                    |        |
1256  * Array_B  <-------- +        |
1257  *      elem_type == Array_A --+
1258  */
1259 {
1260         .descr = "loop test #3",
1261         .raw_types = {
1262                 /* int */                               /* [1] */
1263                 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
1264                 /* Array_A */                           /* [2] */
1265                 BTF_TYPE_ARRAY_ENC(3, 1, 8),
1266                 /* Array_B */                           /* [3] */
1267                 BTF_TYPE_ARRAY_ENC(2, 1, 8),
1268                 BTF_END_RAW,
1269         },
1270         .str_sec = "",
1271         .str_sec_size = sizeof(""),
1272         .map_type = BPF_MAP_TYPE_ARRAY,
1273         .map_name = "loop_test3_map",
1274         .key_size = sizeof(int),
1275         .value_size = sizeof(sizeof(int) * 8),
1276         .key_type_id = 1,
1277         .value_type_id = 2,
1278         .max_entries = 4,
1279         .btf_load_err = true,
1280         .err_str = "Loop detected",
1281 },
1282
1283 /* typedef is _between_ the BTF type of Array_A and Array_B
1284  *
1285  * typedef Array_B int_array;
1286  *
1287  * Array_A  <------------------+
1288  *     elem_type == int_array  |
1289  *                    |        |
1290  *                    |        |
1291  * Array_B  <-------- +        |
1292  *      elem_type == Array_A --+
1293  */
1294 {
1295         .descr = "loop test #4",
1296         .raw_types = {
1297                 /* int */                               /* [1] */
1298                 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
1299                 /* Array_A */                           /* [2] */
1300                 BTF_TYPE_ARRAY_ENC(3, 1, 8),
1301                 /* typedef Array_B int_array */         /* [3] */
1302                 BTF_TYPEDEF_ENC(NAME_TBD, 4),
1303                 /* Array_B */                           /* [4] */
1304                 BTF_TYPE_ARRAY_ENC(2, 1, 8),
1305                 BTF_END_RAW,
1306         },
1307         .str_sec = "\0int_array\0",
1308         .str_sec_size = sizeof("\0int_array"),
1309         .map_type = BPF_MAP_TYPE_ARRAY,
1310         .map_name = "loop_test4_map",
1311         .key_size = sizeof(int),
1312         .value_size = sizeof(sizeof(int) * 8),
1313         .key_type_id = 1,
1314         .value_type_id = 2,
1315         .max_entries = 4,
1316         .btf_load_err = true,
1317         .err_str = "Loop detected",
1318 },
1319
1320 /* typedef struct B Struct_B
1321  *
1322  * struct A {
1323  *     int x;
1324  *     Struct_B y;
1325  * };
1326  *
1327  * struct B {
1328  *     int x;
1329  *     struct A y;
1330  * };
1331  */
1332 {
1333         .descr = "loop test #5",
1334         .raw_types = {
1335                 /* int */
1336                 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),  /* [1] */
1337                 /* struct A */                                  /* [2] */
1338                 BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 2), 8),
1339                 BTF_MEMBER_ENC(NAME_TBD, 1, 0), /* int x;       */
1340                 BTF_MEMBER_ENC(NAME_TBD, 3, 32),/* Struct_B y;  */
1341                 /* typedef struct B Struct_B */
1342                 BTF_TYPEDEF_ENC(NAME_TBD, 4),                   /* [3] */
1343                 /* struct B */                                  /* [4] */
1344                 BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 2), 8),
1345                 BTF_MEMBER_ENC(NAME_TBD, 1, 0), /* int x;       */
1346                 BTF_MEMBER_ENC(NAME_TBD, 2, 32),/* struct A y;  */
1347                 BTF_END_RAW,
1348         },
1349         .str_sec = "\0A\0x\0y\0Struct_B\0B\0x\0y",
1350         .str_sec_size = sizeof("\0A\0x\0y\0Struct_B\0B\0x\0y"),
1351         .map_type = BPF_MAP_TYPE_ARRAY,
1352         .map_name = "loop_test5_map",
1353         .key_size = sizeof(int),
1354         .value_size = 8,
1355         .key_type_id = 1,
1356         .value_type_id = 2,
1357         .max_entries = 4,
1358         .btf_load_err = true,
1359         .err_str = "Loop detected",
1360 },
1361
1362 /* struct A {
1363  *     int x;
1364  *     struct A array_a[4];
1365  * };
1366  */
1367 {
1368         .descr = "loop test #6",
1369         .raw_types = {
1370                 /* int */
1371                 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),  /* [1] */
1372                 BTF_TYPE_ARRAY_ENC(3, 1, 4),                    /* [2] */
1373                 /* struct A */                                  /* [3] */
1374                 BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 2), 8),
1375                 BTF_MEMBER_ENC(NAME_TBD, 1, 0), /* int x;               */
1376                 BTF_MEMBER_ENC(NAME_TBD, 2, 32),/* struct A array_a[4]; */
1377                 BTF_END_RAW,
1378         },
1379         .str_sec = "\0A\0x\0y",
1380         .str_sec_size = sizeof("\0A\0x\0y"),
1381         .map_type = BPF_MAP_TYPE_ARRAY,
1382         .map_name = "loop_test6_map",
1383         .key_size = sizeof(int),
1384         .value_size = 8,
1385         .key_type_id = 1,
1386         .value_type_id = 2,
1387         .max_entries = 4,
1388         .btf_load_err = true,
1389         .err_str = "Loop detected",
1390 },
1391
1392 {
1393         .descr = "loop test #7",
1394         .raw_types = {
1395                 /* int */                               /* [1] */
1396                 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
1397                 /* struct A { */                        /* [2] */
1398                 BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 1), sizeof(void *)),
1399                 /*     const void *m;   */
1400                 BTF_MEMBER_ENC(NAME_TBD, 3, 0),
1401                 /* CONST type_id=3      */              /* [3] */
1402                 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_CONST, 0, 0), 4),
1403                 /* PTR type_id=2        */              /* [4] */
1404                 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_PTR, 0, 0), 3),
1405                 BTF_END_RAW,
1406         },
1407         .str_sec = "\0A\0m",
1408         .str_sec_size = sizeof("\0A\0m"),
1409         .map_type = BPF_MAP_TYPE_ARRAY,
1410         .map_name = "loop_test7_map",
1411         .key_size = sizeof(int),
1412         .value_size = sizeof(void *),
1413         .key_type_id = 1,
1414         .value_type_id = 2,
1415         .max_entries = 4,
1416         .btf_load_err = true,
1417         .err_str = "Loop detected",
1418 },
1419
1420 {
1421         .descr = "loop test #8",
1422         .raw_types = {
1423                 /* int */                               /* [1] */
1424                 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
1425                 /* struct A { */                        /* [2] */
1426                 BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 1), sizeof(void *)),
1427                 /*     const void *m;   */
1428                 BTF_MEMBER_ENC(NAME_TBD, 4, 0),
1429                 /* struct B { */                        /* [3] */
1430                 BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 1), sizeof(void *)),
1431                 /*     const void *n;   */
1432                 BTF_MEMBER_ENC(NAME_TBD, 6, 0),
1433                 /* CONST type_id=5      */              /* [4] */
1434                 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_CONST, 0, 0), 5),
1435                 /* PTR type_id=6        */              /* [5] */
1436                 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_PTR, 0, 0), 6),
1437                 /* CONST type_id=7      */              /* [6] */
1438                 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_CONST, 0, 0), 7),
1439                 /* PTR type_id=4        */              /* [7] */
1440                 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_PTR, 0, 0), 4),
1441                 BTF_END_RAW,
1442         },
1443         .str_sec = "\0A\0m\0B\0n",
1444         .str_sec_size = sizeof("\0A\0m\0B\0n"),
1445         .map_type = BPF_MAP_TYPE_ARRAY,
1446         .map_name = "loop_test8_map",
1447         .key_size = sizeof(int),
1448         .value_size = sizeof(void *),
1449         .key_type_id = 1,
1450         .value_type_id = 2,
1451         .max_entries = 4,
1452         .btf_load_err = true,
1453         .err_str = "Loop detected",
1454 },
1455
1456 {
1457         .descr = "string section does not end with null",
1458         .raw_types = {
1459                 /* int */                               /* [1] */
1460                 BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),
1461                 BTF_END_RAW,
1462         },
1463         .str_sec = "\0int",
1464         .str_sec_size = sizeof("\0int") - 1,
1465         .map_type = BPF_MAP_TYPE_ARRAY,
1466         .map_name = "hdr_test_map",
1467         .key_size = sizeof(int),
1468         .value_size = sizeof(int),
1469         .key_type_id = 1,
1470         .value_type_id = 1,
1471         .max_entries = 4,
1472         .btf_load_err = true,
1473         .err_str = "Invalid string section",
1474 },
1475
1476 {
1477         .descr = "empty string section",
1478         .raw_types = {
1479                 /* int */                               /* [1] */
1480                 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
1481                 BTF_END_RAW,
1482         },
1483         .str_sec = "",
1484         .str_sec_size = 0,
1485         .map_type = BPF_MAP_TYPE_ARRAY,
1486         .map_name = "hdr_test_map",
1487         .key_size = sizeof(int),
1488         .value_size = sizeof(int),
1489         .key_type_id = 1,
1490         .value_type_id = 1,
1491         .max_entries = 4,
1492         .btf_load_err = true,
1493         .err_str = "Invalid string section",
1494 },
1495
1496 {
1497         .descr = "empty type section",
1498         .raw_types = {
1499                 BTF_END_RAW,
1500         },
1501         .str_sec = "\0int",
1502         .str_sec_size = sizeof("\0int"),
1503         .map_type = BPF_MAP_TYPE_ARRAY,
1504         .map_name = "hdr_test_map",
1505         .key_size = sizeof(int),
1506         .value_size = sizeof(int),
1507         .key_type_id = 1,
1508         .value_type_id = 1,
1509         .max_entries = 4,
1510         .btf_load_err = true,
1511         .err_str = "No type found",
1512 },
1513
1514 {
1515         .descr = "btf_header test. Longer hdr_len",
1516         .raw_types = {
1517                 /* int */                               /* [1] */
1518                 BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),
1519                 BTF_END_RAW,
1520         },
1521         .str_sec = "\0int",
1522         .str_sec_size = sizeof("\0int"),
1523         .map_type = BPF_MAP_TYPE_ARRAY,
1524         .map_name = "hdr_test_map",
1525         .key_size = sizeof(int),
1526         .value_size = sizeof(int),
1527         .key_type_id = 1,
1528         .value_type_id = 1,
1529         .max_entries = 4,
1530         .btf_load_err = true,
1531         .hdr_len_delta = 4,
1532         .err_str = "Unsupported btf_header",
1533 },
1534
1535 {
1536         .descr = "btf_header test. Gap between hdr and type",
1537         .raw_types = {
1538                 /* int */                               /* [1] */
1539                 BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),
1540                 BTF_END_RAW,
1541         },
1542         .str_sec = "\0int",
1543         .str_sec_size = sizeof("\0int"),
1544         .map_type = BPF_MAP_TYPE_ARRAY,
1545         .map_name = "hdr_test_map",
1546         .key_size = sizeof(int),
1547         .value_size = sizeof(int),
1548         .key_type_id = 1,
1549         .value_type_id = 1,
1550         .max_entries = 4,
1551         .btf_load_err = true,
1552         .type_off_delta = 4,
1553         .err_str = "Unsupported section found",
1554 },
1555
1556 {
1557         .descr = "btf_header test. Gap between type and str",
1558         .raw_types = {
1559                 /* int */                               /* [1] */
1560                 BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),
1561                 BTF_END_RAW,
1562         },
1563         .str_sec = "\0int",
1564         .str_sec_size = sizeof("\0int"),
1565         .map_type = BPF_MAP_TYPE_ARRAY,
1566         .map_name = "hdr_test_map",
1567         .key_size = sizeof(int),
1568         .value_size = sizeof(int),
1569         .key_type_id = 1,
1570         .value_type_id = 1,
1571         .max_entries = 4,
1572         .btf_load_err = true,
1573         .str_off_delta = 4,
1574         .err_str = "Unsupported section found",
1575 },
1576
1577 {
1578         .descr = "btf_header test. Overlap between type and str",
1579         .raw_types = {
1580                 /* int */                               /* [1] */
1581                 BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),
1582                 BTF_END_RAW,
1583         },
1584         .str_sec = "\0int",
1585         .str_sec_size = sizeof("\0int"),
1586         .map_type = BPF_MAP_TYPE_ARRAY,
1587         .map_name = "hdr_test_map",
1588         .key_size = sizeof(int),
1589         .value_size = sizeof(int),
1590         .key_type_id = 1,
1591         .value_type_id = 1,
1592         .max_entries = 4,
1593         .btf_load_err = true,
1594         .str_off_delta = -4,
1595         .err_str = "Section overlap found",
1596 },
1597
1598 {
1599         .descr = "btf_header test. Larger BTF size",
1600         .raw_types = {
1601                 /* int */                               /* [1] */
1602                 BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),
1603                 BTF_END_RAW,
1604         },
1605         .str_sec = "\0int",
1606         .str_sec_size = sizeof("\0int"),
1607         .map_type = BPF_MAP_TYPE_ARRAY,
1608         .map_name = "hdr_test_map",
1609         .key_size = sizeof(int),
1610         .value_size = sizeof(int),
1611         .key_type_id = 1,
1612         .value_type_id = 1,
1613         .max_entries = 4,
1614         .btf_load_err = true,
1615         .str_len_delta = -4,
1616         .err_str = "Unsupported section found",
1617 },
1618
1619 {
1620         .descr = "btf_header test. Smaller BTF size",
1621         .raw_types = {
1622                 /* int */                               /* [1] */
1623                 BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),
1624                 BTF_END_RAW,
1625         },
1626         .str_sec = "\0int",
1627         .str_sec_size = sizeof("\0int"),
1628         .map_type = BPF_MAP_TYPE_ARRAY,
1629         .map_name = "hdr_test_map",
1630         .key_size = sizeof(int),
1631         .value_size = sizeof(int),
1632         .key_type_id = 1,
1633         .value_type_id = 1,
1634         .max_entries = 4,
1635         .btf_load_err = true,
1636         .str_len_delta = 4,
1637         .err_str = "Total section length too long",
1638 },
1639
1640 {
1641         .descr = "array test. index_type/elem_type \"int\"",
1642         .raw_types = {
1643                 /* int */                               /* [1] */
1644                 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
1645                 /* int[16] */                           /* [2] */
1646                 BTF_TYPE_ARRAY_ENC(1, 1, 16),
1647                 BTF_END_RAW,
1648         },
1649         .str_sec = "",
1650         .str_sec_size = sizeof(""),
1651         .map_type = BPF_MAP_TYPE_ARRAY,
1652         .map_name = "array_test_map",
1653         .key_size = sizeof(int),
1654         .value_size = sizeof(int),
1655         .key_type_id = 1,
1656         .value_type_id = 1,
1657         .max_entries = 4,
1658 },
1659
1660 {
1661         .descr = "array test. index_type/elem_type \"const int\"",
1662         .raw_types = {
1663                 /* int */                               /* [1] */
1664                 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
1665                 /* int[16] */                           /* [2] */
1666                 BTF_TYPE_ARRAY_ENC(3, 3, 16),
1667                 /* CONST type_id=1 */                   /* [3] */
1668                 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_CONST, 0, 0), 1),
1669                 BTF_END_RAW,
1670         },
1671         .str_sec = "",
1672         .str_sec_size = sizeof(""),
1673         .map_type = BPF_MAP_TYPE_ARRAY,
1674         .map_name = "array_test_map",
1675         .key_size = sizeof(int),
1676         .value_size = sizeof(int),
1677         .key_type_id = 1,
1678         .value_type_id = 1,
1679         .max_entries = 4,
1680 },
1681
1682 {
1683         .descr = "array test. index_type \"const int:31\"",
1684         .raw_types = {
1685                 /* int */                               /* [1] */
1686                 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
1687                 /* int:31 */                            /* [2] */
1688                 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 31, 4),
1689                 /* int[16] */                           /* [3] */
1690                 BTF_TYPE_ARRAY_ENC(1, 4, 16),
1691                 /* CONST type_id=2 */                   /* [4] */
1692                 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_CONST, 0, 0), 2),
1693                 BTF_END_RAW,
1694         },
1695         .str_sec = "",
1696         .str_sec_size = sizeof(""),
1697         .map_type = BPF_MAP_TYPE_ARRAY,
1698         .map_name = "array_test_map",
1699         .key_size = sizeof(int),
1700         .value_size = sizeof(int),
1701         .key_type_id = 1,
1702         .value_type_id = 1,
1703         .max_entries = 4,
1704         .btf_load_err = true,
1705         .err_str = "Invalid index",
1706 },
1707
1708 {
1709         .descr = "array test. elem_type \"const int:31\"",
1710         .raw_types = {
1711                 /* int */                               /* [1] */
1712                 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
1713                 /* int:31 */                            /* [2] */
1714                 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 31, 4),
1715                 /* int[16] */                           /* [3] */
1716                 BTF_TYPE_ARRAY_ENC(4, 1, 16),
1717                 /* CONST type_id=2 */                   /* [4] */
1718                 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_CONST, 0, 0), 2),
1719                 BTF_END_RAW,
1720         },
1721         .str_sec = "",
1722         .str_sec_size = sizeof(""),
1723         .map_type = BPF_MAP_TYPE_ARRAY,
1724         .map_name = "array_test_map",
1725         .key_size = sizeof(int),
1726         .value_size = sizeof(int),
1727         .key_type_id = 1,
1728         .value_type_id = 1,
1729         .max_entries = 4,
1730         .btf_load_err = true,
1731         .err_str = "Invalid array of int",
1732 },
1733
1734 {
1735         .descr = "array test. index_type \"void\"",
1736         .raw_types = {
1737                 /* int */                               /* [1] */
1738                 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
1739                 /* int[16] */                           /* [2] */
1740                 BTF_TYPE_ARRAY_ENC(1, 0, 16),
1741                 BTF_END_RAW,
1742         },
1743         .str_sec = "",
1744         .str_sec_size = sizeof(""),
1745         .map_type = BPF_MAP_TYPE_ARRAY,
1746         .map_name = "array_test_map",
1747         .key_size = sizeof(int),
1748         .value_size = sizeof(int),
1749         .key_type_id = 1,
1750         .value_type_id = 1,
1751         .max_entries = 4,
1752         .btf_load_err = true,
1753         .err_str = "Invalid index",
1754 },
1755
1756 {
1757         .descr = "array test. index_type \"const void\"",
1758         .raw_types = {
1759                 /* int */                               /* [1] */
1760                 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
1761                 /* int[16] */                           /* [2] */
1762                 BTF_TYPE_ARRAY_ENC(1, 3, 16),
1763                 /* CONST type_id=0 (void) */            /* [3] */
1764                 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_CONST, 0, 0), 0),
1765                 BTF_END_RAW,
1766         },
1767         .str_sec = "",
1768         .str_sec_size = sizeof(""),
1769         .map_type = BPF_MAP_TYPE_ARRAY,
1770         .map_name = "array_test_map",
1771         .key_size = sizeof(int),
1772         .value_size = sizeof(int),
1773         .key_type_id = 1,
1774         .value_type_id = 1,
1775         .max_entries = 4,
1776         .btf_load_err = true,
1777         .err_str = "Invalid index",
1778 },
1779
1780 {
1781         .descr = "array test. elem_type \"const void\"",
1782         .raw_types = {
1783                 /* int */                               /* [1] */
1784                 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
1785                 /* int[16] */                           /* [2] */
1786                 BTF_TYPE_ARRAY_ENC(3, 1, 16),
1787                 /* CONST type_id=0 (void) */            /* [3] */
1788                 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_CONST, 0, 0), 0),
1789                 BTF_END_RAW,
1790         },
1791         .str_sec = "",
1792         .str_sec_size = sizeof(""),
1793         .map_type = BPF_MAP_TYPE_ARRAY,
1794         .map_name = "array_test_map",
1795         .key_size = sizeof(int),
1796         .value_size = sizeof(int),
1797         .key_type_id = 1,
1798         .value_type_id = 1,
1799         .max_entries = 4,
1800         .btf_load_err = true,
1801         .err_str = "Invalid elem",
1802 },
1803
1804 {
1805         .descr = "array test. elem_type \"const void *\"",
1806         .raw_types = {
1807                 /* int */                               /* [1] */
1808                 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
1809                 /* const void *[16] */                  /* [2] */
1810                 BTF_TYPE_ARRAY_ENC(3, 1, 16),
1811                 /* CONST type_id=4 */                   /* [3] */
1812                 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_CONST, 0, 0), 4),
1813                 /* void* */                             /* [4] */
1814                 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_PTR, 0, 0), 0),
1815                 BTF_END_RAW,
1816         },
1817         .str_sec = "",
1818         .str_sec_size = sizeof(""),
1819         .map_type = BPF_MAP_TYPE_ARRAY,
1820         .map_name = "array_test_map",
1821         .key_size = sizeof(int),
1822         .value_size = sizeof(int),
1823         .key_type_id = 1,
1824         .value_type_id = 1,
1825         .max_entries = 4,
1826 },
1827
1828 {
1829         .descr = "array test. index_type \"const void *\"",
1830         .raw_types = {
1831                 /* int */                               /* [1] */
1832                 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
1833                 /* const void *[16] */                  /* [2] */
1834                 BTF_TYPE_ARRAY_ENC(3, 3, 16),
1835                 /* CONST type_id=4 */                   /* [3] */
1836                 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_CONST, 0, 0), 4),
1837                 /* void* */                             /* [4] */
1838                 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_PTR, 0, 0), 0),
1839                 BTF_END_RAW,
1840         },
1841         .str_sec = "",
1842         .str_sec_size = sizeof(""),
1843         .map_type = BPF_MAP_TYPE_ARRAY,
1844         .map_name = "array_test_map",
1845         .key_size = sizeof(int),
1846         .value_size = sizeof(int),
1847         .key_type_id = 1,
1848         .value_type_id = 1,
1849         .max_entries = 4,
1850         .btf_load_err = true,
1851         .err_str = "Invalid index",
1852 },
1853
1854 {
1855         .descr = "array test. t->size != 0\"",
1856         .raw_types = {
1857                 /* int */                               /* [1] */
1858                 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
1859                 /* int[16] */                           /* [2] */
1860                 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_ARRAY, 0, 0), 1),
1861                 BTF_ARRAY_ENC(1, 1, 16),
1862                 BTF_END_RAW,
1863         },
1864         .str_sec = "",
1865         .str_sec_size = sizeof(""),
1866         .map_type = BPF_MAP_TYPE_ARRAY,
1867         .map_name = "array_test_map",
1868         .key_size = sizeof(int),
1869         .value_size = sizeof(int),
1870         .key_type_id = 1,
1871         .value_type_id = 1,
1872         .max_entries = 4,
1873         .btf_load_err = true,
1874         .err_str = "size != 0",
1875 },
1876
1877 {
1878         .descr = "int test. invalid int_data",
1879         .raw_types = {
1880                 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_INT, 0, 0), 4),
1881                 0x10000000,
1882                 BTF_END_RAW,
1883         },
1884         .str_sec = "",
1885         .str_sec_size = sizeof(""),
1886         .map_type = BPF_MAP_TYPE_ARRAY,
1887         .map_name = "array_test_map",
1888         .key_size = sizeof(int),
1889         .value_size = sizeof(int),
1890         .key_type_id = 1,
1891         .value_type_id = 1,
1892         .max_entries = 4,
1893         .btf_load_err = true,
1894         .err_str = "Invalid int_data",
1895 },
1896
1897 {
1898         .descr = "invalid BTF_INFO",
1899         .raw_types = {
1900                 /* int */                               /* [1] */
1901                 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
1902                 BTF_TYPE_ENC(0, 0x10000000, 4),
1903                 BTF_END_RAW,
1904         },
1905         .str_sec = "",
1906         .str_sec_size = sizeof(""),
1907         .map_type = BPF_MAP_TYPE_ARRAY,
1908         .map_name = "array_test_map",
1909         .key_size = sizeof(int),
1910         .value_size = sizeof(int),
1911         .key_type_id = 1,
1912         .value_type_id = 1,
1913         .max_entries = 4,
1914         .btf_load_err = true,
1915         .err_str = "Invalid btf_info",
1916 },
1917
1918 {
1919         .descr = "fwd test. t->type != 0\"",
1920         .raw_types = {
1921                 /* int */                               /* [1] */
1922                 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
1923                 /* fwd type */                          /* [2] */
1924                 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_FWD, 0, 0), 1),
1925                 BTF_END_RAW,
1926         },
1927         .str_sec = "",
1928         .str_sec_size = sizeof(""),
1929         .map_type = BPF_MAP_TYPE_ARRAY,
1930         .map_name = "fwd_test_map",
1931         .key_size = sizeof(int),
1932         .value_size = sizeof(int),
1933         .key_type_id = 1,
1934         .value_type_id = 1,
1935         .max_entries = 4,
1936         .btf_load_err = true,
1937         .err_str = "type != 0",
1938 },
1939
1940 {
1941         .descr = "typedef (invalid name, name_off = 0)",
1942         .raw_types = {
1943                 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),  /* [1] */
1944                 BTF_TYPEDEF_ENC(0, 1),                          /* [2] */
1945                 BTF_END_RAW,
1946         },
1947         .str_sec = "\0__int",
1948         .str_sec_size = sizeof("\0__int"),
1949         .map_type = BPF_MAP_TYPE_ARRAY,
1950         .map_name = "typedef_check_btf",
1951         .key_size = sizeof(int),
1952         .value_size = sizeof(int),
1953         .key_type_id = 1,
1954         .value_type_id = 1,
1955         .max_entries = 4,
1956         .btf_load_err = true,
1957         .err_str = "Invalid name",
1958 },
1959
1960 {
1961         .descr = "typedef (invalid name, invalid identifier)",
1962         .raw_types = {
1963                 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),  /* [1] */
1964                 BTF_TYPEDEF_ENC(NAME_TBD, 1),                   /* [2] */
1965                 BTF_END_RAW,
1966         },
1967         .str_sec = "\0__!int",
1968         .str_sec_size = sizeof("\0__!int"),
1969         .map_type = BPF_MAP_TYPE_ARRAY,
1970         .map_name = "typedef_check_btf",
1971         .key_size = sizeof(int),
1972         .value_size = sizeof(int),
1973         .key_type_id = 1,
1974         .value_type_id = 1,
1975         .max_entries = 4,
1976         .btf_load_err = true,
1977         .err_str = "Invalid name",
1978 },
1979
1980 {
1981         .descr = "ptr type (invalid name, name_off <> 0)",
1982         .raw_types = {
1983                 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),          /* [1] */
1984                 BTF_TYPE_ENC(NAME_TBD,
1985                              BTF_INFO_ENC(BTF_KIND_PTR, 0, 0), 1),      /* [2] */
1986                 BTF_END_RAW,
1987         },
1988         .str_sec = "\0__int",
1989         .str_sec_size = sizeof("\0__int"),
1990         .map_type = BPF_MAP_TYPE_ARRAY,
1991         .map_name = "ptr_type_check_btf",
1992         .key_size = sizeof(int),
1993         .value_size = sizeof(int),
1994         .key_type_id = 1,
1995         .value_type_id = 1,
1996         .max_entries = 4,
1997         .btf_load_err = true,
1998         .err_str = "Invalid name",
1999 },
2000
2001 {
2002         .descr = "volatile type (invalid name, name_off <> 0)",
2003         .raw_types = {
2004                 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),          /* [1] */
2005                 BTF_TYPE_ENC(NAME_TBD,
2006                              BTF_INFO_ENC(BTF_KIND_VOLATILE, 0, 0), 1), /* [2] */
2007                 BTF_END_RAW,
2008         },
2009         .str_sec = "\0__int",
2010         .str_sec_size = sizeof("\0__int"),
2011         .map_type = BPF_MAP_TYPE_ARRAY,
2012         .map_name = "volatile_type_check_btf",
2013         .key_size = sizeof(int),
2014         .value_size = sizeof(int),
2015         .key_type_id = 1,
2016         .value_type_id = 1,
2017         .max_entries = 4,
2018         .btf_load_err = true,
2019         .err_str = "Invalid name",
2020 },
2021
2022 {
2023         .descr = "const type (invalid name, name_off <> 0)",
2024         .raw_types = {
2025                 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),          /* [1] */
2026                 BTF_TYPE_ENC(NAME_TBD,
2027                              BTF_INFO_ENC(BTF_KIND_CONST, 0, 0), 1),    /* [2] */
2028                 BTF_END_RAW,
2029         },
2030         .str_sec = "\0__int",
2031         .str_sec_size = sizeof("\0__int"),
2032         .map_type = BPF_MAP_TYPE_ARRAY,
2033         .map_name = "const_type_check_btf",
2034         .key_size = sizeof(int),
2035         .value_size = sizeof(int),
2036         .key_type_id = 1,
2037         .value_type_id = 1,
2038         .max_entries = 4,
2039         .btf_load_err = true,
2040         .err_str = "Invalid name",
2041 },
2042
2043 {
2044         .descr = "restrict type (invalid name, name_off <> 0)",
2045         .raw_types = {
2046                 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),          /* [1] */
2047                 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_PTR, 0, 0), 1),   /* [2] */
2048                 BTF_TYPE_ENC(NAME_TBD,
2049                              BTF_INFO_ENC(BTF_KIND_RESTRICT, 0, 0), 2), /* [3] */
2050                 BTF_END_RAW,
2051         },
2052         .str_sec = "\0__int",
2053         .str_sec_size = sizeof("\0__int"),
2054         .map_type = BPF_MAP_TYPE_ARRAY,
2055         .map_name = "restrict_type_check_btf",
2056         .key_size = sizeof(int),
2057         .value_size = sizeof(int),
2058         .key_type_id = 1,
2059         .value_type_id = 1,
2060         .max_entries = 4,
2061         .btf_load_err = true,
2062         .err_str = "Invalid name",
2063 },
2064
2065 {
2066         .descr = "fwd type (invalid name, name_off = 0)",
2067         .raw_types = {
2068                 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),          /* [1] */
2069                 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_FWD, 0, 0), 0),   /* [2] */
2070                 BTF_END_RAW,
2071         },
2072         .str_sec = "\0__skb",
2073         .str_sec_size = sizeof("\0__skb"),
2074         .map_type = BPF_MAP_TYPE_ARRAY,
2075         .map_name = "fwd_type_check_btf",
2076         .key_size = sizeof(int),
2077         .value_size = sizeof(int),
2078         .key_type_id = 1,
2079         .value_type_id = 1,
2080         .max_entries = 4,
2081         .btf_load_err = true,
2082         .err_str = "Invalid name",
2083 },
2084
2085 {
2086         .descr = "fwd type (invalid name, invalid identifier)",
2087         .raw_types = {
2088                 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),          /* [1] */
2089                 BTF_TYPE_ENC(NAME_TBD,
2090                              BTF_INFO_ENC(BTF_KIND_FWD, 0, 0), 0),      /* [2] */
2091                 BTF_END_RAW,
2092         },
2093         .str_sec = "\0__!skb",
2094         .str_sec_size = sizeof("\0__!skb"),
2095         .map_type = BPF_MAP_TYPE_ARRAY,
2096         .map_name = "fwd_type_check_btf",
2097         .key_size = sizeof(int),
2098         .value_size = sizeof(int),
2099         .key_type_id = 1,
2100         .value_type_id = 1,
2101         .max_entries = 4,
2102         .btf_load_err = true,
2103         .err_str = "Invalid name",
2104 },
2105
2106 {
2107         .descr = "array type (invalid name, name_off <> 0)",
2108         .raw_types = {
2109                 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),          /* [1] */
2110                 BTF_TYPE_ENC(NAME_TBD,
2111                              BTF_INFO_ENC(BTF_KIND_ARRAY, 0, 0), 0),    /* [2] */
2112                 BTF_ARRAY_ENC(1, 1, 4),
2113                 BTF_END_RAW,
2114         },
2115         .str_sec = "\0__skb",
2116         .str_sec_size = sizeof("\0__skb"),
2117         .map_type = BPF_MAP_TYPE_ARRAY,
2118         .map_name = "array_type_check_btf",
2119         .key_size = sizeof(int),
2120         .value_size = sizeof(int),
2121         .key_type_id = 1,
2122         .value_type_id = 1,
2123         .max_entries = 4,
2124         .btf_load_err = true,
2125         .err_str = "Invalid name",
2126 },
2127
2128 {
2129         .descr = "struct type (name_off = 0)",
2130         .raw_types = {
2131                 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),          /* [1] */
2132                 BTF_TYPE_ENC(0,
2133                              BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 1), 4),   /* [2] */
2134                 BTF_MEMBER_ENC(NAME_TBD, 1, 0),
2135                 BTF_END_RAW,
2136         },
2137         .str_sec = "\0A",
2138         .str_sec_size = sizeof("\0A"),
2139         .map_type = BPF_MAP_TYPE_ARRAY,
2140         .map_name = "struct_type_check_btf",
2141         .key_size = sizeof(int),
2142         .value_size = sizeof(int),
2143         .key_type_id = 1,
2144         .value_type_id = 1,
2145         .max_entries = 4,
2146 },
2147
2148 {
2149         .descr = "struct type (invalid name, invalid identifier)",
2150         .raw_types = {
2151                 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),          /* [1] */
2152                 BTF_TYPE_ENC(NAME_TBD,
2153                              BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 1), 4),   /* [2] */
2154                 BTF_MEMBER_ENC(NAME_TBD, 1, 0),
2155                 BTF_END_RAW,
2156         },
2157         .str_sec = "\0A!\0B",
2158         .str_sec_size = sizeof("\0A!\0B"),
2159         .map_type = BPF_MAP_TYPE_ARRAY,
2160         .map_name = "struct_type_check_btf",
2161         .key_size = sizeof(int),
2162         .value_size = sizeof(int),
2163         .key_type_id = 1,
2164         .value_type_id = 1,
2165         .max_entries = 4,
2166         .btf_load_err = true,
2167         .err_str = "Invalid name",
2168 },
2169
2170 {
2171         .descr = "struct member (name_off = 0)",
2172         .raw_types = {
2173                 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),          /* [1] */
2174                 BTF_TYPE_ENC(0,
2175                              BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 1), 4),   /* [2] */
2176                 BTF_MEMBER_ENC(NAME_TBD, 1, 0),
2177                 BTF_END_RAW,
2178         },
2179         .str_sec = "\0A",
2180         .str_sec_size = sizeof("\0A"),
2181         .map_type = BPF_MAP_TYPE_ARRAY,
2182         .map_name = "struct_type_check_btf",
2183         .key_size = sizeof(int),
2184         .value_size = sizeof(int),
2185         .key_type_id = 1,
2186         .value_type_id = 1,
2187         .max_entries = 4,
2188 },
2189
2190 {
2191         .descr = "struct member (invalid name, invalid identifier)",
2192         .raw_types = {
2193                 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),          /* [1] */
2194                 BTF_TYPE_ENC(NAME_TBD,
2195                              BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 1), 4),   /* [2] */
2196                 BTF_MEMBER_ENC(NAME_TBD, 1, 0),
2197                 BTF_END_RAW,
2198         },
2199         .str_sec = "\0A\0B*",
2200         .str_sec_size = sizeof("\0A\0B*"),
2201         .map_type = BPF_MAP_TYPE_ARRAY,
2202         .map_name = "struct_type_check_btf",
2203         .key_size = sizeof(int),
2204         .value_size = sizeof(int),
2205         .key_type_id = 1,
2206         .value_type_id = 1,
2207         .max_entries = 4,
2208         .btf_load_err = true,
2209         .err_str = "Invalid name",
2210 },
2211
2212 {
2213         .descr = "enum type (name_off = 0)",
2214         .raw_types = {
2215                 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),          /* [1] */
2216                 BTF_TYPE_ENC(0,
2217                              BTF_INFO_ENC(BTF_KIND_ENUM, 0, 1),
2218                              sizeof(int)),                              /* [2] */
2219                 BTF_ENUM_ENC(NAME_TBD, 0),
2220                 BTF_END_RAW,
2221         },
2222         .str_sec = "\0A\0B",
2223         .str_sec_size = sizeof("\0A\0B"),
2224         .map_type = BPF_MAP_TYPE_ARRAY,
2225         .map_name = "enum_type_check_btf",
2226         .key_size = sizeof(int),
2227         .value_size = sizeof(int),
2228         .key_type_id = 1,
2229         .value_type_id = 1,
2230         .max_entries = 4,
2231 },
2232
2233 {
2234         .descr = "enum type (invalid name, invalid identifier)",
2235         .raw_types = {
2236                 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),          /* [1] */
2237                 BTF_TYPE_ENC(NAME_TBD,
2238                              BTF_INFO_ENC(BTF_KIND_ENUM, 0, 1),
2239                              sizeof(int)),                              /* [2] */
2240                 BTF_ENUM_ENC(NAME_TBD, 0),
2241                 BTF_END_RAW,
2242         },
2243         .str_sec = "\0A!\0B",
2244         .str_sec_size = sizeof("\0A!\0B"),
2245         .map_type = BPF_MAP_TYPE_ARRAY,
2246         .map_name = "enum_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 name",
2254 },
2255
2256 {
2257         .descr = "enum member (invalid name, name_off = 0)",
2258         .raw_types = {
2259                 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),          /* [1] */
2260                 BTF_TYPE_ENC(0,
2261                              BTF_INFO_ENC(BTF_KIND_ENUM, 0, 1),
2262                              sizeof(int)),                              /* [2] */
2263                 BTF_ENUM_ENC(0, 0),
2264                 BTF_END_RAW,
2265         },
2266         .str_sec = "",
2267         .str_sec_size = sizeof(""),
2268         .map_type = BPF_MAP_TYPE_ARRAY,
2269         .map_name = "enum_type_check_btf",
2270         .key_size = sizeof(int),
2271         .value_size = sizeof(int),
2272         .key_type_id = 1,
2273         .value_type_id = 1,
2274         .max_entries = 4,
2275         .btf_load_err = true,
2276         .err_str = "Invalid name",
2277 },
2278
2279 {
2280         .descr = "enum member (invalid name, invalid identifier)",
2281         .raw_types = {
2282                 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),          /* [1] */
2283                 BTF_TYPE_ENC(0,
2284                              BTF_INFO_ENC(BTF_KIND_ENUM, 0, 1),
2285                              sizeof(int)),                              /* [2] */
2286                 BTF_ENUM_ENC(NAME_TBD, 0),
2287                 BTF_END_RAW,
2288         },
2289         .str_sec = "\0A!",
2290         .str_sec_size = sizeof("\0A!"),
2291         .map_type = BPF_MAP_TYPE_ARRAY,
2292         .map_name = "enum_type_check_btf",
2293         .key_size = sizeof(int),
2294         .value_size = sizeof(int),
2295         .key_type_id = 1,
2296         .value_type_id = 1,
2297         .max_entries = 4,
2298         .btf_load_err = true,
2299         .err_str = "Invalid name",
2300 },
2301 {
2302         .descr = "arraymap invalid btf key (a bit field)",
2303         .raw_types = {
2304                 /* int */                               /* [1] */
2305                 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
2306                 /* 32 bit int with 32 bit offset */     /* [2] */
2307                 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 32, 32, 8),
2308                 BTF_END_RAW,
2309         },
2310         .str_sec = "",
2311         .str_sec_size = sizeof(""),
2312         .map_type = BPF_MAP_TYPE_ARRAY,
2313         .map_name = "array_map_check_btf",
2314         .key_size = sizeof(int),
2315         .value_size = sizeof(int),
2316         .key_type_id = 2,
2317         .value_type_id = 1,
2318         .max_entries = 4,
2319         .map_create_err = true,
2320 },
2321
2322 {
2323         .descr = "arraymap invalid btf key (!= 32 bits)",
2324         .raw_types = {
2325                 /* int */                               /* [1] */
2326                 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
2327                 /* 16 bit int with 0 bit offset */      /* [2] */
2328                 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 16, 2),
2329                 BTF_END_RAW,
2330         },
2331         .str_sec = "",
2332         .str_sec_size = sizeof(""),
2333         .map_type = BPF_MAP_TYPE_ARRAY,
2334         .map_name = "array_map_check_btf",
2335         .key_size = sizeof(int),
2336         .value_size = sizeof(int),
2337         .key_type_id = 2,
2338         .value_type_id = 1,
2339         .max_entries = 4,
2340         .map_create_err = true,
2341 },
2342
2343 {
2344         .descr = "arraymap invalid btf value (too small)",
2345         .raw_types = {
2346                 /* int */                               /* [1] */
2347                 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
2348                 BTF_END_RAW,
2349         },
2350         .str_sec = "",
2351         .str_sec_size = sizeof(""),
2352         .map_type = BPF_MAP_TYPE_ARRAY,
2353         .map_name = "array_map_check_btf",
2354         .key_size = sizeof(int),
2355         /* btf_value_size < map->value_size */
2356         .value_size = sizeof(__u64),
2357         .key_type_id = 1,
2358         .value_type_id = 1,
2359         .max_entries = 4,
2360         .map_create_err = true,
2361 },
2362
2363 {
2364         .descr = "arraymap invalid btf value (too big)",
2365         .raw_types = {
2366                 /* int */                               /* [1] */
2367                 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
2368                 BTF_END_RAW,
2369         },
2370         .str_sec = "",
2371         .str_sec_size = sizeof(""),
2372         .map_type = BPF_MAP_TYPE_ARRAY,
2373         .map_name = "array_map_check_btf",
2374         .key_size = sizeof(int),
2375         /* btf_value_size > map->value_size */
2376         .value_size = sizeof(__u16),
2377         .key_type_id = 1,
2378         .value_type_id = 1,
2379         .max_entries = 4,
2380         .map_create_err = true,
2381 },
2382
2383 {
2384         .descr = "func proto (int (*)(int, unsigned int))",
2385         .raw_types = {
2386                 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
2387                 BTF_TYPE_INT_ENC(0, 0, 0, 32, 4),               /* [2] */
2388                 /* int (*)(int, unsigned int) */
2389                 BTF_FUNC_PROTO_ENC(1, 2),                       /* [3] */
2390                         BTF_FUNC_PROTO_ARG_ENC(0, 1),
2391                         BTF_FUNC_PROTO_ARG_ENC(0, 2),
2392                 BTF_END_RAW,
2393         },
2394         .str_sec = "",
2395         .str_sec_size = sizeof(""),
2396         .map_type = BPF_MAP_TYPE_ARRAY,
2397         .map_name = "func_proto_type_check_btf",
2398         .key_size = sizeof(int),
2399         .value_size = sizeof(int),
2400         .key_type_id = 1,
2401         .value_type_id = 1,
2402         .max_entries = 4,
2403 },
2404
2405 {
2406         .descr = "func proto (vararg)",
2407         .raw_types = {
2408                 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),  /* [1] */
2409                 BTF_TYPE_INT_ENC(0, 0, 0, 32, 4),               /* [2] */
2410                 /* void (*)(int, unsigned int, ...) */
2411                 BTF_FUNC_PROTO_ENC(0, 3),                       /* [3] */
2412                         BTF_FUNC_PROTO_ARG_ENC(0, 1),
2413                         BTF_FUNC_PROTO_ARG_ENC(0, 2),
2414                         BTF_FUNC_PROTO_ARG_ENC(0, 0),
2415                 BTF_END_RAW,
2416         },
2417         .str_sec = "",
2418         .str_sec_size = sizeof(""),
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 },
2427
2428 {
2429         .descr = "func proto (vararg with name)",
2430         .raw_types = {
2431                 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),  /* [1] */
2432                 BTF_TYPE_INT_ENC(0, 0, 0, 32, 4),               /* [2] */
2433                 /* void (*)(int a, unsigned int b, ... c) */
2434                 BTF_FUNC_PROTO_ENC(0, 3),                       /* [3] */
2435                         BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
2436                         BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 2),
2437                         BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 0),
2438                 BTF_END_RAW,
2439         },
2440         .str_sec = "\0a\0b\0c",
2441         .str_sec_size = sizeof("\0a\0b\0c"),
2442         .map_type = BPF_MAP_TYPE_ARRAY,
2443         .map_name = "func_proto_type_check_btf",
2444         .key_size = sizeof(int),
2445         .value_size = sizeof(int),
2446         .key_type_id = 1,
2447         .value_type_id = 1,
2448         .max_entries = 4,
2449         .btf_load_err = true,
2450         .err_str = "Invalid arg#3",
2451 },
2452
2453 {
2454         .descr = "func proto (arg after vararg)",
2455         .raw_types = {
2456                 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),  /* [1] */
2457                 BTF_TYPE_INT_ENC(0, 0, 0, 32, 4),               /* [2] */
2458                 /* void (*)(int a, ..., unsigned int b) */
2459                 BTF_FUNC_PROTO_ENC(0, 3),                       /* [3] */
2460                         BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
2461                         BTF_FUNC_PROTO_ARG_ENC(0, 0),
2462                         BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 2),
2463                 BTF_END_RAW,
2464         },
2465         .str_sec = "\0a\0b",
2466         .str_sec_size = sizeof("\0a\0b"),
2467         .map_type = BPF_MAP_TYPE_ARRAY,
2468         .map_name = "func_proto_type_check_btf",
2469         .key_size = sizeof(int),
2470         .value_size = sizeof(int),
2471         .key_type_id = 1,
2472         .value_type_id = 1,
2473         .max_entries = 4,
2474         .btf_load_err = true,
2475         .err_str = "Invalid arg#2",
2476 },
2477
2478 {
2479         .descr = "func proto (CONST=>TYPEDEF=>PTR=>FUNC_PROTO)",
2480         .raw_types = {
2481                 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),  /* [1] */
2482                 BTF_TYPE_INT_ENC(0, 0, 0, 32, 4),               /* [2] */
2483                 /* typedef void (*func_ptr)(int, unsigned int) */
2484                 BTF_TYPEDEF_ENC(NAME_TBD, 5),                   /* [3] */
2485                 /* const func_ptr */
2486                 BTF_CONST_ENC(3),                               /* [4] */
2487                 BTF_PTR_ENC(6),                                 /* [5] */
2488                 BTF_FUNC_PROTO_ENC(0, 2),                       /* [6] */
2489                         BTF_FUNC_PROTO_ARG_ENC(0, 1),
2490                         BTF_FUNC_PROTO_ARG_ENC(0, 2),
2491                 BTF_END_RAW,
2492         },
2493         .str_sec = "\0func_ptr",
2494         .str_sec_size = sizeof("\0func_ptr"),
2495         .map_type = BPF_MAP_TYPE_ARRAY,
2496         .map_name = "func_proto_type_check_btf",
2497         .key_size = sizeof(int),
2498         .value_size = sizeof(int),
2499         .key_type_id = 1,
2500         .value_type_id = 1,
2501         .max_entries = 4,
2502 },
2503
2504 {
2505         .descr = "func proto (TYPEDEF=>FUNC_PROTO)",
2506         .raw_types = {
2507                 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),  /* [1] */
2508                 BTF_TYPE_INT_ENC(0, 0, 0, 32, 4),               /* [2] */
2509                 BTF_TYPEDEF_ENC(NAME_TBD, 4),                   /* [3] */
2510                 BTF_FUNC_PROTO_ENC(0, 2),                       /* [4] */
2511                         BTF_FUNC_PROTO_ARG_ENC(0, 1),
2512                         BTF_FUNC_PROTO_ARG_ENC(0, 2),
2513                 BTF_END_RAW,
2514         },
2515         .str_sec = "\0func_typedef",
2516         .str_sec_size = sizeof("\0func_typedef"),
2517         .map_type = BPF_MAP_TYPE_ARRAY,
2518         .map_name = "func_proto_type_check_btf",
2519         .key_size = sizeof(int),
2520         .value_size = sizeof(int),
2521         .key_type_id = 1,
2522         .value_type_id = 1,
2523         .max_entries = 4,
2524 },
2525
2526 {
2527         .descr = "func proto (btf_resolve(arg))",
2528         .raw_types = {
2529                 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),  /* [1] */
2530                 /* void (*)(const void *) */
2531                 BTF_FUNC_PROTO_ENC(0, 1),                       /* [2] */
2532                         BTF_FUNC_PROTO_ARG_ENC(0, 3),
2533                 BTF_CONST_ENC(4),                               /* [3] */
2534                 BTF_PTR_ENC(0),                                 /* [4] */
2535                 BTF_END_RAW,
2536         },
2537         .str_sec = "",
2538         .str_sec_size = sizeof(""),
2539         .map_type = BPF_MAP_TYPE_ARRAY,
2540         .map_name = "func_proto_type_check_btf",
2541         .key_size = sizeof(int),
2542         .value_size = sizeof(int),
2543         .key_type_id = 1,
2544         .value_type_id = 1,
2545         .max_entries = 4,
2546 },
2547
2548 {
2549         .descr = "func proto (Not all arg has name)",
2550         .raw_types = {
2551                 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),  /* [1] */
2552                 BTF_TYPE_INT_ENC(0, 0, 0, 32, 4),               /* [2] */
2553                 /* void (*)(int, unsigned int b) */
2554                 BTF_FUNC_PROTO_ENC(0, 2),                       /* [3] */
2555                         BTF_FUNC_PROTO_ARG_ENC(0, 1),
2556                         BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 2),
2557                 BTF_END_RAW,
2558         },
2559         .str_sec = "\0b",
2560         .str_sec_size = sizeof("\0b"),
2561         .map_type = BPF_MAP_TYPE_ARRAY,
2562         .map_name = "func_proto_type_check_btf",
2563         .key_size = sizeof(int),
2564         .value_size = sizeof(int),
2565         .key_type_id = 1,
2566         .value_type_id = 1,
2567         .max_entries = 4,
2568 },
2569
2570 {
2571         .descr = "func proto (Bad arg name_off)",
2572         .raw_types = {
2573                 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),  /* [1] */
2574                 BTF_TYPE_INT_ENC(0, 0, 0, 32, 4),               /* [2] */
2575                 /* void (*)(int a, unsigned int <bad_name_off>) */
2576                 BTF_FUNC_PROTO_ENC(0, 2),                       /* [3] */
2577                         BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
2578                         BTF_FUNC_PROTO_ARG_ENC(0x0fffffff, 2),
2579                 BTF_END_RAW,
2580         },
2581         .str_sec = "\0a",
2582         .str_sec_size = sizeof("\0a"),
2583         .map_type = BPF_MAP_TYPE_ARRAY,
2584         .map_name = "func_proto_type_check_btf",
2585         .key_size = sizeof(int),
2586         .value_size = sizeof(int),
2587         .key_type_id = 1,
2588         .value_type_id = 1,
2589         .max_entries = 4,
2590         .btf_load_err = true,
2591         .err_str = "Invalid arg#2",
2592 },
2593
2594 {
2595         .descr = "func proto (Bad arg name)",
2596         .raw_types = {
2597                 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),  /* [1] */
2598                 BTF_TYPE_INT_ENC(0, 0, 0, 32, 4),               /* [2] */
2599                 /* void (*)(int a, unsigned int !!!) */
2600                 BTF_FUNC_PROTO_ENC(0, 2),                       /* [3] */
2601                         BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
2602                         BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 2),
2603                 BTF_END_RAW,
2604         },
2605         .str_sec = "\0a\0!!!",
2606         .str_sec_size = sizeof("\0a\0!!!"),
2607         .map_type = BPF_MAP_TYPE_ARRAY,
2608         .map_name = "func_proto_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 arg#2",
2616 },
2617
2618 {
2619         .descr = "func proto (Invalid return type)",
2620         .raw_types = {
2621                 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),  /* [1] */
2622                 BTF_TYPE_INT_ENC(0, 0, 0, 32, 4),               /* [2] */
2623                 /* <bad_ret_type> (*)(int, unsigned int) */
2624                 BTF_FUNC_PROTO_ENC(100, 2),                     /* [3] */
2625                         BTF_FUNC_PROTO_ARG_ENC(0, 1),
2626                         BTF_FUNC_PROTO_ARG_ENC(0, 2),
2627                 BTF_END_RAW,
2628         },
2629         .str_sec = "",
2630         .str_sec_size = sizeof(""),
2631         .map_type = BPF_MAP_TYPE_ARRAY,
2632         .map_name = "func_proto_type_check_btf",
2633         .key_size = sizeof(int),
2634         .value_size = sizeof(int),
2635         .key_type_id = 1,
2636         .value_type_id = 1,
2637         .max_entries = 4,
2638         .btf_load_err = true,
2639         .err_str = "Invalid return type",
2640 },
2641
2642 {
2643         .descr = "func proto (with func name)",
2644         .raw_types = {
2645                 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),  /* [1] */
2646                 BTF_TYPE_INT_ENC(0, 0, 0, 32, 4),               /* [2] */
2647                 /* void func_proto(int, unsigned int) */
2648                 BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_FUNC_PROTO, 0, 2), 0),     /* [3] */
2649                         BTF_FUNC_PROTO_ARG_ENC(0, 1),
2650                         BTF_FUNC_PROTO_ARG_ENC(0, 2),
2651                 BTF_END_RAW,
2652         },
2653         .str_sec = "\0func_proto",
2654         .str_sec_size = sizeof("\0func_proto"),
2655         .map_type = BPF_MAP_TYPE_ARRAY,
2656         .map_name = "func_proto_type_check_btf",
2657         .key_size = sizeof(int),
2658         .value_size = sizeof(int),
2659         .key_type_id = 1,
2660         .value_type_id = 1,
2661         .max_entries = 4,
2662         .btf_load_err = true,
2663         .err_str = "Invalid name",
2664 },
2665
2666 {
2667         .descr = "func proto (const void arg)",
2668         .raw_types = {
2669                 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),  /* [1] */
2670                 BTF_TYPE_INT_ENC(0, 0, 0, 32, 4),               /* [2] */
2671                 /* void (*)(const void) */
2672                 BTF_FUNC_PROTO_ENC(0, 1),                       /* [3] */
2673                         BTF_FUNC_PROTO_ARG_ENC(0, 4),
2674                 BTF_CONST_ENC(0),                               /* [4] */
2675                 BTF_END_RAW,
2676         },
2677         .str_sec = "",
2678         .str_sec_size = sizeof(""),
2679         .map_type = BPF_MAP_TYPE_ARRAY,
2680         .map_name = "func_proto_type_check_btf",
2681         .key_size = sizeof(int),
2682         .value_size = sizeof(int),
2683         .key_type_id = 1,
2684         .value_type_id = 1,
2685         .max_entries = 4,
2686         .btf_load_err = true,
2687         .err_str = "Invalid arg#1",
2688 },
2689
2690 {
2691         .descr = "func (void func(int a, unsigned int b))",
2692         .raw_types = {
2693                 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),  /* [1] */
2694                 BTF_TYPE_INT_ENC(0, 0, 0, 32, 4),               /* [2] */
2695                 /* void (*)(int a, unsigned int b) */
2696                 BTF_FUNC_PROTO_ENC(0, 2),                       /* [3] */
2697                         BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
2698                         BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 2),
2699                 /* void func(int a, unsigned int b) */
2700                 BTF_FUNC_ENC(NAME_TBD, 3),                      /* [4] */
2701                 BTF_END_RAW,
2702         },
2703         .str_sec = "\0a\0b\0func",
2704         .str_sec_size = sizeof("\0a\0b\0func"),
2705         .map_type = BPF_MAP_TYPE_ARRAY,
2706         .map_name = "func_type_check_btf",
2707         .key_size = sizeof(int),
2708         .value_size = sizeof(int),
2709         .key_type_id = 1,
2710         .value_type_id = 1,
2711         .max_entries = 4,
2712 },
2713
2714 {
2715         .descr = "func (No func name)",
2716         .raw_types = {
2717                 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),  /* [1] */
2718                 BTF_TYPE_INT_ENC(0, 0, 0, 32, 4),               /* [2] */
2719                 /* void (*)(int a, unsigned int b) */
2720                 BTF_FUNC_PROTO_ENC(0, 2),                       /* [3] */
2721                         BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
2722                         BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 2),
2723                 /* void <no_name>(int a, unsigned int b) */
2724                 BTF_FUNC_ENC(0, 3),                             /* [4] */
2725                 BTF_END_RAW,
2726         },
2727         .str_sec = "\0a\0b",
2728         .str_sec_size = sizeof("\0a\0b"),
2729         .map_type = BPF_MAP_TYPE_ARRAY,
2730         .map_name = "func_type_check_btf",
2731         .key_size = sizeof(int),
2732         .value_size = sizeof(int),
2733         .key_type_id = 1,
2734         .value_type_id = 1,
2735         .max_entries = 4,
2736         .btf_load_err = true,
2737         .err_str = "Invalid name",
2738 },
2739
2740 {
2741         .descr = "func (Invalid func name)",
2742         .raw_types = {
2743                 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),  /* [1] */
2744                 BTF_TYPE_INT_ENC(0, 0, 0, 32, 4),               /* [2] */
2745                 /* void (*)(int a, unsigned int b) */
2746                 BTF_FUNC_PROTO_ENC(0, 2),                       /* [3] */
2747                         BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
2748                         BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 2),
2749                 /* void !!!(int a, unsigned int b) */
2750                 BTF_FUNC_ENC(NAME_TBD, 3),                      /* [4] */
2751                 BTF_END_RAW,
2752         },
2753         .str_sec = "\0a\0b\0!!!",
2754         .str_sec_size = sizeof("\0a\0b\0!!!"),
2755         .map_type = BPF_MAP_TYPE_ARRAY,
2756         .map_name = "func_type_check_btf",
2757         .key_size = sizeof(int),
2758         .value_size = sizeof(int),
2759         .key_type_id = 1,
2760         .value_type_id = 1,
2761         .max_entries = 4,
2762         .btf_load_err = true,
2763         .err_str = "Invalid name",
2764 },
2765
2766 {
2767         .descr = "func (Some arg has no name)",
2768         .raw_types = {
2769                 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),  /* [1] */
2770                 BTF_TYPE_INT_ENC(0, 0, 0, 32, 4),               /* [2] */
2771                 /* void (*)(int a, unsigned int) */
2772                 BTF_FUNC_PROTO_ENC(0, 2),                       /* [3] */
2773                         BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
2774                         BTF_FUNC_PROTO_ARG_ENC(0, 2),
2775                 /* void func(int a, unsigned int) */
2776                 BTF_FUNC_ENC(NAME_TBD, 3),                      /* [4] */
2777                 BTF_END_RAW,
2778         },
2779         .str_sec = "\0a\0func",
2780         .str_sec_size = sizeof("\0a\0func"),
2781         .map_type = BPF_MAP_TYPE_ARRAY,
2782         .map_name = "func_type_check_btf",
2783         .key_size = sizeof(int),
2784         .value_size = sizeof(int),
2785         .key_type_id = 1,
2786         .value_type_id = 1,
2787         .max_entries = 4,
2788         .btf_load_err = true,
2789         .err_str = "Invalid arg#2",
2790 },
2791
2792 {
2793         .descr = "func (Non zero vlen)",
2794         .raw_types = {
2795                 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),  /* [1] */
2796                 BTF_TYPE_INT_ENC(0, 0, 0, 32, 4),               /* [2] */
2797                 /* void (*)(int a, unsigned int b) */
2798                 BTF_FUNC_PROTO_ENC(0, 2),                       /* [3] */
2799                         BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
2800                         BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 2),
2801                 /* void func(int a, unsigned int b) */
2802                 BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_FUNC, 0, 2), 3),   /* [4] */
2803                 BTF_END_RAW,
2804         },
2805         .str_sec = "\0a\0b\0func",
2806         .str_sec_size = sizeof("\0a\0b\0func"),
2807         .map_type = BPF_MAP_TYPE_ARRAY,
2808         .map_name = "func_type_check_btf",
2809         .key_size = sizeof(int),
2810         .value_size = sizeof(int),
2811         .key_type_id = 1,
2812         .value_type_id = 1,
2813         .max_entries = 4,
2814         .btf_load_err = true,
2815         .err_str = "vlen != 0",
2816 },
2817
2818 {
2819         .descr = "func (Not referring to FUNC_PROTO)",
2820         .raw_types = {
2821                 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),  /* [1] */
2822                 BTF_FUNC_ENC(NAME_TBD, 1),                      /* [2] */
2823                 BTF_END_RAW,
2824         },
2825         .str_sec = "\0func",
2826         .str_sec_size = sizeof("\0func"),
2827         .map_type = BPF_MAP_TYPE_ARRAY,
2828         .map_name = "func_type_check_btf",
2829         .key_size = sizeof(int),
2830         .value_size = sizeof(int),
2831         .key_type_id = 1,
2832         .value_type_id = 1,
2833         .max_entries = 4,
2834         .btf_load_err = true,
2835         .err_str = "Invalid type_id",
2836 },
2837
2838 {
2839         .descr = "invalid int kind_flag",
2840         .raw_types = {
2841                 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),          /* [1] */
2842                 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_INT, 1, 0), 4),   /* [2] */
2843                 BTF_INT_ENC(0, 0, 32),
2844                 BTF_END_RAW,
2845         },
2846         BTF_STR_SEC(""),
2847         .map_type = BPF_MAP_TYPE_ARRAY,
2848         .map_name = "int_type_check_btf",
2849         .key_size = sizeof(int),
2850         .value_size = sizeof(int),
2851         .key_type_id = 1,
2852         .value_type_id = 1,
2853         .max_entries = 4,
2854         .btf_load_err = true,
2855         .err_str = "Invalid btf_info kind_flag",
2856 },
2857
2858 {
2859         .descr = "invalid ptr kind_flag",
2860         .raw_types = {
2861                 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),          /* [1] */
2862                 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_PTR, 1, 0), 1),   /* [2] */
2863                 BTF_END_RAW,
2864         },
2865         BTF_STR_SEC(""),
2866         .map_type = BPF_MAP_TYPE_ARRAY,
2867         .map_name = "ptr_type_check_btf",
2868         .key_size = sizeof(int),
2869         .value_size = sizeof(int),
2870         .key_type_id = 1,
2871         .value_type_id = 1,
2872         .max_entries = 4,
2873         .btf_load_err = true,
2874         .err_str = "Invalid btf_info kind_flag",
2875 },
2876
2877 {
2878         .descr = "invalid array kind_flag",
2879         .raw_types = {
2880                 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),          /* [1] */
2881                 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_ARRAY, 1, 0), 0), /* [2] */
2882                 BTF_ARRAY_ENC(1, 1, 1),
2883                 BTF_END_RAW,
2884         },
2885         BTF_STR_SEC(""),
2886         .map_type = BPF_MAP_TYPE_ARRAY,
2887         .map_name = "array_type_check_btf",
2888         .key_size = sizeof(int),
2889         .value_size = sizeof(int),
2890         .key_type_id = 1,
2891         .value_type_id = 1,
2892         .max_entries = 4,
2893         .btf_load_err = true,
2894         .err_str = "Invalid btf_info kind_flag",
2895 },
2896
2897 {
2898         .descr = "invalid enum kind_flag",
2899         .raw_types = {
2900                 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),          /* [1] */
2901                 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_ENUM, 1, 1), 4),  /* [2] */
2902                 BTF_ENUM_ENC(NAME_TBD, 0),
2903                 BTF_END_RAW,
2904         },
2905         BTF_STR_SEC("\0A"),
2906         .map_type = BPF_MAP_TYPE_ARRAY,
2907         .map_name = "enum_type_check_btf",
2908         .key_size = sizeof(int),
2909         .value_size = sizeof(int),
2910         .key_type_id = 1,
2911         .value_type_id = 1,
2912         .max_entries = 4,
2913         .btf_load_err = true,
2914         .err_str = "Invalid btf_info kind_flag",
2915 },
2916
2917 {
2918         .descr = "valid fwd kind_flag",
2919         .raw_types = {
2920                 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),          /* [1] */
2921                 BTF_TYPE_ENC(NAME_TBD,
2922                              BTF_INFO_ENC(BTF_KIND_FWD, 1, 0), 0),      /* [2] */
2923                 BTF_END_RAW,
2924         },
2925         BTF_STR_SEC("\0A"),
2926         .map_type = BPF_MAP_TYPE_ARRAY,
2927         .map_name = "fwd_type_check_btf",
2928         .key_size = sizeof(int),
2929         .value_size = sizeof(int),
2930         .key_type_id = 1,
2931         .value_type_id = 1,
2932         .max_entries = 4,
2933 },
2934
2935 {
2936         .descr = "invalid typedef kind_flag",
2937         .raw_types = {
2938                 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),          /* [1] */
2939                 BTF_TYPE_ENC(NAME_TBD,
2940                              BTF_INFO_ENC(BTF_KIND_TYPEDEF, 1, 0), 1),  /* [2] */
2941                 BTF_END_RAW,
2942         },
2943         BTF_STR_SEC("\0A"),
2944         .map_type = BPF_MAP_TYPE_ARRAY,
2945         .map_name = "typedef_type_check_btf",
2946         .key_size = sizeof(int),
2947         .value_size = sizeof(int),
2948         .key_type_id = 1,
2949         .value_type_id = 1,
2950         .max_entries = 4,
2951         .btf_load_err = true,
2952         .err_str = "Invalid btf_info kind_flag",
2953 },
2954
2955 {
2956         .descr = "invalid volatile kind_flag",
2957         .raw_types = {
2958                 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),                  /* [1] */
2959                 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_VOLATILE, 1, 0), 1),      /* [2] */
2960                 BTF_END_RAW,
2961         },
2962         BTF_STR_SEC(""),
2963         .map_type = BPF_MAP_TYPE_ARRAY,
2964         .map_name = "volatile_type_check_btf",
2965         .key_size = sizeof(int),
2966         .value_size = sizeof(int),
2967         .key_type_id = 1,
2968         .value_type_id = 1,
2969         .max_entries = 4,
2970         .btf_load_err = true,
2971         .err_str = "Invalid btf_info kind_flag",
2972 },
2973
2974 {
2975         .descr = "invalid const kind_flag",
2976         .raw_types = {
2977                 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),          /* [1] */
2978                 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_CONST, 1, 0), 1), /* [2] */
2979                 BTF_END_RAW,
2980         },
2981         BTF_STR_SEC(""),
2982         .map_type = BPF_MAP_TYPE_ARRAY,
2983         .map_name = "const_type_check_btf",
2984         .key_size = sizeof(int),
2985         .value_size = sizeof(int),
2986         .key_type_id = 1,
2987         .value_type_id = 1,
2988         .max_entries = 4,
2989         .btf_load_err = true,
2990         .err_str = "Invalid btf_info kind_flag",
2991 },
2992
2993 {
2994         .descr = "invalid restrict kind_flag",
2995         .raw_types = {
2996                 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),                  /* [1] */
2997                 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_RESTRICT, 1, 0), 1),      /* [2] */
2998                 BTF_END_RAW,
2999         },
3000         BTF_STR_SEC(""),
3001         .map_type = BPF_MAP_TYPE_ARRAY,
3002         .map_name = "restrict_type_check_btf",
3003         .key_size = sizeof(int),
3004         .value_size = sizeof(int),
3005         .key_type_id = 1,
3006         .value_type_id = 1,
3007         .max_entries = 4,
3008         .btf_load_err = true,
3009         .err_str = "Invalid btf_info kind_flag",
3010 },
3011
3012 {
3013         .descr = "invalid func kind_flag",
3014         .raw_types = {
3015                 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),                  /* [1] */
3016                 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_FUNC_PROTO, 0, 0), 0),    /* [2] */
3017                 BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_FUNC, 1, 0), 2),   /* [3] */
3018                 BTF_END_RAW,
3019         },
3020         BTF_STR_SEC("\0A"),
3021         .map_type = BPF_MAP_TYPE_ARRAY,
3022         .map_name = "func_type_check_btf",
3023         .key_size = sizeof(int),
3024         .value_size = sizeof(int),
3025         .key_type_id = 1,
3026         .value_type_id = 1,
3027         .max_entries = 4,
3028         .btf_load_err = true,
3029         .err_str = "Invalid btf_info kind_flag",
3030 },
3031
3032 {
3033         .descr = "invalid func_proto kind_flag",
3034         .raw_types = {
3035                 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),                  /* [1] */
3036                 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_FUNC_PROTO, 1, 0), 0),    /* [2] */
3037                 BTF_END_RAW,
3038         },
3039         BTF_STR_SEC(""),
3040         .map_type = BPF_MAP_TYPE_ARRAY,
3041         .map_name = "func_proto_type_check_btf",
3042         .key_size = sizeof(int),
3043         .value_size = sizeof(int),
3044         .key_type_id = 1,
3045         .value_type_id = 1,
3046         .max_entries = 4,
3047         .btf_load_err = true,
3048         .err_str = "Invalid btf_info kind_flag",
3049 },
3050
3051 {
3052         .descr = "valid struct, kind_flag, bitfield_size = 0",
3053         .raw_types = {
3054                 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),                  /* [1] */
3055                 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_STRUCT, 1, 2), 8),        /* [2] */
3056                 BTF_MEMBER_ENC(NAME_TBD, 1, BTF_MEMBER_OFFSET(0, 0)),
3057                 BTF_MEMBER_ENC(NAME_TBD, 1, BTF_MEMBER_OFFSET(0, 32)),
3058                 BTF_END_RAW,
3059         },
3060         BTF_STR_SEC("\0A\0B"),
3061         .map_type = BPF_MAP_TYPE_ARRAY,
3062         .map_name = "struct_type_check_btf",
3063         .key_size = sizeof(int),
3064         .value_size = sizeof(int),
3065         .key_type_id = 1,
3066         .value_type_id = 1,
3067         .max_entries = 4,
3068 },
3069
3070 {
3071         .descr = "valid struct, kind_flag, int member, bitfield_size != 0",
3072         .raw_types = {
3073                 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),                  /* [1] */
3074                 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_STRUCT, 1, 2), 4),        /* [2] */
3075                 BTF_MEMBER_ENC(NAME_TBD, 1, BTF_MEMBER_OFFSET(4, 0)),
3076                 BTF_MEMBER_ENC(NAME_TBD, 1, BTF_MEMBER_OFFSET(4, 4)),
3077                 BTF_END_RAW,
3078         },
3079         BTF_STR_SEC("\0A\0B"),
3080         .map_type = BPF_MAP_TYPE_ARRAY,
3081         .map_name = "struct_type_check_btf",
3082         .key_size = sizeof(int),
3083         .value_size = sizeof(int),
3084         .key_type_id = 1,
3085         .value_type_id = 1,
3086         .max_entries = 4,
3087 },
3088
3089 {
3090         .descr = "valid union, kind_flag, int member, bitfield_size != 0",
3091         .raw_types = {
3092                 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),          /* [1] */
3093                 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_UNION, 1, 2), 4), /* [2] */
3094                 BTF_MEMBER_ENC(NAME_TBD, 1, BTF_MEMBER_OFFSET(4, 0)),
3095                 BTF_MEMBER_ENC(NAME_TBD, 1, BTF_MEMBER_OFFSET(4, 0)),
3096                 BTF_END_RAW,
3097         },
3098         BTF_STR_SEC("\0A\0B"),
3099         .map_type = BPF_MAP_TYPE_ARRAY,
3100         .map_name = "union_type_check_btf",
3101         .key_size = sizeof(int),
3102         .value_size = sizeof(int),
3103         .key_type_id = 1,
3104         .value_type_id = 1,
3105         .max_entries = 4,
3106 },
3107
3108 {
3109         .descr = "valid struct, kind_flag, enum member, bitfield_size != 0",
3110         .raw_types = {
3111                 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),          /* [1] */
3112                 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_ENUM, 0, 1), 4),  /* [2] */
3113                 BTF_ENUM_ENC(NAME_TBD, 0),
3114                 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_STRUCT, 1, 2), 4),/* [3] */
3115                 BTF_MEMBER_ENC(NAME_TBD, 2, BTF_MEMBER_OFFSET(4, 0)),
3116                 BTF_MEMBER_ENC(NAME_TBD, 2, BTF_MEMBER_OFFSET(4, 4)),
3117                 BTF_END_RAW,
3118         },
3119         BTF_STR_SEC("\0A\0B\0C"),
3120         .map_type = BPF_MAP_TYPE_ARRAY,
3121         .map_name = "struct_type_check_btf",
3122         .key_size = sizeof(int),
3123         .value_size = sizeof(int),
3124         .key_type_id = 1,
3125         .value_type_id = 1,
3126         .max_entries = 4,
3127 },
3128
3129 {
3130         .descr = "valid union, kind_flag, enum member, bitfield_size != 0",
3131         .raw_types = {
3132                 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),          /* [1] */
3133                 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_ENUM, 0, 1), 4),  /* [2] */
3134                 BTF_ENUM_ENC(NAME_TBD, 0),
3135                 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_UNION, 1, 2), 4), /* [3] */
3136                 BTF_MEMBER_ENC(NAME_TBD, 2, BTF_MEMBER_OFFSET(4, 0)),
3137                 BTF_MEMBER_ENC(NAME_TBD, 2, BTF_MEMBER_OFFSET(4, 0)),
3138                 BTF_END_RAW,
3139         },
3140         BTF_STR_SEC("\0A\0B\0C"),
3141         .map_type = BPF_MAP_TYPE_ARRAY,
3142         .map_name = "union_type_check_btf",
3143         .key_size = sizeof(int),
3144         .value_size = sizeof(int),
3145         .key_type_id = 1,
3146         .value_type_id = 1,
3147         .max_entries = 4,
3148 },
3149
3150 {
3151         .descr = "valid struct, kind_flag, typedef member, bitfield_size != 0",
3152         .raw_types = {
3153                 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),          /* [1] */
3154                 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_ENUM, 0, 1), 4),  /* [2] */
3155                 BTF_ENUM_ENC(NAME_TBD, 0),
3156                 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_STRUCT, 1, 2), 4),/* [3] */
3157                 BTF_MEMBER_ENC(NAME_TBD, 4, BTF_MEMBER_OFFSET(4, 0)),
3158                 BTF_MEMBER_ENC(NAME_TBD, 5, BTF_MEMBER_OFFSET(4, 4)),
3159                 BTF_TYPEDEF_ENC(NAME_TBD, 1),                           /* [4] */
3160                 BTF_TYPEDEF_ENC(NAME_TBD, 2),                           /* [5] */
3161                 BTF_END_RAW,
3162         },
3163         BTF_STR_SEC("\0A\0B\0C\0D\0E"),
3164         .map_type = BPF_MAP_TYPE_ARRAY,
3165         .map_name = "struct_type_check_btf",
3166         .key_size = sizeof(int),
3167         .value_size = sizeof(int),
3168         .key_type_id = 1,
3169         .value_type_id = 1,
3170         .max_entries = 4,
3171 },
3172
3173 {
3174         .descr = "valid union, kind_flag, typedef member, bitfield_size != 0",
3175         .raw_types = {
3176                 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),          /* [1] */
3177                 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_ENUM, 0, 1), 4),  /* [2] */
3178                 BTF_ENUM_ENC(NAME_TBD, 0),
3179                 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_UNION, 1, 2), 4), /* [3] */
3180                 BTF_MEMBER_ENC(NAME_TBD, 4, BTF_MEMBER_OFFSET(4, 0)),
3181                 BTF_MEMBER_ENC(NAME_TBD, 5, BTF_MEMBER_OFFSET(4, 0)),
3182                 BTF_TYPEDEF_ENC(NAME_TBD, 1),                           /* [4] */
3183                 BTF_TYPEDEF_ENC(NAME_TBD, 2),                           /* [5] */
3184                 BTF_END_RAW,
3185         },
3186         BTF_STR_SEC("\0A\0B\0C\0D\0E"),
3187         .map_type = BPF_MAP_TYPE_ARRAY,
3188         .map_name = "union_type_check_btf",
3189         .key_size = sizeof(int),
3190         .value_size = sizeof(int),
3191         .key_type_id = 1,
3192         .value_type_id = 1,
3193         .max_entries = 4,
3194 },
3195
3196 {
3197         .descr = "invalid struct, kind_flag, bitfield_size greater than struct size",
3198         .raw_types = {
3199                 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),                  /* [1] */
3200                 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_STRUCT, 1, 2), 4),        /* [2] */
3201                 BTF_MEMBER_ENC(NAME_TBD, 1, BTF_MEMBER_OFFSET(20, 0)),
3202                 BTF_MEMBER_ENC(NAME_TBD, 1, BTF_MEMBER_OFFSET(20, 20)),
3203                 BTF_END_RAW,
3204         },
3205         BTF_STR_SEC("\0A\0B"),
3206         .map_type = BPF_MAP_TYPE_ARRAY,
3207         .map_name = "struct_type_check_btf",
3208         .key_size = sizeof(int),
3209         .value_size = sizeof(int),
3210         .key_type_id = 1,
3211         .value_type_id = 1,
3212         .max_entries = 4,
3213         .btf_load_err = true,
3214         .err_str = "Member exceeds struct_size",
3215 },
3216
3217 {
3218         .descr = "invalid struct, kind_flag, bitfield base_type int not regular",
3219         .raw_types = {
3220                 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),                  /* [1] */
3221                 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 20, 4),                  /* [2] */
3222                 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_STRUCT, 1, 2), 4),        /* [3] */
3223                 BTF_MEMBER_ENC(NAME_TBD, 2, BTF_MEMBER_OFFSET(20, 0)),
3224                 BTF_MEMBER_ENC(NAME_TBD, 2, BTF_MEMBER_OFFSET(20, 20)),
3225                 BTF_END_RAW,
3226         },
3227         BTF_STR_SEC("\0A\0B"),
3228         .map_type = BPF_MAP_TYPE_ARRAY,
3229         .map_name = "struct_type_check_btf",
3230         .key_size = sizeof(int),
3231         .value_size = sizeof(int),
3232         .key_type_id = 1,
3233         .value_type_id = 1,
3234         .max_entries = 4,
3235         .btf_load_err = true,
3236         .err_str = "Invalid member base type",
3237 },
3238
3239 {
3240         .descr = "invalid struct, kind_flag, base_type int not regular",
3241         .raw_types = {
3242                 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),                  /* [1] */
3243                 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 12, 4),                  /* [2] */
3244                 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_STRUCT, 1, 2), 4),        /* [3] */
3245                 BTF_MEMBER_ENC(NAME_TBD, 2, BTF_MEMBER_OFFSET(8, 0)),
3246                 BTF_MEMBER_ENC(NAME_TBD, 2, BTF_MEMBER_OFFSET(8, 8)),
3247                 BTF_END_RAW,
3248         },
3249         BTF_STR_SEC("\0A\0B"),
3250         .map_type = BPF_MAP_TYPE_ARRAY,
3251         .map_name = "struct_type_check_btf",
3252         .key_size = sizeof(int),
3253         .value_size = sizeof(int),
3254         .key_type_id = 1,
3255         .value_type_id = 1,
3256         .max_entries = 4,
3257         .btf_load_err = true,
3258         .err_str = "Invalid member base type",
3259 },
3260
3261 {
3262         .descr = "invalid union, kind_flag, bitfield_size greater than struct size",
3263         .raw_types = {
3264                 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),          /* [1] */
3265                 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_UNION, 1, 2), 2), /* [2] */
3266                 BTF_MEMBER_ENC(NAME_TBD, 1, BTF_MEMBER_OFFSET(8, 0)),
3267                 BTF_MEMBER_ENC(NAME_TBD, 1, BTF_MEMBER_OFFSET(20, 0)),
3268                 BTF_END_RAW,
3269         },
3270         BTF_STR_SEC("\0A\0B"),
3271         .map_type = BPF_MAP_TYPE_ARRAY,
3272         .map_name = "union_type_check_btf",
3273         .key_size = sizeof(int),
3274         .value_size = sizeof(int),
3275         .key_type_id = 1,
3276         .value_type_id = 1,
3277         .max_entries = 4,
3278         .btf_load_err = true,
3279         .err_str = "Member exceeds struct_size",
3280 },
3281
3282 {
3283         .descr = "invalid struct, kind_flag, int member, bitfield_size = 0, wrong byte alignment",
3284         .raw_types = {
3285                 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),                  /* [1] */
3286                 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),                  /* [2] */
3287                 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_STRUCT, 1, 2), 12),       /* [3] */
3288                 BTF_MEMBER_ENC(NAME_TBD, 2, BTF_MEMBER_OFFSET(0, 0)),
3289                 BTF_MEMBER_ENC(NAME_TBD, 2, BTF_MEMBER_OFFSET(0, 36)),
3290                 BTF_END_RAW,
3291         },
3292         BTF_STR_SEC("\0A\0B"),
3293         .map_type = BPF_MAP_TYPE_ARRAY,
3294         .map_name = "struct_type_check_btf",
3295         .key_size = sizeof(int),
3296         .value_size = sizeof(int),
3297         .key_type_id = 1,
3298         .value_type_id = 1,
3299         .max_entries = 4,
3300         .btf_load_err = true,
3301         .err_str = "Invalid member offset",
3302 },
3303
3304 {
3305         .descr = "invalid struct, kind_flag, enum member, bitfield_size = 0, wrong byte alignment",
3306         .raw_types = {
3307                 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),                  /* [1] */
3308                 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),                  /* [2] */
3309                 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_ENUM, 0, 1), 4),  /* [2] */
3310                 BTF_ENUM_ENC(NAME_TBD, 0),
3311                 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_STRUCT, 1, 2), 12),       /* [3] */
3312                 BTF_MEMBER_ENC(NAME_TBD, 2, BTF_MEMBER_OFFSET(0, 0)),
3313                 BTF_MEMBER_ENC(NAME_TBD, 2, BTF_MEMBER_OFFSET(0, 36)),
3314                 BTF_END_RAW,
3315         },
3316         BTF_STR_SEC("\0A\0B\0C"),
3317         .map_type = BPF_MAP_TYPE_ARRAY,
3318         .map_name = "struct_type_check_btf",
3319         .key_size = sizeof(int),
3320         .value_size = sizeof(int),
3321         .key_type_id = 1,
3322         .value_type_id = 1,
3323         .max_entries = 4,
3324         .btf_load_err = true,
3325         .err_str = "Invalid member offset",
3326 },
3327
3328 {
3329         .descr = "128-bit int",
3330         .raw_types = {
3331                 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),                  /* [1] */
3332                 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 128, 16),                /* [2] */
3333                 BTF_END_RAW,
3334         },
3335         BTF_STR_SEC("\0A"),
3336         .map_type = BPF_MAP_TYPE_ARRAY,
3337         .map_name = "int_type_check_btf",
3338         .key_size = sizeof(int),
3339         .value_size = sizeof(int),
3340         .key_type_id = 1,
3341         .value_type_id = 1,
3342         .max_entries = 4,
3343 },
3344
3345 {
3346         .descr = "struct, 128-bit int member",
3347         .raw_types = {
3348                 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),                  /* [1] */
3349                 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 128, 16),                /* [2] */
3350                 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 1), 16),       /* [3] */
3351                 BTF_MEMBER_ENC(NAME_TBD, 2, 0),
3352                 BTF_END_RAW,
3353         },
3354         BTF_STR_SEC("\0A"),
3355         .map_type = BPF_MAP_TYPE_ARRAY,
3356         .map_name = "struct_type_check_btf",
3357         .key_size = sizeof(int),
3358         .value_size = sizeof(int),
3359         .key_type_id = 1,
3360         .value_type_id = 1,
3361         .max_entries = 4,
3362 },
3363
3364 {
3365         .descr = "struct, 120-bit int member bitfield",
3366         .raw_types = {
3367                 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),                  /* [1] */
3368                 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 120, 16),                /* [2] */
3369                 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 1), 16),       /* [3] */
3370                 BTF_MEMBER_ENC(NAME_TBD, 2, 0),
3371                 BTF_END_RAW,
3372         },
3373         BTF_STR_SEC("\0A"),
3374         .map_type = BPF_MAP_TYPE_ARRAY,
3375         .map_name = "struct_type_check_btf",
3376         .key_size = sizeof(int),
3377         .value_size = sizeof(int),
3378         .key_type_id = 1,
3379         .value_type_id = 1,
3380         .max_entries = 4,
3381 },
3382
3383 {
3384         .descr = "struct, kind_flag, 128-bit int member",
3385         .raw_types = {
3386                 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),                  /* [1] */
3387                 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 128, 16),                /* [2] */
3388                 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_STRUCT, 1, 1), 16),       /* [3] */
3389                 BTF_MEMBER_ENC(NAME_TBD, 2, BTF_MEMBER_OFFSET(0, 0)),
3390                 BTF_END_RAW,
3391         },
3392         BTF_STR_SEC("\0A"),
3393         .map_type = BPF_MAP_TYPE_ARRAY,
3394         .map_name = "struct_type_check_btf",
3395         .key_size = sizeof(int),
3396         .value_size = sizeof(int),
3397         .key_type_id = 1,
3398         .value_type_id = 1,
3399         .max_entries = 4,
3400 },
3401
3402 {
3403         .descr = "struct, kind_flag, 120-bit int member bitfield",
3404         .raw_types = {
3405                 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),                  /* [1] */
3406                 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 128, 16),                /* [2] */
3407                 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_STRUCT, 1, 1), 16),       /* [3] */
3408                 BTF_MEMBER_ENC(NAME_TBD, 2, BTF_MEMBER_OFFSET(120, 0)),
3409                 BTF_END_RAW,
3410         },
3411         BTF_STR_SEC("\0A"),
3412         .map_type = BPF_MAP_TYPE_ARRAY,
3413         .map_name = "struct_type_check_btf",
3414         .key_size = sizeof(int),
3415         .value_size = sizeof(int),
3416         .key_type_id = 1,
3417         .value_type_id = 1,
3418         .max_entries = 4,
3419 },
3420 /*
3421  * typedef int arr_t[16];
3422  * struct s {
3423  *      arr_t *a;
3424  * };
3425  */
3426 {
3427         .descr = "struct->ptr->typedef->array->int size resolution",
3428         .raw_types = {
3429                 BTF_STRUCT_ENC(NAME_TBD, 1, 8),                 /* [1] */
3430                 BTF_MEMBER_ENC(NAME_TBD, 2, 0),
3431                 BTF_PTR_ENC(3),                                 /* [2] */
3432                 BTF_TYPEDEF_ENC(NAME_TBD, 4),                   /* [3] */
3433                 BTF_TYPE_ARRAY_ENC(5, 5, 16),                   /* [4] */
3434                 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),  /* [5] */
3435                 BTF_END_RAW,
3436         },
3437         BTF_STR_SEC("\0s\0a\0arr_t"),
3438         .map_type = BPF_MAP_TYPE_ARRAY,
3439         .map_name = "ptr_mod_chain_size_resolve_map",
3440         .key_size = sizeof(int),
3441         .value_size = sizeof(int) * 16,
3442         .key_type_id = 5 /* int */,
3443         .value_type_id = 3 /* arr_t */,
3444         .max_entries = 4,
3445 },
3446 /*
3447  * typedef int arr_t[16][8][4];
3448  * struct s {
3449  *      arr_t *a;
3450  * };
3451  */
3452 {
3453         .descr = "struct->ptr->typedef->multi-array->int size resolution",
3454         .raw_types = {
3455                 BTF_STRUCT_ENC(NAME_TBD, 1, 8),                 /* [1] */
3456                 BTF_MEMBER_ENC(NAME_TBD, 2, 0),
3457                 BTF_PTR_ENC(3),                                 /* [2] */
3458                 BTF_TYPEDEF_ENC(NAME_TBD, 4),                   /* [3] */
3459                 BTF_TYPE_ARRAY_ENC(5, 7, 16),                   /* [4] */
3460                 BTF_TYPE_ARRAY_ENC(6, 7, 8),                    /* [5] */
3461                 BTF_TYPE_ARRAY_ENC(7, 7, 4),                    /* [6] */
3462                 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),  /* [7] */
3463                 BTF_END_RAW,
3464         },
3465         BTF_STR_SEC("\0s\0a\0arr_t"),
3466         .map_type = BPF_MAP_TYPE_ARRAY,
3467         .map_name = "multi_arr_size_resolve_map",
3468         .key_size = sizeof(int),
3469         .value_size = sizeof(int) * 16 * 8 * 4,
3470         .key_type_id = 7 /* int */,
3471         .value_type_id = 3 /* arr_t */,
3472         .max_entries = 4,
3473 },
3474 /*
3475  * typedef int int_t;
3476  * typedef int_t arr3_t[4];
3477  * typedef arr3_t arr2_t[8];
3478  * typedef arr2_t arr1_t[16];
3479  * struct s {
3480  *      arr1_t *a;
3481  * };
3482  */
3483 {
3484         .descr = "typedef/multi-arr mix size resolution",
3485         .raw_types = {
3486                 BTF_STRUCT_ENC(NAME_TBD, 1, 8),                 /* [1] */
3487                 BTF_MEMBER_ENC(NAME_TBD, 2, 0),
3488                 BTF_PTR_ENC(3),                                 /* [2] */
3489                 BTF_TYPEDEF_ENC(NAME_TBD, 4),                   /* [3] */
3490                 BTF_TYPE_ARRAY_ENC(5, 10, 16),                  /* [4] */
3491                 BTF_TYPEDEF_ENC(NAME_TBD, 6),                   /* [5] */
3492                 BTF_TYPE_ARRAY_ENC(7, 10, 8),                   /* [6] */
3493                 BTF_TYPEDEF_ENC(NAME_TBD, 8),                   /* [7] */
3494                 BTF_TYPE_ARRAY_ENC(9, 10, 4),                   /* [8] */
3495                 BTF_TYPEDEF_ENC(NAME_TBD, 10),                  /* [9] */
3496                 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),  /* [10] */
3497                 BTF_END_RAW,
3498         },
3499         BTF_STR_SEC("\0s\0a\0arr1_t\0arr2_t\0arr3_t\0int_t"),
3500         .map_type = BPF_MAP_TYPE_ARRAY,
3501         .map_name = "typedef_arra_mix_size_resolve_map",
3502         .key_size = sizeof(int),
3503         .value_size = sizeof(int) * 16 * 8 * 4,
3504         .key_type_id = 10 /* int */,
3505         .value_type_id = 3 /* arr_t */,
3506         .max_entries = 4,
3507 },
3508
3509 }; /* struct btf_raw_test raw_tests[] */
3510
3511 static const char *get_next_str(const char *start, const char *end)
3512 {
3513         return start < end - 1 ? start + 1 : NULL;
3514 }
3515
3516 static int get_raw_sec_size(const __u32 *raw_types)
3517 {
3518         int i;
3519
3520         for (i = MAX_NR_RAW_U32 - 1;
3521              i >= 0 && raw_types[i] != BTF_END_RAW;
3522              i--)
3523                 ;
3524
3525         return i < 0 ? i : i * sizeof(raw_types[0]);
3526 }
3527
3528 static void *btf_raw_create(const struct btf_header *hdr,
3529                             const __u32 *raw_types,
3530                             const char *str,
3531                             unsigned int str_sec_size,
3532                             unsigned int *btf_size,
3533                             const char **ret_next_str)
3534 {
3535         const char *next_str = str, *end_str = str + str_sec_size;
3536         const char **strs_idx = NULL, **tmp_strs_idx;
3537         int strs_cap = 0, strs_cnt = 0, next_str_idx = 0;
3538         unsigned int size_needed, offset;
3539         struct btf_header *ret_hdr;
3540         int i, type_sec_size, err = 0;
3541         uint32_t *ret_types;
3542         void *raw_btf = NULL;
3543
3544         type_sec_size = get_raw_sec_size(raw_types);
3545         if (CHECK(type_sec_size < 0, "Cannot get nr_raw_types"))
3546                 return NULL;
3547
3548         size_needed = sizeof(*hdr) + type_sec_size + str_sec_size;
3549         raw_btf = malloc(size_needed);
3550         if (CHECK(!raw_btf, "Cannot allocate memory for raw_btf"))
3551                 return NULL;
3552
3553         /* Copy header */
3554         memcpy(raw_btf, hdr, sizeof(*hdr));
3555         offset = sizeof(*hdr);
3556
3557         /* Index strings */
3558         while ((next_str = get_next_str(next_str, end_str))) {
3559                 if (strs_cnt == strs_cap) {
3560                         strs_cap += max(16, strs_cap / 2);
3561                         tmp_strs_idx = realloc(strs_idx,
3562                                                sizeof(*strs_idx) * strs_cap);
3563                         if (CHECK(!tmp_strs_idx,
3564                                   "Cannot allocate memory for strs_idx")) {
3565                                 err = -1;
3566                                 goto done;
3567                         }
3568                         strs_idx = tmp_strs_idx;
3569                 }
3570                 strs_idx[strs_cnt++] = next_str;
3571                 next_str += strlen(next_str);
3572         }
3573
3574         /* Copy type section */
3575         ret_types = raw_btf + offset;
3576         for (i = 0; i < type_sec_size / sizeof(raw_types[0]); i++) {
3577                 if (raw_types[i] == NAME_TBD) {
3578                         if (CHECK(next_str_idx == strs_cnt,
3579                                   "Error in getting next_str #%d",
3580                                   next_str_idx)) {
3581                                 err = -1;
3582                                 goto done;
3583                         }
3584                         ret_types[i] = strs_idx[next_str_idx++] - str;
3585                 } else if (IS_NAME_NTH(raw_types[i])) {
3586                         int idx = GET_NAME_NTH_IDX(raw_types[i]);
3587
3588                         if (CHECK(idx <= 0 || idx > strs_cnt,
3589                                   "Error getting string #%d, strs_cnt:%d",
3590                                   idx, strs_cnt)) {
3591                                 err = -1;
3592                                 goto done;
3593                         }
3594                         ret_types[i] = strs_idx[idx-1] - str;
3595                 } else {
3596                         ret_types[i] = raw_types[i];
3597                 }
3598         }
3599         offset += type_sec_size;
3600
3601         /* Copy string section */
3602         memcpy(raw_btf + offset, str, str_sec_size);
3603
3604         ret_hdr = (struct btf_header *)raw_btf;
3605         ret_hdr->type_len = type_sec_size;
3606         ret_hdr->str_off = type_sec_size;
3607         ret_hdr->str_len = str_sec_size;
3608
3609         *btf_size = size_needed;
3610         if (ret_next_str)
3611                 *ret_next_str =
3612                         next_str_idx < strs_cnt ? strs_idx[next_str_idx] : NULL;
3613
3614 done:
3615         if (err) {
3616                 if (raw_btf)
3617                         free(raw_btf);
3618                 if (strs_idx)
3619                         free(strs_idx);
3620                 return NULL;
3621         }
3622         return raw_btf;
3623 }
3624
3625 static int do_test_raw(unsigned int test_num)
3626 {
3627         struct btf_raw_test *test = &raw_tests[test_num - 1];
3628         struct bpf_create_map_attr create_attr = {};
3629         int map_fd = -1, btf_fd = -1;
3630         unsigned int raw_btf_size;
3631         struct btf_header *hdr;
3632         void *raw_btf;
3633         int err;
3634
3635         fprintf(stderr, "BTF raw test[%u] (%s): ", test_num, test->descr);
3636         raw_btf = btf_raw_create(&hdr_tmpl,
3637                                  test->raw_types,
3638                                  test->str_sec,
3639                                  test->str_sec_size,
3640                                  &raw_btf_size, NULL);
3641
3642         if (!raw_btf)
3643                 return -1;
3644
3645         hdr = raw_btf;
3646
3647         hdr->hdr_len = (int)hdr->hdr_len + test->hdr_len_delta;
3648         hdr->type_off = (int)hdr->type_off + test->type_off_delta;
3649         hdr->str_off = (int)hdr->str_off + test->str_off_delta;
3650         hdr->str_len = (int)hdr->str_len + test->str_len_delta;
3651
3652         *btf_log_buf = '\0';
3653         btf_fd = bpf_load_btf(raw_btf, raw_btf_size,
3654                               btf_log_buf, BTF_LOG_BUF_SIZE,
3655                               args.always_log);
3656         free(raw_btf);
3657
3658         err = ((btf_fd == -1) != test->btf_load_err);
3659         if (CHECK(err, "btf_fd:%d test->btf_load_err:%u",
3660                   btf_fd, test->btf_load_err) ||
3661             CHECK(test->err_str && !strstr(btf_log_buf, test->err_str),
3662                   "expected err_str:%s", test->err_str)) {
3663                 err = -1;
3664                 goto done;
3665         }
3666
3667         if (err || btf_fd == -1)
3668                 goto done;
3669
3670         create_attr.name = test->map_name;
3671         create_attr.map_type = test->map_type;
3672         create_attr.key_size = test->key_size;
3673         create_attr.value_size = test->value_size;
3674         create_attr.max_entries = test->max_entries;
3675         create_attr.btf_fd = btf_fd;
3676         create_attr.btf_key_type_id = test->key_type_id;
3677         create_attr.btf_value_type_id = test->value_type_id;
3678
3679         map_fd = bpf_create_map_xattr(&create_attr);
3680
3681         err = ((map_fd == -1) != test->map_create_err);
3682         CHECK(err, "map_fd:%d test->map_create_err:%u",
3683               map_fd, test->map_create_err);
3684
3685 done:
3686         if (!err)
3687                 fprintf(stderr, "OK");
3688
3689         if (*btf_log_buf && (err || args.always_log))
3690                 fprintf(stderr, "\n%s", btf_log_buf);
3691
3692         if (btf_fd != -1)
3693                 close(btf_fd);
3694         if (map_fd != -1)
3695                 close(map_fd);
3696
3697         return err;
3698 }
3699
3700 static int test_raw(void)
3701 {
3702         unsigned int i;
3703         int err = 0;
3704
3705         if (args.raw_test_num)
3706                 return count_result(do_test_raw(args.raw_test_num));
3707
3708         for (i = 1; i <= ARRAY_SIZE(raw_tests); i++)
3709                 err |= count_result(do_test_raw(i));
3710
3711         return err;
3712 }
3713
3714 struct btf_get_info_test {
3715         const char *descr;
3716         const char *str_sec;
3717         __u32 raw_types[MAX_NR_RAW_U32];
3718         __u32 str_sec_size;
3719         int btf_size_delta;
3720         int (*special_test)(unsigned int test_num);
3721 };
3722
3723 static int test_big_btf_info(unsigned int test_num);
3724 static int test_btf_id(unsigned int test_num);
3725
3726 const struct btf_get_info_test get_info_tests[] = {
3727 {
3728         .descr = "== raw_btf_size+1",
3729         .raw_types = {
3730                 /* int */                               /* [1] */
3731                 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
3732                 BTF_END_RAW,
3733         },
3734         .str_sec = "",
3735         .str_sec_size = sizeof(""),
3736         .btf_size_delta = 1,
3737 },
3738 {
3739         .descr = "== raw_btf_size-3",
3740         .raw_types = {
3741                 /* int */                               /* [1] */
3742                 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
3743                 BTF_END_RAW,
3744         },
3745         .str_sec = "",
3746         .str_sec_size = sizeof(""),
3747         .btf_size_delta = -3,
3748 },
3749 {
3750         .descr = "Large bpf_btf_info",
3751         .raw_types = {
3752                 /* int */                               /* [1] */
3753                 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
3754                 BTF_END_RAW,
3755         },
3756         .str_sec = "",
3757         .str_sec_size = sizeof(""),
3758         .special_test = test_big_btf_info,
3759 },
3760 {
3761         .descr = "BTF ID",
3762         .raw_types = {
3763                 /* int */                               /* [1] */
3764                 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
3765                 /* unsigned int */                      /* [2] */
3766                 BTF_TYPE_INT_ENC(0, 0, 0, 32, 4),
3767                 BTF_END_RAW,
3768         },
3769         .str_sec = "",
3770         .str_sec_size = sizeof(""),
3771         .special_test = test_btf_id,
3772 },
3773 };
3774
3775 static inline __u64 ptr_to_u64(const void *ptr)
3776 {
3777         return (__u64)(unsigned long)ptr;
3778 }
3779
3780 static int test_big_btf_info(unsigned int test_num)
3781 {
3782         const struct btf_get_info_test *test = &get_info_tests[test_num - 1];
3783         uint8_t *raw_btf = NULL, *user_btf = NULL;
3784         unsigned int raw_btf_size;
3785         struct {
3786                 struct bpf_btf_info info;
3787                 uint64_t garbage;
3788         } info_garbage;
3789         struct bpf_btf_info *info;
3790         int btf_fd = -1, err;
3791         uint32_t info_len;
3792
3793         raw_btf = btf_raw_create(&hdr_tmpl,
3794                                  test->raw_types,
3795                                  test->str_sec,
3796                                  test->str_sec_size,
3797                                  &raw_btf_size, NULL);
3798
3799         if (!raw_btf)
3800                 return -1;
3801
3802         *btf_log_buf = '\0';
3803
3804         user_btf = malloc(raw_btf_size);
3805         if (CHECK(!user_btf, "!user_btf")) {
3806                 err = -1;
3807                 goto done;
3808         }
3809
3810         btf_fd = bpf_load_btf(raw_btf, raw_btf_size,
3811                               btf_log_buf, BTF_LOG_BUF_SIZE,
3812                               args.always_log);
3813         if (CHECK(btf_fd == -1, "errno:%d", errno)) {
3814                 err = -1;
3815                 goto done;
3816         }
3817
3818         /*
3819          * GET_INFO should error out if the userspace info
3820          * has non zero tailing bytes.
3821          */
3822         info = &info_garbage.info;
3823         memset(info, 0, sizeof(*info));
3824         info_garbage.garbage = 0xdeadbeef;
3825         info_len = sizeof(info_garbage);
3826         info->btf = ptr_to_u64(user_btf);
3827         info->btf_size = raw_btf_size;
3828
3829         err = bpf_obj_get_info_by_fd(btf_fd, info, &info_len);
3830         if (CHECK(!err, "!err")) {
3831                 err = -1;
3832                 goto done;
3833         }
3834
3835         /*
3836          * GET_INFO should succeed even info_len is larger than
3837          * the kernel supported as long as tailing bytes are zero.
3838          * The kernel supported info len should also be returned
3839          * to userspace.
3840          */
3841         info_garbage.garbage = 0;
3842         err = bpf_obj_get_info_by_fd(btf_fd, info, &info_len);
3843         if (CHECK(err || info_len != sizeof(*info),
3844                   "err:%d errno:%d info_len:%u sizeof(*info):%lu",
3845                   err, errno, info_len, sizeof(*info))) {
3846                 err = -1;
3847                 goto done;
3848         }
3849
3850         fprintf(stderr, "OK");
3851
3852 done:
3853         if (*btf_log_buf && (err || args.always_log))
3854                 fprintf(stderr, "\n%s", btf_log_buf);
3855
3856         free(raw_btf);
3857         free(user_btf);
3858
3859         if (btf_fd != -1)
3860                 close(btf_fd);
3861
3862         return err;
3863 }
3864
3865 static int test_btf_id(unsigned int test_num)
3866 {
3867         const struct btf_get_info_test *test = &get_info_tests[test_num - 1];
3868         struct bpf_create_map_attr create_attr = {};
3869         uint8_t *raw_btf = NULL, *user_btf[2] = {};
3870         int btf_fd[2] = {-1, -1}, map_fd = -1;
3871         struct bpf_map_info map_info = {};
3872         struct bpf_btf_info info[2] = {};
3873         unsigned int raw_btf_size;
3874         uint32_t info_len;
3875         int err, i, ret;
3876
3877         raw_btf = btf_raw_create(&hdr_tmpl,
3878                                  test->raw_types,
3879                                  test->str_sec,
3880                                  test->str_sec_size,
3881                                  &raw_btf_size, NULL);
3882
3883         if (!raw_btf)
3884                 return -1;
3885
3886         *btf_log_buf = '\0';
3887
3888         for (i = 0; i < 2; i++) {
3889                 user_btf[i] = malloc(raw_btf_size);
3890                 if (CHECK(!user_btf[i], "!user_btf[%d]", i)) {
3891                         err = -1;
3892                         goto done;
3893                 }
3894                 info[i].btf = ptr_to_u64(user_btf[i]);
3895                 info[i].btf_size = raw_btf_size;
3896         }
3897
3898         btf_fd[0] = bpf_load_btf(raw_btf, raw_btf_size,
3899                                  btf_log_buf, BTF_LOG_BUF_SIZE,
3900                                  args.always_log);
3901         if (CHECK(btf_fd[0] == -1, "errno:%d", errno)) {
3902                 err = -1;
3903                 goto done;
3904         }
3905
3906         /* Test BPF_OBJ_GET_INFO_BY_ID on btf_id */
3907         info_len = sizeof(info[0]);
3908         err = bpf_obj_get_info_by_fd(btf_fd[0], &info[0], &info_len);
3909         if (CHECK(err, "errno:%d", errno)) {
3910                 err = -1;
3911                 goto done;
3912         }
3913
3914         btf_fd[1] = bpf_btf_get_fd_by_id(info[0].id);
3915         if (CHECK(btf_fd[1] == -1, "errno:%d", errno)) {
3916                 err = -1;
3917                 goto done;
3918         }
3919
3920         ret = 0;
3921         err = bpf_obj_get_info_by_fd(btf_fd[1], &info[1], &info_len);
3922         if (CHECK(err || info[0].id != info[1].id ||
3923                   info[0].btf_size != info[1].btf_size ||
3924                   (ret = memcmp(user_btf[0], user_btf[1], info[0].btf_size)),
3925                   "err:%d errno:%d id0:%u id1:%u btf_size0:%u btf_size1:%u memcmp:%d",
3926                   err, errno, info[0].id, info[1].id,
3927                   info[0].btf_size, info[1].btf_size, ret)) {
3928                 err = -1;
3929                 goto done;
3930         }
3931
3932         /* Test btf members in struct bpf_map_info */
3933         create_attr.name = "test_btf_id";
3934         create_attr.map_type = BPF_MAP_TYPE_ARRAY;
3935         create_attr.key_size = sizeof(int);
3936         create_attr.value_size = sizeof(unsigned int);
3937         create_attr.max_entries = 4;
3938         create_attr.btf_fd = btf_fd[0];
3939         create_attr.btf_key_type_id = 1;
3940         create_attr.btf_value_type_id = 2;
3941
3942         map_fd = bpf_create_map_xattr(&create_attr);
3943         if (CHECK(map_fd == -1, "errno:%d", errno)) {
3944                 err = -1;
3945                 goto done;
3946         }
3947
3948         info_len = sizeof(map_info);
3949         err = bpf_obj_get_info_by_fd(map_fd, &map_info, &info_len);
3950         if (CHECK(err || map_info.btf_id != info[0].id ||
3951                   map_info.btf_key_type_id != 1 || map_info.btf_value_type_id != 2,
3952                   "err:%d errno:%d info.id:%u btf_id:%u btf_key_type_id:%u btf_value_type_id:%u",
3953                   err, errno, info[0].id, map_info.btf_id, map_info.btf_key_type_id,
3954                   map_info.btf_value_type_id)) {
3955                 err = -1;
3956                 goto done;
3957         }
3958
3959         for (i = 0; i < 2; i++) {
3960                 close(btf_fd[i]);
3961                 btf_fd[i] = -1;
3962         }
3963
3964         /* Test BTF ID is removed from the kernel */
3965         btf_fd[0] = bpf_btf_get_fd_by_id(map_info.btf_id);
3966         if (CHECK(btf_fd[0] == -1, "errno:%d", errno)) {
3967                 err = -1;
3968                 goto done;
3969         }
3970         close(btf_fd[0]);
3971         btf_fd[0] = -1;
3972
3973         /* The map holds the last ref to BTF and its btf_id */
3974         close(map_fd);
3975         map_fd = -1;
3976         btf_fd[0] = bpf_btf_get_fd_by_id(map_info.btf_id);
3977         if (CHECK(btf_fd[0] != -1, "BTF lingers")) {
3978                 err = -1;
3979                 goto done;
3980         }
3981
3982         fprintf(stderr, "OK");
3983
3984 done:
3985         if (*btf_log_buf && (err || args.always_log))
3986                 fprintf(stderr, "\n%s", btf_log_buf);
3987
3988         free(raw_btf);
3989         if (map_fd != -1)
3990                 close(map_fd);
3991         for (i = 0; i < 2; i++) {
3992                 free(user_btf[i]);
3993                 if (btf_fd[i] != -1)
3994                         close(btf_fd[i]);
3995         }
3996
3997         return err;
3998 }
3999
4000 static int do_test_get_info(unsigned int test_num)
4001 {
4002         const struct btf_get_info_test *test = &get_info_tests[test_num - 1];
4003         unsigned int raw_btf_size, user_btf_size, expected_nbytes;
4004         uint8_t *raw_btf = NULL, *user_btf = NULL;
4005         struct bpf_btf_info info = {};
4006         int btf_fd = -1, err, ret;
4007         uint32_t info_len;
4008
4009         fprintf(stderr, "BTF GET_INFO test[%u] (%s): ",
4010                 test_num, test->descr);
4011
4012         if (test->special_test)
4013                 return test->special_test(test_num);
4014
4015         raw_btf = btf_raw_create(&hdr_tmpl,
4016                                  test->raw_types,
4017                                  test->str_sec,
4018                                  test->str_sec_size,
4019                                  &raw_btf_size, NULL);
4020
4021         if (!raw_btf)
4022                 return -1;
4023
4024         *btf_log_buf = '\0';
4025
4026         user_btf = malloc(raw_btf_size);
4027         if (CHECK(!user_btf, "!user_btf")) {
4028                 err = -1;
4029                 goto done;
4030         }
4031
4032         btf_fd = bpf_load_btf(raw_btf, raw_btf_size,
4033                               btf_log_buf, BTF_LOG_BUF_SIZE,
4034                               args.always_log);
4035         if (CHECK(btf_fd == -1, "errno:%d", errno)) {
4036                 err = -1;
4037                 goto done;
4038         }
4039
4040         user_btf_size = (int)raw_btf_size + test->btf_size_delta;
4041         expected_nbytes = min(raw_btf_size, user_btf_size);
4042         if (raw_btf_size > expected_nbytes)
4043                 memset(user_btf + expected_nbytes, 0xff,
4044                        raw_btf_size - expected_nbytes);
4045
4046         info_len = sizeof(info);
4047         info.btf = ptr_to_u64(user_btf);
4048         info.btf_size = user_btf_size;
4049
4050         ret = 0;
4051         err = bpf_obj_get_info_by_fd(btf_fd, &info, &info_len);
4052         if (CHECK(err || !info.id || info_len != sizeof(info) ||
4053                   info.btf_size != raw_btf_size ||
4054                   (ret = memcmp(raw_btf, user_btf, expected_nbytes)),
4055                   "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",
4056                   err, errno, info.id, info_len, sizeof(info),
4057                   raw_btf_size, info.btf_size, expected_nbytes, ret)) {
4058                 err = -1;
4059                 goto done;
4060         }
4061
4062         while (expected_nbytes < raw_btf_size) {
4063                 fprintf(stderr, "%u...", expected_nbytes);
4064                 if (CHECK(user_btf[expected_nbytes++] != 0xff,
4065                           "user_btf[%u]:%x != 0xff", expected_nbytes - 1,
4066                           user_btf[expected_nbytes - 1])) {
4067                         err = -1;
4068                         goto done;
4069                 }
4070         }
4071
4072         fprintf(stderr, "OK");
4073
4074 done:
4075         if (*btf_log_buf && (err || args.always_log))
4076                 fprintf(stderr, "\n%s", btf_log_buf);
4077
4078         free(raw_btf);
4079         free(user_btf);
4080
4081         if (btf_fd != -1)
4082                 close(btf_fd);
4083
4084         return err;
4085 }
4086
4087 static int test_get_info(void)
4088 {
4089         unsigned int i;
4090         int err = 0;
4091
4092         if (args.get_info_test_num)
4093                 return count_result(do_test_get_info(args.get_info_test_num));
4094
4095         for (i = 1; i <= ARRAY_SIZE(get_info_tests); i++)
4096                 err |= count_result(do_test_get_info(i));
4097
4098         return err;
4099 }
4100
4101 struct btf_file_test {
4102         const char *file;
4103         bool btf_kv_notfound;
4104 };
4105
4106 static struct btf_file_test file_tests[] = {
4107         { .file = "test_btf_haskv.o", },
4108         { .file = "test_btf_newkv.o", },
4109         { .file = "test_btf_nokv.o", .btf_kv_notfound = true, },
4110 };
4111
4112 static int do_test_file(unsigned int test_num)
4113 {
4114         const struct btf_file_test *test = &file_tests[test_num - 1];
4115         const char *expected_fnames[] = {"_dummy_tracepoint",
4116                                          "test_long_fname_1",
4117                                          "test_long_fname_2"};
4118         struct btf_ext *btf_ext = NULL;
4119         struct bpf_prog_info info = {};
4120         struct bpf_object *obj = NULL;
4121         struct bpf_func_info *finfo;
4122         struct bpf_program *prog;
4123         __u32 info_len, rec_size;
4124         bool has_btf_ext = false;
4125         struct btf *btf = NULL;
4126         void *func_info = NULL;
4127         struct bpf_map *map;
4128         int i, err, prog_fd;
4129
4130         fprintf(stderr, "BTF libbpf test[%u] (%s): ", test_num,
4131                 test->file);
4132
4133         btf = btf__parse_elf(test->file, &btf_ext);
4134         if (IS_ERR(btf)) {
4135                 if (PTR_ERR(btf) == -ENOENT) {
4136                         fprintf(stderr, "SKIP. No ELF %s found", BTF_ELF_SEC);
4137                         skip_cnt++;
4138                         return 0;
4139                 }
4140                 return PTR_ERR(btf);
4141         }
4142         btf__free(btf);
4143
4144         has_btf_ext = btf_ext != NULL;
4145         btf_ext__free(btf_ext);
4146
4147         obj = bpf_object__open(test->file);
4148         if (CHECK(IS_ERR(obj), "obj: %ld", PTR_ERR(obj)))
4149                 return PTR_ERR(obj);
4150
4151         prog = bpf_program__next(NULL, obj);
4152         if (CHECK(!prog, "Cannot find bpf_prog")) {
4153                 err = -1;
4154                 goto done;
4155         }
4156
4157         bpf_program__set_type(prog, BPF_PROG_TYPE_TRACEPOINT);
4158         err = bpf_object__load(obj);
4159         if (CHECK(err < 0, "bpf_object__load: %d", err))
4160                 goto done;
4161         prog_fd = bpf_program__fd(prog);
4162
4163         map = bpf_object__find_map_by_name(obj, "btf_map");
4164         if (CHECK(!map, "btf_map not found")) {
4165                 err = -1;
4166                 goto done;
4167         }
4168
4169         err = (bpf_map__btf_key_type_id(map) == 0 || bpf_map__btf_value_type_id(map) == 0)
4170                 != test->btf_kv_notfound;
4171         if (CHECK(err, "btf_key_type_id:%u btf_value_type_id:%u test->btf_kv_notfound:%u",
4172                   bpf_map__btf_key_type_id(map), bpf_map__btf_value_type_id(map),
4173                   test->btf_kv_notfound))
4174                 goto done;
4175
4176         if (!has_btf_ext)
4177                 goto skip;
4178
4179         /* get necessary program info */
4180         info_len = sizeof(struct bpf_prog_info);
4181         err = bpf_obj_get_info_by_fd(prog_fd, &info, &info_len);
4182
4183         if (CHECK(err == -1, "invalid get info (1st) errno:%d", errno)) {
4184                 fprintf(stderr, "%s\n", btf_log_buf);
4185                 err = -1;
4186                 goto done;
4187         }
4188         if (CHECK(info.nr_func_info != 3,
4189                   "incorrect info.nr_func_info (1st) %d",
4190                   info.nr_func_info)) {
4191                 err = -1;
4192                 goto done;
4193         }
4194         rec_size = info.func_info_rec_size;
4195         if (CHECK(rec_size != sizeof(struct bpf_func_info),
4196                   "incorrect info.func_info_rec_size (1st) %d\n", rec_size)) {
4197                 err = -1;
4198                 goto done;
4199         }
4200
4201         func_info = malloc(info.nr_func_info * rec_size);
4202         if (CHECK(!func_info, "out of memory")) {
4203                 err = -1;
4204                 goto done;
4205         }
4206
4207         /* reset info to only retrieve func_info related data */
4208         memset(&info, 0, sizeof(info));
4209         info.nr_func_info = 3;
4210         info.func_info_rec_size = rec_size;
4211         info.func_info = ptr_to_u64(func_info);
4212
4213         err = bpf_obj_get_info_by_fd(prog_fd, &info, &info_len);
4214
4215         if (CHECK(err == -1, "invalid get info (2nd) errno:%d", errno)) {
4216                 fprintf(stderr, "%s\n", btf_log_buf);
4217                 err = -1;
4218                 goto done;
4219         }
4220         if (CHECK(info.nr_func_info != 3,
4221                   "incorrect info.nr_func_info (2nd) %d",
4222                   info.nr_func_info)) {
4223                 err = -1;
4224                 goto done;
4225         }
4226         if (CHECK(info.func_info_rec_size != rec_size,
4227                   "incorrect info.func_info_rec_size (2nd) %d",
4228                   info.func_info_rec_size)) {
4229                 err = -1;
4230                 goto done;
4231         }
4232
4233         err = btf__get_from_id(info.btf_id, &btf);
4234         if (CHECK(err, "cannot get btf from kernel, err: %d", err))
4235                 goto done;
4236
4237         /* check three functions */
4238         finfo = func_info;
4239         for (i = 0; i < 3; i++) {
4240                 const struct btf_type *t;
4241                 const char *fname;
4242
4243                 t = btf__type_by_id(btf, finfo->type_id);
4244                 if (CHECK(!t, "btf__type_by_id failure: id %u",
4245                           finfo->type_id)) {
4246                         err = -1;
4247                         goto done;
4248                 }
4249
4250                 fname = btf__name_by_offset(btf, t->name_off);
4251                 err = strcmp(fname, expected_fnames[i]);
4252                 /* for the second and third functions in .text section,
4253                  * the compiler may order them either way.
4254                  */
4255                 if (i && err)
4256                         err = strcmp(fname, expected_fnames[3 - i]);
4257                 if (CHECK(err, "incorrect fname %s", fname ? : "")) {
4258                         err = -1;
4259                         goto done;
4260                 }
4261
4262                 finfo = (void *)finfo + rec_size;
4263         }
4264
4265 skip:
4266         fprintf(stderr, "OK");
4267
4268 done:
4269         free(func_info);
4270         bpf_object__close(obj);
4271         return err;
4272 }
4273
4274 static int test_file(void)
4275 {
4276         unsigned int i;
4277         int err = 0;
4278
4279         if (args.file_test_num)
4280                 return count_result(do_test_file(args.file_test_num));
4281
4282         for (i = 1; i <= ARRAY_SIZE(file_tests); i++)
4283                 err |= count_result(do_test_file(i));
4284
4285         return err;
4286 }
4287
4288 const char *pprint_enum_str[] = {
4289         "ENUM_ZERO",
4290         "ENUM_ONE",
4291         "ENUM_TWO",
4292         "ENUM_THREE",
4293 };
4294
4295 struct pprint_mapv {
4296         uint32_t ui32;
4297         uint16_t ui16;
4298         /* 2 bytes hole */
4299         int32_t si32;
4300         uint32_t unused_bits2a:2,
4301                 bits28:28,
4302                 unused_bits2b:2;
4303         union {
4304                 uint64_t ui64;
4305                 uint8_t ui8a[8];
4306         };
4307         enum {
4308                 ENUM_ZERO,
4309                 ENUM_ONE,
4310                 ENUM_TWO,
4311                 ENUM_THREE,
4312         } aenum;
4313         uint32_t ui32b;
4314         uint32_t bits2c:2;
4315         uint8_t si8_4[2][2];
4316 };
4317
4318 #ifdef __SIZEOF_INT128__
4319 struct pprint_mapv_int128 {
4320         __int128 si128a;
4321         __int128 si128b;
4322         unsigned __int128 bits3:3;
4323         unsigned __int128 bits80:80;
4324         unsigned __int128 ui128;
4325 };
4326 #endif
4327
4328 static struct btf_raw_test pprint_test_template[] = {
4329 {
4330         .raw_types = {
4331                 /* unsighed char */                     /* [1] */
4332                 BTF_TYPE_INT_ENC(NAME_TBD, 0, 0, 8, 1),
4333                 /* unsigned short */                    /* [2] */
4334                 BTF_TYPE_INT_ENC(NAME_TBD, 0, 0, 16, 2),
4335                 /* unsigned int */                      /* [3] */
4336                 BTF_TYPE_INT_ENC(NAME_TBD, 0, 0, 32, 4),
4337                 /* int */                               /* [4] */
4338                 BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),
4339                 /* unsigned long long */                /* [5] */
4340                 BTF_TYPE_INT_ENC(NAME_TBD, 0, 0, 64, 8),
4341                 /* 2 bits */                            /* [6] */
4342                 BTF_TYPE_INT_ENC(0, 0, 0, 2, 2),
4343                 /* 28 bits */                           /* [7] */
4344                 BTF_TYPE_INT_ENC(0, 0, 0, 28, 4),
4345                 /* uint8_t[8] */                        /* [8] */
4346                 BTF_TYPE_ARRAY_ENC(9, 1, 8),
4347                 /* typedef unsigned char uint8_t */     /* [9] */
4348                 BTF_TYPEDEF_ENC(NAME_TBD, 1),
4349                 /* typedef unsigned short uint16_t */   /* [10] */
4350                 BTF_TYPEDEF_ENC(NAME_TBD, 2),
4351                 /* typedef unsigned int uint32_t */     /* [11] */
4352                 BTF_TYPEDEF_ENC(NAME_TBD, 3),
4353                 /* typedef int int32_t */               /* [12] */
4354                 BTF_TYPEDEF_ENC(NAME_TBD, 4),
4355                 /* typedef unsigned long long uint64_t *//* [13] */
4356                 BTF_TYPEDEF_ENC(NAME_TBD, 5),
4357                 /* union (anon) */                      /* [14] */
4358                 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_UNION, 0, 2), 8),
4359                 BTF_MEMBER_ENC(NAME_TBD, 13, 0),/* uint64_t ui64; */
4360                 BTF_MEMBER_ENC(NAME_TBD, 8, 0), /* uint8_t ui8a[8]; */
4361                 /* enum (anon) */                       /* [15] */
4362                 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_ENUM, 0, 4), 4),
4363                 BTF_ENUM_ENC(NAME_TBD, 0),
4364                 BTF_ENUM_ENC(NAME_TBD, 1),
4365                 BTF_ENUM_ENC(NAME_TBD, 2),
4366                 BTF_ENUM_ENC(NAME_TBD, 3),
4367                 /* struct pprint_mapv */                /* [16] */
4368                 BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 11), 40),
4369                 BTF_MEMBER_ENC(NAME_TBD, 11, 0),        /* uint32_t ui32 */
4370                 BTF_MEMBER_ENC(NAME_TBD, 10, 32),       /* uint16_t ui16 */
4371                 BTF_MEMBER_ENC(NAME_TBD, 12, 64),       /* int32_t si32 */
4372                 BTF_MEMBER_ENC(NAME_TBD, 6, 96),        /* unused_bits2a */
4373                 BTF_MEMBER_ENC(NAME_TBD, 7, 98),        /* bits28 */
4374                 BTF_MEMBER_ENC(NAME_TBD, 6, 126),       /* unused_bits2b */
4375                 BTF_MEMBER_ENC(0, 14, 128),             /* union (anon) */
4376                 BTF_MEMBER_ENC(NAME_TBD, 15, 192),      /* aenum */
4377                 BTF_MEMBER_ENC(NAME_TBD, 11, 224),      /* uint32_t ui32b */
4378                 BTF_MEMBER_ENC(NAME_TBD, 6, 256),       /* bits2c */
4379                 BTF_MEMBER_ENC(NAME_TBD, 17, 264),      /* si8_4 */
4380                 BTF_TYPE_ARRAY_ENC(18, 1, 2),           /* [17] */
4381                 BTF_TYPE_ARRAY_ENC(1, 1, 2),            /* [18] */
4382                 BTF_END_RAW,
4383         },
4384         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\0si8_4"),
4385         .key_size = sizeof(unsigned int),
4386         .value_size = sizeof(struct pprint_mapv),
4387         .key_type_id = 3,       /* unsigned int */
4388         .value_type_id = 16,    /* struct pprint_mapv */
4389         .max_entries = 128 * 1024,
4390 },
4391
4392 {
4393         /* this type will have the same type as the
4394          * first .raw_types definition, but struct type will
4395          * be encoded with kind_flag set.
4396          */
4397         .raw_types = {
4398                 /* unsighed char */                     /* [1] */
4399                 BTF_TYPE_INT_ENC(NAME_TBD, 0, 0, 8, 1),
4400                 /* unsigned short */                    /* [2] */
4401                 BTF_TYPE_INT_ENC(NAME_TBD, 0, 0, 16, 2),
4402                 /* unsigned int */                      /* [3] */
4403                 BTF_TYPE_INT_ENC(NAME_TBD, 0, 0, 32, 4),
4404                 /* int */                               /* [4] */
4405                 BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),
4406                 /* unsigned long long */                /* [5] */
4407                 BTF_TYPE_INT_ENC(NAME_TBD, 0, 0, 64, 8),
4408                 BTF_TYPE_INT_ENC(0, 0, 0, 32, 4),       /* [6] */
4409                 BTF_TYPE_INT_ENC(0, 0, 0, 32, 4),       /* [7] */
4410                 /* uint8_t[8] */                        /* [8] */
4411                 BTF_TYPE_ARRAY_ENC(9, 1, 8),
4412                 /* typedef unsigned char uint8_t */     /* [9] */
4413                 BTF_TYPEDEF_ENC(NAME_TBD, 1),
4414                 /* typedef unsigned short uint16_t */   /* [10] */
4415                 BTF_TYPEDEF_ENC(NAME_TBD, 2),
4416                 /* typedef unsigned int uint32_t */     /* [11] */
4417                 BTF_TYPEDEF_ENC(NAME_TBD, 3),
4418                 /* typedef int int32_t */               /* [12] */
4419                 BTF_TYPEDEF_ENC(NAME_TBD, 4),
4420                 /* typedef unsigned long long uint64_t *//* [13] */
4421                 BTF_TYPEDEF_ENC(NAME_TBD, 5),
4422                 /* union (anon) */                      /* [14] */
4423                 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_UNION, 0, 2), 8),
4424                 BTF_MEMBER_ENC(NAME_TBD, 13, 0),/* uint64_t ui64; */
4425                 BTF_MEMBER_ENC(NAME_TBD, 8, 0), /* uint8_t ui8a[8]; */
4426                 /* enum (anon) */                       /* [15] */
4427                 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_ENUM, 0, 4), 4),
4428                 BTF_ENUM_ENC(NAME_TBD, 0),
4429                 BTF_ENUM_ENC(NAME_TBD, 1),
4430                 BTF_ENUM_ENC(NAME_TBD, 2),
4431                 BTF_ENUM_ENC(NAME_TBD, 3),
4432                 /* struct pprint_mapv */                /* [16] */
4433                 BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 1, 11), 40),
4434                 BTF_MEMBER_ENC(NAME_TBD, 11, BTF_MEMBER_OFFSET(0, 0)),  /* uint32_t ui32 */
4435                 BTF_MEMBER_ENC(NAME_TBD, 10, BTF_MEMBER_OFFSET(0, 32)), /* uint16_t ui16 */
4436                 BTF_MEMBER_ENC(NAME_TBD, 12, BTF_MEMBER_OFFSET(0, 64)), /* int32_t si32 */
4437                 BTF_MEMBER_ENC(NAME_TBD, 6, BTF_MEMBER_OFFSET(2, 96)),  /* unused_bits2a */
4438                 BTF_MEMBER_ENC(NAME_TBD, 7, BTF_MEMBER_OFFSET(28, 98)), /* bits28 */
4439                 BTF_MEMBER_ENC(NAME_TBD, 6, BTF_MEMBER_OFFSET(2, 126)), /* unused_bits2b */
4440                 BTF_MEMBER_ENC(0, 14, BTF_MEMBER_OFFSET(0, 128)),       /* union (anon) */
4441                 BTF_MEMBER_ENC(NAME_TBD, 15, BTF_MEMBER_OFFSET(0, 192)),        /* aenum */
4442                 BTF_MEMBER_ENC(NAME_TBD, 11, BTF_MEMBER_OFFSET(0, 224)),        /* uint32_t ui32b */
4443                 BTF_MEMBER_ENC(NAME_TBD, 6, BTF_MEMBER_OFFSET(2, 256)), /* bits2c */
4444                 BTF_MEMBER_ENC(NAME_TBD, 17, 264),      /* si8_4 */
4445                 BTF_TYPE_ARRAY_ENC(18, 1, 2),           /* [17] */
4446                 BTF_TYPE_ARRAY_ENC(1, 1, 2),            /* [18] */
4447                 BTF_END_RAW,
4448         },
4449         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\0si8_4"),
4450         .key_size = sizeof(unsigned int),
4451         .value_size = sizeof(struct pprint_mapv),
4452         .key_type_id = 3,       /* unsigned int */
4453         .value_type_id = 16,    /* struct pprint_mapv */
4454         .max_entries = 128 * 1024,
4455 },
4456
4457 {
4458         /* this type will have the same layout as the
4459          * first .raw_types definition. The struct type will
4460          * be encoded with kind_flag set, bitfield members
4461          * are added typedef/const/volatile, and bitfield members
4462          * will have both int and enum types.
4463          */
4464         .raw_types = {
4465                 /* unsighed char */                     /* [1] */
4466                 BTF_TYPE_INT_ENC(NAME_TBD, 0, 0, 8, 1),
4467                 /* unsigned short */                    /* [2] */
4468                 BTF_TYPE_INT_ENC(NAME_TBD, 0, 0, 16, 2),
4469                 /* unsigned int */                      /* [3] */
4470                 BTF_TYPE_INT_ENC(NAME_TBD, 0, 0, 32, 4),
4471                 /* int */                               /* [4] */
4472                 BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),
4473                 /* unsigned long long */                /* [5] */
4474                 BTF_TYPE_INT_ENC(NAME_TBD, 0, 0, 64, 8),
4475                 BTF_TYPE_INT_ENC(0, 0, 0, 32, 4),       /* [6] */
4476                 BTF_TYPE_INT_ENC(0, 0, 0, 32, 4),       /* [7] */
4477                 /* uint8_t[8] */                        /* [8] */
4478                 BTF_TYPE_ARRAY_ENC(9, 1, 8),
4479                 /* typedef unsigned char uint8_t */     /* [9] */
4480                 BTF_TYPEDEF_ENC(NAME_TBD, 1),
4481                 /* typedef unsigned short uint16_t */   /* [10] */
4482                 BTF_TYPEDEF_ENC(NAME_TBD, 2),
4483                 /* typedef unsigned int uint32_t */     /* [11] */
4484                 BTF_TYPEDEF_ENC(NAME_TBD, 3),
4485                 /* typedef int int32_t */               /* [12] */
4486                 BTF_TYPEDEF_ENC(NAME_TBD, 4),
4487                 /* typedef unsigned long long uint64_t *//* [13] */
4488                 BTF_TYPEDEF_ENC(NAME_TBD, 5),
4489                 /* union (anon) */                      /* [14] */
4490                 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_UNION, 0, 2), 8),
4491                 BTF_MEMBER_ENC(NAME_TBD, 13, 0),/* uint64_t ui64; */
4492                 BTF_MEMBER_ENC(NAME_TBD, 8, 0), /* uint8_t ui8a[8]; */
4493                 /* enum (anon) */                       /* [15] */
4494                 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_ENUM, 0, 4), 4),
4495                 BTF_ENUM_ENC(NAME_TBD, 0),
4496                 BTF_ENUM_ENC(NAME_TBD, 1),
4497                 BTF_ENUM_ENC(NAME_TBD, 2),
4498                 BTF_ENUM_ENC(NAME_TBD, 3),
4499                 /* struct pprint_mapv */                /* [16] */
4500                 BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 1, 11), 40),
4501                 BTF_MEMBER_ENC(NAME_TBD, 11, BTF_MEMBER_OFFSET(0, 0)),  /* uint32_t ui32 */
4502                 BTF_MEMBER_ENC(NAME_TBD, 10, BTF_MEMBER_OFFSET(0, 32)), /* uint16_t ui16 */
4503                 BTF_MEMBER_ENC(NAME_TBD, 12, BTF_MEMBER_OFFSET(0, 64)), /* int32_t si32 */
4504                 BTF_MEMBER_ENC(NAME_TBD, 17, BTF_MEMBER_OFFSET(2, 96)), /* unused_bits2a */
4505                 BTF_MEMBER_ENC(NAME_TBD, 7, BTF_MEMBER_OFFSET(28, 98)), /* bits28 */
4506                 BTF_MEMBER_ENC(NAME_TBD, 19, BTF_MEMBER_OFFSET(2, 126)),/* unused_bits2b */
4507                 BTF_MEMBER_ENC(0, 14, BTF_MEMBER_OFFSET(0, 128)),       /* union (anon) */
4508                 BTF_MEMBER_ENC(NAME_TBD, 15, BTF_MEMBER_OFFSET(0, 192)),        /* aenum */
4509                 BTF_MEMBER_ENC(NAME_TBD, 11, BTF_MEMBER_OFFSET(0, 224)),        /* uint32_t ui32b */
4510                 BTF_MEMBER_ENC(NAME_TBD, 17, BTF_MEMBER_OFFSET(2, 256)),        /* bits2c */
4511                 BTF_MEMBER_ENC(NAME_TBD, 20, BTF_MEMBER_OFFSET(0, 264)),        /* si8_4 */
4512                 /* typedef unsigned int ___int */       /* [17] */
4513                 BTF_TYPEDEF_ENC(NAME_TBD, 18),
4514                 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_VOLATILE, 0, 0), 6),      /* [18] */
4515                 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_CONST, 0, 0), 15),        /* [19] */
4516                 BTF_TYPE_ARRAY_ENC(21, 1, 2),                                   /* [20] */
4517                 BTF_TYPE_ARRAY_ENC(1, 1, 2),                                    /* [21] */
4518                 BTF_END_RAW,
4519         },
4520         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\0si8_4"),
4521         .key_size = sizeof(unsigned int),
4522         .value_size = sizeof(struct pprint_mapv),
4523         .key_type_id = 3,       /* unsigned int */
4524         .value_type_id = 16,    /* struct pprint_mapv */
4525         .max_entries = 128 * 1024,
4526 },
4527
4528 #ifdef __SIZEOF_INT128__
4529 {
4530         /* test int128 */
4531         .raw_types = {
4532                 /* unsigned int */                              /* [1] */
4533                 BTF_TYPE_INT_ENC(NAME_TBD, 0, 0, 32, 4),
4534                 /* __int128 */                                  /* [2] */
4535                 BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 128, 16),
4536                 /* unsigned __int128 */                         /* [3] */
4537                 BTF_TYPE_INT_ENC(NAME_TBD, 0, 0, 128, 16),
4538                 /* struct pprint_mapv_int128 */                 /* [4] */
4539                 BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 1, 5), 64),
4540                 BTF_MEMBER_ENC(NAME_TBD, 2, BTF_MEMBER_OFFSET(0, 0)),           /* si128a */
4541                 BTF_MEMBER_ENC(NAME_TBD, 2, BTF_MEMBER_OFFSET(0, 128)),         /* si128b */
4542                 BTF_MEMBER_ENC(NAME_TBD, 3, BTF_MEMBER_OFFSET(3, 256)),         /* bits3 */
4543                 BTF_MEMBER_ENC(NAME_TBD, 3, BTF_MEMBER_OFFSET(80, 259)),        /* bits80 */
4544                 BTF_MEMBER_ENC(NAME_TBD, 3, BTF_MEMBER_OFFSET(0, 384)),         /* ui128 */
4545                 BTF_END_RAW,
4546         },
4547         BTF_STR_SEC("\0unsigned int\0__int128\0unsigned __int128\0pprint_mapv_int128\0si128a\0si128b\0bits3\0bits80\0ui128"),
4548         .key_size = sizeof(unsigned int),
4549         .value_size = sizeof(struct pprint_mapv_int128),
4550         .key_type_id = 1,
4551         .value_type_id = 4,
4552         .max_entries = 128 * 1024,
4553         .mapv_kind = PPRINT_MAPV_KIND_INT128,
4554 },
4555 #endif
4556
4557 };
4558
4559 static struct btf_pprint_test_meta {
4560         const char *descr;
4561         enum bpf_map_type map_type;
4562         const char *map_name;
4563         bool ordered_map;
4564         bool lossless_map;
4565         bool percpu_map;
4566 } pprint_tests_meta[] = {
4567 {
4568         .descr = "BTF pretty print array",
4569         .map_type = BPF_MAP_TYPE_ARRAY,
4570         .map_name = "pprint_test_array",
4571         .ordered_map = true,
4572         .lossless_map = true,
4573         .percpu_map = false,
4574 },
4575
4576 {
4577         .descr = "BTF pretty print hash",
4578         .map_type = BPF_MAP_TYPE_HASH,
4579         .map_name = "pprint_test_hash",
4580         .ordered_map = false,
4581         .lossless_map = true,
4582         .percpu_map = false,
4583 },
4584
4585 {
4586         .descr = "BTF pretty print lru hash",
4587         .map_type = BPF_MAP_TYPE_LRU_HASH,
4588         .map_name = "pprint_test_lru_hash",
4589         .ordered_map = false,
4590         .lossless_map = false,
4591         .percpu_map = false,
4592 },
4593
4594 {
4595         .descr = "BTF pretty print percpu array",
4596         .map_type = BPF_MAP_TYPE_PERCPU_ARRAY,
4597         .map_name = "pprint_test_percpu_array",
4598         .ordered_map = true,
4599         .lossless_map = true,
4600         .percpu_map = true,
4601 },
4602
4603 {
4604         .descr = "BTF pretty print percpu hash",
4605         .map_type = BPF_MAP_TYPE_PERCPU_HASH,
4606         .map_name = "pprint_test_percpu_hash",
4607         .ordered_map = false,
4608         .lossless_map = true,
4609         .percpu_map = true,
4610 },
4611
4612 {
4613         .descr = "BTF pretty print lru percpu hash",
4614         .map_type = BPF_MAP_TYPE_LRU_PERCPU_HASH,
4615         .map_name = "pprint_test_lru_percpu_hash",
4616         .ordered_map = false,
4617         .lossless_map = false,
4618         .percpu_map = true,
4619 },
4620
4621 };
4622
4623 static size_t get_pprint_mapv_size(enum pprint_mapv_kind_t mapv_kind)
4624 {
4625         if (mapv_kind == PPRINT_MAPV_KIND_BASIC)
4626                 return sizeof(struct pprint_mapv);
4627
4628 #ifdef __SIZEOF_INT128__
4629         if (mapv_kind == PPRINT_MAPV_KIND_INT128)
4630                 return sizeof(struct pprint_mapv_int128);
4631 #endif
4632
4633         assert(0);
4634 }
4635
4636 static void set_pprint_mapv(enum pprint_mapv_kind_t mapv_kind,
4637                             void *mapv, uint32_t i,
4638                             int num_cpus, int rounded_value_size)
4639 {
4640         int cpu;
4641
4642         if (mapv_kind == PPRINT_MAPV_KIND_BASIC) {
4643                 struct pprint_mapv *v = mapv;
4644
4645                 for (cpu = 0; cpu < num_cpus; cpu++) {
4646                         v->ui32 = i + cpu;
4647                         v->si32 = -i;
4648                         v->unused_bits2a = 3;
4649                         v->bits28 = i;
4650                         v->unused_bits2b = 3;
4651                         v->ui64 = i;
4652                         v->aenum = i & 0x03;
4653                         v->ui32b = 4;
4654                         v->bits2c = 1;
4655                         v->si8_4[0][0] = (cpu + i) & 0xff;
4656                         v->si8_4[0][1] = (cpu + i + 1) & 0xff;
4657                         v->si8_4[1][0] = (cpu + i + 2) & 0xff;
4658                         v->si8_4[1][1] = (cpu + i + 3) & 0xff;
4659                         v = (void *)v + rounded_value_size;
4660                 }
4661         }
4662
4663 #ifdef __SIZEOF_INT128__
4664         if (mapv_kind == PPRINT_MAPV_KIND_INT128) {
4665                 struct pprint_mapv_int128 *v = mapv;
4666
4667                 for (cpu = 0; cpu < num_cpus; cpu++) {
4668                         v->si128a = i;
4669                         v->si128b = -i;
4670                         v->bits3 = i & 0x07;
4671                         v->bits80 = (((unsigned __int128)1) << 64) + i;
4672                         v->ui128 = (((unsigned __int128)2) << 64) + i;
4673                         v = (void *)v + rounded_value_size;
4674                 }
4675         }
4676 #endif
4677 }
4678
4679 ssize_t get_pprint_expected_line(enum pprint_mapv_kind_t mapv_kind,
4680                                  char *expected_line, ssize_t line_size,
4681                                  bool percpu_map, unsigned int next_key,
4682                                  int cpu, void *mapv)
4683 {
4684         ssize_t nexpected_line = -1;
4685
4686         if (mapv_kind == PPRINT_MAPV_KIND_BASIC) {
4687                 struct pprint_mapv *v = mapv;
4688
4689                 nexpected_line = snprintf(expected_line, line_size,
4690                                           "%s%u: {%u,0,%d,0x%x,0x%x,0x%x,"
4691                                           "{%lu|[%u,%u,%u,%u,%u,%u,%u,%u]},%s,"
4692                                           "%u,0x%x,[[%d,%d],[%d,%d]]}\n",
4693                                           percpu_map ? "\tcpu" : "",
4694                                           percpu_map ? cpu : next_key,
4695                                           v->ui32, v->si32,
4696                                           v->unused_bits2a,
4697                                           v->bits28,
4698                                           v->unused_bits2b,
4699                                           v->ui64,
4700                                           v->ui8a[0], v->ui8a[1],
4701                                           v->ui8a[2], v->ui8a[3],
4702                                           v->ui8a[4], v->ui8a[5],
4703                                           v->ui8a[6], v->ui8a[7],
4704                                           pprint_enum_str[v->aenum],
4705                                           v->ui32b,
4706                                           v->bits2c,
4707                                           v->si8_4[0][0], v->si8_4[0][1],
4708                                           v->si8_4[1][0], v->si8_4[1][1]);
4709         }
4710
4711 #ifdef __SIZEOF_INT128__
4712         if (mapv_kind == PPRINT_MAPV_KIND_INT128) {
4713                 struct pprint_mapv_int128 *v = mapv;
4714
4715                 nexpected_line = snprintf(expected_line, line_size,
4716                                           "%s%u: {0x%lx,0x%lx,0x%lx,"
4717                                           "0x%lx%016lx,0x%lx%016lx}\n",
4718                                           percpu_map ? "\tcpu" : "",
4719                                           percpu_map ? cpu : next_key,
4720                                           (uint64_t)v->si128a,
4721                                           (uint64_t)v->si128b,
4722                                           (uint64_t)v->bits3,
4723                                           (uint64_t)(v->bits80 >> 64),
4724                                           (uint64_t)v->bits80,
4725                                           (uint64_t)(v->ui128 >> 64),
4726                                           (uint64_t)v->ui128);
4727         }
4728 #endif
4729
4730         return nexpected_line;
4731 }
4732
4733 static int check_line(const char *expected_line, int nexpected_line,
4734                       int expected_line_len, const char *line)
4735 {
4736         if (CHECK(nexpected_line == expected_line_len,
4737                   "expected_line is too long"))
4738                 return -1;
4739
4740         if (strcmp(expected_line, line)) {
4741                 fprintf(stderr, "unexpected pprint output\n");
4742                 fprintf(stderr, "expected: %s", expected_line);
4743                 fprintf(stderr, "    read: %s", line);
4744                 return -1;
4745         }
4746
4747         return 0;
4748 }
4749
4750
4751 static int do_test_pprint(int test_num)
4752 {
4753         const struct btf_raw_test *test = &pprint_test_template[test_num];
4754         enum pprint_mapv_kind_t mapv_kind = test->mapv_kind;
4755         struct bpf_create_map_attr create_attr = {};
4756         bool ordered_map, lossless_map, percpu_map;
4757         int err, ret, num_cpus, rounded_value_size;
4758         unsigned int key, nr_read_elems;
4759         int map_fd = -1, btf_fd = -1;
4760         unsigned int raw_btf_size;
4761         char expected_line[255];
4762         FILE *pin_file = NULL;
4763         char pin_path[255];
4764         size_t line_len = 0;
4765         char *line = NULL;
4766         void *mapv = NULL;
4767         uint8_t *raw_btf;
4768         ssize_t nread;
4769
4770         fprintf(stderr, "%s(#%d)......", test->descr, test_num);
4771         raw_btf = btf_raw_create(&hdr_tmpl, test->raw_types,
4772                                  test->str_sec, test->str_sec_size,
4773                                  &raw_btf_size, NULL);
4774
4775         if (!raw_btf)
4776                 return -1;
4777
4778         *btf_log_buf = '\0';
4779         btf_fd = bpf_load_btf(raw_btf, raw_btf_size,
4780                               btf_log_buf, BTF_LOG_BUF_SIZE,
4781                               args.always_log);
4782         free(raw_btf);
4783
4784         if (CHECK(btf_fd == -1, "errno:%d", errno)) {
4785                 err = -1;
4786                 goto done;
4787         }
4788
4789         create_attr.name = test->map_name;
4790         create_attr.map_type = test->map_type;
4791         create_attr.key_size = test->key_size;
4792         create_attr.value_size = test->value_size;
4793         create_attr.max_entries = test->max_entries;
4794         create_attr.btf_fd = btf_fd;
4795         create_attr.btf_key_type_id = test->key_type_id;
4796         create_attr.btf_value_type_id = test->value_type_id;
4797
4798         map_fd = bpf_create_map_xattr(&create_attr);
4799         if (CHECK(map_fd == -1, "errno:%d", errno)) {
4800                 err = -1;
4801                 goto done;
4802         }
4803
4804         ret = snprintf(pin_path, sizeof(pin_path), "%s/%s",
4805                        "/sys/fs/bpf", test->map_name);
4806
4807         if (CHECK(ret == sizeof(pin_path), "pin_path %s/%s is too long",
4808                   "/sys/fs/bpf", test->map_name)) {
4809                 err = -1;
4810                 goto done;
4811         }
4812
4813         err = bpf_obj_pin(map_fd, pin_path);
4814         if (CHECK(err, "bpf_obj_pin(%s): errno:%d.", pin_path, errno))
4815                 goto done;
4816
4817         percpu_map = test->percpu_map;
4818         num_cpus = percpu_map ? bpf_num_possible_cpus() : 1;
4819         rounded_value_size = round_up(get_pprint_mapv_size(mapv_kind), 8);
4820         mapv = calloc(num_cpus, rounded_value_size);
4821         if (CHECK(!mapv, "mapv allocation failure")) {
4822                 err = -1;
4823                 goto done;
4824         }
4825
4826         for (key = 0; key < test->max_entries; key++) {
4827                 set_pprint_mapv(mapv_kind, mapv, key, num_cpus, rounded_value_size);
4828                 bpf_map_update_elem(map_fd, &key, mapv, 0);
4829         }
4830
4831         pin_file = fopen(pin_path, "r");
4832         if (CHECK(!pin_file, "fopen(%s): errno:%d", pin_path, errno)) {
4833                 err = -1;
4834                 goto done;
4835         }
4836
4837         /* Skip lines start with '#' */
4838         while ((nread = getline(&line, &line_len, pin_file)) > 0 &&
4839                *line == '#')
4840                 ;
4841
4842         if (CHECK(nread <= 0, "Unexpected EOF")) {
4843                 err = -1;
4844                 goto done;
4845         }
4846
4847         nr_read_elems = 0;
4848         ordered_map = test->ordered_map;
4849         lossless_map = test->lossless_map;
4850         do {
4851                 ssize_t nexpected_line;
4852                 unsigned int next_key;
4853                 void *cmapv;
4854                 int cpu;
4855
4856                 next_key = ordered_map ? nr_read_elems : atoi(line);
4857                 set_pprint_mapv(mapv_kind, mapv, next_key, num_cpus, rounded_value_size);
4858                 cmapv = mapv;
4859
4860                 for (cpu = 0; cpu < num_cpus; cpu++) {
4861                         if (percpu_map) {
4862                                 /* for percpu map, the format looks like:
4863                                  * <key>: {
4864                                  *      cpu0: <value_on_cpu0>
4865                                  *      cpu1: <value_on_cpu1>
4866                                  *      ...
4867                                  *      cpun: <value_on_cpun>
4868                                  * }
4869                                  *
4870                                  * let us verify the line containing the key here.
4871                                  */
4872                                 if (cpu == 0) {
4873                                         nexpected_line = snprintf(expected_line,
4874                                                                   sizeof(expected_line),
4875                                                                   "%u: {\n",
4876                                                                   next_key);
4877
4878                                         err = check_line(expected_line, nexpected_line,
4879                                                          sizeof(expected_line), line);
4880                                         if (err == -1)
4881                                                 goto done;
4882                                 }
4883
4884                                 /* read value@cpu */
4885                                 nread = getline(&line, &line_len, pin_file);
4886                                 if (nread < 0)
4887                                         break;
4888                         }
4889
4890                         nexpected_line = get_pprint_expected_line(mapv_kind, expected_line,
4891                                                                   sizeof(expected_line),
4892                                                                   percpu_map, next_key,
4893                                                                   cpu, cmapv);
4894                         err = check_line(expected_line, nexpected_line,
4895                                          sizeof(expected_line), line);
4896                         if (err == -1)
4897                                 goto done;
4898
4899                         cmapv = cmapv + rounded_value_size;
4900                 }
4901
4902                 if (percpu_map) {
4903                         /* skip the last bracket for the percpu map */
4904                         nread = getline(&line, &line_len, pin_file);
4905                         if (nread < 0)
4906                                 break;
4907                 }
4908
4909                 nread = getline(&line, &line_len, pin_file);
4910         } while (++nr_read_elems < test->max_entries && nread > 0);
4911
4912         if (lossless_map &&
4913             CHECK(nr_read_elems < test->max_entries,
4914                   "Unexpected EOF. nr_read_elems:%u test->max_entries:%u",
4915                   nr_read_elems, test->max_entries)) {
4916                 err = -1;
4917                 goto done;
4918         }
4919
4920         if (CHECK(nread > 0, "Unexpected extra pprint output: %s", line)) {
4921                 err = -1;
4922                 goto done;
4923         }
4924
4925         err = 0;
4926
4927 done:
4928         if (mapv)
4929                 free(mapv);
4930         if (!err)
4931                 fprintf(stderr, "OK");
4932         if (*btf_log_buf && (err || args.always_log))
4933                 fprintf(stderr, "\n%s", btf_log_buf);
4934         if (btf_fd != -1)
4935                 close(btf_fd);
4936         if (map_fd != -1)
4937                 close(map_fd);
4938         if (pin_file)
4939                 fclose(pin_file);
4940         unlink(pin_path);
4941         free(line);
4942
4943         return err;
4944 }
4945
4946 static int test_pprint(void)
4947 {
4948         unsigned int i;
4949         int err = 0;
4950
4951         /* test various maps with the first test template */
4952         for (i = 0; i < ARRAY_SIZE(pprint_tests_meta); i++) {
4953                 pprint_test_template[0].descr = pprint_tests_meta[i].descr;
4954                 pprint_test_template[0].map_type = pprint_tests_meta[i].map_type;
4955                 pprint_test_template[0].map_name = pprint_tests_meta[i].map_name;
4956                 pprint_test_template[0].ordered_map = pprint_tests_meta[i].ordered_map;
4957                 pprint_test_template[0].lossless_map = pprint_tests_meta[i].lossless_map;
4958                 pprint_test_template[0].percpu_map = pprint_tests_meta[i].percpu_map;
4959
4960                 err |= count_result(do_test_pprint(0));
4961         }
4962
4963         /* test rest test templates with the first map */
4964         for (i = 1; i < ARRAY_SIZE(pprint_test_template); i++) {
4965                 pprint_test_template[i].descr = pprint_tests_meta[0].descr;
4966                 pprint_test_template[i].map_type = pprint_tests_meta[0].map_type;
4967                 pprint_test_template[i].map_name = pprint_tests_meta[0].map_name;
4968                 pprint_test_template[i].ordered_map = pprint_tests_meta[0].ordered_map;
4969                 pprint_test_template[i].lossless_map = pprint_tests_meta[0].lossless_map;
4970                 pprint_test_template[i].percpu_map = pprint_tests_meta[0].percpu_map;
4971                 err |= count_result(do_test_pprint(i));
4972         }
4973
4974         return err;
4975 }
4976
4977 #define BPF_LINE_INFO_ENC(insn_off, file_off, line_off, line_num, line_col) \
4978         (insn_off), (file_off), (line_off), ((line_num) << 10 | ((line_col) & 0x3ff))
4979
4980 static struct prog_info_raw_test {
4981         const char *descr;
4982         const char *str_sec;
4983         const char *err_str;
4984         __u32 raw_types[MAX_NR_RAW_U32];
4985         __u32 str_sec_size;
4986         struct bpf_insn insns[MAX_INSNS];
4987         __u32 prog_type;
4988         __u32 func_info[MAX_SUBPROGS][2];
4989         __u32 func_info_rec_size;
4990         __u32 func_info_cnt;
4991         __u32 line_info[MAX_NR_RAW_U32];
4992         __u32 line_info_rec_size;
4993         __u32 nr_jited_ksyms;
4994         bool expected_prog_load_failure;
4995         __u32 dead_code_cnt;
4996         __u32 dead_code_mask;
4997         __u32 dead_func_cnt;
4998         __u32 dead_func_mask;
4999 } info_raw_tests[] = {
5000 {
5001         .descr = "func_type (main func + one sub)",
5002         .raw_types = {
5003                 BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),   /* [1] */
5004                 BTF_TYPE_INT_ENC(NAME_TBD, 0, 0, 32, 4),        /* [2] */
5005                 BTF_FUNC_PROTO_ENC(1, 2),                       /* [3] */
5006                         BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
5007                         BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 2),
5008                 BTF_FUNC_PROTO_ENC(1, 2),                       /* [4] */
5009                         BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 2),
5010                         BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
5011                 BTF_FUNC_ENC(NAME_TBD, 3),                      /* [5] */
5012                 BTF_FUNC_ENC(NAME_TBD, 4),                      /* [6] */
5013                 BTF_END_RAW,
5014         },
5015         .str_sec = "\0int\0unsigned int\0a\0b\0c\0d\0funcA\0funcB",
5016         .str_sec_size = sizeof("\0int\0unsigned int\0a\0b\0c\0d\0funcA\0funcB"),
5017         .insns = {
5018                 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2),
5019                 BPF_MOV64_IMM(BPF_REG_0, 1),
5020                 BPF_EXIT_INSN(),
5021                 BPF_MOV64_IMM(BPF_REG_0, 2),
5022                 BPF_EXIT_INSN(),
5023         },
5024         .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5025         .func_info = { {0, 5}, {3, 6} },
5026         .func_info_rec_size = 8,
5027         .func_info_cnt = 2,
5028         .line_info = { BTF_END_RAW },
5029 },
5030
5031 {
5032         .descr = "func_type (Incorrect func_info_rec_size)",
5033         .raw_types = {
5034                 BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),   /* [1] */
5035                 BTF_TYPE_INT_ENC(NAME_TBD, 0, 0, 32, 4),        /* [2] */
5036                 BTF_FUNC_PROTO_ENC(1, 2),                       /* [3] */
5037                         BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
5038                         BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 2),
5039                 BTF_FUNC_PROTO_ENC(1, 2),                       /* [4] */
5040                         BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 2),
5041                         BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
5042                 BTF_FUNC_ENC(NAME_TBD, 3),                      /* [5] */
5043                 BTF_FUNC_ENC(NAME_TBD, 4),                      /* [6] */
5044                 BTF_END_RAW,
5045         },
5046         .str_sec = "\0int\0unsigned int\0a\0b\0c\0d\0funcA\0funcB",
5047         .str_sec_size = sizeof("\0int\0unsigned int\0a\0b\0c\0d\0funcA\0funcB"),
5048         .insns = {
5049                 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2),
5050                 BPF_MOV64_IMM(BPF_REG_0, 1),
5051                 BPF_EXIT_INSN(),
5052                 BPF_MOV64_IMM(BPF_REG_0, 2),
5053                 BPF_EXIT_INSN(),
5054         },
5055         .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5056         .func_info = { {0, 5}, {3, 6} },
5057         .func_info_rec_size = 4,
5058         .func_info_cnt = 2,
5059         .line_info = { BTF_END_RAW },
5060         .expected_prog_load_failure = true,
5061 },
5062
5063 {
5064         .descr = "func_type (Incorrect func_info_cnt)",
5065         .raw_types = {
5066                 BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),   /* [1] */
5067                 BTF_TYPE_INT_ENC(NAME_TBD, 0, 0, 32, 4),        /* [2] */
5068                 BTF_FUNC_PROTO_ENC(1, 2),                       /* [3] */
5069                         BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
5070                         BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 2),
5071                 BTF_FUNC_PROTO_ENC(1, 2),                       /* [4] */
5072                         BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 2),
5073                         BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
5074                 BTF_FUNC_ENC(NAME_TBD, 3),                      /* [5] */
5075                 BTF_FUNC_ENC(NAME_TBD, 4),                      /* [6] */
5076                 BTF_END_RAW,
5077         },
5078         .str_sec = "\0int\0unsigned int\0a\0b\0c\0d\0funcA\0funcB",
5079         .str_sec_size = sizeof("\0int\0unsigned int\0a\0b\0c\0d\0funcA\0funcB"),
5080         .insns = {
5081                 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2),
5082                 BPF_MOV64_IMM(BPF_REG_0, 1),
5083                 BPF_EXIT_INSN(),
5084                 BPF_MOV64_IMM(BPF_REG_0, 2),
5085                 BPF_EXIT_INSN(),
5086         },
5087         .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5088         .func_info = { {0, 5}, {3, 6} },
5089         .func_info_rec_size = 8,
5090         .func_info_cnt = 1,
5091         .line_info = { BTF_END_RAW },
5092         .expected_prog_load_failure = true,
5093 },
5094
5095 {
5096         .descr = "func_type (Incorrect bpf_func_info.insn_off)",
5097         .raw_types = {
5098                 BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),   /* [1] */
5099                 BTF_TYPE_INT_ENC(NAME_TBD, 0, 0, 32, 4),        /* [2] */
5100                 BTF_FUNC_PROTO_ENC(1, 2),                       /* [3] */
5101                         BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
5102                         BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 2),
5103                 BTF_FUNC_PROTO_ENC(1, 2),                       /* [4] */
5104                         BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 2),
5105                         BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
5106                 BTF_FUNC_ENC(NAME_TBD, 3),                      /* [5] */
5107                 BTF_FUNC_ENC(NAME_TBD, 4),                      /* [6] */
5108                 BTF_END_RAW,
5109         },
5110         .str_sec = "\0int\0unsigned int\0a\0b\0c\0d\0funcA\0funcB",
5111         .str_sec_size = sizeof("\0int\0unsigned int\0a\0b\0c\0d\0funcA\0funcB"),
5112         .insns = {
5113                 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2),
5114                 BPF_MOV64_IMM(BPF_REG_0, 1),
5115                 BPF_EXIT_INSN(),
5116                 BPF_MOV64_IMM(BPF_REG_0, 2),
5117                 BPF_EXIT_INSN(),
5118         },
5119         .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5120         .func_info = { {0, 5}, {2, 6} },
5121         .func_info_rec_size = 8,
5122         .func_info_cnt = 2,
5123         .line_info = { BTF_END_RAW },
5124         .expected_prog_load_failure = true,
5125 },
5126
5127 {
5128         .descr = "line_info (No subprog)",
5129         .raw_types = {
5130                 BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),   /* [1] */
5131                 BTF_END_RAW,
5132         },
5133         BTF_STR_SEC("\0int\0int a=1;\0int b=2;\0return a + b;\0return a + b;"),
5134         .insns = {
5135                 BPF_MOV64_IMM(BPF_REG_0, 1),
5136                 BPF_MOV64_IMM(BPF_REG_1, 2),
5137                 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
5138                 BPF_EXIT_INSN(),
5139         },
5140         .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5141         .func_info_cnt = 0,
5142         .line_info = {
5143                 BPF_LINE_INFO_ENC(0, 0, NAME_TBD, 1, 10),
5144                 BPF_LINE_INFO_ENC(1, 0, NAME_TBD, 2, 9),
5145                 BPF_LINE_INFO_ENC(2, 0, NAME_TBD, 3, 8),
5146                 BPF_LINE_INFO_ENC(3, 0, NAME_TBD, 4, 7),
5147                 BTF_END_RAW,
5148         },
5149         .line_info_rec_size = sizeof(struct bpf_line_info),
5150         .nr_jited_ksyms = 1,
5151 },
5152
5153 {
5154         .descr = "line_info (No subprog. insn_off >= prog->len)",
5155         .raw_types = {
5156                 BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),   /* [1] */
5157                 BTF_END_RAW,
5158         },
5159         BTF_STR_SEC("\0int\0int a=1;\0int b=2;\0return a + b;\0return a + b;"),
5160         .insns = {
5161                 BPF_MOV64_IMM(BPF_REG_0, 1),
5162                 BPF_MOV64_IMM(BPF_REG_1, 2),
5163                 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
5164                 BPF_EXIT_INSN(),
5165         },
5166         .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5167         .func_info_cnt = 0,
5168         .line_info = {
5169                 BPF_LINE_INFO_ENC(0, 0, NAME_TBD, 1, 10),
5170                 BPF_LINE_INFO_ENC(1, 0, NAME_TBD, 2, 9),
5171                 BPF_LINE_INFO_ENC(2, 0, NAME_TBD, 3, 8),
5172                 BPF_LINE_INFO_ENC(3, 0, NAME_TBD, 4, 7),
5173                 BPF_LINE_INFO_ENC(4, 0, 0, 5, 6),
5174                 BTF_END_RAW,
5175         },
5176         .line_info_rec_size = sizeof(struct bpf_line_info),
5177         .nr_jited_ksyms = 1,
5178         .err_str = "line_info[4].insn_off",
5179         .expected_prog_load_failure = true,
5180 },
5181
5182 {
5183         .descr = "line_info (Zero bpf insn code)",
5184         .raw_types = {
5185                 BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),   /* [1] */
5186                 BTF_TYPE_INT_ENC(NAME_TBD, 0, 0, 64, 8),        /* [2] */
5187                 BTF_TYPEDEF_ENC(NAME_TBD, 2),                   /* [3] */
5188                 BTF_END_RAW,
5189         },
5190         BTF_STR_SEC("\0int\0unsigned long\0u64\0u64 a=1;\0return a;"),
5191         .insns = {
5192                 BPF_LD_IMM64(BPF_REG_0, 1),
5193                 BPF_EXIT_INSN(),
5194         },
5195         .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5196         .func_info_cnt = 0,
5197         .line_info = {
5198                 BPF_LINE_INFO_ENC(0, 0, NAME_TBD, 1, 10),
5199                 BPF_LINE_INFO_ENC(1, 0, 0, 2, 9),
5200                 BPF_LINE_INFO_ENC(2, 0, NAME_TBD, 3, 8),
5201                 BTF_END_RAW,
5202         },
5203         .line_info_rec_size = sizeof(struct bpf_line_info),
5204         .nr_jited_ksyms = 1,
5205         .err_str = "Invalid insn code at line_info[1]",
5206         .expected_prog_load_failure = true,
5207 },
5208
5209 {
5210         .descr = "line_info (No subprog. zero tailing line_info",
5211         .raw_types = {
5212                 BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),   /* [1] */
5213                 BTF_END_RAW,
5214         },
5215         BTF_STR_SEC("\0int\0int a=1;\0int b=2;\0return a + b;\0return a + b;"),
5216         .insns = {
5217                 BPF_MOV64_IMM(BPF_REG_0, 1),
5218                 BPF_MOV64_IMM(BPF_REG_1, 2),
5219                 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
5220                 BPF_EXIT_INSN(),
5221         },
5222         .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5223         .func_info_cnt = 0,
5224         .line_info = {
5225                 BPF_LINE_INFO_ENC(0, 0, NAME_TBD, 1, 10), 0,
5226                 BPF_LINE_INFO_ENC(1, 0, NAME_TBD, 2, 9), 0,
5227                 BPF_LINE_INFO_ENC(2, 0, NAME_TBD, 3, 8), 0,
5228                 BPF_LINE_INFO_ENC(3, 0, NAME_TBD, 4, 7), 0,
5229                 BTF_END_RAW,
5230         },
5231         .line_info_rec_size = sizeof(struct bpf_line_info) + sizeof(__u32),
5232         .nr_jited_ksyms = 1,
5233 },
5234
5235 {
5236         .descr = "line_info (No subprog. nonzero tailing line_info)",
5237         .raw_types = {
5238                 BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),   /* [1] */
5239                 BTF_END_RAW,
5240         },
5241         BTF_STR_SEC("\0int\0int a=1;\0int b=2;\0return a + b;\0return a + b;"),
5242         .insns = {
5243                 BPF_MOV64_IMM(BPF_REG_0, 1),
5244                 BPF_MOV64_IMM(BPF_REG_1, 2),
5245                 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
5246                 BPF_EXIT_INSN(),
5247         },
5248         .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5249         .func_info_cnt = 0,
5250         .line_info = {
5251                 BPF_LINE_INFO_ENC(0, 0, NAME_TBD, 1, 10), 0,
5252                 BPF_LINE_INFO_ENC(1, 0, NAME_TBD, 2, 9), 0,
5253                 BPF_LINE_INFO_ENC(2, 0, NAME_TBD, 3, 8), 0,
5254                 BPF_LINE_INFO_ENC(3, 0, NAME_TBD, 4, 7), 1,
5255                 BTF_END_RAW,
5256         },
5257         .line_info_rec_size = sizeof(struct bpf_line_info) + sizeof(__u32),
5258         .nr_jited_ksyms = 1,
5259         .err_str = "nonzero tailing record in line_info",
5260         .expected_prog_load_failure = true,
5261 },
5262
5263 {
5264         .descr = "line_info (subprog)",
5265         .raw_types = {
5266                 BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),   /* [1] */
5267                 BTF_END_RAW,
5268         },
5269         BTF_STR_SEC("\0int\0int a=1+1;\0return func(a);\0b+=1;\0return b;"),
5270         .insns = {
5271                 BPF_MOV64_IMM(BPF_REG_2, 1),
5272                 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, 1),
5273                 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
5274                 BPF_CALL_REL(1),
5275                 BPF_EXIT_INSN(),
5276                 BPF_MOV64_REG(BPF_REG_0, BPF_REG_1),
5277                 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 1),
5278                 BPF_EXIT_INSN(),
5279         },
5280         .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5281         .func_info_cnt = 0,
5282         .line_info = {
5283                 BPF_LINE_INFO_ENC(0, 0, NAME_TBD, 1, 10),
5284                 BPF_LINE_INFO_ENC(2, 0, NAME_TBD, 2, 9),
5285                 BPF_LINE_INFO_ENC(5, 0, NAME_TBD, 3, 8),
5286                 BPF_LINE_INFO_ENC(7, 0, NAME_TBD, 4, 7),
5287                 BTF_END_RAW,
5288         },
5289         .line_info_rec_size = sizeof(struct bpf_line_info),
5290         .nr_jited_ksyms = 2,
5291 },
5292
5293 {
5294         .descr = "line_info (subprog + func_info)",
5295         .raw_types = {
5296                 BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),   /* [1] */
5297                 BTF_FUNC_PROTO_ENC(1, 1),                       /* [2] */
5298                         BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
5299                 BTF_FUNC_ENC(NAME_TBD, 2),                      /* [3] */
5300                 BTF_FUNC_ENC(NAME_TBD, 2),                      /* [4] */
5301                 BTF_END_RAW,
5302         },
5303         BTF_STR_SEC("\0int\0x\0sub\0main\0int a=1+1;\0return func(a);\0b+=1;\0return b;"),
5304         .insns = {
5305                 BPF_MOV64_IMM(BPF_REG_2, 1),
5306                 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, 1),
5307                 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
5308                 BPF_CALL_REL(1),
5309                 BPF_EXIT_INSN(),
5310                 BPF_MOV64_REG(BPF_REG_0, BPF_REG_1),
5311                 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 1),
5312                 BPF_EXIT_INSN(),
5313         },
5314         .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5315         .func_info_cnt = 2,
5316         .func_info_rec_size = 8,
5317         .func_info = { {0, 4}, {5, 3} },
5318         .line_info = {
5319                 BPF_LINE_INFO_ENC(0, 0, NAME_TBD, 1, 10),
5320                 BPF_LINE_INFO_ENC(2, 0, NAME_TBD, 2, 9),
5321                 BPF_LINE_INFO_ENC(5, 0, NAME_TBD, 3, 8),
5322                 BPF_LINE_INFO_ENC(7, 0, NAME_TBD, 4, 7),
5323                 BTF_END_RAW,
5324         },
5325         .line_info_rec_size = sizeof(struct bpf_line_info),
5326         .nr_jited_ksyms = 2,
5327 },
5328
5329 {
5330         .descr = "line_info (subprog. missing 1st func line info)",
5331         .raw_types = {
5332                 BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),   /* [1] */
5333                 BTF_END_RAW,
5334         },
5335         BTF_STR_SEC("\0int\0int a=1+1;\0return func(a);\0b+=1;\0return b;"),
5336         .insns = {
5337                 BPF_MOV64_IMM(BPF_REG_2, 1),
5338                 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, 1),
5339                 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
5340                 BPF_CALL_REL(1),
5341                 BPF_EXIT_INSN(),
5342                 BPF_MOV64_REG(BPF_REG_0, BPF_REG_1),
5343                 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 1),
5344                 BPF_EXIT_INSN(),
5345         },
5346         .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5347         .func_info_cnt = 0,
5348         .line_info = {
5349                 BPF_LINE_INFO_ENC(1, 0, NAME_TBD, 1, 10),
5350                 BPF_LINE_INFO_ENC(2, 0, NAME_TBD, 2, 9),
5351                 BPF_LINE_INFO_ENC(5, 0, NAME_TBD, 3, 8),
5352                 BPF_LINE_INFO_ENC(7, 0, NAME_TBD, 4, 7),
5353                 BTF_END_RAW,
5354         },
5355         .line_info_rec_size = sizeof(struct bpf_line_info),
5356         .nr_jited_ksyms = 2,
5357         .err_str = "missing bpf_line_info for func#0",
5358         .expected_prog_load_failure = true,
5359 },
5360
5361 {
5362         .descr = "line_info (subprog. missing 2nd func line info)",
5363         .raw_types = {
5364                 BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),   /* [1] */
5365                 BTF_END_RAW,
5366         },
5367         BTF_STR_SEC("\0int\0int a=1+1;\0return func(a);\0b+=1;\0return b;"),
5368         .insns = {
5369                 BPF_MOV64_IMM(BPF_REG_2, 1),
5370                 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, 1),
5371                 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
5372                 BPF_CALL_REL(1),
5373                 BPF_EXIT_INSN(),
5374                 BPF_MOV64_REG(BPF_REG_0, BPF_REG_1),
5375                 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 1),
5376                 BPF_EXIT_INSN(),
5377         },
5378         .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5379         .func_info_cnt = 0,
5380         .line_info = {
5381                 BPF_LINE_INFO_ENC(0, 0, NAME_TBD, 1, 10),
5382                 BPF_LINE_INFO_ENC(2, 0, NAME_TBD, 2, 9),
5383                 BPF_LINE_INFO_ENC(6, 0, NAME_TBD, 3, 8),
5384                 BPF_LINE_INFO_ENC(7, 0, NAME_TBD, 4, 7),
5385                 BTF_END_RAW,
5386         },
5387         .line_info_rec_size = sizeof(struct bpf_line_info),
5388         .nr_jited_ksyms = 2,
5389         .err_str = "missing bpf_line_info for func#1",
5390         .expected_prog_load_failure = true,
5391 },
5392
5393 {
5394         .descr = "line_info (subprog. unordered insn offset)",
5395         .raw_types = {
5396                 BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),   /* [1] */
5397                 BTF_END_RAW,
5398         },
5399         BTF_STR_SEC("\0int\0int a=1+1;\0return func(a);\0b+=1;\0return b;"),
5400         .insns = {
5401                 BPF_MOV64_IMM(BPF_REG_2, 1),
5402                 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, 1),
5403                 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
5404                 BPF_CALL_REL(1),
5405                 BPF_EXIT_INSN(),
5406                 BPF_MOV64_REG(BPF_REG_0, BPF_REG_1),
5407                 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 1),
5408                 BPF_EXIT_INSN(),
5409         },
5410         .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5411         .func_info_cnt = 0,
5412         .line_info = {
5413                 BPF_LINE_INFO_ENC(0, 0, NAME_TBD, 1, 10),
5414                 BPF_LINE_INFO_ENC(5, 0, NAME_TBD, 2, 9),
5415                 BPF_LINE_INFO_ENC(2, 0, NAME_TBD, 3, 8),
5416                 BPF_LINE_INFO_ENC(7, 0, NAME_TBD, 4, 7),
5417                 BTF_END_RAW,
5418         },
5419         .line_info_rec_size = sizeof(struct bpf_line_info),
5420         .nr_jited_ksyms = 2,
5421         .err_str = "Invalid line_info[2].insn_off",
5422         .expected_prog_load_failure = true,
5423 },
5424
5425 {
5426         .descr = "line_info (dead start)",
5427         .raw_types = {
5428                 BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),   /* [1] */
5429                 BTF_END_RAW,
5430         },
5431         BTF_STR_SEC("\0int\0/* dead jmp */\0int a=1;\0int b=2;\0return a + b;\0return a + b;"),
5432         .insns = {
5433                 BPF_JMP_IMM(BPF_JA, 0, 0, 0),
5434                 BPF_MOV64_IMM(BPF_REG_0, 1),
5435                 BPF_MOV64_IMM(BPF_REG_1, 2),
5436                 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
5437                 BPF_EXIT_INSN(),
5438         },
5439         .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5440         .func_info_cnt = 0,
5441         .line_info = {
5442                 BPF_LINE_INFO_ENC(0, 0, NAME_TBD, 1, 10),
5443                 BPF_LINE_INFO_ENC(1, 0, NAME_TBD, 2, 9),
5444                 BPF_LINE_INFO_ENC(2, 0, NAME_TBD, 3, 8),
5445                 BPF_LINE_INFO_ENC(3, 0, NAME_TBD, 4, 7),
5446                 BPF_LINE_INFO_ENC(4, 0, NAME_TBD, 5, 6),
5447                 BTF_END_RAW,
5448         },
5449         .line_info_rec_size = sizeof(struct bpf_line_info),
5450         .nr_jited_ksyms = 1,
5451         .dead_code_cnt = 1,
5452         .dead_code_mask = 0x01,
5453 },
5454
5455 {
5456         .descr = "line_info (dead end)",
5457         .raw_types = {
5458                 BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),   /* [1] */
5459                 BTF_END_RAW,
5460         },
5461         BTF_STR_SEC("\0int\0int a=1;\0int b=2;\0return a + b;\0/* dead jmp */\0return a + b;\0/* dead exit */"),
5462         .insns = {
5463                 BPF_MOV64_IMM(BPF_REG_0, 1),
5464                 BPF_MOV64_IMM(BPF_REG_1, 2),
5465                 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
5466                 BPF_JMP_IMM(BPF_JGE, BPF_REG_0, 10, 1),
5467                 BPF_EXIT_INSN(),
5468                 BPF_EXIT_INSN(),
5469         },
5470         .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5471         .func_info_cnt = 0,
5472         .line_info = {
5473                 BPF_LINE_INFO_ENC(0, 0, NAME_TBD, 1, 12),
5474                 BPF_LINE_INFO_ENC(1, 0, NAME_TBD, 2, 11),
5475                 BPF_LINE_INFO_ENC(2, 0, NAME_TBD, 3, 10),
5476                 BPF_LINE_INFO_ENC(3, 0, NAME_TBD, 4, 9),
5477                 BPF_LINE_INFO_ENC(4, 0, NAME_TBD, 5, 8),
5478                 BPF_LINE_INFO_ENC(5, 0, NAME_TBD, 6, 7),
5479                 BTF_END_RAW,
5480         },
5481         .line_info_rec_size = sizeof(struct bpf_line_info),
5482         .nr_jited_ksyms = 1,
5483         .dead_code_cnt = 2,
5484         .dead_code_mask = 0x28,
5485 },
5486
5487 {
5488         .descr = "line_info (dead code + subprog + func_info)",
5489         .raw_types = {
5490                 BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),   /* [1] */
5491                 BTF_FUNC_PROTO_ENC(1, 1),                       /* [2] */
5492                         BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
5493                 BTF_FUNC_ENC(NAME_TBD, 2),                      /* [3] */
5494                 BTF_FUNC_ENC(NAME_TBD, 2),                      /* [4] */
5495                 BTF_END_RAW,
5496         },
5497         BTF_STR_SEC("\0int\0x\0sub\0main\0int a=1+1;\0/* dead jmp */"
5498                     "\0/* dead */\0/* dead */\0/* dead */\0/* dead */"
5499                     "\0/* dead */\0/* dead */\0/* dead */\0/* dead */"
5500                     "\0return func(a);\0b+=1;\0return b;"),
5501         .insns = {
5502                 BPF_MOV64_IMM(BPF_REG_2, 1),
5503                 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, 1),
5504                 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
5505                 BPF_JMP_IMM(BPF_JGE, BPF_REG_2, 0, 8),
5506                 BPF_MOV64_IMM(BPF_REG_2, 1),
5507                 BPF_MOV64_IMM(BPF_REG_2, 1),
5508                 BPF_MOV64_IMM(BPF_REG_2, 1),
5509                 BPF_MOV64_IMM(BPF_REG_2, 1),
5510                 BPF_MOV64_IMM(BPF_REG_2, 1),
5511                 BPF_MOV64_IMM(BPF_REG_2, 1),
5512                 BPF_MOV64_IMM(BPF_REG_2, 1),
5513                 BPF_MOV64_IMM(BPF_REG_2, 1),
5514                 BPF_CALL_REL(1),
5515                 BPF_EXIT_INSN(),
5516                 BPF_MOV64_REG(BPF_REG_0, BPF_REG_1),
5517                 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 1),
5518                 BPF_EXIT_INSN(),
5519         },
5520         .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5521         .func_info_cnt = 2,
5522         .func_info_rec_size = 8,
5523         .func_info = { {0, 4}, {14, 3} },
5524         .line_info = {
5525                 BPF_LINE_INFO_ENC(0, 0, NAME_TBD, 1, 10),
5526                 BPF_LINE_INFO_ENC(3, 0, NAME_TBD, 1, 10),
5527                 BPF_LINE_INFO_ENC(4, 0, NAME_TBD, 1, 10),
5528                 BPF_LINE_INFO_ENC(5, 0, NAME_TBD, 1, 10),
5529                 BPF_LINE_INFO_ENC(6, 0, NAME_TBD, 1, 10),
5530                 BPF_LINE_INFO_ENC(7, 0, NAME_TBD, 1, 10),
5531                 BPF_LINE_INFO_ENC(8, 0, NAME_TBD, 1, 10),
5532                 BPF_LINE_INFO_ENC(9, 0, NAME_TBD, 1, 10),
5533                 BPF_LINE_INFO_ENC(10, 0, NAME_TBD, 1, 10),
5534                 BPF_LINE_INFO_ENC(11, 0, NAME_TBD, 2, 9),
5535                 BPF_LINE_INFO_ENC(12, 0, NAME_TBD, 2, 9),
5536                 BPF_LINE_INFO_ENC(14, 0, NAME_TBD, 3, 8),
5537                 BPF_LINE_INFO_ENC(16, 0, NAME_TBD, 4, 7),
5538                 BTF_END_RAW,
5539         },
5540         .line_info_rec_size = sizeof(struct bpf_line_info),
5541         .nr_jited_ksyms = 2,
5542         .dead_code_cnt = 9,
5543         .dead_code_mask = 0x3fe,
5544 },
5545
5546 {
5547         .descr = "line_info (dead subprog)",
5548         .raw_types = {
5549                 BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),   /* [1] */
5550                 BTF_FUNC_PROTO_ENC(1, 1),                       /* [2] */
5551                         BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
5552                 BTF_FUNC_ENC(NAME_TBD, 2),                      /* [3] */
5553                 BTF_FUNC_ENC(NAME_TBD, 2),                      /* [4] */
5554                 BTF_FUNC_ENC(NAME_TBD, 2),                      /* [5] */
5555                 BTF_END_RAW,
5556         },
5557         BTF_STR_SEC("\0int\0x\0dead\0main\0func\0int a=1+1;\0/* live call */"
5558                     "\0return 0;\0return 0;\0/* dead */\0/* dead */"
5559                     "\0/* dead */\0return bla + 1;\0return bla + 1;"
5560                     "\0return bla + 1;\0return func(a);\0b+=1;\0return b;"),
5561         .insns = {
5562                 BPF_MOV64_IMM(BPF_REG_2, 1),
5563                 BPF_JMP_IMM(BPF_JGE, BPF_REG_2, 0, 1),
5564                 BPF_CALL_REL(3),
5565                 BPF_CALL_REL(5),
5566                 BPF_MOV64_IMM(BPF_REG_0, 0),
5567                 BPF_EXIT_INSN(),
5568                 BPF_MOV64_IMM(BPF_REG_0, 0),
5569                 BPF_CALL_REL(1),
5570                 BPF_EXIT_INSN(),
5571                 BPF_MOV64_REG(BPF_REG_0, 2),
5572                 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 1),
5573                 BPF_EXIT_INSN(),
5574         },
5575         .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5576         .func_info_cnt = 3,
5577         .func_info_rec_size = 8,
5578                 .func_info = { {0, 4}, {6, 3}, {9, 5} },
5579         .line_info = {
5580                 BPF_LINE_INFO_ENC(0, 0, NAME_TBD, 1, 10),
5581                 BPF_LINE_INFO_ENC(3, 0, NAME_TBD, 1, 10),
5582                 BPF_LINE_INFO_ENC(4, 0, NAME_TBD, 1, 10),
5583                 BPF_LINE_INFO_ENC(5, 0, NAME_TBD, 1, 10),
5584                 BPF_LINE_INFO_ENC(6, 0, NAME_TBD, 1, 10),
5585                 BPF_LINE_INFO_ENC(7, 0, NAME_TBD, 1, 10),
5586                 BPF_LINE_INFO_ENC(8, 0, NAME_TBD, 1, 10),
5587                 BPF_LINE_INFO_ENC(9, 0, NAME_TBD, 1, 10),
5588                 BPF_LINE_INFO_ENC(10, 0, NAME_TBD, 1, 10),
5589                 BPF_LINE_INFO_ENC(11, 0, NAME_TBD, 2, 9),
5590                 BTF_END_RAW,
5591         },
5592         .line_info_rec_size = sizeof(struct bpf_line_info),
5593         .nr_jited_ksyms = 2,
5594         .dead_code_cnt = 3,
5595         .dead_code_mask = 0x70,
5596         .dead_func_cnt = 1,
5597         .dead_func_mask = 0x2,
5598 },
5599
5600 {
5601         .descr = "line_info (dead last subprog)",
5602         .raw_types = {
5603                 BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),   /* [1] */
5604                 BTF_FUNC_PROTO_ENC(1, 1),                       /* [2] */
5605                         BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
5606                 BTF_FUNC_ENC(NAME_TBD, 2),                      /* [3] */
5607                 BTF_FUNC_ENC(NAME_TBD, 2),                      /* [5] */
5608                 BTF_END_RAW,
5609         },
5610         BTF_STR_SEC("\0int\0x\0dead\0main\0int a=1+1;\0/* live call */"
5611                     "\0return 0;\0/* dead */\0/* dead */"),
5612         .insns = {
5613                 BPF_MOV64_IMM(BPF_REG_2, 1),
5614                 BPF_JMP_IMM(BPF_JGE, BPF_REG_2, 0, 1),
5615                 BPF_CALL_REL(2),
5616                 BPF_MOV64_IMM(BPF_REG_0, 0),
5617                 BPF_EXIT_INSN(),
5618                 BPF_MOV64_IMM(BPF_REG_0, 0),
5619                 BPF_EXIT_INSN(),
5620         },
5621         .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5622         .func_info_cnt = 2,
5623         .func_info_rec_size = 8,
5624                 .func_info = { {0, 4}, {5, 3} },
5625         .line_info = {
5626                 BPF_LINE_INFO_ENC(0, 0, NAME_TBD, 1, 10),
5627                 BPF_LINE_INFO_ENC(3, 0, NAME_TBD, 1, 10),
5628                 BPF_LINE_INFO_ENC(4, 0, NAME_TBD, 1, 10),
5629                 BPF_LINE_INFO_ENC(5, 0, NAME_TBD, 1, 10),
5630                 BPF_LINE_INFO_ENC(6, 0, NAME_TBD, 1, 10),
5631                 BTF_END_RAW,
5632         },
5633         .line_info_rec_size = sizeof(struct bpf_line_info),
5634         .nr_jited_ksyms = 1,
5635         .dead_code_cnt = 2,
5636         .dead_code_mask = 0x18,
5637         .dead_func_cnt = 1,
5638         .dead_func_mask = 0x2,
5639 },
5640
5641 {
5642         .descr = "line_info (dead subprog + dead start)",
5643         .raw_types = {
5644                 BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),   /* [1] */
5645                 BTF_FUNC_PROTO_ENC(1, 1),                       /* [2] */
5646                         BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
5647                 BTF_FUNC_ENC(NAME_TBD, 2),                      /* [3] */
5648                 BTF_FUNC_ENC(NAME_TBD, 2),                      /* [4] */
5649                 BTF_FUNC_ENC(NAME_TBD, 2),                      /* [5] */
5650                 BTF_END_RAW,
5651         },
5652         BTF_STR_SEC("\0int\0x\0dead\0main\0func\0int a=1+1;\0/* dead */"
5653                     "\0return 0;\0return 0;\0return 0;"
5654                     "\0/* dead */\0/* dead */\0/* dead */\0/* dead */"
5655                     "\0return b + 1;\0return b + 1;\0return b + 1;"),
5656         .insns = {
5657                 BPF_JMP_IMM(BPF_JA, 0, 0, 0),
5658                 BPF_MOV64_IMM(BPF_REG_2, 1),
5659                 BPF_JMP_IMM(BPF_JGE, BPF_REG_2, 0, 1),
5660                 BPF_CALL_REL(3),
5661                 BPF_CALL_REL(5),
5662                 BPF_MOV64_IMM(BPF_REG_0, 0),
5663                 BPF_EXIT_INSN(),
5664                 BPF_MOV64_IMM(BPF_REG_0, 0),
5665                 BPF_CALL_REL(1),
5666                 BPF_EXIT_INSN(),
5667                 BPF_JMP_IMM(BPF_JA, 0, 0, 0),
5668                 BPF_MOV64_REG(BPF_REG_0, 2),
5669                 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 1),
5670                 BPF_EXIT_INSN(),
5671         },
5672         .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5673         .func_info_cnt = 3,
5674         .func_info_rec_size = 8,
5675                 .func_info = { {0, 4}, {7, 3}, {10, 5} },
5676         .line_info = {
5677                 BPF_LINE_INFO_ENC(0, 0, NAME_TBD, 1, 10),
5678                 BPF_LINE_INFO_ENC(3, 0, NAME_TBD, 1, 10),
5679                 BPF_LINE_INFO_ENC(4, 0, NAME_TBD, 1, 10),
5680                 BPF_LINE_INFO_ENC(5, 0, NAME_TBD, 1, 10),
5681                 BPF_LINE_INFO_ENC(6, 0, NAME_TBD, 1, 10),
5682                 BPF_LINE_INFO_ENC(7, 0, NAME_TBD, 1, 10),
5683                 BPF_LINE_INFO_ENC(8, 0, NAME_TBD, 1, 10),
5684                 BPF_LINE_INFO_ENC(9, 0, NAME_TBD, 1, 10),
5685                 BPF_LINE_INFO_ENC(10, 0, NAME_TBD, 1, 10),
5686                 BPF_LINE_INFO_ENC(11, 0, NAME_TBD, 2, 9),
5687                 BPF_LINE_INFO_ENC(12, 0, NAME_TBD, 2, 9),
5688                 BPF_LINE_INFO_ENC(13, 0, NAME_TBD, 2, 9),
5689                 BTF_END_RAW,
5690         },
5691         .line_info_rec_size = sizeof(struct bpf_line_info),
5692         .nr_jited_ksyms = 2,
5693         .dead_code_cnt = 5,
5694         .dead_code_mask = 0x1e2,
5695         .dead_func_cnt = 1,
5696         .dead_func_mask = 0x2,
5697 },
5698
5699 {
5700         .descr = "line_info (dead subprog + dead start w/ move)",
5701         .raw_types = {
5702                 BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),   /* [1] */
5703                 BTF_FUNC_PROTO_ENC(1, 1),                       /* [2] */
5704                         BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
5705                 BTF_FUNC_ENC(NAME_TBD, 2),                      /* [3] */
5706                 BTF_FUNC_ENC(NAME_TBD, 2),                      /* [4] */
5707                 BTF_FUNC_ENC(NAME_TBD, 2),                      /* [5] */
5708                 BTF_END_RAW,
5709         },
5710         BTF_STR_SEC("\0int\0x\0dead\0main\0func\0int a=1+1;\0/* live call */"
5711                     "\0return 0;\0return 0;\0/* dead */\0/* dead */"
5712                     "\0/* dead */\0return bla + 1;\0return bla + 1;"
5713                     "\0return bla + 1;\0return func(a);\0b+=1;\0return b;"),
5714         .insns = {
5715                 BPF_MOV64_IMM(BPF_REG_2, 1),
5716                 BPF_JMP_IMM(BPF_JGE, BPF_REG_2, 0, 1),
5717                 BPF_CALL_REL(3),
5718                 BPF_CALL_REL(5),
5719                 BPF_MOV64_IMM(BPF_REG_0, 0),
5720                 BPF_EXIT_INSN(),
5721                 BPF_MOV64_IMM(BPF_REG_0, 0),
5722                 BPF_CALL_REL(1),
5723                 BPF_EXIT_INSN(),
5724                 BPF_JMP_IMM(BPF_JA, 0, 0, 0),
5725                 BPF_MOV64_REG(BPF_REG_0, 2),
5726                 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 1),
5727                 BPF_EXIT_INSN(),
5728         },
5729         .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5730         .func_info_cnt = 3,
5731         .func_info_rec_size = 8,
5732                 .func_info = { {0, 4}, {6, 3}, {9, 5} },
5733         .line_info = {
5734                 BPF_LINE_INFO_ENC(0, 0, NAME_TBD, 1, 10),
5735                 BPF_LINE_INFO_ENC(3, 0, NAME_TBD, 1, 10),
5736                 BPF_LINE_INFO_ENC(4, 0, NAME_TBD, 1, 10),
5737                 BPF_LINE_INFO_ENC(5, 0, NAME_TBD, 1, 10),
5738                 BPF_LINE_INFO_ENC(6, 0, NAME_TBD, 1, 10),
5739                 BPF_LINE_INFO_ENC(7, 0, NAME_TBD, 1, 10),
5740                 BPF_LINE_INFO_ENC(8, 0, NAME_TBD, 1, 10),
5741                 BPF_LINE_INFO_ENC(9, 0, NAME_TBD, 1, 10),
5742                 BPF_LINE_INFO_ENC(11, 0, NAME_TBD, 1, 10),
5743                 BPF_LINE_INFO_ENC(12, 0, NAME_TBD, 2, 9),
5744                 BTF_END_RAW,
5745         },
5746         .line_info_rec_size = sizeof(struct bpf_line_info),
5747         .nr_jited_ksyms = 2,
5748         .dead_code_cnt = 3,
5749         .dead_code_mask = 0x70,
5750         .dead_func_cnt = 1,
5751         .dead_func_mask = 0x2,
5752 },
5753
5754 {
5755         .descr = "line_info (dead end + subprog start w/ no linfo)",
5756         .raw_types = {
5757                 BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),   /* [1] */
5758                 BTF_FUNC_PROTO_ENC(1, 1),                       /* [2] */
5759                         BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
5760                 BTF_FUNC_ENC(NAME_TBD, 2),                      /* [3] */
5761                 BTF_FUNC_ENC(NAME_TBD, 2),                      /* [4] */
5762                 BTF_END_RAW,
5763         },
5764         BTF_STR_SEC("\0int\0x\0main\0func\0/* main linfo */\0/* func linfo */"),
5765         .insns = {
5766                 BPF_MOV64_IMM(BPF_REG_0, 0),
5767                 BPF_JMP_IMM(BPF_JGE, BPF_REG_0, 1, 3),
5768                 BPF_CALL_REL(3),
5769                 BPF_MOV64_IMM(BPF_REG_0, 0),
5770                 BPF_EXIT_INSN(),
5771                 BPF_EXIT_INSN(),
5772                 BPF_JMP_IMM(BPF_JA, 0, 0, 0),
5773                 BPF_EXIT_INSN(),
5774         },
5775         .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5776         .func_info_cnt = 2,
5777         .func_info_rec_size = 8,
5778         .func_info = { {0, 3}, {6, 4}, },
5779         .line_info = {
5780                 BPF_LINE_INFO_ENC(0, 0, NAME_TBD, 1, 10),
5781                 BPF_LINE_INFO_ENC(6, 0, NAME_TBD, 1, 10),
5782                 BTF_END_RAW,
5783         },
5784         .line_info_rec_size = sizeof(struct bpf_line_info),
5785         .nr_jited_ksyms = 2,
5786 },
5787
5788 };
5789
5790 static size_t probe_prog_length(const struct bpf_insn *fp)
5791 {
5792         size_t len;
5793
5794         for (len = MAX_INSNS - 1; len > 0; --len)
5795                 if (fp[len].code != 0 || fp[len].imm != 0)
5796                         break;
5797         return len + 1;
5798 }
5799
5800 static __u32 *patch_name_tbd(const __u32 *raw_u32,
5801                              const char *str, __u32 str_off,
5802                              unsigned int str_sec_size,
5803                              unsigned int *ret_size)
5804 {
5805         int i, raw_u32_size = get_raw_sec_size(raw_u32);
5806         const char *end_str = str + str_sec_size;
5807         const char *next_str = str + str_off;
5808         __u32 *new_u32 = NULL;
5809
5810         if (raw_u32_size == -1)
5811                 return ERR_PTR(-EINVAL);
5812
5813         if (!raw_u32_size) {
5814                 *ret_size = 0;
5815                 return NULL;
5816         }
5817
5818         new_u32 = malloc(raw_u32_size);
5819         if (!new_u32)
5820                 return ERR_PTR(-ENOMEM);
5821
5822         for (i = 0; i < raw_u32_size / sizeof(raw_u32[0]); i++) {
5823                 if (raw_u32[i] == NAME_TBD) {
5824                         next_str = get_next_str(next_str, end_str);
5825                         if (CHECK(!next_str, "Error in getting next_str\n")) {
5826                                 free(new_u32);
5827                                 return ERR_PTR(-EINVAL);
5828                         }
5829                         new_u32[i] = next_str - str;
5830                         next_str += strlen(next_str);
5831                 } else {
5832                         new_u32[i] = raw_u32[i];
5833                 }
5834         }
5835
5836         *ret_size = raw_u32_size;
5837         return new_u32;
5838 }
5839
5840 static int test_get_finfo(const struct prog_info_raw_test *test,
5841                           int prog_fd)
5842 {
5843         struct bpf_prog_info info = {};
5844         struct bpf_func_info *finfo;
5845         __u32 info_len, rec_size, i;
5846         void *func_info = NULL;
5847         __u32 nr_func_info;
5848         int err;
5849
5850         /* get necessary lens */
5851         info_len = sizeof(struct bpf_prog_info);
5852         err = bpf_obj_get_info_by_fd(prog_fd, &info, &info_len);
5853         if (CHECK(err == -1, "invalid get info (1st) errno:%d", errno)) {
5854                 fprintf(stderr, "%s\n", btf_log_buf);
5855                 return -1;
5856         }
5857         nr_func_info = test->func_info_cnt - test->dead_func_cnt;
5858         if (CHECK(info.nr_func_info != nr_func_info,
5859                   "incorrect info.nr_func_info (1st) %d",
5860                   info.nr_func_info)) {
5861                 return -1;
5862         }
5863
5864         rec_size = info.func_info_rec_size;
5865         if (CHECK(rec_size != sizeof(struct bpf_func_info),
5866                   "incorrect info.func_info_rec_size (1st) %d", rec_size)) {
5867                 return -1;
5868         }
5869
5870         if (!info.nr_func_info)
5871                 return 0;
5872
5873         func_info = malloc(info.nr_func_info * rec_size);
5874         if (CHECK(!func_info, "out of memory"))
5875                 return -1;
5876
5877         /* reset info to only retrieve func_info related data */
5878         memset(&info, 0, sizeof(info));
5879         info.nr_func_info = nr_func_info;
5880         info.func_info_rec_size = rec_size;
5881         info.func_info = ptr_to_u64(func_info);
5882         err = bpf_obj_get_info_by_fd(prog_fd, &info, &info_len);
5883         if (CHECK(err == -1, "invalid get info (2nd) errno:%d", errno)) {
5884                 fprintf(stderr, "%s\n", btf_log_buf);
5885                 err = -1;
5886                 goto done;
5887         }
5888         if (CHECK(info.nr_func_info != nr_func_info,
5889                   "incorrect info.nr_func_info (2nd) %d",
5890                   info.nr_func_info)) {
5891                 err = -1;
5892                 goto done;
5893         }
5894         if (CHECK(info.func_info_rec_size != rec_size,
5895                   "incorrect info.func_info_rec_size (2nd) %d",
5896                   info.func_info_rec_size)) {
5897                 err = -1;
5898                 goto done;
5899         }
5900
5901         finfo = func_info;
5902         for (i = 0; i < nr_func_info; i++) {
5903                 if (test->dead_func_mask & (1 << i))
5904                         continue;
5905                 if (CHECK(finfo->type_id != test->func_info[i][1],
5906                           "incorrect func_type %u expected %u",
5907                           finfo->type_id, test->func_info[i][1])) {
5908                         err = -1;
5909                         goto done;
5910                 }
5911                 finfo = (void *)finfo + rec_size;
5912         }
5913
5914         err = 0;
5915
5916 done:
5917         free(func_info);
5918         return err;
5919 }
5920
5921 static int test_get_linfo(const struct prog_info_raw_test *test,
5922                           const void *patched_linfo,
5923                           __u32 cnt, int prog_fd)
5924 {
5925         __u32 i, info_len, nr_jited_ksyms, nr_jited_func_lens;
5926         __u64 *jited_linfo = NULL, *jited_ksyms = NULL;
5927         __u32 rec_size, jited_rec_size, jited_cnt;
5928         struct bpf_line_info *linfo = NULL;
5929         __u32 cur_func_len, ksyms_found;
5930         struct bpf_prog_info info = {};
5931         __u32 *jited_func_lens = NULL;
5932         __u64 cur_func_ksyms;
5933         __u32 dead_insns;
5934         int err;
5935
5936         jited_cnt = cnt;
5937         rec_size = sizeof(*linfo);
5938         jited_rec_size = sizeof(*jited_linfo);
5939         if (test->nr_jited_ksyms)
5940                 nr_jited_ksyms = test->nr_jited_ksyms;
5941         else
5942                 nr_jited_ksyms = test->func_info_cnt - test->dead_func_cnt;
5943         nr_jited_func_lens = nr_jited_ksyms;
5944
5945         info_len = sizeof(struct bpf_prog_info);
5946         err = bpf_obj_get_info_by_fd(prog_fd, &info, &info_len);
5947         if (CHECK(err == -1, "err:%d errno:%d", err, errno)) {
5948                 err = -1;
5949                 goto done;
5950         }
5951
5952         if (!info.jited_prog_len) {
5953                 /* prog is not jited */
5954                 jited_cnt = 0;
5955                 nr_jited_ksyms = 1;
5956                 nr_jited_func_lens = 1;
5957         }
5958
5959         if (CHECK(info.nr_line_info != cnt ||
5960                   info.nr_jited_line_info != jited_cnt ||
5961                   info.nr_jited_ksyms != nr_jited_ksyms ||
5962                   info.nr_jited_func_lens != nr_jited_func_lens ||
5963                   (!info.nr_line_info && info.nr_jited_line_info),
5964                   "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)",
5965                   info.nr_line_info, cnt,
5966                   info.nr_jited_line_info, jited_cnt,
5967                   info.nr_jited_ksyms, nr_jited_ksyms,
5968                   info.nr_jited_func_lens, nr_jited_func_lens)) {
5969                 err = -1;
5970                 goto done;
5971         }
5972
5973         if (CHECK(info.line_info_rec_size != sizeof(struct bpf_line_info) ||
5974                   info.jited_line_info_rec_size != sizeof(__u64),
5975                   "info: line_info_rec_size:%u(userspace expected:%u) jited_line_info_rec_size:%u(userspace expected:%u)",
5976                   info.line_info_rec_size, rec_size,
5977                   info.jited_line_info_rec_size, jited_rec_size)) {
5978                 err = -1;
5979                 goto done;
5980         }
5981
5982         if (!cnt)
5983                 return 0;
5984
5985         rec_size = info.line_info_rec_size;
5986         jited_rec_size = info.jited_line_info_rec_size;
5987
5988         memset(&info, 0, sizeof(info));
5989
5990         linfo = calloc(cnt, rec_size);
5991         if (CHECK(!linfo, "!linfo")) {
5992                 err = -1;
5993                 goto done;
5994         }
5995         info.nr_line_info = cnt;
5996         info.line_info_rec_size = rec_size;
5997         info.line_info = ptr_to_u64(linfo);
5998
5999         if (jited_cnt) {
6000                 jited_linfo = calloc(jited_cnt, jited_rec_size);
6001                 jited_ksyms = calloc(nr_jited_ksyms, sizeof(*jited_ksyms));
6002                 jited_func_lens = calloc(nr_jited_func_lens,
6003                                          sizeof(*jited_func_lens));
6004                 if (CHECK(!jited_linfo || !jited_ksyms || !jited_func_lens,
6005                           "jited_linfo:%p jited_ksyms:%p jited_func_lens:%p",
6006                           jited_linfo, jited_ksyms, jited_func_lens)) {
6007                         err = -1;
6008                         goto done;
6009                 }
6010
6011                 info.nr_jited_line_info = jited_cnt;
6012                 info.jited_line_info_rec_size = jited_rec_size;
6013                 info.jited_line_info = ptr_to_u64(jited_linfo);
6014                 info.nr_jited_ksyms = nr_jited_ksyms;
6015                 info.jited_ksyms = ptr_to_u64(jited_ksyms);
6016                 info.nr_jited_func_lens = nr_jited_func_lens;
6017                 info.jited_func_lens = ptr_to_u64(jited_func_lens);
6018         }
6019
6020         err = bpf_obj_get_info_by_fd(prog_fd, &info, &info_len);
6021
6022         /*
6023          * Only recheck the info.*line_info* fields.
6024          * Other fields are not the concern of this test.
6025          */
6026         if (CHECK(err == -1 ||
6027                   info.nr_line_info != cnt ||
6028                   (jited_cnt && !info.jited_line_info) ||
6029                   info.nr_jited_line_info != jited_cnt ||
6030                   info.line_info_rec_size != rec_size ||
6031                   info.jited_line_info_rec_size != jited_rec_size,
6032                   "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",
6033                   err, errno,
6034                   info.nr_line_info, cnt,
6035                   info.nr_jited_line_info, jited_cnt,
6036                   info.line_info_rec_size, rec_size,
6037                   info.jited_line_info_rec_size, jited_rec_size,
6038                   (void *)(long)info.line_info,
6039                   (void *)(long)info.jited_line_info)) {
6040                 err = -1;
6041                 goto done;
6042         }
6043
6044         dead_insns = 0;
6045         while (test->dead_code_mask & (1 << dead_insns))
6046                 dead_insns++;
6047
6048         CHECK(linfo[0].insn_off, "linfo[0].insn_off:%u",
6049               linfo[0].insn_off);
6050         for (i = 1; i < cnt; i++) {
6051                 const struct bpf_line_info *expected_linfo;
6052
6053                 while (test->dead_code_mask & (1 << (i + dead_insns)))
6054                         dead_insns++;
6055
6056                 expected_linfo = patched_linfo +
6057                         ((i + dead_insns) * test->line_info_rec_size);
6058                 if (CHECK(linfo[i].insn_off <= linfo[i - 1].insn_off,
6059                           "linfo[%u].insn_off:%u <= linfo[%u].insn_off:%u",
6060                           i, linfo[i].insn_off,
6061                           i - 1, linfo[i - 1].insn_off)) {
6062                         err = -1;
6063                         goto done;
6064                 }
6065                 if (CHECK(linfo[i].file_name_off != expected_linfo->file_name_off ||
6066                           linfo[i].line_off != expected_linfo->line_off ||
6067                           linfo[i].line_col != expected_linfo->line_col,
6068                           "linfo[%u] (%u, %u, %u) != (%u, %u, %u)", i,
6069                           linfo[i].file_name_off,
6070                           linfo[i].line_off,
6071                           linfo[i].line_col,
6072                           expected_linfo->file_name_off,
6073                           expected_linfo->line_off,
6074                           expected_linfo->line_col)) {
6075                         err = -1;
6076                         goto done;
6077                 }
6078         }
6079
6080         if (!jited_cnt) {
6081                 fprintf(stderr, "not jited. skipping jited_line_info check. ");
6082                 err = 0;
6083                 goto done;
6084         }
6085
6086         if (CHECK(jited_linfo[0] != jited_ksyms[0],
6087                   "jited_linfo[0]:%lx != jited_ksyms[0]:%lx",
6088                   (long)(jited_linfo[0]), (long)(jited_ksyms[0]))) {
6089                 err = -1;
6090                 goto done;
6091         }
6092
6093         ksyms_found = 1;
6094         cur_func_len = jited_func_lens[0];
6095         cur_func_ksyms = jited_ksyms[0];
6096         for (i = 1; i < jited_cnt; i++) {
6097                 if (ksyms_found < nr_jited_ksyms &&
6098                     jited_linfo[i] == jited_ksyms[ksyms_found]) {
6099                         cur_func_ksyms = jited_ksyms[ksyms_found];
6100                         cur_func_len = jited_ksyms[ksyms_found];
6101                         ksyms_found++;
6102                         continue;
6103                 }
6104
6105                 if (CHECK(jited_linfo[i] <= jited_linfo[i - 1],
6106                           "jited_linfo[%u]:%lx <= jited_linfo[%u]:%lx",
6107                           i, (long)jited_linfo[i],
6108                           i - 1, (long)(jited_linfo[i - 1]))) {
6109                         err = -1;
6110                         goto done;
6111                 }
6112
6113                 if (CHECK(jited_linfo[i] - cur_func_ksyms > cur_func_len,
6114                           "jited_linfo[%u]:%lx - %lx > %u",
6115                           i, (long)jited_linfo[i], (long)cur_func_ksyms,
6116                           cur_func_len)) {
6117                         err = -1;
6118                         goto done;
6119                 }
6120         }
6121
6122         if (CHECK(ksyms_found != nr_jited_ksyms,
6123                   "ksyms_found:%u != nr_jited_ksyms:%u",
6124                   ksyms_found, nr_jited_ksyms)) {
6125                 err = -1;
6126                 goto done;
6127         }
6128
6129         err = 0;
6130
6131 done:
6132         free(linfo);
6133         free(jited_linfo);
6134         free(jited_ksyms);
6135         free(jited_func_lens);
6136         return err;
6137 }
6138
6139 static int do_test_info_raw(unsigned int test_num)
6140 {
6141         const struct prog_info_raw_test *test = &info_raw_tests[test_num - 1];
6142         unsigned int raw_btf_size, linfo_str_off, linfo_size;
6143         int btf_fd = -1, prog_fd = -1, err = 0;
6144         void *raw_btf, *patched_linfo = NULL;
6145         const char *ret_next_str;
6146         union bpf_attr attr = {};
6147
6148         fprintf(stderr, "BTF prog info raw test[%u] (%s): ", test_num, test->descr);
6149         raw_btf = btf_raw_create(&hdr_tmpl, test->raw_types,
6150                                  test->str_sec, test->str_sec_size,
6151                                  &raw_btf_size, &ret_next_str);
6152
6153         if (!raw_btf)
6154                 return -1;
6155
6156         *btf_log_buf = '\0';
6157         btf_fd = bpf_load_btf(raw_btf, raw_btf_size,
6158                               btf_log_buf, BTF_LOG_BUF_SIZE,
6159                               args.always_log);
6160         free(raw_btf);
6161
6162         if (CHECK(btf_fd == -1, "invalid btf_fd errno:%d", errno)) {
6163                 err = -1;
6164                 goto done;
6165         }
6166
6167         if (*btf_log_buf && args.always_log)
6168                 fprintf(stderr, "\n%s", btf_log_buf);
6169         *btf_log_buf = '\0';
6170
6171         linfo_str_off = ret_next_str - test->str_sec;
6172         patched_linfo = patch_name_tbd(test->line_info,
6173                                        test->str_sec, linfo_str_off,
6174                                        test->str_sec_size, &linfo_size);
6175         if (IS_ERR(patched_linfo)) {
6176                 fprintf(stderr, "error in creating raw bpf_line_info");
6177                 err = -1;
6178                 goto done;
6179         }
6180
6181         attr.prog_type = test->prog_type;
6182         attr.insns = ptr_to_u64(test->insns);
6183         attr.insn_cnt = probe_prog_length(test->insns);
6184         attr.license = ptr_to_u64("GPL");
6185         attr.prog_btf_fd = btf_fd;
6186         attr.func_info_rec_size = test->func_info_rec_size;
6187         attr.func_info_cnt = test->func_info_cnt;
6188         attr.func_info = ptr_to_u64(test->func_info);
6189         attr.log_buf = ptr_to_u64(btf_log_buf);
6190         attr.log_size = BTF_LOG_BUF_SIZE;
6191         attr.log_level = 1;
6192         if (linfo_size) {
6193                 attr.line_info_rec_size = test->line_info_rec_size;
6194                 attr.line_info = ptr_to_u64(patched_linfo);
6195                 attr.line_info_cnt = linfo_size / attr.line_info_rec_size;
6196         }
6197
6198         prog_fd = syscall(__NR_bpf, BPF_PROG_LOAD, &attr, sizeof(attr));
6199         err = ((prog_fd == -1) != test->expected_prog_load_failure);
6200         if (CHECK(err, "prog_fd:%d expected_prog_load_failure:%u errno:%d",
6201                   prog_fd, test->expected_prog_load_failure, errno) ||
6202             CHECK(test->err_str && !strstr(btf_log_buf, test->err_str),
6203                   "expected err_str:%s", test->err_str)) {
6204                 err = -1;
6205                 goto done;
6206         }
6207
6208         if (prog_fd == -1)
6209                 goto done;
6210
6211         err = test_get_finfo(test, prog_fd);
6212         if (err)
6213                 goto done;
6214
6215         err = test_get_linfo(test, patched_linfo,
6216                              attr.line_info_cnt - test->dead_code_cnt,
6217                              prog_fd);
6218         if (err)
6219                 goto done;
6220
6221 done:
6222         if (!err)
6223                 fprintf(stderr, "OK");
6224
6225         if (*btf_log_buf && (err || args.always_log))
6226                 fprintf(stderr, "\n%s", btf_log_buf);
6227
6228         if (btf_fd != -1)
6229                 close(btf_fd);
6230         if (prog_fd != -1)
6231                 close(prog_fd);
6232
6233         if (!IS_ERR(patched_linfo))
6234                 free(patched_linfo);
6235
6236         return err;
6237 }
6238
6239 static int test_info_raw(void)
6240 {
6241         unsigned int i;
6242         int err = 0;
6243
6244         if (args.info_raw_test_num)
6245                 return count_result(do_test_info_raw(args.info_raw_test_num));
6246
6247         for (i = 1; i <= ARRAY_SIZE(info_raw_tests); i++)
6248                 err |= count_result(do_test_info_raw(i));
6249
6250         return err;
6251 }
6252
6253 struct btf_raw_data {
6254         __u32 raw_types[MAX_NR_RAW_U32];
6255         const char *str_sec;
6256         __u32 str_sec_size;
6257 };
6258
6259 struct btf_dedup_test {
6260         const char *descr;
6261         struct btf_raw_data input;
6262         struct btf_raw_data expect;
6263         struct btf_dedup_opts opts;
6264 };
6265
6266 const struct btf_dedup_test dedup_tests[] = {
6267
6268 {
6269         .descr = "dedup: unused strings filtering",
6270         .input = {
6271                 .raw_types = {
6272                         BTF_TYPE_INT_ENC(NAME_NTH(2), BTF_INT_SIGNED, 0, 32, 4),
6273                         BTF_TYPE_INT_ENC(NAME_NTH(5), BTF_INT_SIGNED, 0, 64, 8),
6274                         BTF_END_RAW,
6275                 },
6276                 BTF_STR_SEC("\0unused\0int\0foo\0bar\0long"),
6277         },
6278         .expect = {
6279                 .raw_types = {
6280                         BTF_TYPE_INT_ENC(NAME_NTH(1), BTF_INT_SIGNED, 0, 32, 4),
6281                         BTF_TYPE_INT_ENC(NAME_NTH(2), BTF_INT_SIGNED, 0, 64, 8),
6282                         BTF_END_RAW,
6283                 },
6284                 BTF_STR_SEC("\0int\0long"),
6285         },
6286         .opts = {
6287                 .dont_resolve_fwds = false,
6288         },
6289 },
6290 {
6291         .descr = "dedup: strings deduplication",
6292         .input = {
6293                 .raw_types = {
6294                         BTF_TYPE_INT_ENC(NAME_NTH(1), BTF_INT_SIGNED, 0, 32, 4),
6295                         BTF_TYPE_INT_ENC(NAME_NTH(2), BTF_INT_SIGNED, 0, 64, 8),
6296                         BTF_TYPE_INT_ENC(NAME_NTH(3), BTF_INT_SIGNED, 0, 32, 4),
6297                         BTF_TYPE_INT_ENC(NAME_NTH(4), BTF_INT_SIGNED, 0, 64, 8),
6298                         BTF_TYPE_INT_ENC(NAME_NTH(5), BTF_INT_SIGNED, 0, 32, 4),
6299                         BTF_END_RAW,
6300                 },
6301                 BTF_STR_SEC("\0int\0long int\0int\0long int\0int"),
6302         },
6303         .expect = {
6304                 .raw_types = {
6305                         BTF_TYPE_INT_ENC(NAME_NTH(1), BTF_INT_SIGNED, 0, 32, 4),
6306                         BTF_TYPE_INT_ENC(NAME_NTH(2), BTF_INT_SIGNED, 0, 64, 8),
6307                         BTF_END_RAW,
6308                 },
6309                 BTF_STR_SEC("\0int\0long int"),
6310         },
6311         .opts = {
6312                 .dont_resolve_fwds = false,
6313         },
6314 },
6315 {
6316         .descr = "dedup: struct example #1",
6317         /*
6318          * struct s {
6319          *      struct s *next;
6320          *      const int *a;
6321          *      int b[16];
6322          *      int c;
6323          * }
6324          */
6325         .input = {
6326                 .raw_types = {
6327                         /* int */
6328                         BTF_TYPE_INT_ENC(NAME_NTH(1), BTF_INT_SIGNED, 0, 32, 4),        /* [1] */
6329                         /* int[16] */
6330                         BTF_TYPE_ARRAY_ENC(1, 1, 16),                                   /* [2] */
6331                         /* struct s { */
6332                         BTF_STRUCT_ENC(NAME_NTH(2), 4, 84),                             /* [3] */
6333                                 BTF_MEMBER_ENC(NAME_NTH(3), 4, 0),      /* struct s *next;      */
6334                                 BTF_MEMBER_ENC(NAME_NTH(4), 5, 64),     /* const int *a;        */
6335                                 BTF_MEMBER_ENC(NAME_NTH(5), 2, 128),    /* int b[16];           */
6336                                 BTF_MEMBER_ENC(NAME_NTH(6), 1, 640),    /* int c;               */
6337                         /* ptr -> [3] struct s */
6338                         BTF_PTR_ENC(3),                                                 /* [4] */
6339                         /* ptr -> [6] const int */
6340                         BTF_PTR_ENC(6),                                                 /* [5] */
6341                         /* const -> [1] int */
6342                         BTF_CONST_ENC(1),                                               /* [6] */
6343
6344                         /* full copy of the above */
6345                         BTF_TYPE_INT_ENC(NAME_NTH(1), BTF_INT_SIGNED, 0, 32, 4),        /* [7] */
6346                         BTF_TYPE_ARRAY_ENC(7, 7, 16),                                   /* [8] */
6347                         BTF_STRUCT_ENC(NAME_NTH(2), 4, 84),                             /* [9] */
6348                                 BTF_MEMBER_ENC(NAME_NTH(3), 10, 0),
6349                                 BTF_MEMBER_ENC(NAME_NTH(4), 11, 64),
6350                                 BTF_MEMBER_ENC(NAME_NTH(5), 8, 128),
6351                                 BTF_MEMBER_ENC(NAME_NTH(6), 7, 640),
6352                         BTF_PTR_ENC(9),                                                 /* [10] */
6353                         BTF_PTR_ENC(12),                                                /* [11] */
6354                         BTF_CONST_ENC(7),                                               /* [12] */
6355                         BTF_END_RAW,
6356                 },
6357                 BTF_STR_SEC("\0int\0s\0next\0a\0b\0c\0"),
6358         },
6359         .expect = {
6360                 .raw_types = {
6361                         /* int */
6362                         BTF_TYPE_INT_ENC(NAME_NTH(4), BTF_INT_SIGNED, 0, 32, 4),        /* [1] */
6363                         /* int[16] */
6364                         BTF_TYPE_ARRAY_ENC(1, 1, 16),                                   /* [2] */
6365                         /* struct s { */
6366                         BTF_STRUCT_ENC(NAME_NTH(6), 4, 84),                             /* [3] */
6367                                 BTF_MEMBER_ENC(NAME_NTH(5), 4, 0),      /* struct s *next;      */
6368                                 BTF_MEMBER_ENC(NAME_NTH(1), 5, 64),     /* const int *a;        */
6369                                 BTF_MEMBER_ENC(NAME_NTH(2), 2, 128),    /* int b[16];           */
6370                                 BTF_MEMBER_ENC(NAME_NTH(3), 1, 640),    /* int c;               */
6371                         /* ptr -> [3] struct s */
6372                         BTF_PTR_ENC(3),                                                 /* [4] */
6373                         /* ptr -> [6] const int */
6374                         BTF_PTR_ENC(6),                                                 /* [5] */
6375                         /* const -> [1] int */
6376                         BTF_CONST_ENC(1),                                               /* [6] */
6377                         BTF_END_RAW,
6378                 },
6379                 BTF_STR_SEC("\0a\0b\0c\0int\0next\0s"),
6380         },
6381         .opts = {
6382                 .dont_resolve_fwds = false,
6383         },
6384 },
6385 {
6386         .descr = "dedup: struct <-> fwd resolution w/ hash collision",
6387         /*
6388          * // CU 1:
6389          * struct x;
6390          * struct s {
6391          *      struct x *x;
6392          * };
6393          * // CU 2:
6394          * struct x {};
6395          * struct s {
6396          *      struct x *x;
6397          * };
6398          */
6399         .input = {
6400                 .raw_types = {
6401                         /* CU 1 */
6402                         BTF_FWD_ENC(NAME_TBD, 0 /* struct fwd */),      /* [1] fwd x      */
6403                         BTF_PTR_ENC(1),                                 /* [2] ptr -> [1] */
6404                         BTF_STRUCT_ENC(NAME_TBD, 1, 8),                 /* [3] struct s   */
6405                                 BTF_MEMBER_ENC(NAME_TBD, 2, 0),
6406                         /* CU 2 */
6407                         BTF_STRUCT_ENC(NAME_TBD, 0, 0),                 /* [4] struct x   */
6408                         BTF_PTR_ENC(4),                                 /* [5] ptr -> [4] */
6409                         BTF_STRUCT_ENC(NAME_TBD, 1, 8),                 /* [6] struct s   */
6410                                 BTF_MEMBER_ENC(NAME_TBD, 5, 0),
6411                         BTF_END_RAW,
6412                 },
6413                 BTF_STR_SEC("\0x\0s\0x\0x\0s\0x\0"),
6414         },
6415         .expect = {
6416                 .raw_types = {
6417                         BTF_PTR_ENC(3),                                 /* [1] ptr -> [3] */
6418                         BTF_STRUCT_ENC(NAME_TBD, 1, 8),                 /* [2] struct s   */
6419                                 BTF_MEMBER_ENC(NAME_TBD, 1, 0),
6420                         BTF_STRUCT_ENC(NAME_NTH(2), 0, 0),              /* [3] struct x   */
6421                         BTF_END_RAW,
6422                 },
6423                 BTF_STR_SEC("\0s\0x"),
6424         },
6425         .opts = {
6426                 .dont_resolve_fwds = false,
6427                 .dedup_table_size = 1, /* force hash collisions */
6428         },
6429 },
6430 {
6431         .descr = "dedup: void equiv check",
6432         /*
6433          * // CU 1:
6434          * struct s {
6435          *      struct {} *x;
6436          * };
6437          * // CU 2:
6438          * struct s {
6439          *      int *x;
6440          * };
6441          */
6442         .input = {
6443                 .raw_types = {
6444                         /* CU 1 */
6445                         BTF_STRUCT_ENC(0, 0, 1),                                /* [1] struct {}  */
6446                         BTF_PTR_ENC(1),                                         /* [2] ptr -> [1] */
6447                         BTF_STRUCT_ENC(NAME_NTH(1), 1, 8),                      /* [3] struct s   */
6448                                 BTF_MEMBER_ENC(NAME_NTH(2), 2, 0),
6449                         /* CU 2 */
6450                         BTF_PTR_ENC(0),                                         /* [4] ptr -> void */
6451                         BTF_STRUCT_ENC(NAME_NTH(1), 1, 8),                      /* [5] struct s   */
6452                                 BTF_MEMBER_ENC(NAME_NTH(2), 4, 0),
6453                         BTF_END_RAW,
6454                 },
6455                 BTF_STR_SEC("\0s\0x"),
6456         },
6457         .expect = {
6458                 .raw_types = {
6459                         /* CU 1 */
6460                         BTF_STRUCT_ENC(0, 0, 1),                                /* [1] struct {}  */
6461                         BTF_PTR_ENC(1),                                         /* [2] ptr -> [1] */
6462                         BTF_STRUCT_ENC(NAME_NTH(1), 1, 8),                      /* [3] struct s   */
6463                                 BTF_MEMBER_ENC(NAME_NTH(2), 2, 0),
6464                         /* CU 2 */
6465                         BTF_PTR_ENC(0),                                         /* [4] ptr -> void */
6466                         BTF_STRUCT_ENC(NAME_NTH(1), 1, 8),                      /* [5] struct s   */
6467                                 BTF_MEMBER_ENC(NAME_NTH(2), 4, 0),
6468                         BTF_END_RAW,
6469                 },
6470                 BTF_STR_SEC("\0s\0x"),
6471         },
6472         .opts = {
6473                 .dont_resolve_fwds = false,
6474                 .dedup_table_size = 1, /* force hash collisions */
6475         },
6476 },
6477 {
6478         .descr = "dedup: all possible kinds (no duplicates)",
6479         .input = {
6480                 .raw_types = {
6481                         BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 8),           /* [1] int */
6482                         BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_ENUM, 0, 2), 4),   /* [2] enum */
6483                                 BTF_ENUM_ENC(NAME_TBD, 0),
6484                                 BTF_ENUM_ENC(NAME_TBD, 1),
6485                         BTF_FWD_ENC(NAME_TBD, 1 /* union kind_flag */),                 /* [3] fwd */
6486                         BTF_TYPE_ARRAY_ENC(2, 1, 7),                                    /* [4] array */
6487                         BTF_STRUCT_ENC(NAME_TBD, 1, 4),                                 /* [5] struct */
6488                                 BTF_MEMBER_ENC(NAME_TBD, 1, 0),
6489                         BTF_UNION_ENC(NAME_TBD, 1, 4),                                  /* [6] union */
6490                                 BTF_MEMBER_ENC(NAME_TBD, 1, 0),
6491                         BTF_TYPEDEF_ENC(NAME_TBD, 1),                                   /* [7] typedef */
6492                         BTF_PTR_ENC(0),                                                 /* [8] ptr */
6493                         BTF_CONST_ENC(8),                                               /* [9] const */
6494                         BTF_VOLATILE_ENC(8),                                            /* [10] volatile */
6495                         BTF_RESTRICT_ENC(8),                                            /* [11] restrict */
6496                         BTF_FUNC_PROTO_ENC(1, 2),                                       /* [12] func_proto */
6497                                 BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
6498                                 BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 8),
6499                         BTF_FUNC_ENC(NAME_TBD, 12),                                     /* [13] func */
6500                         BTF_END_RAW,
6501                 },
6502                 BTF_STR_SEC("\0A\0B\0C\0D\0E\0F\0G\0H\0I\0J\0K\0L\0M"),
6503         },
6504         .expect = {
6505                 .raw_types = {
6506                         BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 8),           /* [1] int */
6507                         BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_ENUM, 0, 2), 4),   /* [2] enum */
6508                                 BTF_ENUM_ENC(NAME_TBD, 0),
6509                                 BTF_ENUM_ENC(NAME_TBD, 1),
6510                         BTF_FWD_ENC(NAME_TBD, 1 /* union kind_flag */),                 /* [3] fwd */
6511                         BTF_TYPE_ARRAY_ENC(2, 1, 7),                                    /* [4] array */
6512                         BTF_STRUCT_ENC(NAME_TBD, 1, 4),                                 /* [5] struct */
6513                                 BTF_MEMBER_ENC(NAME_TBD, 1, 0),
6514                         BTF_UNION_ENC(NAME_TBD, 1, 4),                                  /* [6] union */
6515                                 BTF_MEMBER_ENC(NAME_TBD, 1, 0),
6516                         BTF_TYPEDEF_ENC(NAME_TBD, 1),                                   /* [7] typedef */
6517                         BTF_PTR_ENC(0),                                                 /* [8] ptr */
6518                         BTF_CONST_ENC(8),                                               /* [9] const */
6519                         BTF_VOLATILE_ENC(8),                                            /* [10] volatile */
6520                         BTF_RESTRICT_ENC(8),                                            /* [11] restrict */
6521                         BTF_FUNC_PROTO_ENC(1, 2),                                       /* [12] func_proto */
6522                                 BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
6523                                 BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 8),
6524                         BTF_FUNC_ENC(NAME_TBD, 12),                                     /* [13] func */
6525                         BTF_END_RAW,
6526                 },
6527                 BTF_STR_SEC("\0A\0B\0C\0D\0E\0F\0G\0H\0I\0J\0K\0L\0M"),
6528         },
6529         .opts = {
6530                 .dont_resolve_fwds = false,
6531         },
6532 },
6533 {
6534         .descr = "dedup: no int duplicates",
6535         .input = {
6536                 .raw_types = {
6537                         BTF_TYPE_INT_ENC(NAME_NTH(1), BTF_INT_SIGNED, 0, 32, 8),
6538                         /* different name */
6539                         BTF_TYPE_INT_ENC(NAME_NTH(2), BTF_INT_SIGNED, 0, 32, 8),
6540                         /* different encoding */
6541                         BTF_TYPE_INT_ENC(NAME_NTH(1), BTF_INT_CHAR, 0, 32, 8),
6542                         BTF_TYPE_INT_ENC(NAME_NTH(1), BTF_INT_BOOL, 0, 32, 8),
6543                         /* different bit offset */
6544                         BTF_TYPE_INT_ENC(NAME_NTH(1), BTF_INT_SIGNED, 8, 32, 8),
6545                         /* different bit size */
6546                         BTF_TYPE_INT_ENC(NAME_NTH(1), BTF_INT_SIGNED, 0, 27, 8),
6547                         /* different byte size */
6548                         BTF_TYPE_INT_ENC(NAME_NTH(1), BTF_INT_SIGNED, 0, 32, 4),
6549                         BTF_END_RAW,
6550                 },
6551                 BTF_STR_SEC("\0int\0some other int"),
6552         },
6553         .expect = {
6554                 .raw_types = {
6555                         BTF_TYPE_INT_ENC(NAME_NTH(1), BTF_INT_SIGNED, 0, 32, 8),
6556                         /* different name */
6557                         BTF_TYPE_INT_ENC(NAME_NTH(2), BTF_INT_SIGNED, 0, 32, 8),
6558                         /* different encoding */
6559                         BTF_TYPE_INT_ENC(NAME_NTH(1), BTF_INT_CHAR, 0, 32, 8),
6560                         BTF_TYPE_INT_ENC(NAME_NTH(1), BTF_INT_BOOL, 0, 32, 8),
6561                         /* different bit offset */
6562                         BTF_TYPE_INT_ENC(NAME_NTH(1), BTF_INT_SIGNED, 8, 32, 8),
6563                         /* different bit size */
6564                         BTF_TYPE_INT_ENC(NAME_NTH(1), BTF_INT_SIGNED, 0, 27, 8),
6565                         /* different byte size */
6566                         BTF_TYPE_INT_ENC(NAME_NTH(1), BTF_INT_SIGNED, 0, 32, 4),
6567                         BTF_END_RAW,
6568                 },
6569                 BTF_STR_SEC("\0int\0some other int"),
6570         },
6571         .opts = {
6572                 .dont_resolve_fwds = false,
6573         },
6574 },
6575 {
6576         .descr = "dedup: enum fwd resolution",
6577         .input = {
6578                 .raw_types = {
6579                         /* [1] fwd enum 'e1' before full enum */
6580                         BTF_TYPE_ENC(NAME_NTH(1), BTF_INFO_ENC(BTF_KIND_ENUM, 0, 0), 4),
6581                         /* [2] full enum 'e1' after fwd */
6582                         BTF_TYPE_ENC(NAME_NTH(1), BTF_INFO_ENC(BTF_KIND_ENUM, 0, 1), 4),
6583                                 BTF_ENUM_ENC(NAME_NTH(2), 123),
6584                         /* [3] full enum 'e2' before fwd */
6585                         BTF_TYPE_ENC(NAME_NTH(3), BTF_INFO_ENC(BTF_KIND_ENUM, 0, 1), 4),
6586                                 BTF_ENUM_ENC(NAME_NTH(4), 456),
6587                         /* [4] fwd enum 'e2' after full enum */
6588                         BTF_TYPE_ENC(NAME_NTH(3), BTF_INFO_ENC(BTF_KIND_ENUM, 0, 0), 4),
6589                         /* [5] incompatible fwd enum with different size */
6590                         BTF_TYPE_ENC(NAME_NTH(1), BTF_INFO_ENC(BTF_KIND_ENUM, 0, 0), 1),
6591                         /* [6] incompatible full enum with different value */
6592                         BTF_TYPE_ENC(NAME_NTH(1), BTF_INFO_ENC(BTF_KIND_ENUM, 0, 1), 4),
6593                                 BTF_ENUM_ENC(NAME_NTH(2), 321),
6594                         BTF_END_RAW,
6595                 },
6596                 BTF_STR_SEC("\0e1\0e1_val\0e2\0e2_val"),
6597         },
6598         .expect = {
6599                 .raw_types = {
6600                         /* [1] full enum 'e1' */
6601                         BTF_TYPE_ENC(NAME_NTH(1), BTF_INFO_ENC(BTF_KIND_ENUM, 0, 1), 4),
6602                                 BTF_ENUM_ENC(NAME_NTH(2), 123),
6603                         /* [2] full enum 'e2' */
6604                         BTF_TYPE_ENC(NAME_NTH(3), BTF_INFO_ENC(BTF_KIND_ENUM, 0, 1), 4),
6605                                 BTF_ENUM_ENC(NAME_NTH(4), 456),
6606                         /* [3] incompatible fwd enum with different size */
6607                         BTF_TYPE_ENC(NAME_NTH(1), BTF_INFO_ENC(BTF_KIND_ENUM, 0, 0), 1),
6608                         /* [4] incompatible full enum with different value */
6609                         BTF_TYPE_ENC(NAME_NTH(1), BTF_INFO_ENC(BTF_KIND_ENUM, 0, 1), 4),
6610                                 BTF_ENUM_ENC(NAME_NTH(2), 321),
6611                         BTF_END_RAW,
6612                 },
6613                 BTF_STR_SEC("\0e1\0e1_val\0e2\0e2_val"),
6614         },
6615         .opts = {
6616                 .dont_resolve_fwds = false,
6617         },
6618 },
6619 {
6620         .descr = "dedup: datasec and vars pass-through",
6621         .input = {
6622                 .raw_types = {
6623                         /* int */
6624                         BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),  /* [1] */
6625                         /* static int t */
6626                         BTF_VAR_ENC(NAME_NTH(2), 1, 0),                 /* [2] */
6627                         /* .bss section */                              /* [3] */
6628                         BTF_TYPE_ENC(NAME_NTH(1), BTF_INFO_ENC(BTF_KIND_DATASEC, 0, 1), 4),
6629                         BTF_VAR_SECINFO_ENC(2, 0, 4),
6630                         /* int, referenced from [5] */
6631                         BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),  /* [4] */
6632                         /* another static int t */
6633                         BTF_VAR_ENC(NAME_NTH(2), 4, 0),                 /* [5] */
6634                         /* another .bss section */                      /* [6] */
6635                         BTF_TYPE_ENC(NAME_NTH(1), BTF_INFO_ENC(BTF_KIND_DATASEC, 0, 1), 4),
6636                         BTF_VAR_SECINFO_ENC(5, 0, 4),
6637                         BTF_END_RAW,
6638                 },
6639                 BTF_STR_SEC("\0.bss\0t"),
6640         },
6641         .expect = {
6642                 .raw_types = {
6643                         /* int */
6644                         BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),  /* [1] */
6645                         /* static int t */
6646                         BTF_VAR_ENC(NAME_NTH(2), 1, 0),                 /* [2] */
6647                         /* .bss section */                              /* [3] */
6648                         BTF_TYPE_ENC(NAME_NTH(1), BTF_INFO_ENC(BTF_KIND_DATASEC, 0, 1), 4),
6649                         BTF_VAR_SECINFO_ENC(2, 0, 4),
6650                         /* another static int t */
6651                         BTF_VAR_ENC(NAME_NTH(2), 1, 0),                 /* [4] */
6652                         /* another .bss section */                      /* [5] */
6653                         BTF_TYPE_ENC(NAME_NTH(1), BTF_INFO_ENC(BTF_KIND_DATASEC, 0, 1), 4),
6654                         BTF_VAR_SECINFO_ENC(4, 0, 4),
6655                         BTF_END_RAW,
6656                 },
6657                 BTF_STR_SEC("\0.bss\0t"),
6658         },
6659         .opts = {
6660                 .dont_resolve_fwds = false,
6661                 .dedup_table_size = 1
6662         },
6663 },
6664
6665 };
6666
6667 static int btf_type_size(const struct btf_type *t)
6668 {
6669         int base_size = sizeof(struct btf_type);
6670         __u16 vlen = BTF_INFO_VLEN(t->info);
6671         __u16 kind = BTF_INFO_KIND(t->info);
6672
6673         switch (kind) {
6674         case BTF_KIND_FWD:
6675         case BTF_KIND_CONST:
6676         case BTF_KIND_VOLATILE:
6677         case BTF_KIND_RESTRICT:
6678         case BTF_KIND_PTR:
6679         case BTF_KIND_TYPEDEF:
6680         case BTF_KIND_FUNC:
6681                 return base_size;
6682         case BTF_KIND_INT:
6683                 return base_size + sizeof(__u32);
6684         case BTF_KIND_ENUM:
6685                 return base_size + vlen * sizeof(struct btf_enum);
6686         case BTF_KIND_ARRAY:
6687                 return base_size + sizeof(struct btf_array);
6688         case BTF_KIND_STRUCT:
6689         case BTF_KIND_UNION:
6690                 return base_size + vlen * sizeof(struct btf_member);
6691         case BTF_KIND_FUNC_PROTO:
6692                 return base_size + vlen * sizeof(struct btf_param);
6693         case BTF_KIND_VAR:
6694                 return base_size + sizeof(struct btf_var);
6695         case BTF_KIND_DATASEC:
6696                 return base_size + vlen * sizeof(struct btf_var_secinfo);
6697         default:
6698                 fprintf(stderr, "Unsupported BTF_KIND:%u\n", kind);
6699                 return -EINVAL;
6700         }
6701 }
6702
6703 static void dump_btf_strings(const char *strs, __u32 len)
6704 {
6705         const char *cur = strs;
6706         int i = 0;
6707
6708         while (cur < strs + len) {
6709                 fprintf(stderr, "string #%d: '%s'\n", i, cur);
6710                 cur += strlen(cur) + 1;
6711                 i++;
6712         }
6713 }
6714
6715 static int do_test_dedup(unsigned int test_num)
6716 {
6717         const struct btf_dedup_test *test = &dedup_tests[test_num - 1];
6718         __u32 test_nr_types, expect_nr_types, test_btf_size, expect_btf_size;
6719         const struct btf_header *test_hdr, *expect_hdr;
6720         struct btf *test_btf = NULL, *expect_btf = NULL;
6721         const void *test_btf_data, *expect_btf_data;
6722         const char *ret_test_next_str, *ret_expect_next_str;
6723         const char *test_strs, *expect_strs;
6724         const char *test_str_cur, *test_str_end;
6725         const char *expect_str_cur, *expect_str_end;
6726         unsigned int raw_btf_size;
6727         void *raw_btf;
6728         int err = 0, i;
6729
6730         fprintf(stderr, "BTF dedup test[%u] (%s):", test_num, test->descr);
6731
6732         raw_btf = btf_raw_create(&hdr_tmpl, test->input.raw_types,
6733                                  test->input.str_sec, test->input.str_sec_size,
6734                                  &raw_btf_size, &ret_test_next_str);
6735         if (!raw_btf)
6736                 return -1;
6737         test_btf = btf__new((__u8 *)raw_btf, raw_btf_size);
6738         free(raw_btf);
6739         if (CHECK(IS_ERR(test_btf), "invalid test_btf errno:%ld",
6740                   PTR_ERR(test_btf))) {
6741                 err = -1;
6742                 goto done;
6743         }
6744
6745         raw_btf = btf_raw_create(&hdr_tmpl, test->expect.raw_types,
6746                                  test->expect.str_sec,
6747                                  test->expect.str_sec_size,
6748                                  &raw_btf_size, &ret_expect_next_str);
6749         if (!raw_btf)
6750                 return -1;
6751         expect_btf = btf__new((__u8 *)raw_btf, raw_btf_size);
6752         free(raw_btf);
6753         if (CHECK(IS_ERR(expect_btf), "invalid expect_btf errno:%ld",
6754                   PTR_ERR(expect_btf))) {
6755                 err = -1;
6756                 goto done;
6757         }
6758
6759         err = btf__dedup(test_btf, NULL, &test->opts);
6760         if (CHECK(err, "btf_dedup failed errno:%d", err)) {
6761                 err = -1;
6762                 goto done;
6763         }
6764
6765         test_btf_data = btf__get_raw_data(test_btf, &test_btf_size);
6766         expect_btf_data = btf__get_raw_data(expect_btf, &expect_btf_size);
6767         if (CHECK(test_btf_size != expect_btf_size,
6768                   "test_btf_size:%u != expect_btf_size:%u",
6769                   test_btf_size, expect_btf_size)) {
6770                 err = -1;
6771                 goto done;
6772         }
6773
6774         test_hdr = test_btf_data;
6775         test_strs = test_btf_data + sizeof(*test_hdr) + test_hdr->str_off;
6776         expect_hdr = expect_btf_data;
6777         expect_strs = expect_btf_data + sizeof(*test_hdr) + expect_hdr->str_off;
6778         if (CHECK(test_hdr->str_len != expect_hdr->str_len,
6779                   "test_hdr->str_len:%u != expect_hdr->str_len:%u",
6780                   test_hdr->str_len, expect_hdr->str_len)) {
6781                 fprintf(stderr, "\ntest strings:\n");
6782                 dump_btf_strings(test_strs, test_hdr->str_len);
6783                 fprintf(stderr, "\nexpected strings:\n");
6784                 dump_btf_strings(expect_strs, expect_hdr->str_len);
6785                 err = -1;
6786                 goto done;
6787         }
6788
6789         test_str_cur = test_strs;
6790         test_str_end = test_strs + test_hdr->str_len;
6791         expect_str_cur = expect_strs;
6792         expect_str_end = expect_strs + expect_hdr->str_len;
6793         while (test_str_cur < test_str_end && expect_str_cur < expect_str_end) {
6794                 size_t test_len, expect_len;
6795
6796                 test_len = strlen(test_str_cur);
6797                 expect_len = strlen(expect_str_cur);
6798                 if (CHECK(test_len != expect_len,
6799                           "test_len:%zu != expect_len:%zu "
6800                           "(test_str:%s, expect_str:%s)",
6801                           test_len, expect_len, test_str_cur, expect_str_cur)) {
6802                         err = -1;
6803                         goto done;
6804                 }
6805                 if (CHECK(strcmp(test_str_cur, expect_str_cur),
6806                           "test_str:%s != expect_str:%s",
6807                           test_str_cur, expect_str_cur)) {
6808                         err = -1;
6809                         goto done;
6810                 }
6811                 test_str_cur += test_len + 1;
6812                 expect_str_cur += expect_len + 1;
6813         }
6814         if (CHECK(test_str_cur != test_str_end,
6815                   "test_str_cur:%p != test_str_end:%p",
6816                   test_str_cur, test_str_end)) {
6817                 err = -1;
6818                 goto done;
6819         }
6820
6821         test_nr_types = btf__get_nr_types(test_btf);
6822         expect_nr_types = btf__get_nr_types(expect_btf);
6823         if (CHECK(test_nr_types != expect_nr_types,
6824                   "test_nr_types:%u != expect_nr_types:%u",
6825                   test_nr_types, expect_nr_types)) {
6826                 err = -1;
6827                 goto done;
6828         }
6829
6830         for (i = 1; i <= test_nr_types; i++) {
6831                 const struct btf_type *test_type, *expect_type;
6832                 int test_size, expect_size;
6833
6834                 test_type = btf__type_by_id(test_btf, i);
6835                 expect_type = btf__type_by_id(expect_btf, i);
6836                 test_size = btf_type_size(test_type);
6837                 expect_size = btf_type_size(expect_type);
6838
6839                 if (CHECK(test_size != expect_size,
6840                           "type #%d: test_size:%d != expect_size:%u",
6841                           i, test_size, expect_size)) {
6842                         err = -1;
6843                         goto done;
6844                 }
6845                 if (CHECK(memcmp((void *)test_type,
6846                                  (void *)expect_type,
6847                                  test_size),
6848                           "type #%d: contents differ", i)) {
6849                         err = -1;
6850                         goto done;
6851                 }
6852         }
6853
6854 done:
6855         if (!err)
6856                 fprintf(stderr, "OK");
6857         if (!IS_ERR(test_btf))
6858                 btf__free(test_btf);
6859         if (!IS_ERR(expect_btf))
6860                 btf__free(expect_btf);
6861
6862         return err;
6863 }
6864
6865 static int test_dedup(void)
6866 {
6867         unsigned int i;
6868         int err = 0;
6869
6870         if (args.dedup_test_num)
6871                 return count_result(do_test_dedup(args.dedup_test_num));
6872
6873         for (i = 1; i <= ARRAY_SIZE(dedup_tests); i++)
6874                 err |= count_result(do_test_dedup(i));
6875
6876         return err;
6877 }
6878
6879 static void usage(const char *cmd)
6880 {
6881         fprintf(stderr, "Usage: %s [-l] [[-r btf_raw_test_num (1 - %zu)] |\n"
6882                         "\t[-g btf_get_info_test_num (1 - %zu)] |\n"
6883                         "\t[-f btf_file_test_num (1 - %zu)] |\n"
6884                         "\t[-k btf_prog_info_raw_test_num (1 - %zu)] |\n"
6885                         "\t[-p (pretty print test)] |\n"
6886                         "\t[-d btf_dedup_test_num (1 - %zu)]]\n",
6887                 cmd, ARRAY_SIZE(raw_tests), ARRAY_SIZE(get_info_tests),
6888                 ARRAY_SIZE(file_tests), ARRAY_SIZE(info_raw_tests),
6889                 ARRAY_SIZE(dedup_tests));
6890 }
6891
6892 static int parse_args(int argc, char **argv)
6893 {
6894         const char *optstr = "hlpk:f:r:g:d:";
6895         int opt;
6896
6897         while ((opt = getopt(argc, argv, optstr)) != -1) {
6898                 switch (opt) {
6899                 case 'l':
6900                         args.always_log = true;
6901                         break;
6902                 case 'f':
6903                         args.file_test_num = atoi(optarg);
6904                         args.file_test = true;
6905                         break;
6906                 case 'r':
6907                         args.raw_test_num = atoi(optarg);
6908                         args.raw_test = true;
6909                         break;
6910                 case 'g':
6911                         args.get_info_test_num = atoi(optarg);
6912                         args.get_info_test = true;
6913                         break;
6914                 case 'p':
6915                         args.pprint_test = true;
6916                         break;
6917                 case 'k':
6918                         args.info_raw_test_num = atoi(optarg);
6919                         args.info_raw_test = true;
6920                         break;
6921                 case 'd':
6922                         args.dedup_test_num = atoi(optarg);
6923                         args.dedup_test = true;
6924                         break;
6925                 case 'h':
6926                         usage(argv[0]);
6927                         exit(0);
6928                 default:
6929                         usage(argv[0]);
6930                         return -1;
6931                 }
6932         }
6933
6934         if (args.raw_test_num &&
6935             (args.raw_test_num < 1 ||
6936              args.raw_test_num > ARRAY_SIZE(raw_tests))) {
6937                 fprintf(stderr, "BTF raw test number must be [1 - %zu]\n",
6938                         ARRAY_SIZE(raw_tests));
6939                 return -1;
6940         }
6941
6942         if (args.file_test_num &&
6943             (args.file_test_num < 1 ||
6944              args.file_test_num > ARRAY_SIZE(file_tests))) {
6945                 fprintf(stderr, "BTF file test number must be [1 - %zu]\n",
6946                         ARRAY_SIZE(file_tests));
6947                 return -1;
6948         }
6949
6950         if (args.get_info_test_num &&
6951             (args.get_info_test_num < 1 ||
6952              args.get_info_test_num > ARRAY_SIZE(get_info_tests))) {
6953                 fprintf(stderr, "BTF get info test number must be [1 - %zu]\n",
6954                         ARRAY_SIZE(get_info_tests));
6955                 return -1;
6956         }
6957
6958         if (args.info_raw_test_num &&
6959             (args.info_raw_test_num < 1 ||
6960              args.info_raw_test_num > ARRAY_SIZE(info_raw_tests))) {
6961                 fprintf(stderr, "BTF prog info raw test number must be [1 - %zu]\n",
6962                         ARRAY_SIZE(info_raw_tests));
6963                 return -1;
6964         }
6965
6966         if (args.dedup_test_num &&
6967             (args.dedup_test_num < 1 ||
6968              args.dedup_test_num > ARRAY_SIZE(dedup_tests))) {
6969                 fprintf(stderr, "BTF dedup test number must be [1 - %zu]\n",
6970                         ARRAY_SIZE(dedup_tests));
6971                 return -1;
6972         }
6973
6974         return 0;
6975 }
6976
6977 static void print_summary(void)
6978 {
6979         fprintf(stderr, "PASS:%u SKIP:%u FAIL:%u\n",
6980                 pass_cnt - skip_cnt, skip_cnt, error_cnt);
6981 }
6982
6983 int main(int argc, char **argv)
6984 {
6985         int err = 0;
6986
6987         err = parse_args(argc, argv);
6988         if (err)
6989                 return err;
6990
6991         if (args.always_log)
6992                 libbpf_set_print(__base_pr);
6993
6994         if (args.raw_test)
6995                 err |= test_raw();
6996
6997         if (args.get_info_test)
6998                 err |= test_get_info();
6999
7000         if (args.file_test)
7001                 err |= test_file();
7002
7003         if (args.pprint_test)
7004                 err |= test_pprint();
7005
7006         if (args.info_raw_test)
7007                 err |= test_info_raw();
7008
7009         if (args.dedup_test)
7010                 err |= test_dedup();
7011
7012         if (args.raw_test || args.get_info_test || args.file_test ||
7013             args.pprint_test || args.info_raw_test || args.dedup_test)
7014                 goto done;
7015
7016         err |= test_raw();
7017         err |= test_get_info();
7018         err |= test_file();
7019         err |= test_info_raw();
7020         err |= test_dedup();
7021
7022 done:
7023         print_summary();
7024         return err;
7025 }