net/mlx5: Replace kfree with kvfree
[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 }; /* struct btf_raw_test raw_tests[] */
3422
3423 static const char *get_next_str(const char *start, const char *end)
3424 {
3425         return start < end - 1 ? start + 1 : NULL;
3426 }
3427
3428 static int get_raw_sec_size(const __u32 *raw_types)
3429 {
3430         int i;
3431
3432         for (i = MAX_NR_RAW_U32 - 1;
3433              i >= 0 && raw_types[i] != BTF_END_RAW;
3434              i--)
3435                 ;
3436
3437         return i < 0 ? i : i * sizeof(raw_types[0]);
3438 }
3439
3440 static void *btf_raw_create(const struct btf_header *hdr,
3441                             const __u32 *raw_types,
3442                             const char *str,
3443                             unsigned int str_sec_size,
3444                             unsigned int *btf_size,
3445                             const char **ret_next_str)
3446 {
3447         const char *next_str = str, *end_str = str + str_sec_size;
3448         const char **strs_idx = NULL, **tmp_strs_idx;
3449         int strs_cap = 0, strs_cnt = 0, next_str_idx = 0;
3450         unsigned int size_needed, offset;
3451         struct btf_header *ret_hdr;
3452         int i, type_sec_size, err = 0;
3453         uint32_t *ret_types;
3454         void *raw_btf = NULL;
3455
3456         type_sec_size = get_raw_sec_size(raw_types);
3457         if (CHECK(type_sec_size < 0, "Cannot get nr_raw_types"))
3458                 return NULL;
3459
3460         size_needed = sizeof(*hdr) + type_sec_size + str_sec_size;
3461         raw_btf = malloc(size_needed);
3462         if (CHECK(!raw_btf, "Cannot allocate memory for raw_btf"))
3463                 return NULL;
3464
3465         /* Copy header */
3466         memcpy(raw_btf, hdr, sizeof(*hdr));
3467         offset = sizeof(*hdr);
3468
3469         /* Index strings */
3470         while ((next_str = get_next_str(next_str, end_str))) {
3471                 if (strs_cnt == strs_cap) {
3472                         strs_cap += max(16, strs_cap / 2);
3473                         tmp_strs_idx = realloc(strs_idx,
3474                                                sizeof(*strs_idx) * strs_cap);
3475                         if (CHECK(!tmp_strs_idx,
3476                                   "Cannot allocate memory for strs_idx")) {
3477                                 err = -1;
3478                                 goto done;
3479                         }
3480                         strs_idx = tmp_strs_idx;
3481                 }
3482                 strs_idx[strs_cnt++] = next_str;
3483                 next_str += strlen(next_str);
3484         }
3485
3486         /* Copy type section */
3487         ret_types = raw_btf + offset;
3488         for (i = 0; i < type_sec_size / sizeof(raw_types[0]); i++) {
3489                 if (raw_types[i] == NAME_TBD) {
3490                         if (CHECK(next_str_idx == strs_cnt,
3491                                   "Error in getting next_str #%d",
3492                                   next_str_idx)) {
3493                                 err = -1;
3494                                 goto done;
3495                         }
3496                         ret_types[i] = strs_idx[next_str_idx++] - str;
3497                 } else if (IS_NAME_NTH(raw_types[i])) {
3498                         int idx = GET_NAME_NTH_IDX(raw_types[i]);
3499
3500                         if (CHECK(idx <= 0 || idx > strs_cnt,
3501                                   "Error getting string #%d, strs_cnt:%d",
3502                                   idx, strs_cnt)) {
3503                                 err = -1;
3504                                 goto done;
3505                         }
3506                         ret_types[i] = strs_idx[idx-1] - str;
3507                 } else {
3508                         ret_types[i] = raw_types[i];
3509                 }
3510         }
3511         offset += type_sec_size;
3512
3513         /* Copy string section */
3514         memcpy(raw_btf + offset, str, str_sec_size);
3515
3516         ret_hdr = (struct btf_header *)raw_btf;
3517         ret_hdr->type_len = type_sec_size;
3518         ret_hdr->str_off = type_sec_size;
3519         ret_hdr->str_len = str_sec_size;
3520
3521         *btf_size = size_needed;
3522         if (ret_next_str)
3523                 *ret_next_str =
3524                         next_str_idx < strs_cnt ? strs_idx[next_str_idx] : NULL;
3525
3526 done:
3527         if (err) {
3528                 if (raw_btf)
3529                         free(raw_btf);
3530                 if (strs_idx)
3531                         free(strs_idx);
3532                 return NULL;
3533         }
3534         return raw_btf;
3535 }
3536
3537 static int do_test_raw(unsigned int test_num)
3538 {
3539         struct btf_raw_test *test = &raw_tests[test_num - 1];
3540         struct bpf_create_map_attr create_attr = {};
3541         int map_fd = -1, btf_fd = -1;
3542         unsigned int raw_btf_size;
3543         struct btf_header *hdr;
3544         void *raw_btf;
3545         int err;
3546
3547         fprintf(stderr, "BTF raw test[%u] (%s): ", test_num, test->descr);
3548         raw_btf = btf_raw_create(&hdr_tmpl,
3549                                  test->raw_types,
3550                                  test->str_sec,
3551                                  test->str_sec_size,
3552                                  &raw_btf_size, NULL);
3553
3554         if (!raw_btf)
3555                 return -1;
3556
3557         hdr = raw_btf;
3558
3559         hdr->hdr_len = (int)hdr->hdr_len + test->hdr_len_delta;
3560         hdr->type_off = (int)hdr->type_off + test->type_off_delta;
3561         hdr->str_off = (int)hdr->str_off + test->str_off_delta;
3562         hdr->str_len = (int)hdr->str_len + test->str_len_delta;
3563
3564         *btf_log_buf = '\0';
3565         btf_fd = bpf_load_btf(raw_btf, raw_btf_size,
3566                               btf_log_buf, BTF_LOG_BUF_SIZE,
3567                               args.always_log);
3568         free(raw_btf);
3569
3570         err = ((btf_fd == -1) != test->btf_load_err);
3571         if (CHECK(err, "btf_fd:%d test->btf_load_err:%u",
3572                   btf_fd, test->btf_load_err) ||
3573             CHECK(test->err_str && !strstr(btf_log_buf, test->err_str),
3574                   "expected err_str:%s", test->err_str)) {
3575                 err = -1;
3576                 goto done;
3577         }
3578
3579         if (err || btf_fd == -1)
3580                 goto done;
3581
3582         create_attr.name = test->map_name;
3583         create_attr.map_type = test->map_type;
3584         create_attr.key_size = test->key_size;
3585         create_attr.value_size = test->value_size;
3586         create_attr.max_entries = test->max_entries;
3587         create_attr.btf_fd = btf_fd;
3588         create_attr.btf_key_type_id = test->key_type_id;
3589         create_attr.btf_value_type_id = test->value_type_id;
3590
3591         map_fd = bpf_create_map_xattr(&create_attr);
3592
3593         err = ((map_fd == -1) != test->map_create_err);
3594         CHECK(err, "map_fd:%d test->map_create_err:%u",
3595               map_fd, test->map_create_err);
3596
3597 done:
3598         if (!err)
3599                 fprintf(stderr, "OK");
3600
3601         if (*btf_log_buf && (err || args.always_log))
3602                 fprintf(stderr, "\n%s", btf_log_buf);
3603
3604         if (btf_fd != -1)
3605                 close(btf_fd);
3606         if (map_fd != -1)
3607                 close(map_fd);
3608
3609         return err;
3610 }
3611
3612 static int test_raw(void)
3613 {
3614         unsigned int i;
3615         int err = 0;
3616
3617         if (args.raw_test_num)
3618                 return count_result(do_test_raw(args.raw_test_num));
3619
3620         for (i = 1; i <= ARRAY_SIZE(raw_tests); i++)
3621                 err |= count_result(do_test_raw(i));
3622
3623         return err;
3624 }
3625
3626 struct btf_get_info_test {
3627         const char *descr;
3628         const char *str_sec;
3629         __u32 raw_types[MAX_NR_RAW_U32];
3630         __u32 str_sec_size;
3631         int btf_size_delta;
3632         int (*special_test)(unsigned int test_num);
3633 };
3634
3635 static int test_big_btf_info(unsigned int test_num);
3636 static int test_btf_id(unsigned int test_num);
3637
3638 const struct btf_get_info_test get_info_tests[] = {
3639 {
3640         .descr = "== raw_btf_size+1",
3641         .raw_types = {
3642                 /* int */                               /* [1] */
3643                 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
3644                 BTF_END_RAW,
3645         },
3646         .str_sec = "",
3647         .str_sec_size = sizeof(""),
3648         .btf_size_delta = 1,
3649 },
3650 {
3651         .descr = "== raw_btf_size-3",
3652         .raw_types = {
3653                 /* int */                               /* [1] */
3654                 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
3655                 BTF_END_RAW,
3656         },
3657         .str_sec = "",
3658         .str_sec_size = sizeof(""),
3659         .btf_size_delta = -3,
3660 },
3661 {
3662         .descr = "Large bpf_btf_info",
3663         .raw_types = {
3664                 /* int */                               /* [1] */
3665                 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
3666                 BTF_END_RAW,
3667         },
3668         .str_sec = "",
3669         .str_sec_size = sizeof(""),
3670         .special_test = test_big_btf_info,
3671 },
3672 {
3673         .descr = "BTF ID",
3674         .raw_types = {
3675                 /* int */                               /* [1] */
3676                 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
3677                 /* unsigned int */                      /* [2] */
3678                 BTF_TYPE_INT_ENC(0, 0, 0, 32, 4),
3679                 BTF_END_RAW,
3680         },
3681         .str_sec = "",
3682         .str_sec_size = sizeof(""),
3683         .special_test = test_btf_id,
3684 },
3685 };
3686
3687 static inline __u64 ptr_to_u64(const void *ptr)
3688 {
3689         return (__u64)(unsigned long)ptr;
3690 }
3691
3692 static int test_big_btf_info(unsigned int test_num)
3693 {
3694         const struct btf_get_info_test *test = &get_info_tests[test_num - 1];
3695         uint8_t *raw_btf = NULL, *user_btf = NULL;
3696         unsigned int raw_btf_size;
3697         struct {
3698                 struct bpf_btf_info info;
3699                 uint64_t garbage;
3700         } info_garbage;
3701         struct bpf_btf_info *info;
3702         int btf_fd = -1, err;
3703         uint32_t info_len;
3704
3705         raw_btf = btf_raw_create(&hdr_tmpl,
3706                                  test->raw_types,
3707                                  test->str_sec,
3708                                  test->str_sec_size,
3709                                  &raw_btf_size, NULL);
3710
3711         if (!raw_btf)
3712                 return -1;
3713
3714         *btf_log_buf = '\0';
3715
3716         user_btf = malloc(raw_btf_size);
3717         if (CHECK(!user_btf, "!user_btf")) {
3718                 err = -1;
3719                 goto done;
3720         }
3721
3722         btf_fd = bpf_load_btf(raw_btf, raw_btf_size,
3723                               btf_log_buf, BTF_LOG_BUF_SIZE,
3724                               args.always_log);
3725         if (CHECK(btf_fd == -1, "errno:%d", errno)) {
3726                 err = -1;
3727                 goto done;
3728         }
3729
3730         /*
3731          * GET_INFO should error out if the userspace info
3732          * has non zero tailing bytes.
3733          */
3734         info = &info_garbage.info;
3735         memset(info, 0, sizeof(*info));
3736         info_garbage.garbage = 0xdeadbeef;
3737         info_len = sizeof(info_garbage);
3738         info->btf = ptr_to_u64(user_btf);
3739         info->btf_size = raw_btf_size;
3740
3741         err = bpf_obj_get_info_by_fd(btf_fd, info, &info_len);
3742         if (CHECK(!err, "!err")) {
3743                 err = -1;
3744                 goto done;
3745         }
3746
3747         /*
3748          * GET_INFO should succeed even info_len is larger than
3749          * the kernel supported as long as tailing bytes are zero.
3750          * The kernel supported info len should also be returned
3751          * to userspace.
3752          */
3753         info_garbage.garbage = 0;
3754         err = bpf_obj_get_info_by_fd(btf_fd, info, &info_len);
3755         if (CHECK(err || info_len != sizeof(*info),
3756                   "err:%d errno:%d info_len:%u sizeof(*info):%lu",
3757                   err, errno, info_len, sizeof(*info))) {
3758                 err = -1;
3759                 goto done;
3760         }
3761
3762         fprintf(stderr, "OK");
3763
3764 done:
3765         if (*btf_log_buf && (err || args.always_log))
3766                 fprintf(stderr, "\n%s", btf_log_buf);
3767
3768         free(raw_btf);
3769         free(user_btf);
3770
3771         if (btf_fd != -1)
3772                 close(btf_fd);
3773
3774         return err;
3775 }
3776
3777 static int test_btf_id(unsigned int test_num)
3778 {
3779         const struct btf_get_info_test *test = &get_info_tests[test_num - 1];
3780         struct bpf_create_map_attr create_attr = {};
3781         uint8_t *raw_btf = NULL, *user_btf[2] = {};
3782         int btf_fd[2] = {-1, -1}, map_fd = -1;
3783         struct bpf_map_info map_info = {};
3784         struct bpf_btf_info info[2] = {};
3785         unsigned int raw_btf_size;
3786         uint32_t info_len;
3787         int err, i, ret;
3788
3789         raw_btf = btf_raw_create(&hdr_tmpl,
3790                                  test->raw_types,
3791                                  test->str_sec,
3792                                  test->str_sec_size,
3793                                  &raw_btf_size, NULL);
3794
3795         if (!raw_btf)
3796                 return -1;
3797
3798         *btf_log_buf = '\0';
3799
3800         for (i = 0; i < 2; i++) {
3801                 user_btf[i] = malloc(raw_btf_size);
3802                 if (CHECK(!user_btf[i], "!user_btf[%d]", i)) {
3803                         err = -1;
3804                         goto done;
3805                 }
3806                 info[i].btf = ptr_to_u64(user_btf[i]);
3807                 info[i].btf_size = raw_btf_size;
3808         }
3809
3810         btf_fd[0] = 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[0] == -1, "errno:%d", errno)) {
3814                 err = -1;
3815                 goto done;
3816         }
3817
3818         /* Test BPF_OBJ_GET_INFO_BY_ID on btf_id */
3819         info_len = sizeof(info[0]);
3820         err = bpf_obj_get_info_by_fd(btf_fd[0], &info[0], &info_len);
3821         if (CHECK(err, "errno:%d", errno)) {
3822                 err = -1;
3823                 goto done;
3824         }
3825
3826         btf_fd[1] = bpf_btf_get_fd_by_id(info[0].id);
3827         if (CHECK(btf_fd[1] == -1, "errno:%d", errno)) {
3828                 err = -1;
3829                 goto done;
3830         }
3831
3832         ret = 0;
3833         err = bpf_obj_get_info_by_fd(btf_fd[1], &info[1], &info_len);
3834         if (CHECK(err || info[0].id != info[1].id ||
3835                   info[0].btf_size != info[1].btf_size ||
3836                   (ret = memcmp(user_btf[0], user_btf[1], info[0].btf_size)),
3837                   "err:%d errno:%d id0:%u id1:%u btf_size0:%u btf_size1:%u memcmp:%d",
3838                   err, errno, info[0].id, info[1].id,
3839                   info[0].btf_size, info[1].btf_size, ret)) {
3840                 err = -1;
3841                 goto done;
3842         }
3843
3844         /* Test btf members in struct bpf_map_info */
3845         create_attr.name = "test_btf_id";
3846         create_attr.map_type = BPF_MAP_TYPE_ARRAY;
3847         create_attr.key_size = sizeof(int);
3848         create_attr.value_size = sizeof(unsigned int);
3849         create_attr.max_entries = 4;
3850         create_attr.btf_fd = btf_fd[0];
3851         create_attr.btf_key_type_id = 1;
3852         create_attr.btf_value_type_id = 2;
3853
3854         map_fd = bpf_create_map_xattr(&create_attr);
3855         if (CHECK(map_fd == -1, "errno:%d", errno)) {
3856                 err = -1;
3857                 goto done;
3858         }
3859
3860         info_len = sizeof(map_info);
3861         err = bpf_obj_get_info_by_fd(map_fd, &map_info, &info_len);
3862         if (CHECK(err || map_info.btf_id != info[0].id ||
3863                   map_info.btf_key_type_id != 1 || map_info.btf_value_type_id != 2,
3864                   "err:%d errno:%d info.id:%u btf_id:%u btf_key_type_id:%u btf_value_type_id:%u",
3865                   err, errno, info[0].id, map_info.btf_id, map_info.btf_key_type_id,
3866                   map_info.btf_value_type_id)) {
3867                 err = -1;
3868                 goto done;
3869         }
3870
3871         for (i = 0; i < 2; i++) {
3872                 close(btf_fd[i]);
3873                 btf_fd[i] = -1;
3874         }
3875
3876         /* Test BTF ID is removed from the kernel */
3877         btf_fd[0] = bpf_btf_get_fd_by_id(map_info.btf_id);
3878         if (CHECK(btf_fd[0] == -1, "errno:%d", errno)) {
3879                 err = -1;
3880                 goto done;
3881         }
3882         close(btf_fd[0]);
3883         btf_fd[0] = -1;
3884
3885         /* The map holds the last ref to BTF and its btf_id */
3886         close(map_fd);
3887         map_fd = -1;
3888         btf_fd[0] = bpf_btf_get_fd_by_id(map_info.btf_id);
3889         if (CHECK(btf_fd[0] != -1, "BTF lingers")) {
3890                 err = -1;
3891                 goto done;
3892         }
3893
3894         fprintf(stderr, "OK");
3895
3896 done:
3897         if (*btf_log_buf && (err || args.always_log))
3898                 fprintf(stderr, "\n%s", btf_log_buf);
3899
3900         free(raw_btf);
3901         if (map_fd != -1)
3902                 close(map_fd);
3903         for (i = 0; i < 2; i++) {
3904                 free(user_btf[i]);
3905                 if (btf_fd[i] != -1)
3906                         close(btf_fd[i]);
3907         }
3908
3909         return err;
3910 }
3911
3912 static int do_test_get_info(unsigned int test_num)
3913 {
3914         const struct btf_get_info_test *test = &get_info_tests[test_num - 1];
3915         unsigned int raw_btf_size, user_btf_size, expected_nbytes;
3916         uint8_t *raw_btf = NULL, *user_btf = NULL;
3917         struct bpf_btf_info info = {};
3918         int btf_fd = -1, err, ret;
3919         uint32_t info_len;
3920
3921         fprintf(stderr, "BTF GET_INFO test[%u] (%s): ",
3922                 test_num, test->descr);
3923
3924         if (test->special_test)
3925                 return test->special_test(test_num);
3926
3927         raw_btf = btf_raw_create(&hdr_tmpl,
3928                                  test->raw_types,
3929                                  test->str_sec,
3930                                  test->str_sec_size,
3931                                  &raw_btf_size, NULL);
3932
3933         if (!raw_btf)
3934                 return -1;
3935
3936         *btf_log_buf = '\0';
3937
3938         user_btf = malloc(raw_btf_size);
3939         if (CHECK(!user_btf, "!user_btf")) {
3940                 err = -1;
3941                 goto done;
3942         }
3943
3944         btf_fd = bpf_load_btf(raw_btf, raw_btf_size,
3945                               btf_log_buf, BTF_LOG_BUF_SIZE,
3946                               args.always_log);
3947         if (CHECK(btf_fd == -1, "errno:%d", errno)) {
3948                 err = -1;
3949                 goto done;
3950         }
3951
3952         user_btf_size = (int)raw_btf_size + test->btf_size_delta;
3953         expected_nbytes = min(raw_btf_size, user_btf_size);
3954         if (raw_btf_size > expected_nbytes)
3955                 memset(user_btf + expected_nbytes, 0xff,
3956                        raw_btf_size - expected_nbytes);
3957
3958         info_len = sizeof(info);
3959         info.btf = ptr_to_u64(user_btf);
3960         info.btf_size = user_btf_size;
3961
3962         ret = 0;
3963         err = bpf_obj_get_info_by_fd(btf_fd, &info, &info_len);
3964         if (CHECK(err || !info.id || info_len != sizeof(info) ||
3965                   info.btf_size != raw_btf_size ||
3966                   (ret = memcmp(raw_btf, user_btf, expected_nbytes)),
3967                   "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",
3968                   err, errno, info.id, info_len, sizeof(info),
3969                   raw_btf_size, info.btf_size, expected_nbytes, ret)) {
3970                 err = -1;
3971                 goto done;
3972         }
3973
3974         while (expected_nbytes < raw_btf_size) {
3975                 fprintf(stderr, "%u...", expected_nbytes);
3976                 if (CHECK(user_btf[expected_nbytes++] != 0xff,
3977                           "user_btf[%u]:%x != 0xff", expected_nbytes - 1,
3978                           user_btf[expected_nbytes - 1])) {
3979                         err = -1;
3980                         goto done;
3981                 }
3982         }
3983
3984         fprintf(stderr, "OK");
3985
3986 done:
3987         if (*btf_log_buf && (err || args.always_log))
3988                 fprintf(stderr, "\n%s", btf_log_buf);
3989
3990         free(raw_btf);
3991         free(user_btf);
3992
3993         if (btf_fd != -1)
3994                 close(btf_fd);
3995
3996         return err;
3997 }
3998
3999 static int test_get_info(void)
4000 {
4001         unsigned int i;
4002         int err = 0;
4003
4004         if (args.get_info_test_num)
4005                 return count_result(do_test_get_info(args.get_info_test_num));
4006
4007         for (i = 1; i <= ARRAY_SIZE(get_info_tests); i++)
4008                 err |= count_result(do_test_get_info(i));
4009
4010         return err;
4011 }
4012
4013 struct btf_file_test {
4014         const char *file;
4015         bool btf_kv_notfound;
4016 };
4017
4018 static struct btf_file_test file_tests[] = {
4019         { .file = "test_btf_haskv.o", },
4020         { .file = "test_btf_newkv.o", },
4021         { .file = "test_btf_nokv.o", .btf_kv_notfound = true, },
4022 };
4023
4024 static int do_test_file(unsigned int test_num)
4025 {
4026         const struct btf_file_test *test = &file_tests[test_num - 1];
4027         const char *expected_fnames[] = {"_dummy_tracepoint",
4028                                          "test_long_fname_1",
4029                                          "test_long_fname_2"};
4030         struct btf_ext *btf_ext = NULL;
4031         struct bpf_prog_info info = {};
4032         struct bpf_object *obj = NULL;
4033         struct bpf_func_info *finfo;
4034         struct bpf_program *prog;
4035         __u32 info_len, rec_size;
4036         bool has_btf_ext = false;
4037         struct btf *btf = NULL;
4038         void *func_info = NULL;
4039         struct bpf_map *map;
4040         int i, err, prog_fd;
4041
4042         fprintf(stderr, "BTF libbpf test[%u] (%s): ", test_num,
4043                 test->file);
4044
4045         btf = btf__parse_elf(test->file, &btf_ext);
4046         if (IS_ERR(btf)) {
4047                 if (PTR_ERR(btf) == -ENOENT) {
4048                         fprintf(stderr, "SKIP. No ELF %s found", BTF_ELF_SEC);
4049                         skip_cnt++;
4050                         return 0;
4051                 }
4052                 return PTR_ERR(btf);
4053         }
4054         btf__free(btf);
4055
4056         has_btf_ext = btf_ext != NULL;
4057         btf_ext__free(btf_ext);
4058
4059         obj = bpf_object__open(test->file);
4060         if (CHECK(IS_ERR(obj), "obj: %ld", PTR_ERR(obj)))
4061                 return PTR_ERR(obj);
4062
4063         err = bpf_object__btf_fd(obj);
4064         if (CHECK(err == -1, "bpf_object__btf_fd: -1"))
4065                 goto done;
4066
4067         prog = bpf_program__next(NULL, obj);
4068         if (CHECK(!prog, "Cannot find bpf_prog")) {
4069                 err = -1;
4070                 goto done;
4071         }
4072
4073         bpf_program__set_type(prog, BPF_PROG_TYPE_TRACEPOINT);
4074         err = bpf_object__load(obj);
4075         if (CHECK(err < 0, "bpf_object__load: %d", err))
4076                 goto done;
4077         prog_fd = bpf_program__fd(prog);
4078
4079         map = bpf_object__find_map_by_name(obj, "btf_map");
4080         if (CHECK(!map, "btf_map not found")) {
4081                 err = -1;
4082                 goto done;
4083         }
4084
4085         err = (bpf_map__btf_key_type_id(map) == 0 || bpf_map__btf_value_type_id(map) == 0)
4086                 != test->btf_kv_notfound;
4087         if (CHECK(err, "btf_key_type_id:%u btf_value_type_id:%u test->btf_kv_notfound:%u",
4088                   bpf_map__btf_key_type_id(map), bpf_map__btf_value_type_id(map),
4089                   test->btf_kv_notfound))
4090                 goto done;
4091
4092         if (!has_btf_ext)
4093                 goto skip;
4094
4095         /* get necessary program info */
4096         info_len = sizeof(struct bpf_prog_info);
4097         err = bpf_obj_get_info_by_fd(prog_fd, &info, &info_len);
4098
4099         if (CHECK(err == -1, "invalid get info (1st) errno:%d", errno)) {
4100                 fprintf(stderr, "%s\n", btf_log_buf);
4101                 err = -1;
4102                 goto done;
4103         }
4104         if (CHECK(info.nr_func_info != 3,
4105                   "incorrect info.nr_func_info (1st) %d",
4106                   info.nr_func_info)) {
4107                 err = -1;
4108                 goto done;
4109         }
4110         rec_size = info.func_info_rec_size;
4111         if (CHECK(rec_size != sizeof(struct bpf_func_info),
4112                   "incorrect info.func_info_rec_size (1st) %d\n", rec_size)) {
4113                 err = -1;
4114                 goto done;
4115         }
4116
4117         func_info = malloc(info.nr_func_info * rec_size);
4118         if (CHECK(!func_info, "out of memory")) {
4119                 err = -1;
4120                 goto done;
4121         }
4122
4123         /* reset info to only retrieve func_info related data */
4124         memset(&info, 0, sizeof(info));
4125         info.nr_func_info = 3;
4126         info.func_info_rec_size = rec_size;
4127         info.func_info = ptr_to_u64(func_info);
4128
4129         err = bpf_obj_get_info_by_fd(prog_fd, &info, &info_len);
4130
4131         if (CHECK(err == -1, "invalid get info (2nd) errno:%d", errno)) {
4132                 fprintf(stderr, "%s\n", btf_log_buf);
4133                 err = -1;
4134                 goto done;
4135         }
4136         if (CHECK(info.nr_func_info != 3,
4137                   "incorrect info.nr_func_info (2nd) %d",
4138                   info.nr_func_info)) {
4139                 err = -1;
4140                 goto done;
4141         }
4142         if (CHECK(info.func_info_rec_size != rec_size,
4143                   "incorrect info.func_info_rec_size (2nd) %d",
4144                   info.func_info_rec_size)) {
4145                 err = -1;
4146                 goto done;
4147         }
4148
4149         err = btf__get_from_id(info.btf_id, &btf);
4150         if (CHECK(err, "cannot get btf from kernel, err: %d", err))
4151                 goto done;
4152
4153         /* check three functions */
4154         finfo = func_info;
4155         for (i = 0; i < 3; i++) {
4156                 const struct btf_type *t;
4157                 const char *fname;
4158
4159                 t = btf__type_by_id(btf, finfo->type_id);
4160                 if (CHECK(!t, "btf__type_by_id failure: id %u",
4161                           finfo->type_id)) {
4162                         err = -1;
4163                         goto done;
4164                 }
4165
4166                 fname = btf__name_by_offset(btf, t->name_off);
4167                 err = strcmp(fname, expected_fnames[i]);
4168                 /* for the second and third functions in .text section,
4169                  * the compiler may order them either way.
4170                  */
4171                 if (i && err)
4172                         err = strcmp(fname, expected_fnames[3 - i]);
4173                 if (CHECK(err, "incorrect fname %s", fname ? : "")) {
4174                         err = -1;
4175                         goto done;
4176                 }
4177
4178                 finfo = (void *)finfo + rec_size;
4179         }
4180
4181 skip:
4182         fprintf(stderr, "OK");
4183
4184 done:
4185         free(func_info);
4186         bpf_object__close(obj);
4187         return err;
4188 }
4189
4190 static int test_file(void)
4191 {
4192         unsigned int i;
4193         int err = 0;
4194
4195         if (args.file_test_num)
4196                 return count_result(do_test_file(args.file_test_num));
4197
4198         for (i = 1; i <= ARRAY_SIZE(file_tests); i++)
4199                 err |= count_result(do_test_file(i));
4200
4201         return err;
4202 }
4203
4204 const char *pprint_enum_str[] = {
4205         "ENUM_ZERO",
4206         "ENUM_ONE",
4207         "ENUM_TWO",
4208         "ENUM_THREE",
4209 };
4210
4211 struct pprint_mapv {
4212         uint32_t ui32;
4213         uint16_t ui16;
4214         /* 2 bytes hole */
4215         int32_t si32;
4216         uint32_t unused_bits2a:2,
4217                 bits28:28,
4218                 unused_bits2b:2;
4219         union {
4220                 uint64_t ui64;
4221                 uint8_t ui8a[8];
4222         };
4223         enum {
4224                 ENUM_ZERO,
4225                 ENUM_ONE,
4226                 ENUM_TWO,
4227                 ENUM_THREE,
4228         } aenum;
4229         uint32_t ui32b;
4230         uint32_t bits2c:2;
4231         uint8_t si8_4[2][2];
4232 };
4233
4234 #ifdef __SIZEOF_INT128__
4235 struct pprint_mapv_int128 {
4236         __int128 si128a;
4237         __int128 si128b;
4238         unsigned __int128 bits3:3;
4239         unsigned __int128 bits80:80;
4240         unsigned __int128 ui128;
4241 };
4242 #endif
4243
4244 static struct btf_raw_test pprint_test_template[] = {
4245 {
4246         .raw_types = {
4247                 /* unsighed char */                     /* [1] */
4248                 BTF_TYPE_INT_ENC(NAME_TBD, 0, 0, 8, 1),
4249                 /* unsigned short */                    /* [2] */
4250                 BTF_TYPE_INT_ENC(NAME_TBD, 0, 0, 16, 2),
4251                 /* unsigned int */                      /* [3] */
4252                 BTF_TYPE_INT_ENC(NAME_TBD, 0, 0, 32, 4),
4253                 /* int */                               /* [4] */
4254                 BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),
4255                 /* unsigned long long */                /* [5] */
4256                 BTF_TYPE_INT_ENC(NAME_TBD, 0, 0, 64, 8),
4257                 /* 2 bits */                            /* [6] */
4258                 BTF_TYPE_INT_ENC(0, 0, 0, 2, 2),
4259                 /* 28 bits */                           /* [7] */
4260                 BTF_TYPE_INT_ENC(0, 0, 0, 28, 4),
4261                 /* uint8_t[8] */                        /* [8] */
4262                 BTF_TYPE_ARRAY_ENC(9, 1, 8),
4263                 /* typedef unsigned char uint8_t */     /* [9] */
4264                 BTF_TYPEDEF_ENC(NAME_TBD, 1),
4265                 /* typedef unsigned short uint16_t */   /* [10] */
4266                 BTF_TYPEDEF_ENC(NAME_TBD, 2),
4267                 /* typedef unsigned int uint32_t */     /* [11] */
4268                 BTF_TYPEDEF_ENC(NAME_TBD, 3),
4269                 /* typedef int int32_t */               /* [12] */
4270                 BTF_TYPEDEF_ENC(NAME_TBD, 4),
4271                 /* typedef unsigned long long uint64_t *//* [13] */
4272                 BTF_TYPEDEF_ENC(NAME_TBD, 5),
4273                 /* union (anon) */                      /* [14] */
4274                 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_UNION, 0, 2), 8),
4275                 BTF_MEMBER_ENC(NAME_TBD, 13, 0),/* uint64_t ui64; */
4276                 BTF_MEMBER_ENC(NAME_TBD, 8, 0), /* uint8_t ui8a[8]; */
4277                 /* enum (anon) */                       /* [15] */
4278                 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_ENUM, 0, 4), 4),
4279                 BTF_ENUM_ENC(NAME_TBD, 0),
4280                 BTF_ENUM_ENC(NAME_TBD, 1),
4281                 BTF_ENUM_ENC(NAME_TBD, 2),
4282                 BTF_ENUM_ENC(NAME_TBD, 3),
4283                 /* struct pprint_mapv */                /* [16] */
4284                 BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 11), 40),
4285                 BTF_MEMBER_ENC(NAME_TBD, 11, 0),        /* uint32_t ui32 */
4286                 BTF_MEMBER_ENC(NAME_TBD, 10, 32),       /* uint16_t ui16 */
4287                 BTF_MEMBER_ENC(NAME_TBD, 12, 64),       /* int32_t si32 */
4288                 BTF_MEMBER_ENC(NAME_TBD, 6, 96),        /* unused_bits2a */
4289                 BTF_MEMBER_ENC(NAME_TBD, 7, 98),        /* bits28 */
4290                 BTF_MEMBER_ENC(NAME_TBD, 6, 126),       /* unused_bits2b */
4291                 BTF_MEMBER_ENC(0, 14, 128),             /* union (anon) */
4292                 BTF_MEMBER_ENC(NAME_TBD, 15, 192),      /* aenum */
4293                 BTF_MEMBER_ENC(NAME_TBD, 11, 224),      /* uint32_t ui32b */
4294                 BTF_MEMBER_ENC(NAME_TBD, 6, 256),       /* bits2c */
4295                 BTF_MEMBER_ENC(NAME_TBD, 17, 264),      /* si8_4 */
4296                 BTF_TYPE_ARRAY_ENC(18, 1, 2),           /* [17] */
4297                 BTF_TYPE_ARRAY_ENC(1, 1, 2),            /* [18] */
4298                 BTF_END_RAW,
4299         },
4300         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"),
4301         .key_size = sizeof(unsigned int),
4302         .value_size = sizeof(struct pprint_mapv),
4303         .key_type_id = 3,       /* unsigned int */
4304         .value_type_id = 16,    /* struct pprint_mapv */
4305         .max_entries = 128 * 1024,
4306 },
4307
4308 {
4309         /* this type will have the same type as the
4310          * first .raw_types definition, but struct type will
4311          * be encoded with kind_flag set.
4312          */
4313         .raw_types = {
4314                 /* unsighed char */                     /* [1] */
4315                 BTF_TYPE_INT_ENC(NAME_TBD, 0, 0, 8, 1),
4316                 /* unsigned short */                    /* [2] */
4317                 BTF_TYPE_INT_ENC(NAME_TBD, 0, 0, 16, 2),
4318                 /* unsigned int */                      /* [3] */
4319                 BTF_TYPE_INT_ENC(NAME_TBD, 0, 0, 32, 4),
4320                 /* int */                               /* [4] */
4321                 BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),
4322                 /* unsigned long long */                /* [5] */
4323                 BTF_TYPE_INT_ENC(NAME_TBD, 0, 0, 64, 8),
4324                 BTF_TYPE_INT_ENC(0, 0, 0, 32, 4),       /* [6] */
4325                 BTF_TYPE_INT_ENC(0, 0, 0, 32, 4),       /* [7] */
4326                 /* uint8_t[8] */                        /* [8] */
4327                 BTF_TYPE_ARRAY_ENC(9, 1, 8),
4328                 /* typedef unsigned char uint8_t */     /* [9] */
4329                 BTF_TYPEDEF_ENC(NAME_TBD, 1),
4330                 /* typedef unsigned short uint16_t */   /* [10] */
4331                 BTF_TYPEDEF_ENC(NAME_TBD, 2),
4332                 /* typedef unsigned int uint32_t */     /* [11] */
4333                 BTF_TYPEDEF_ENC(NAME_TBD, 3),
4334                 /* typedef int int32_t */               /* [12] */
4335                 BTF_TYPEDEF_ENC(NAME_TBD, 4),
4336                 /* typedef unsigned long long uint64_t *//* [13] */
4337                 BTF_TYPEDEF_ENC(NAME_TBD, 5),
4338                 /* union (anon) */                      /* [14] */
4339                 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_UNION, 0, 2), 8),
4340                 BTF_MEMBER_ENC(NAME_TBD, 13, 0),/* uint64_t ui64; */
4341                 BTF_MEMBER_ENC(NAME_TBD, 8, 0), /* uint8_t ui8a[8]; */
4342                 /* enum (anon) */                       /* [15] */
4343                 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_ENUM, 0, 4), 4),
4344                 BTF_ENUM_ENC(NAME_TBD, 0),
4345                 BTF_ENUM_ENC(NAME_TBD, 1),
4346                 BTF_ENUM_ENC(NAME_TBD, 2),
4347                 BTF_ENUM_ENC(NAME_TBD, 3),
4348                 /* struct pprint_mapv */                /* [16] */
4349                 BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 1, 11), 40),
4350                 BTF_MEMBER_ENC(NAME_TBD, 11, BTF_MEMBER_OFFSET(0, 0)),  /* uint32_t ui32 */
4351                 BTF_MEMBER_ENC(NAME_TBD, 10, BTF_MEMBER_OFFSET(0, 32)), /* uint16_t ui16 */
4352                 BTF_MEMBER_ENC(NAME_TBD, 12, BTF_MEMBER_OFFSET(0, 64)), /* int32_t si32 */
4353                 BTF_MEMBER_ENC(NAME_TBD, 6, BTF_MEMBER_OFFSET(2, 96)),  /* unused_bits2a */
4354                 BTF_MEMBER_ENC(NAME_TBD, 7, BTF_MEMBER_OFFSET(28, 98)), /* bits28 */
4355                 BTF_MEMBER_ENC(NAME_TBD, 6, BTF_MEMBER_OFFSET(2, 126)), /* unused_bits2b */
4356                 BTF_MEMBER_ENC(0, 14, BTF_MEMBER_OFFSET(0, 128)),       /* union (anon) */
4357                 BTF_MEMBER_ENC(NAME_TBD, 15, BTF_MEMBER_OFFSET(0, 192)),        /* aenum */
4358                 BTF_MEMBER_ENC(NAME_TBD, 11, BTF_MEMBER_OFFSET(0, 224)),        /* uint32_t ui32b */
4359                 BTF_MEMBER_ENC(NAME_TBD, 6, BTF_MEMBER_OFFSET(2, 256)), /* bits2c */
4360                 BTF_MEMBER_ENC(NAME_TBD, 17, 264),      /* si8_4 */
4361                 BTF_TYPE_ARRAY_ENC(18, 1, 2),           /* [17] */
4362                 BTF_TYPE_ARRAY_ENC(1, 1, 2),            /* [18] */
4363                 BTF_END_RAW,
4364         },
4365         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"),
4366         .key_size = sizeof(unsigned int),
4367         .value_size = sizeof(struct pprint_mapv),
4368         .key_type_id = 3,       /* unsigned int */
4369         .value_type_id = 16,    /* struct pprint_mapv */
4370         .max_entries = 128 * 1024,
4371 },
4372
4373 {
4374         /* this type will have the same layout as the
4375          * first .raw_types definition. The struct type will
4376          * be encoded with kind_flag set, bitfield members
4377          * are added typedef/const/volatile, and bitfield members
4378          * will have both int and enum types.
4379          */
4380         .raw_types = {
4381                 /* unsighed char */                     /* [1] */
4382                 BTF_TYPE_INT_ENC(NAME_TBD, 0, 0, 8, 1),
4383                 /* unsigned short */                    /* [2] */
4384                 BTF_TYPE_INT_ENC(NAME_TBD, 0, 0, 16, 2),
4385                 /* unsigned int */                      /* [3] */
4386                 BTF_TYPE_INT_ENC(NAME_TBD, 0, 0, 32, 4),
4387                 /* int */                               /* [4] */
4388                 BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),
4389                 /* unsigned long long */                /* [5] */
4390                 BTF_TYPE_INT_ENC(NAME_TBD, 0, 0, 64, 8),
4391                 BTF_TYPE_INT_ENC(0, 0, 0, 32, 4),       /* [6] */
4392                 BTF_TYPE_INT_ENC(0, 0, 0, 32, 4),       /* [7] */
4393                 /* uint8_t[8] */                        /* [8] */
4394                 BTF_TYPE_ARRAY_ENC(9, 1, 8),
4395                 /* typedef unsigned char uint8_t */     /* [9] */
4396                 BTF_TYPEDEF_ENC(NAME_TBD, 1),
4397                 /* typedef unsigned short uint16_t */   /* [10] */
4398                 BTF_TYPEDEF_ENC(NAME_TBD, 2),
4399                 /* typedef unsigned int uint32_t */     /* [11] */
4400                 BTF_TYPEDEF_ENC(NAME_TBD, 3),
4401                 /* typedef int int32_t */               /* [12] */
4402                 BTF_TYPEDEF_ENC(NAME_TBD, 4),
4403                 /* typedef unsigned long long uint64_t *//* [13] */
4404                 BTF_TYPEDEF_ENC(NAME_TBD, 5),
4405                 /* union (anon) */                      /* [14] */
4406                 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_UNION, 0, 2), 8),
4407                 BTF_MEMBER_ENC(NAME_TBD, 13, 0),/* uint64_t ui64; */
4408                 BTF_MEMBER_ENC(NAME_TBD, 8, 0), /* uint8_t ui8a[8]; */
4409                 /* enum (anon) */                       /* [15] */
4410                 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_ENUM, 0, 4), 4),
4411                 BTF_ENUM_ENC(NAME_TBD, 0),
4412                 BTF_ENUM_ENC(NAME_TBD, 1),
4413                 BTF_ENUM_ENC(NAME_TBD, 2),
4414                 BTF_ENUM_ENC(NAME_TBD, 3),
4415                 /* struct pprint_mapv */                /* [16] */
4416                 BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 1, 11), 40),
4417                 BTF_MEMBER_ENC(NAME_TBD, 11, BTF_MEMBER_OFFSET(0, 0)),  /* uint32_t ui32 */
4418                 BTF_MEMBER_ENC(NAME_TBD, 10, BTF_MEMBER_OFFSET(0, 32)), /* uint16_t ui16 */
4419                 BTF_MEMBER_ENC(NAME_TBD, 12, BTF_MEMBER_OFFSET(0, 64)), /* int32_t si32 */
4420                 BTF_MEMBER_ENC(NAME_TBD, 17, BTF_MEMBER_OFFSET(2, 96)), /* unused_bits2a */
4421                 BTF_MEMBER_ENC(NAME_TBD, 7, BTF_MEMBER_OFFSET(28, 98)), /* bits28 */
4422                 BTF_MEMBER_ENC(NAME_TBD, 19, BTF_MEMBER_OFFSET(2, 126)),/* unused_bits2b */
4423                 BTF_MEMBER_ENC(0, 14, BTF_MEMBER_OFFSET(0, 128)),       /* union (anon) */
4424                 BTF_MEMBER_ENC(NAME_TBD, 15, BTF_MEMBER_OFFSET(0, 192)),        /* aenum */
4425                 BTF_MEMBER_ENC(NAME_TBD, 11, BTF_MEMBER_OFFSET(0, 224)),        /* uint32_t ui32b */
4426                 BTF_MEMBER_ENC(NAME_TBD, 17, BTF_MEMBER_OFFSET(2, 256)),        /* bits2c */
4427                 BTF_MEMBER_ENC(NAME_TBD, 20, BTF_MEMBER_OFFSET(0, 264)),        /* si8_4 */
4428                 /* typedef unsigned int ___int */       /* [17] */
4429                 BTF_TYPEDEF_ENC(NAME_TBD, 18),
4430                 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_VOLATILE, 0, 0), 6),      /* [18] */
4431                 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_CONST, 0, 0), 15),        /* [19] */
4432                 BTF_TYPE_ARRAY_ENC(21, 1, 2),                                   /* [20] */
4433                 BTF_TYPE_ARRAY_ENC(1, 1, 2),                                    /* [21] */
4434                 BTF_END_RAW,
4435         },
4436         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"),
4437         .key_size = sizeof(unsigned int),
4438         .value_size = sizeof(struct pprint_mapv),
4439         .key_type_id = 3,       /* unsigned int */
4440         .value_type_id = 16,    /* struct pprint_mapv */
4441         .max_entries = 128 * 1024,
4442 },
4443
4444 #ifdef __SIZEOF_INT128__
4445 {
4446         /* test int128 */
4447         .raw_types = {
4448                 /* unsigned int */                              /* [1] */
4449                 BTF_TYPE_INT_ENC(NAME_TBD, 0, 0, 32, 4),
4450                 /* __int128 */                                  /* [2] */
4451                 BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 128, 16),
4452                 /* unsigned __int128 */                         /* [3] */
4453                 BTF_TYPE_INT_ENC(NAME_TBD, 0, 0, 128, 16),
4454                 /* struct pprint_mapv_int128 */                 /* [4] */
4455                 BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 1, 5), 64),
4456                 BTF_MEMBER_ENC(NAME_TBD, 2, BTF_MEMBER_OFFSET(0, 0)),           /* si128a */
4457                 BTF_MEMBER_ENC(NAME_TBD, 2, BTF_MEMBER_OFFSET(0, 128)),         /* si128b */
4458                 BTF_MEMBER_ENC(NAME_TBD, 3, BTF_MEMBER_OFFSET(3, 256)),         /* bits3 */
4459                 BTF_MEMBER_ENC(NAME_TBD, 3, BTF_MEMBER_OFFSET(80, 259)),        /* bits80 */
4460                 BTF_MEMBER_ENC(NAME_TBD, 3, BTF_MEMBER_OFFSET(0, 384)),         /* ui128 */
4461                 BTF_END_RAW,
4462         },
4463         BTF_STR_SEC("\0unsigned int\0__int128\0unsigned __int128\0pprint_mapv_int128\0si128a\0si128b\0bits3\0bits80\0ui128"),
4464         .key_size = sizeof(unsigned int),
4465         .value_size = sizeof(struct pprint_mapv_int128),
4466         .key_type_id = 1,
4467         .value_type_id = 4,
4468         .max_entries = 128 * 1024,
4469         .mapv_kind = PPRINT_MAPV_KIND_INT128,
4470 },
4471 #endif
4472
4473 };
4474
4475 static struct btf_pprint_test_meta {
4476         const char *descr;
4477         enum bpf_map_type map_type;
4478         const char *map_name;
4479         bool ordered_map;
4480         bool lossless_map;
4481         bool percpu_map;
4482 } pprint_tests_meta[] = {
4483 {
4484         .descr = "BTF pretty print array",
4485         .map_type = BPF_MAP_TYPE_ARRAY,
4486         .map_name = "pprint_test_array",
4487         .ordered_map = true,
4488         .lossless_map = true,
4489         .percpu_map = false,
4490 },
4491
4492 {
4493         .descr = "BTF pretty print hash",
4494         .map_type = BPF_MAP_TYPE_HASH,
4495         .map_name = "pprint_test_hash",
4496         .ordered_map = false,
4497         .lossless_map = true,
4498         .percpu_map = false,
4499 },
4500
4501 {
4502         .descr = "BTF pretty print lru hash",
4503         .map_type = BPF_MAP_TYPE_LRU_HASH,
4504         .map_name = "pprint_test_lru_hash",
4505         .ordered_map = false,
4506         .lossless_map = false,
4507         .percpu_map = false,
4508 },
4509
4510 {
4511         .descr = "BTF pretty print percpu array",
4512         .map_type = BPF_MAP_TYPE_PERCPU_ARRAY,
4513         .map_name = "pprint_test_percpu_array",
4514         .ordered_map = true,
4515         .lossless_map = true,
4516         .percpu_map = true,
4517 },
4518
4519 {
4520         .descr = "BTF pretty print percpu hash",
4521         .map_type = BPF_MAP_TYPE_PERCPU_HASH,
4522         .map_name = "pprint_test_percpu_hash",
4523         .ordered_map = false,
4524         .lossless_map = true,
4525         .percpu_map = true,
4526 },
4527
4528 {
4529         .descr = "BTF pretty print lru percpu hash",
4530         .map_type = BPF_MAP_TYPE_LRU_PERCPU_HASH,
4531         .map_name = "pprint_test_lru_percpu_hash",
4532         .ordered_map = false,
4533         .lossless_map = false,
4534         .percpu_map = true,
4535 },
4536
4537 };
4538
4539 static size_t get_pprint_mapv_size(enum pprint_mapv_kind_t mapv_kind)
4540 {
4541         if (mapv_kind == PPRINT_MAPV_KIND_BASIC)
4542                 return sizeof(struct pprint_mapv);
4543
4544 #ifdef __SIZEOF_INT128__
4545         if (mapv_kind == PPRINT_MAPV_KIND_INT128)
4546                 return sizeof(struct pprint_mapv_int128);
4547 #endif
4548
4549         assert(0);
4550 }
4551
4552 static void set_pprint_mapv(enum pprint_mapv_kind_t mapv_kind,
4553                             void *mapv, uint32_t i,
4554                             int num_cpus, int rounded_value_size)
4555 {
4556         int cpu;
4557
4558         if (mapv_kind == PPRINT_MAPV_KIND_BASIC) {
4559                 struct pprint_mapv *v = mapv;
4560
4561                 for (cpu = 0; cpu < num_cpus; cpu++) {
4562                         v->ui32 = i + cpu;
4563                         v->si32 = -i;
4564                         v->unused_bits2a = 3;
4565                         v->bits28 = i;
4566                         v->unused_bits2b = 3;
4567                         v->ui64 = i;
4568                         v->aenum = i & 0x03;
4569                         v->ui32b = 4;
4570                         v->bits2c = 1;
4571                         v->si8_4[0][0] = (cpu + i) & 0xff;
4572                         v->si8_4[0][1] = (cpu + i + 1) & 0xff;
4573                         v->si8_4[1][0] = (cpu + i + 2) & 0xff;
4574                         v->si8_4[1][1] = (cpu + i + 3) & 0xff;
4575                         v = (void *)v + rounded_value_size;
4576                 }
4577         }
4578
4579 #ifdef __SIZEOF_INT128__
4580         if (mapv_kind == PPRINT_MAPV_KIND_INT128) {
4581                 struct pprint_mapv_int128 *v = mapv;
4582
4583                 for (cpu = 0; cpu < num_cpus; cpu++) {
4584                         v->si128a = i;
4585                         v->si128b = -i;
4586                         v->bits3 = i & 0x07;
4587                         v->bits80 = (((unsigned __int128)1) << 64) + i;
4588                         v->ui128 = (((unsigned __int128)2) << 64) + i;
4589                         v = (void *)v + rounded_value_size;
4590                 }
4591         }
4592 #endif
4593 }
4594
4595 ssize_t get_pprint_expected_line(enum pprint_mapv_kind_t mapv_kind,
4596                                  char *expected_line, ssize_t line_size,
4597                                  bool percpu_map, unsigned int next_key,
4598                                  int cpu, void *mapv)
4599 {
4600         ssize_t nexpected_line = -1;
4601
4602         if (mapv_kind == PPRINT_MAPV_KIND_BASIC) {
4603                 struct pprint_mapv *v = mapv;
4604
4605                 nexpected_line = snprintf(expected_line, line_size,
4606                                           "%s%u: {%u,0,%d,0x%x,0x%x,0x%x,"
4607                                           "{%lu|[%u,%u,%u,%u,%u,%u,%u,%u]},%s,"
4608                                           "%u,0x%x,[[%d,%d],[%d,%d]]}\n",
4609                                           percpu_map ? "\tcpu" : "",
4610                                           percpu_map ? cpu : next_key,
4611                                           v->ui32, v->si32,
4612                                           v->unused_bits2a,
4613                                           v->bits28,
4614                                           v->unused_bits2b,
4615                                           v->ui64,
4616                                           v->ui8a[0], v->ui8a[1],
4617                                           v->ui8a[2], v->ui8a[3],
4618                                           v->ui8a[4], v->ui8a[5],
4619                                           v->ui8a[6], v->ui8a[7],
4620                                           pprint_enum_str[v->aenum],
4621                                           v->ui32b,
4622                                           v->bits2c,
4623                                           v->si8_4[0][0], v->si8_4[0][1],
4624                                           v->si8_4[1][0], v->si8_4[1][1]);
4625         }
4626
4627 #ifdef __SIZEOF_INT128__
4628         if (mapv_kind == PPRINT_MAPV_KIND_INT128) {
4629                 struct pprint_mapv_int128 *v = mapv;
4630
4631                 nexpected_line = snprintf(expected_line, line_size,
4632                                           "%s%u: {0x%lx,0x%lx,0x%lx,"
4633                                           "0x%lx%016lx,0x%lx%016lx}\n",
4634                                           percpu_map ? "\tcpu" : "",
4635                                           percpu_map ? cpu : next_key,
4636                                           (uint64_t)v->si128a,
4637                                           (uint64_t)v->si128b,
4638                                           (uint64_t)v->bits3,
4639                                           (uint64_t)(v->bits80 >> 64),
4640                                           (uint64_t)v->bits80,
4641                                           (uint64_t)(v->ui128 >> 64),
4642                                           (uint64_t)v->ui128);
4643         }
4644 #endif
4645
4646         return nexpected_line;
4647 }
4648
4649 static int check_line(const char *expected_line, int nexpected_line,
4650                       int expected_line_len, const char *line)
4651 {
4652         if (CHECK(nexpected_line == expected_line_len,
4653                   "expected_line is too long"))
4654                 return -1;
4655
4656         if (strcmp(expected_line, line)) {
4657                 fprintf(stderr, "unexpected pprint output\n");
4658                 fprintf(stderr, "expected: %s", expected_line);
4659                 fprintf(stderr, "    read: %s", line);
4660                 return -1;
4661         }
4662
4663         return 0;
4664 }
4665
4666
4667 static int do_test_pprint(int test_num)
4668 {
4669         const struct btf_raw_test *test = &pprint_test_template[test_num];
4670         enum pprint_mapv_kind_t mapv_kind = test->mapv_kind;
4671         struct bpf_create_map_attr create_attr = {};
4672         bool ordered_map, lossless_map, percpu_map;
4673         int err, ret, num_cpus, rounded_value_size;
4674         unsigned int key, nr_read_elems;
4675         int map_fd = -1, btf_fd = -1;
4676         unsigned int raw_btf_size;
4677         char expected_line[255];
4678         FILE *pin_file = NULL;
4679         char pin_path[255];
4680         size_t line_len = 0;
4681         char *line = NULL;
4682         void *mapv = NULL;
4683         uint8_t *raw_btf;
4684         ssize_t nread;
4685
4686         fprintf(stderr, "%s(#%d)......", test->descr, test_num);
4687         raw_btf = btf_raw_create(&hdr_tmpl, test->raw_types,
4688                                  test->str_sec, test->str_sec_size,
4689                                  &raw_btf_size, NULL);
4690
4691         if (!raw_btf)
4692                 return -1;
4693
4694         *btf_log_buf = '\0';
4695         btf_fd = bpf_load_btf(raw_btf, raw_btf_size,
4696                               btf_log_buf, BTF_LOG_BUF_SIZE,
4697                               args.always_log);
4698         free(raw_btf);
4699
4700         if (CHECK(btf_fd == -1, "errno:%d", errno)) {
4701                 err = -1;
4702                 goto done;
4703         }
4704
4705         create_attr.name = test->map_name;
4706         create_attr.map_type = test->map_type;
4707         create_attr.key_size = test->key_size;
4708         create_attr.value_size = test->value_size;
4709         create_attr.max_entries = test->max_entries;
4710         create_attr.btf_fd = btf_fd;
4711         create_attr.btf_key_type_id = test->key_type_id;
4712         create_attr.btf_value_type_id = test->value_type_id;
4713
4714         map_fd = bpf_create_map_xattr(&create_attr);
4715         if (CHECK(map_fd == -1, "errno:%d", errno)) {
4716                 err = -1;
4717                 goto done;
4718         }
4719
4720         ret = snprintf(pin_path, sizeof(pin_path), "%s/%s",
4721                        "/sys/fs/bpf", test->map_name);
4722
4723         if (CHECK(ret == sizeof(pin_path), "pin_path %s/%s is too long",
4724                   "/sys/fs/bpf", test->map_name)) {
4725                 err = -1;
4726                 goto done;
4727         }
4728
4729         err = bpf_obj_pin(map_fd, pin_path);
4730         if (CHECK(err, "bpf_obj_pin(%s): errno:%d.", pin_path, errno))
4731                 goto done;
4732
4733         percpu_map = test->percpu_map;
4734         num_cpus = percpu_map ? bpf_num_possible_cpus() : 1;
4735         rounded_value_size = round_up(get_pprint_mapv_size(mapv_kind), 8);
4736         mapv = calloc(num_cpus, rounded_value_size);
4737         if (CHECK(!mapv, "mapv allocation failure")) {
4738                 err = -1;
4739                 goto done;
4740         }
4741
4742         for (key = 0; key < test->max_entries; key++) {
4743                 set_pprint_mapv(mapv_kind, mapv, key, num_cpus, rounded_value_size);
4744                 bpf_map_update_elem(map_fd, &key, mapv, 0);
4745         }
4746
4747         pin_file = fopen(pin_path, "r");
4748         if (CHECK(!pin_file, "fopen(%s): errno:%d", pin_path, errno)) {
4749                 err = -1;
4750                 goto done;
4751         }
4752
4753         /* Skip lines start with '#' */
4754         while ((nread = getline(&line, &line_len, pin_file)) > 0 &&
4755                *line == '#')
4756                 ;
4757
4758         if (CHECK(nread <= 0, "Unexpected EOF")) {
4759                 err = -1;
4760                 goto done;
4761         }
4762
4763         nr_read_elems = 0;
4764         ordered_map = test->ordered_map;
4765         lossless_map = test->lossless_map;
4766         do {
4767                 ssize_t nexpected_line;
4768                 unsigned int next_key;
4769                 void *cmapv;
4770                 int cpu;
4771
4772                 next_key = ordered_map ? nr_read_elems : atoi(line);
4773                 set_pprint_mapv(mapv_kind, mapv, next_key, num_cpus, rounded_value_size);
4774                 cmapv = mapv;
4775
4776                 for (cpu = 0; cpu < num_cpus; cpu++) {
4777                         if (percpu_map) {
4778                                 /* for percpu map, the format looks like:
4779                                  * <key>: {
4780                                  *      cpu0: <value_on_cpu0>
4781                                  *      cpu1: <value_on_cpu1>
4782                                  *      ...
4783                                  *      cpun: <value_on_cpun>
4784                                  * }
4785                                  *
4786                                  * let us verify the line containing the key here.
4787                                  */
4788                                 if (cpu == 0) {
4789                                         nexpected_line = snprintf(expected_line,
4790                                                                   sizeof(expected_line),
4791                                                                   "%u: {\n",
4792                                                                   next_key);
4793
4794                                         err = check_line(expected_line, nexpected_line,
4795                                                          sizeof(expected_line), line);
4796                                         if (err == -1)
4797                                                 goto done;
4798                                 }
4799
4800                                 /* read value@cpu */
4801                                 nread = getline(&line, &line_len, pin_file);
4802                                 if (nread < 0)
4803                                         break;
4804                         }
4805
4806                         nexpected_line = get_pprint_expected_line(mapv_kind, expected_line,
4807                                                                   sizeof(expected_line),
4808                                                                   percpu_map, next_key,
4809                                                                   cpu, cmapv);
4810                         err = check_line(expected_line, nexpected_line,
4811                                          sizeof(expected_line), line);
4812                         if (err == -1)
4813                                 goto done;
4814
4815                         cmapv = cmapv + rounded_value_size;
4816                 }
4817
4818                 if (percpu_map) {
4819                         /* skip the last bracket for the percpu map */
4820                         nread = getline(&line, &line_len, pin_file);
4821                         if (nread < 0)
4822                                 break;
4823                 }
4824
4825                 nread = getline(&line, &line_len, pin_file);
4826         } while (++nr_read_elems < test->max_entries && nread > 0);
4827
4828         if (lossless_map &&
4829             CHECK(nr_read_elems < test->max_entries,
4830                   "Unexpected EOF. nr_read_elems:%u test->max_entries:%u",
4831                   nr_read_elems, test->max_entries)) {
4832                 err = -1;
4833                 goto done;
4834         }
4835
4836         if (CHECK(nread > 0, "Unexpected extra pprint output: %s", line)) {
4837                 err = -1;
4838                 goto done;
4839         }
4840
4841         err = 0;
4842
4843 done:
4844         if (mapv)
4845                 free(mapv);
4846         if (!err)
4847                 fprintf(stderr, "OK");
4848         if (*btf_log_buf && (err || args.always_log))
4849                 fprintf(stderr, "\n%s", btf_log_buf);
4850         if (btf_fd != -1)
4851                 close(btf_fd);
4852         if (map_fd != -1)
4853                 close(map_fd);
4854         if (pin_file)
4855                 fclose(pin_file);
4856         unlink(pin_path);
4857         free(line);
4858
4859         return err;
4860 }
4861
4862 static int test_pprint(void)
4863 {
4864         unsigned int i;
4865         int err = 0;
4866
4867         /* test various maps with the first test template */
4868         for (i = 0; i < ARRAY_SIZE(pprint_tests_meta); i++) {
4869                 pprint_test_template[0].descr = pprint_tests_meta[i].descr;
4870                 pprint_test_template[0].map_type = pprint_tests_meta[i].map_type;
4871                 pprint_test_template[0].map_name = pprint_tests_meta[i].map_name;
4872                 pprint_test_template[0].ordered_map = pprint_tests_meta[i].ordered_map;
4873                 pprint_test_template[0].lossless_map = pprint_tests_meta[i].lossless_map;
4874                 pprint_test_template[0].percpu_map = pprint_tests_meta[i].percpu_map;
4875
4876                 err |= count_result(do_test_pprint(0));
4877         }
4878
4879         /* test rest test templates with the first map */
4880         for (i = 1; i < ARRAY_SIZE(pprint_test_template); i++) {
4881                 pprint_test_template[i].descr = pprint_tests_meta[0].descr;
4882                 pprint_test_template[i].map_type = pprint_tests_meta[0].map_type;
4883                 pprint_test_template[i].map_name = pprint_tests_meta[0].map_name;
4884                 pprint_test_template[i].ordered_map = pprint_tests_meta[0].ordered_map;
4885                 pprint_test_template[i].lossless_map = pprint_tests_meta[0].lossless_map;
4886                 pprint_test_template[i].percpu_map = pprint_tests_meta[0].percpu_map;
4887                 err |= count_result(do_test_pprint(i));
4888         }
4889
4890         return err;
4891 }
4892
4893 #define BPF_LINE_INFO_ENC(insn_off, file_off, line_off, line_num, line_col) \
4894         (insn_off), (file_off), (line_off), ((line_num) << 10 | ((line_col) & 0x3ff))
4895
4896 static struct prog_info_raw_test {
4897         const char *descr;
4898         const char *str_sec;
4899         const char *err_str;
4900         __u32 raw_types[MAX_NR_RAW_U32];
4901         __u32 str_sec_size;
4902         struct bpf_insn insns[MAX_INSNS];
4903         __u32 prog_type;
4904         __u32 func_info[MAX_SUBPROGS][2];
4905         __u32 func_info_rec_size;
4906         __u32 func_info_cnt;
4907         __u32 line_info[MAX_NR_RAW_U32];
4908         __u32 line_info_rec_size;
4909         __u32 nr_jited_ksyms;
4910         bool expected_prog_load_failure;
4911         __u32 dead_code_cnt;
4912         __u32 dead_code_mask;
4913         __u32 dead_func_cnt;
4914         __u32 dead_func_mask;
4915 } info_raw_tests[] = {
4916 {
4917         .descr = "func_type (main func + one sub)",
4918         .raw_types = {
4919                 BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),   /* [1] */
4920                 BTF_TYPE_INT_ENC(NAME_TBD, 0, 0, 32, 4),        /* [2] */
4921                 BTF_FUNC_PROTO_ENC(1, 2),                       /* [3] */
4922                         BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
4923                         BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 2),
4924                 BTF_FUNC_PROTO_ENC(1, 2),                       /* [4] */
4925                         BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 2),
4926                         BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
4927                 BTF_FUNC_ENC(NAME_TBD, 3),                      /* [5] */
4928                 BTF_FUNC_ENC(NAME_TBD, 4),                      /* [6] */
4929                 BTF_END_RAW,
4930         },
4931         .str_sec = "\0int\0unsigned int\0a\0b\0c\0d\0funcA\0funcB",
4932         .str_sec_size = sizeof("\0int\0unsigned int\0a\0b\0c\0d\0funcA\0funcB"),
4933         .insns = {
4934                 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2),
4935                 BPF_MOV64_IMM(BPF_REG_0, 1),
4936                 BPF_EXIT_INSN(),
4937                 BPF_MOV64_IMM(BPF_REG_0, 2),
4938                 BPF_EXIT_INSN(),
4939         },
4940         .prog_type = BPF_PROG_TYPE_TRACEPOINT,
4941         .func_info = { {0, 5}, {3, 6} },
4942         .func_info_rec_size = 8,
4943         .func_info_cnt = 2,
4944         .line_info = { BTF_END_RAW },
4945 },
4946
4947 {
4948         .descr = "func_type (Incorrect func_info_rec_size)",
4949         .raw_types = {
4950                 BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),   /* [1] */
4951                 BTF_TYPE_INT_ENC(NAME_TBD, 0, 0, 32, 4),        /* [2] */
4952                 BTF_FUNC_PROTO_ENC(1, 2),                       /* [3] */
4953                         BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
4954                         BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 2),
4955                 BTF_FUNC_PROTO_ENC(1, 2),                       /* [4] */
4956                         BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 2),
4957                         BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
4958                 BTF_FUNC_ENC(NAME_TBD, 3),                      /* [5] */
4959                 BTF_FUNC_ENC(NAME_TBD, 4),                      /* [6] */
4960                 BTF_END_RAW,
4961         },
4962         .str_sec = "\0int\0unsigned int\0a\0b\0c\0d\0funcA\0funcB",
4963         .str_sec_size = sizeof("\0int\0unsigned int\0a\0b\0c\0d\0funcA\0funcB"),
4964         .insns = {
4965                 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2),
4966                 BPF_MOV64_IMM(BPF_REG_0, 1),
4967                 BPF_EXIT_INSN(),
4968                 BPF_MOV64_IMM(BPF_REG_0, 2),
4969                 BPF_EXIT_INSN(),
4970         },
4971         .prog_type = BPF_PROG_TYPE_TRACEPOINT,
4972         .func_info = { {0, 5}, {3, 6} },
4973         .func_info_rec_size = 4,
4974         .func_info_cnt = 2,
4975         .line_info = { BTF_END_RAW },
4976         .expected_prog_load_failure = true,
4977 },
4978
4979 {
4980         .descr = "func_type (Incorrect func_info_cnt)",
4981         .raw_types = {
4982                 BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),   /* [1] */
4983                 BTF_TYPE_INT_ENC(NAME_TBD, 0, 0, 32, 4),        /* [2] */
4984                 BTF_FUNC_PROTO_ENC(1, 2),                       /* [3] */
4985                         BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
4986                         BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 2),
4987                 BTF_FUNC_PROTO_ENC(1, 2),                       /* [4] */
4988                         BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 2),
4989                         BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
4990                 BTF_FUNC_ENC(NAME_TBD, 3),                      /* [5] */
4991                 BTF_FUNC_ENC(NAME_TBD, 4),                      /* [6] */
4992                 BTF_END_RAW,
4993         },
4994         .str_sec = "\0int\0unsigned int\0a\0b\0c\0d\0funcA\0funcB",
4995         .str_sec_size = sizeof("\0int\0unsigned int\0a\0b\0c\0d\0funcA\0funcB"),
4996         .insns = {
4997                 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2),
4998                 BPF_MOV64_IMM(BPF_REG_0, 1),
4999                 BPF_EXIT_INSN(),
5000                 BPF_MOV64_IMM(BPF_REG_0, 2),
5001                 BPF_EXIT_INSN(),
5002         },
5003         .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5004         .func_info = { {0, 5}, {3, 6} },
5005         .func_info_rec_size = 8,
5006         .func_info_cnt = 1,
5007         .line_info = { BTF_END_RAW },
5008         .expected_prog_load_failure = true,
5009 },
5010
5011 {
5012         .descr = "func_type (Incorrect bpf_func_info.insn_off)",
5013         .raw_types = {
5014                 BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),   /* [1] */
5015                 BTF_TYPE_INT_ENC(NAME_TBD, 0, 0, 32, 4),        /* [2] */
5016                 BTF_FUNC_PROTO_ENC(1, 2),                       /* [3] */
5017                         BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
5018                         BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 2),
5019                 BTF_FUNC_PROTO_ENC(1, 2),                       /* [4] */
5020                         BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 2),
5021                         BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
5022                 BTF_FUNC_ENC(NAME_TBD, 3),                      /* [5] */
5023                 BTF_FUNC_ENC(NAME_TBD, 4),                      /* [6] */
5024                 BTF_END_RAW,
5025         },
5026         .str_sec = "\0int\0unsigned int\0a\0b\0c\0d\0funcA\0funcB",
5027         .str_sec_size = sizeof("\0int\0unsigned int\0a\0b\0c\0d\0funcA\0funcB"),
5028         .insns = {
5029                 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2),
5030                 BPF_MOV64_IMM(BPF_REG_0, 1),
5031                 BPF_EXIT_INSN(),
5032                 BPF_MOV64_IMM(BPF_REG_0, 2),
5033                 BPF_EXIT_INSN(),
5034         },
5035         .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5036         .func_info = { {0, 5}, {2, 6} },
5037         .func_info_rec_size = 8,
5038         .func_info_cnt = 2,
5039         .line_info = { BTF_END_RAW },
5040         .expected_prog_load_failure = true,
5041 },
5042
5043 {
5044         .descr = "line_info (No subprog)",
5045         .raw_types = {
5046                 BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),   /* [1] */
5047                 BTF_END_RAW,
5048         },
5049         BTF_STR_SEC("\0int\0int a=1;\0int b=2;\0return a + b;\0return a + b;"),
5050         .insns = {
5051                 BPF_MOV64_IMM(BPF_REG_0, 1),
5052                 BPF_MOV64_IMM(BPF_REG_1, 2),
5053                 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
5054                 BPF_EXIT_INSN(),
5055         },
5056         .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5057         .func_info_cnt = 0,
5058         .line_info = {
5059                 BPF_LINE_INFO_ENC(0, 0, NAME_TBD, 1, 10),
5060                 BPF_LINE_INFO_ENC(1, 0, NAME_TBD, 2, 9),
5061                 BPF_LINE_INFO_ENC(2, 0, NAME_TBD, 3, 8),
5062                 BPF_LINE_INFO_ENC(3, 0, NAME_TBD, 4, 7),
5063                 BTF_END_RAW,
5064         },
5065         .line_info_rec_size = sizeof(struct bpf_line_info),
5066         .nr_jited_ksyms = 1,
5067 },
5068
5069 {
5070         .descr = "line_info (No subprog. insn_off >= prog->len)",
5071         .raw_types = {
5072                 BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),   /* [1] */
5073                 BTF_END_RAW,
5074         },
5075         BTF_STR_SEC("\0int\0int a=1;\0int b=2;\0return a + b;\0return a + b;"),
5076         .insns = {
5077                 BPF_MOV64_IMM(BPF_REG_0, 1),
5078                 BPF_MOV64_IMM(BPF_REG_1, 2),
5079                 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
5080                 BPF_EXIT_INSN(),
5081         },
5082         .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5083         .func_info_cnt = 0,
5084         .line_info = {
5085                 BPF_LINE_INFO_ENC(0, 0, NAME_TBD, 1, 10),
5086                 BPF_LINE_INFO_ENC(1, 0, NAME_TBD, 2, 9),
5087                 BPF_LINE_INFO_ENC(2, 0, NAME_TBD, 3, 8),
5088                 BPF_LINE_INFO_ENC(3, 0, NAME_TBD, 4, 7),
5089                 BPF_LINE_INFO_ENC(4, 0, 0, 5, 6),
5090                 BTF_END_RAW,
5091         },
5092         .line_info_rec_size = sizeof(struct bpf_line_info),
5093         .nr_jited_ksyms = 1,
5094         .err_str = "line_info[4].insn_off",
5095         .expected_prog_load_failure = true,
5096 },
5097
5098 {
5099         .descr = "line_info (Zero bpf insn code)",
5100         .raw_types = {
5101                 BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),   /* [1] */
5102                 BTF_TYPE_INT_ENC(NAME_TBD, 0, 0, 64, 8),        /* [2] */
5103                 BTF_TYPEDEF_ENC(NAME_TBD, 2),                   /* [3] */
5104                 BTF_END_RAW,
5105         },
5106         BTF_STR_SEC("\0int\0unsigned long\0u64\0u64 a=1;\0return a;"),
5107         .insns = {
5108                 BPF_LD_IMM64(BPF_REG_0, 1),
5109                 BPF_EXIT_INSN(),
5110         },
5111         .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5112         .func_info_cnt = 0,
5113         .line_info = {
5114                 BPF_LINE_INFO_ENC(0, 0, NAME_TBD, 1, 10),
5115                 BPF_LINE_INFO_ENC(1, 0, 0, 2, 9),
5116                 BPF_LINE_INFO_ENC(2, 0, NAME_TBD, 3, 8),
5117                 BTF_END_RAW,
5118         },
5119         .line_info_rec_size = sizeof(struct bpf_line_info),
5120         .nr_jited_ksyms = 1,
5121         .err_str = "Invalid insn code at line_info[1]",
5122         .expected_prog_load_failure = true,
5123 },
5124
5125 {
5126         .descr = "line_info (No subprog. zero tailing line_info",
5127         .raw_types = {
5128                 BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),   /* [1] */
5129                 BTF_END_RAW,
5130         },
5131         BTF_STR_SEC("\0int\0int a=1;\0int b=2;\0return a + b;\0return a + b;"),
5132         .insns = {
5133                 BPF_MOV64_IMM(BPF_REG_0, 1),
5134                 BPF_MOV64_IMM(BPF_REG_1, 2),
5135                 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
5136                 BPF_EXIT_INSN(),
5137         },
5138         .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5139         .func_info_cnt = 0,
5140         .line_info = {
5141                 BPF_LINE_INFO_ENC(0, 0, NAME_TBD, 1, 10), 0,
5142                 BPF_LINE_INFO_ENC(1, 0, NAME_TBD, 2, 9), 0,
5143                 BPF_LINE_INFO_ENC(2, 0, NAME_TBD, 3, 8), 0,
5144                 BPF_LINE_INFO_ENC(3, 0, NAME_TBD, 4, 7), 0,
5145                 BTF_END_RAW,
5146         },
5147         .line_info_rec_size = sizeof(struct bpf_line_info) + sizeof(__u32),
5148         .nr_jited_ksyms = 1,
5149 },
5150
5151 {
5152         .descr = "line_info (No subprog. nonzero tailing line_info)",
5153         .raw_types = {
5154                 BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),   /* [1] */
5155                 BTF_END_RAW,
5156         },
5157         BTF_STR_SEC("\0int\0int a=1;\0int b=2;\0return a + b;\0return a + b;"),
5158         .insns = {
5159                 BPF_MOV64_IMM(BPF_REG_0, 1),
5160                 BPF_MOV64_IMM(BPF_REG_1, 2),
5161                 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
5162                 BPF_EXIT_INSN(),
5163         },
5164         .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5165         .func_info_cnt = 0,
5166         .line_info = {
5167                 BPF_LINE_INFO_ENC(0, 0, NAME_TBD, 1, 10), 0,
5168                 BPF_LINE_INFO_ENC(1, 0, NAME_TBD, 2, 9), 0,
5169                 BPF_LINE_INFO_ENC(2, 0, NAME_TBD, 3, 8), 0,
5170                 BPF_LINE_INFO_ENC(3, 0, NAME_TBD, 4, 7), 1,
5171                 BTF_END_RAW,
5172         },
5173         .line_info_rec_size = sizeof(struct bpf_line_info) + sizeof(__u32),
5174         .nr_jited_ksyms = 1,
5175         .err_str = "nonzero tailing record in line_info",
5176         .expected_prog_load_failure = true,
5177 },
5178
5179 {
5180         .descr = "line_info (subprog)",
5181         .raw_types = {
5182                 BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),   /* [1] */
5183                 BTF_END_RAW,
5184         },
5185         BTF_STR_SEC("\0int\0int a=1+1;\0return func(a);\0b+=1;\0return b;"),
5186         .insns = {
5187                 BPF_MOV64_IMM(BPF_REG_2, 1),
5188                 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, 1),
5189                 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
5190                 BPF_CALL_REL(1),
5191                 BPF_EXIT_INSN(),
5192                 BPF_MOV64_REG(BPF_REG_0, BPF_REG_1),
5193                 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 1),
5194                 BPF_EXIT_INSN(),
5195         },
5196         .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5197         .func_info_cnt = 0,
5198         .line_info = {
5199                 BPF_LINE_INFO_ENC(0, 0, NAME_TBD, 1, 10),
5200                 BPF_LINE_INFO_ENC(2, 0, NAME_TBD, 2, 9),
5201                 BPF_LINE_INFO_ENC(5, 0, NAME_TBD, 3, 8),
5202                 BPF_LINE_INFO_ENC(7, 0, NAME_TBD, 4, 7),
5203                 BTF_END_RAW,
5204         },
5205         .line_info_rec_size = sizeof(struct bpf_line_info),
5206         .nr_jited_ksyms = 2,
5207 },
5208
5209 {
5210         .descr = "line_info (subprog + func_info)",
5211         .raw_types = {
5212                 BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),   /* [1] */
5213                 BTF_FUNC_PROTO_ENC(1, 1),                       /* [2] */
5214                         BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
5215                 BTF_FUNC_ENC(NAME_TBD, 2),                      /* [3] */
5216                 BTF_FUNC_ENC(NAME_TBD, 2),                      /* [4] */
5217                 BTF_END_RAW,
5218         },
5219         BTF_STR_SEC("\0int\0x\0sub\0main\0int a=1+1;\0return func(a);\0b+=1;\0return b;"),
5220         .insns = {
5221                 BPF_MOV64_IMM(BPF_REG_2, 1),
5222                 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, 1),
5223                 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
5224                 BPF_CALL_REL(1),
5225                 BPF_EXIT_INSN(),
5226                 BPF_MOV64_REG(BPF_REG_0, BPF_REG_1),
5227                 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 1),
5228                 BPF_EXIT_INSN(),
5229         },
5230         .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5231         .func_info_cnt = 2,
5232         .func_info_rec_size = 8,
5233         .func_info = { {0, 4}, {5, 3} },
5234         .line_info = {
5235                 BPF_LINE_INFO_ENC(0, 0, NAME_TBD, 1, 10),
5236                 BPF_LINE_INFO_ENC(2, 0, NAME_TBD, 2, 9),
5237                 BPF_LINE_INFO_ENC(5, 0, NAME_TBD, 3, 8),
5238                 BPF_LINE_INFO_ENC(7, 0, NAME_TBD, 4, 7),
5239                 BTF_END_RAW,
5240         },
5241         .line_info_rec_size = sizeof(struct bpf_line_info),
5242         .nr_jited_ksyms = 2,
5243 },
5244
5245 {
5246         .descr = "line_info (subprog. missing 1st func line info)",
5247         .raw_types = {
5248                 BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),   /* [1] */
5249                 BTF_END_RAW,
5250         },
5251         BTF_STR_SEC("\0int\0int a=1+1;\0return func(a);\0b+=1;\0return b;"),
5252         .insns = {
5253                 BPF_MOV64_IMM(BPF_REG_2, 1),
5254                 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, 1),
5255                 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
5256                 BPF_CALL_REL(1),
5257                 BPF_EXIT_INSN(),
5258                 BPF_MOV64_REG(BPF_REG_0, BPF_REG_1),
5259                 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 1),
5260                 BPF_EXIT_INSN(),
5261         },
5262         .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5263         .func_info_cnt = 0,
5264         .line_info = {
5265                 BPF_LINE_INFO_ENC(1, 0, NAME_TBD, 1, 10),
5266                 BPF_LINE_INFO_ENC(2, 0, NAME_TBD, 2, 9),
5267                 BPF_LINE_INFO_ENC(5, 0, NAME_TBD, 3, 8),
5268                 BPF_LINE_INFO_ENC(7, 0, NAME_TBD, 4, 7),
5269                 BTF_END_RAW,
5270         },
5271         .line_info_rec_size = sizeof(struct bpf_line_info),
5272         .nr_jited_ksyms = 2,
5273         .err_str = "missing bpf_line_info for func#0",
5274         .expected_prog_load_failure = true,
5275 },
5276
5277 {
5278         .descr = "line_info (subprog. missing 2nd func line info)",
5279         .raw_types = {
5280                 BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),   /* [1] */
5281                 BTF_END_RAW,
5282         },
5283         BTF_STR_SEC("\0int\0int a=1+1;\0return func(a);\0b+=1;\0return b;"),
5284         .insns = {
5285                 BPF_MOV64_IMM(BPF_REG_2, 1),
5286                 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, 1),
5287                 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
5288                 BPF_CALL_REL(1),
5289                 BPF_EXIT_INSN(),
5290                 BPF_MOV64_REG(BPF_REG_0, BPF_REG_1),
5291                 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 1),
5292                 BPF_EXIT_INSN(),
5293         },
5294         .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5295         .func_info_cnt = 0,
5296         .line_info = {
5297                 BPF_LINE_INFO_ENC(0, 0, NAME_TBD, 1, 10),
5298                 BPF_LINE_INFO_ENC(2, 0, NAME_TBD, 2, 9),
5299                 BPF_LINE_INFO_ENC(6, 0, NAME_TBD, 3, 8),
5300                 BPF_LINE_INFO_ENC(7, 0, NAME_TBD, 4, 7),
5301                 BTF_END_RAW,
5302         },
5303         .line_info_rec_size = sizeof(struct bpf_line_info),
5304         .nr_jited_ksyms = 2,
5305         .err_str = "missing bpf_line_info for func#1",
5306         .expected_prog_load_failure = true,
5307 },
5308
5309 {
5310         .descr = "line_info (subprog. unordered insn offset)",
5311         .raw_types = {
5312                 BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),   /* [1] */
5313                 BTF_END_RAW,
5314         },
5315         BTF_STR_SEC("\0int\0int a=1+1;\0return func(a);\0b+=1;\0return b;"),
5316         .insns = {
5317                 BPF_MOV64_IMM(BPF_REG_2, 1),
5318                 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, 1),
5319                 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
5320                 BPF_CALL_REL(1),
5321                 BPF_EXIT_INSN(),
5322                 BPF_MOV64_REG(BPF_REG_0, BPF_REG_1),
5323                 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 1),
5324                 BPF_EXIT_INSN(),
5325         },
5326         .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5327         .func_info_cnt = 0,
5328         .line_info = {
5329                 BPF_LINE_INFO_ENC(0, 0, NAME_TBD, 1, 10),
5330                 BPF_LINE_INFO_ENC(5, 0, NAME_TBD, 2, 9),
5331                 BPF_LINE_INFO_ENC(2, 0, NAME_TBD, 3, 8),
5332                 BPF_LINE_INFO_ENC(7, 0, NAME_TBD, 4, 7),
5333                 BTF_END_RAW,
5334         },
5335         .line_info_rec_size = sizeof(struct bpf_line_info),
5336         .nr_jited_ksyms = 2,
5337         .err_str = "Invalid line_info[2].insn_off",
5338         .expected_prog_load_failure = true,
5339 },
5340
5341 {
5342         .descr = "line_info (dead start)",
5343         .raw_types = {
5344                 BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),   /* [1] */
5345                 BTF_END_RAW,
5346         },
5347         BTF_STR_SEC("\0int\0/* dead jmp */\0int a=1;\0int b=2;\0return a + b;\0return a + b;"),
5348         .insns = {
5349                 BPF_JMP_IMM(BPF_JA, 0, 0, 0),
5350                 BPF_MOV64_IMM(BPF_REG_0, 1),
5351                 BPF_MOV64_IMM(BPF_REG_1, 2),
5352                 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
5353                 BPF_EXIT_INSN(),
5354         },
5355         .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5356         .func_info_cnt = 0,
5357         .line_info = {
5358                 BPF_LINE_INFO_ENC(0, 0, NAME_TBD, 1, 10),
5359                 BPF_LINE_INFO_ENC(1, 0, NAME_TBD, 2, 9),
5360                 BPF_LINE_INFO_ENC(2, 0, NAME_TBD, 3, 8),
5361                 BPF_LINE_INFO_ENC(3, 0, NAME_TBD, 4, 7),
5362                 BPF_LINE_INFO_ENC(4, 0, NAME_TBD, 5, 6),
5363                 BTF_END_RAW,
5364         },
5365         .line_info_rec_size = sizeof(struct bpf_line_info),
5366         .nr_jited_ksyms = 1,
5367         .dead_code_cnt = 1,
5368         .dead_code_mask = 0x01,
5369 },
5370
5371 {
5372         .descr = "line_info (dead end)",
5373         .raw_types = {
5374                 BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),   /* [1] */
5375                 BTF_END_RAW,
5376         },
5377         BTF_STR_SEC("\0int\0int a=1;\0int b=2;\0return a + b;\0/* dead jmp */\0return a + b;\0/* dead exit */"),
5378         .insns = {
5379                 BPF_MOV64_IMM(BPF_REG_0, 1),
5380                 BPF_MOV64_IMM(BPF_REG_1, 2),
5381                 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
5382                 BPF_JMP_IMM(BPF_JGE, BPF_REG_0, 10, 1),
5383                 BPF_EXIT_INSN(),
5384                 BPF_EXIT_INSN(),
5385         },
5386         .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5387         .func_info_cnt = 0,
5388         .line_info = {
5389                 BPF_LINE_INFO_ENC(0, 0, NAME_TBD, 1, 12),
5390                 BPF_LINE_INFO_ENC(1, 0, NAME_TBD, 2, 11),
5391                 BPF_LINE_INFO_ENC(2, 0, NAME_TBD, 3, 10),
5392                 BPF_LINE_INFO_ENC(3, 0, NAME_TBD, 4, 9),
5393                 BPF_LINE_INFO_ENC(4, 0, NAME_TBD, 5, 8),
5394                 BPF_LINE_INFO_ENC(5, 0, NAME_TBD, 6, 7),
5395                 BTF_END_RAW,
5396         },
5397         .line_info_rec_size = sizeof(struct bpf_line_info),
5398         .nr_jited_ksyms = 1,
5399         .dead_code_cnt = 2,
5400         .dead_code_mask = 0x28,
5401 },
5402
5403 {
5404         .descr = "line_info (dead code + subprog + func_info)",
5405         .raw_types = {
5406                 BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),   /* [1] */
5407                 BTF_FUNC_PROTO_ENC(1, 1),                       /* [2] */
5408                         BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
5409                 BTF_FUNC_ENC(NAME_TBD, 2),                      /* [3] */
5410                 BTF_FUNC_ENC(NAME_TBD, 2),                      /* [4] */
5411                 BTF_END_RAW,
5412         },
5413         BTF_STR_SEC("\0int\0x\0sub\0main\0int a=1+1;\0/* dead jmp */"
5414                     "\0/* dead */\0/* dead */\0/* dead */\0/* dead */"
5415                     "\0/* dead */\0/* dead */\0/* dead */\0/* dead */"
5416                     "\0return func(a);\0b+=1;\0return b;"),
5417         .insns = {
5418                 BPF_MOV64_IMM(BPF_REG_2, 1),
5419                 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, 1),
5420                 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
5421                 BPF_JMP_IMM(BPF_JGE, BPF_REG_2, 0, 8),
5422                 BPF_MOV64_IMM(BPF_REG_2, 1),
5423                 BPF_MOV64_IMM(BPF_REG_2, 1),
5424                 BPF_MOV64_IMM(BPF_REG_2, 1),
5425                 BPF_MOV64_IMM(BPF_REG_2, 1),
5426                 BPF_MOV64_IMM(BPF_REG_2, 1),
5427                 BPF_MOV64_IMM(BPF_REG_2, 1),
5428                 BPF_MOV64_IMM(BPF_REG_2, 1),
5429                 BPF_MOV64_IMM(BPF_REG_2, 1),
5430                 BPF_CALL_REL(1),
5431                 BPF_EXIT_INSN(),
5432                 BPF_MOV64_REG(BPF_REG_0, BPF_REG_1),
5433                 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 1),
5434                 BPF_EXIT_INSN(),
5435         },
5436         .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5437         .func_info_cnt = 2,
5438         .func_info_rec_size = 8,
5439         .func_info = { {0, 4}, {14, 3} },
5440         .line_info = {
5441                 BPF_LINE_INFO_ENC(0, 0, NAME_TBD, 1, 10),
5442                 BPF_LINE_INFO_ENC(3, 0, NAME_TBD, 1, 10),
5443                 BPF_LINE_INFO_ENC(4, 0, NAME_TBD, 1, 10),
5444                 BPF_LINE_INFO_ENC(5, 0, NAME_TBD, 1, 10),
5445                 BPF_LINE_INFO_ENC(6, 0, NAME_TBD, 1, 10),
5446                 BPF_LINE_INFO_ENC(7, 0, NAME_TBD, 1, 10),
5447                 BPF_LINE_INFO_ENC(8, 0, NAME_TBD, 1, 10),
5448                 BPF_LINE_INFO_ENC(9, 0, NAME_TBD, 1, 10),
5449                 BPF_LINE_INFO_ENC(10, 0, NAME_TBD, 1, 10),
5450                 BPF_LINE_INFO_ENC(11, 0, NAME_TBD, 2, 9),
5451                 BPF_LINE_INFO_ENC(12, 0, NAME_TBD, 2, 9),
5452                 BPF_LINE_INFO_ENC(14, 0, NAME_TBD, 3, 8),
5453                 BPF_LINE_INFO_ENC(16, 0, NAME_TBD, 4, 7),
5454                 BTF_END_RAW,
5455         },
5456         .line_info_rec_size = sizeof(struct bpf_line_info),
5457         .nr_jited_ksyms = 2,
5458         .dead_code_cnt = 9,
5459         .dead_code_mask = 0x3fe,
5460 },
5461
5462 {
5463         .descr = "line_info (dead subprog)",
5464         .raw_types = {
5465                 BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),   /* [1] */
5466                 BTF_FUNC_PROTO_ENC(1, 1),                       /* [2] */
5467                         BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
5468                 BTF_FUNC_ENC(NAME_TBD, 2),                      /* [3] */
5469                 BTF_FUNC_ENC(NAME_TBD, 2),                      /* [4] */
5470                 BTF_FUNC_ENC(NAME_TBD, 2),                      /* [5] */
5471                 BTF_END_RAW,
5472         },
5473         BTF_STR_SEC("\0int\0x\0dead\0main\0func\0int a=1+1;\0/* live call */"
5474                     "\0return 0;\0return 0;\0/* dead */\0/* dead */"
5475                     "\0/* dead */\0return bla + 1;\0return bla + 1;"
5476                     "\0return bla + 1;\0return func(a);\0b+=1;\0return b;"),
5477         .insns = {
5478                 BPF_MOV64_IMM(BPF_REG_2, 1),
5479                 BPF_JMP_IMM(BPF_JGE, BPF_REG_2, 0, 1),
5480                 BPF_CALL_REL(3),
5481                 BPF_CALL_REL(5),
5482                 BPF_MOV64_IMM(BPF_REG_0, 0),
5483                 BPF_EXIT_INSN(),
5484                 BPF_MOV64_IMM(BPF_REG_0, 0),
5485                 BPF_CALL_REL(1),
5486                 BPF_EXIT_INSN(),
5487                 BPF_MOV64_REG(BPF_REG_0, 2),
5488                 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 1),
5489                 BPF_EXIT_INSN(),
5490         },
5491         .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5492         .func_info_cnt = 3,
5493         .func_info_rec_size = 8,
5494                 .func_info = { {0, 4}, {6, 3}, {9, 5} },
5495         .line_info = {
5496                 BPF_LINE_INFO_ENC(0, 0, NAME_TBD, 1, 10),
5497                 BPF_LINE_INFO_ENC(3, 0, NAME_TBD, 1, 10),
5498                 BPF_LINE_INFO_ENC(4, 0, NAME_TBD, 1, 10),
5499                 BPF_LINE_INFO_ENC(5, 0, NAME_TBD, 1, 10),
5500                 BPF_LINE_INFO_ENC(6, 0, NAME_TBD, 1, 10),
5501                 BPF_LINE_INFO_ENC(7, 0, NAME_TBD, 1, 10),
5502                 BPF_LINE_INFO_ENC(8, 0, NAME_TBD, 1, 10),
5503                 BPF_LINE_INFO_ENC(9, 0, NAME_TBD, 1, 10),
5504                 BPF_LINE_INFO_ENC(10, 0, NAME_TBD, 1, 10),
5505                 BPF_LINE_INFO_ENC(11, 0, NAME_TBD, 2, 9),
5506                 BTF_END_RAW,
5507         },
5508         .line_info_rec_size = sizeof(struct bpf_line_info),
5509         .nr_jited_ksyms = 2,
5510         .dead_code_cnt = 3,
5511         .dead_code_mask = 0x70,
5512         .dead_func_cnt = 1,
5513         .dead_func_mask = 0x2,
5514 },
5515
5516 {
5517         .descr = "line_info (dead last subprog)",
5518         .raw_types = {
5519                 BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),   /* [1] */
5520                 BTF_FUNC_PROTO_ENC(1, 1),                       /* [2] */
5521                         BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
5522                 BTF_FUNC_ENC(NAME_TBD, 2),                      /* [3] */
5523                 BTF_FUNC_ENC(NAME_TBD, 2),                      /* [5] */
5524                 BTF_END_RAW,
5525         },
5526         BTF_STR_SEC("\0int\0x\0dead\0main\0int a=1+1;\0/* live call */"
5527                     "\0return 0;\0/* dead */\0/* dead */"),
5528         .insns = {
5529                 BPF_MOV64_IMM(BPF_REG_2, 1),
5530                 BPF_JMP_IMM(BPF_JGE, BPF_REG_2, 0, 1),
5531                 BPF_CALL_REL(2),
5532                 BPF_MOV64_IMM(BPF_REG_0, 0),
5533                 BPF_EXIT_INSN(),
5534                 BPF_MOV64_IMM(BPF_REG_0, 0),
5535                 BPF_EXIT_INSN(),
5536         },
5537         .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5538         .func_info_cnt = 2,
5539         .func_info_rec_size = 8,
5540                 .func_info = { {0, 4}, {5, 3} },
5541         .line_info = {
5542                 BPF_LINE_INFO_ENC(0, 0, NAME_TBD, 1, 10),
5543                 BPF_LINE_INFO_ENC(3, 0, NAME_TBD, 1, 10),
5544                 BPF_LINE_INFO_ENC(4, 0, NAME_TBD, 1, 10),
5545                 BPF_LINE_INFO_ENC(5, 0, NAME_TBD, 1, 10),
5546                 BPF_LINE_INFO_ENC(6, 0, NAME_TBD, 1, 10),
5547                 BTF_END_RAW,
5548         },
5549         .line_info_rec_size = sizeof(struct bpf_line_info),
5550         .nr_jited_ksyms = 1,
5551         .dead_code_cnt = 2,
5552         .dead_code_mask = 0x18,
5553         .dead_func_cnt = 1,
5554         .dead_func_mask = 0x2,
5555 },
5556
5557 {
5558         .descr = "line_info (dead subprog + dead start)",
5559         .raw_types = {
5560                 BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),   /* [1] */
5561                 BTF_FUNC_PROTO_ENC(1, 1),                       /* [2] */
5562                         BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
5563                 BTF_FUNC_ENC(NAME_TBD, 2),                      /* [3] */
5564                 BTF_FUNC_ENC(NAME_TBD, 2),                      /* [4] */
5565                 BTF_FUNC_ENC(NAME_TBD, 2),                      /* [5] */
5566                 BTF_END_RAW,
5567         },
5568         BTF_STR_SEC("\0int\0x\0dead\0main\0func\0int a=1+1;\0/* dead */"
5569                     "\0return 0;\0return 0;\0return 0;"
5570                     "\0/* dead */\0/* dead */\0/* dead */\0/* dead */"
5571                     "\0return b + 1;\0return b + 1;\0return b + 1;"),
5572         .insns = {
5573                 BPF_JMP_IMM(BPF_JA, 0, 0, 0),
5574                 BPF_MOV64_IMM(BPF_REG_2, 1),
5575                 BPF_JMP_IMM(BPF_JGE, BPF_REG_2, 0, 1),
5576                 BPF_CALL_REL(3),
5577                 BPF_CALL_REL(5),
5578                 BPF_MOV64_IMM(BPF_REG_0, 0),
5579                 BPF_EXIT_INSN(),
5580                 BPF_MOV64_IMM(BPF_REG_0, 0),
5581                 BPF_CALL_REL(1),
5582                 BPF_EXIT_INSN(),
5583                 BPF_JMP_IMM(BPF_JA, 0, 0, 0),
5584                 BPF_MOV64_REG(BPF_REG_0, 2),
5585                 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 1),
5586                 BPF_EXIT_INSN(),
5587         },
5588         .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5589         .func_info_cnt = 3,
5590         .func_info_rec_size = 8,
5591                 .func_info = { {0, 4}, {7, 3}, {10, 5} },
5592         .line_info = {
5593                 BPF_LINE_INFO_ENC(0, 0, NAME_TBD, 1, 10),
5594                 BPF_LINE_INFO_ENC(3, 0, NAME_TBD, 1, 10),
5595                 BPF_LINE_INFO_ENC(4, 0, NAME_TBD, 1, 10),
5596                 BPF_LINE_INFO_ENC(5, 0, NAME_TBD, 1, 10),
5597                 BPF_LINE_INFO_ENC(6, 0, NAME_TBD, 1, 10),
5598                 BPF_LINE_INFO_ENC(7, 0, NAME_TBD, 1, 10),
5599                 BPF_LINE_INFO_ENC(8, 0, NAME_TBD, 1, 10),
5600                 BPF_LINE_INFO_ENC(9, 0, NAME_TBD, 1, 10),
5601                 BPF_LINE_INFO_ENC(10, 0, NAME_TBD, 1, 10),
5602                 BPF_LINE_INFO_ENC(11, 0, NAME_TBD, 2, 9),
5603                 BPF_LINE_INFO_ENC(12, 0, NAME_TBD, 2, 9),
5604                 BPF_LINE_INFO_ENC(13, 0, NAME_TBD, 2, 9),
5605                 BTF_END_RAW,
5606         },
5607         .line_info_rec_size = sizeof(struct bpf_line_info),
5608         .nr_jited_ksyms = 2,
5609         .dead_code_cnt = 5,
5610         .dead_code_mask = 0x1e2,
5611         .dead_func_cnt = 1,
5612         .dead_func_mask = 0x2,
5613 },
5614
5615 {
5616         .descr = "line_info (dead subprog + dead start w/ move)",
5617         .raw_types = {
5618                 BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),   /* [1] */
5619                 BTF_FUNC_PROTO_ENC(1, 1),                       /* [2] */
5620                         BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
5621                 BTF_FUNC_ENC(NAME_TBD, 2),                      /* [3] */
5622                 BTF_FUNC_ENC(NAME_TBD, 2),                      /* [4] */
5623                 BTF_FUNC_ENC(NAME_TBD, 2),                      /* [5] */
5624                 BTF_END_RAW,
5625         },
5626         BTF_STR_SEC("\0int\0x\0dead\0main\0func\0int a=1+1;\0/* live call */"
5627                     "\0return 0;\0return 0;\0/* dead */\0/* dead */"
5628                     "\0/* dead */\0return bla + 1;\0return bla + 1;"
5629                     "\0return bla + 1;\0return func(a);\0b+=1;\0return b;"),
5630         .insns = {
5631                 BPF_MOV64_IMM(BPF_REG_2, 1),
5632                 BPF_JMP_IMM(BPF_JGE, BPF_REG_2, 0, 1),
5633                 BPF_CALL_REL(3),
5634                 BPF_CALL_REL(5),
5635                 BPF_MOV64_IMM(BPF_REG_0, 0),
5636                 BPF_EXIT_INSN(),
5637                 BPF_MOV64_IMM(BPF_REG_0, 0),
5638                 BPF_CALL_REL(1),
5639                 BPF_EXIT_INSN(),
5640                 BPF_JMP_IMM(BPF_JA, 0, 0, 0),
5641                 BPF_MOV64_REG(BPF_REG_0, 2),
5642                 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 1),
5643                 BPF_EXIT_INSN(),
5644         },
5645         .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5646         .func_info_cnt = 3,
5647         .func_info_rec_size = 8,
5648                 .func_info = { {0, 4}, {6, 3}, {9, 5} },
5649         .line_info = {
5650                 BPF_LINE_INFO_ENC(0, 0, NAME_TBD, 1, 10),
5651                 BPF_LINE_INFO_ENC(3, 0, NAME_TBD, 1, 10),
5652                 BPF_LINE_INFO_ENC(4, 0, NAME_TBD, 1, 10),
5653                 BPF_LINE_INFO_ENC(5, 0, NAME_TBD, 1, 10),
5654                 BPF_LINE_INFO_ENC(6, 0, NAME_TBD, 1, 10),
5655                 BPF_LINE_INFO_ENC(7, 0, NAME_TBD, 1, 10),
5656                 BPF_LINE_INFO_ENC(8, 0, NAME_TBD, 1, 10),
5657                 BPF_LINE_INFO_ENC(9, 0, NAME_TBD, 1, 10),
5658                 BPF_LINE_INFO_ENC(11, 0, NAME_TBD, 1, 10),
5659                 BPF_LINE_INFO_ENC(12, 0, NAME_TBD, 2, 9),
5660                 BTF_END_RAW,
5661         },
5662         .line_info_rec_size = sizeof(struct bpf_line_info),
5663         .nr_jited_ksyms = 2,
5664         .dead_code_cnt = 3,
5665         .dead_code_mask = 0x70,
5666         .dead_func_cnt = 1,
5667         .dead_func_mask = 0x2,
5668 },
5669
5670 {
5671         .descr = "line_info (dead end + subprog start w/ no linfo)",
5672         .raw_types = {
5673                 BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),   /* [1] */
5674                 BTF_FUNC_PROTO_ENC(1, 1),                       /* [2] */
5675                         BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
5676                 BTF_FUNC_ENC(NAME_TBD, 2),                      /* [3] */
5677                 BTF_FUNC_ENC(NAME_TBD, 2),                      /* [4] */
5678                 BTF_END_RAW,
5679         },
5680         BTF_STR_SEC("\0int\0x\0main\0func\0/* main linfo */\0/* func linfo */"),
5681         .insns = {
5682                 BPF_MOV64_IMM(BPF_REG_0, 0),
5683                 BPF_JMP_IMM(BPF_JGE, BPF_REG_0, 1, 3),
5684                 BPF_CALL_REL(3),
5685                 BPF_MOV64_IMM(BPF_REG_0, 0),
5686                 BPF_EXIT_INSN(),
5687                 BPF_EXIT_INSN(),
5688                 BPF_JMP_IMM(BPF_JA, 0, 0, 0),
5689                 BPF_EXIT_INSN(),
5690         },
5691         .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5692         .func_info_cnt = 2,
5693         .func_info_rec_size = 8,
5694         .func_info = { {0, 3}, {6, 4}, },
5695         .line_info = {
5696                 BPF_LINE_INFO_ENC(0, 0, NAME_TBD, 1, 10),
5697                 BPF_LINE_INFO_ENC(6, 0, NAME_TBD, 1, 10),
5698                 BTF_END_RAW,
5699         },
5700         .line_info_rec_size = sizeof(struct bpf_line_info),
5701         .nr_jited_ksyms = 2,
5702 },
5703
5704 };
5705
5706 static size_t probe_prog_length(const struct bpf_insn *fp)
5707 {
5708         size_t len;
5709
5710         for (len = MAX_INSNS - 1; len > 0; --len)
5711                 if (fp[len].code != 0 || fp[len].imm != 0)
5712                         break;
5713         return len + 1;
5714 }
5715
5716 static __u32 *patch_name_tbd(const __u32 *raw_u32,
5717                              const char *str, __u32 str_off,
5718                              unsigned int str_sec_size,
5719                              unsigned int *ret_size)
5720 {
5721         int i, raw_u32_size = get_raw_sec_size(raw_u32);
5722         const char *end_str = str + str_sec_size;
5723         const char *next_str = str + str_off;
5724         __u32 *new_u32 = NULL;
5725
5726         if (raw_u32_size == -1)
5727                 return ERR_PTR(-EINVAL);
5728
5729         if (!raw_u32_size) {
5730                 *ret_size = 0;
5731                 return NULL;
5732         }
5733
5734         new_u32 = malloc(raw_u32_size);
5735         if (!new_u32)
5736                 return ERR_PTR(-ENOMEM);
5737
5738         for (i = 0; i < raw_u32_size / sizeof(raw_u32[0]); i++) {
5739                 if (raw_u32[i] == NAME_TBD) {
5740                         next_str = get_next_str(next_str, end_str);
5741                         if (CHECK(!next_str, "Error in getting next_str\n")) {
5742                                 free(new_u32);
5743                                 return ERR_PTR(-EINVAL);
5744                         }
5745                         new_u32[i] = next_str - str;
5746                         next_str += strlen(next_str);
5747                 } else {
5748                         new_u32[i] = raw_u32[i];
5749                 }
5750         }
5751
5752         *ret_size = raw_u32_size;
5753         return new_u32;
5754 }
5755
5756 static int test_get_finfo(const struct prog_info_raw_test *test,
5757                           int prog_fd)
5758 {
5759         struct bpf_prog_info info = {};
5760         struct bpf_func_info *finfo;
5761         __u32 info_len, rec_size, i;
5762         void *func_info = NULL;
5763         __u32 nr_func_info;
5764         int err;
5765
5766         /* get necessary lens */
5767         info_len = sizeof(struct bpf_prog_info);
5768         err = bpf_obj_get_info_by_fd(prog_fd, &info, &info_len);
5769         if (CHECK(err == -1, "invalid get info (1st) errno:%d", errno)) {
5770                 fprintf(stderr, "%s\n", btf_log_buf);
5771                 return -1;
5772         }
5773         nr_func_info = test->func_info_cnt - test->dead_func_cnt;
5774         if (CHECK(info.nr_func_info != nr_func_info,
5775                   "incorrect info.nr_func_info (1st) %d",
5776                   info.nr_func_info)) {
5777                 return -1;
5778         }
5779
5780         rec_size = info.func_info_rec_size;
5781         if (CHECK(rec_size != sizeof(struct bpf_func_info),
5782                   "incorrect info.func_info_rec_size (1st) %d", rec_size)) {
5783                 return -1;
5784         }
5785
5786         if (!info.nr_func_info)
5787                 return 0;
5788
5789         func_info = malloc(info.nr_func_info * rec_size);
5790         if (CHECK(!func_info, "out of memory"))
5791                 return -1;
5792
5793         /* reset info to only retrieve func_info related data */
5794         memset(&info, 0, sizeof(info));
5795         info.nr_func_info = nr_func_info;
5796         info.func_info_rec_size = rec_size;
5797         info.func_info = ptr_to_u64(func_info);
5798         err = bpf_obj_get_info_by_fd(prog_fd, &info, &info_len);
5799         if (CHECK(err == -1, "invalid get info (2nd) errno:%d", errno)) {
5800                 fprintf(stderr, "%s\n", btf_log_buf);
5801                 err = -1;
5802                 goto done;
5803         }
5804         if (CHECK(info.nr_func_info != nr_func_info,
5805                   "incorrect info.nr_func_info (2nd) %d",
5806                   info.nr_func_info)) {
5807                 err = -1;
5808                 goto done;
5809         }
5810         if (CHECK(info.func_info_rec_size != rec_size,
5811                   "incorrect info.func_info_rec_size (2nd) %d",
5812                   info.func_info_rec_size)) {
5813                 err = -1;
5814                 goto done;
5815         }
5816
5817         finfo = func_info;
5818         for (i = 0; i < nr_func_info; i++) {
5819                 if (test->dead_func_mask & (1 << i))
5820                         continue;
5821                 if (CHECK(finfo->type_id != test->func_info[i][1],
5822                           "incorrect func_type %u expected %u",
5823                           finfo->type_id, test->func_info[i][1])) {
5824                         err = -1;
5825                         goto done;
5826                 }
5827                 finfo = (void *)finfo + rec_size;
5828         }
5829
5830         err = 0;
5831
5832 done:
5833         free(func_info);
5834         return err;
5835 }
5836
5837 static int test_get_linfo(const struct prog_info_raw_test *test,
5838                           const void *patched_linfo,
5839                           __u32 cnt, int prog_fd)
5840 {
5841         __u32 i, info_len, nr_jited_ksyms, nr_jited_func_lens;
5842         __u64 *jited_linfo = NULL, *jited_ksyms = NULL;
5843         __u32 rec_size, jited_rec_size, jited_cnt;
5844         struct bpf_line_info *linfo = NULL;
5845         __u32 cur_func_len, ksyms_found;
5846         struct bpf_prog_info info = {};
5847         __u32 *jited_func_lens = NULL;
5848         __u64 cur_func_ksyms;
5849         __u32 dead_insns;
5850         int err;
5851
5852         jited_cnt = cnt;
5853         rec_size = sizeof(*linfo);
5854         jited_rec_size = sizeof(*jited_linfo);
5855         if (test->nr_jited_ksyms)
5856                 nr_jited_ksyms = test->nr_jited_ksyms;
5857         else
5858                 nr_jited_ksyms = test->func_info_cnt - test->dead_func_cnt;
5859         nr_jited_func_lens = nr_jited_ksyms;
5860
5861         info_len = sizeof(struct bpf_prog_info);
5862         err = bpf_obj_get_info_by_fd(prog_fd, &info, &info_len);
5863         if (CHECK(err == -1, "err:%d errno:%d", err, errno)) {
5864                 err = -1;
5865                 goto done;
5866         }
5867
5868         if (!info.jited_prog_len) {
5869                 /* prog is not jited */
5870                 jited_cnt = 0;
5871                 nr_jited_ksyms = 1;
5872                 nr_jited_func_lens = 1;
5873         }
5874
5875         if (CHECK(info.nr_line_info != cnt ||
5876                   info.nr_jited_line_info != jited_cnt ||
5877                   info.nr_jited_ksyms != nr_jited_ksyms ||
5878                   info.nr_jited_func_lens != nr_jited_func_lens ||
5879                   (!info.nr_line_info && info.nr_jited_line_info),
5880                   "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)",
5881                   info.nr_line_info, cnt,
5882                   info.nr_jited_line_info, jited_cnt,
5883                   info.nr_jited_ksyms, nr_jited_ksyms,
5884                   info.nr_jited_func_lens, nr_jited_func_lens)) {
5885                 err = -1;
5886                 goto done;
5887         }
5888
5889         if (CHECK(info.line_info_rec_size != sizeof(struct bpf_line_info) ||
5890                   info.jited_line_info_rec_size != sizeof(__u64),
5891                   "info: line_info_rec_size:%u(userspace expected:%u) jited_line_info_rec_size:%u(userspace expected:%u)",
5892                   info.line_info_rec_size, rec_size,
5893                   info.jited_line_info_rec_size, jited_rec_size)) {
5894                 err = -1;
5895                 goto done;
5896         }
5897
5898         if (!cnt)
5899                 return 0;
5900
5901         rec_size = info.line_info_rec_size;
5902         jited_rec_size = info.jited_line_info_rec_size;
5903
5904         memset(&info, 0, sizeof(info));
5905
5906         linfo = calloc(cnt, rec_size);
5907         if (CHECK(!linfo, "!linfo")) {
5908                 err = -1;
5909                 goto done;
5910         }
5911         info.nr_line_info = cnt;
5912         info.line_info_rec_size = rec_size;
5913         info.line_info = ptr_to_u64(linfo);
5914
5915         if (jited_cnt) {
5916                 jited_linfo = calloc(jited_cnt, jited_rec_size);
5917                 jited_ksyms = calloc(nr_jited_ksyms, sizeof(*jited_ksyms));
5918                 jited_func_lens = calloc(nr_jited_func_lens,
5919                                          sizeof(*jited_func_lens));
5920                 if (CHECK(!jited_linfo || !jited_ksyms || !jited_func_lens,
5921                           "jited_linfo:%p jited_ksyms:%p jited_func_lens:%p",
5922                           jited_linfo, jited_ksyms, jited_func_lens)) {
5923                         err = -1;
5924                         goto done;
5925                 }
5926
5927                 info.nr_jited_line_info = jited_cnt;
5928                 info.jited_line_info_rec_size = jited_rec_size;
5929                 info.jited_line_info = ptr_to_u64(jited_linfo);
5930                 info.nr_jited_ksyms = nr_jited_ksyms;
5931                 info.jited_ksyms = ptr_to_u64(jited_ksyms);
5932                 info.nr_jited_func_lens = nr_jited_func_lens;
5933                 info.jited_func_lens = ptr_to_u64(jited_func_lens);
5934         }
5935
5936         err = bpf_obj_get_info_by_fd(prog_fd, &info, &info_len);
5937
5938         /*
5939          * Only recheck the info.*line_info* fields.
5940          * Other fields are not the concern of this test.
5941          */
5942         if (CHECK(err == -1 ||
5943                   info.nr_line_info != cnt ||
5944                   (jited_cnt && !info.jited_line_info) ||
5945                   info.nr_jited_line_info != jited_cnt ||
5946                   info.line_info_rec_size != rec_size ||
5947                   info.jited_line_info_rec_size != jited_rec_size,
5948                   "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",
5949                   err, errno,
5950                   info.nr_line_info, cnt,
5951                   info.nr_jited_line_info, jited_cnt,
5952                   info.line_info_rec_size, rec_size,
5953                   info.jited_line_info_rec_size, jited_rec_size,
5954                   (void *)(long)info.line_info,
5955                   (void *)(long)info.jited_line_info)) {
5956                 err = -1;
5957                 goto done;
5958         }
5959
5960         dead_insns = 0;
5961         while (test->dead_code_mask & (1 << dead_insns))
5962                 dead_insns++;
5963
5964         CHECK(linfo[0].insn_off, "linfo[0].insn_off:%u",
5965               linfo[0].insn_off);
5966         for (i = 1; i < cnt; i++) {
5967                 const struct bpf_line_info *expected_linfo;
5968
5969                 while (test->dead_code_mask & (1 << (i + dead_insns)))
5970                         dead_insns++;
5971
5972                 expected_linfo = patched_linfo +
5973                         ((i + dead_insns) * test->line_info_rec_size);
5974                 if (CHECK(linfo[i].insn_off <= linfo[i - 1].insn_off,
5975                           "linfo[%u].insn_off:%u <= linfo[%u].insn_off:%u",
5976                           i, linfo[i].insn_off,
5977                           i - 1, linfo[i - 1].insn_off)) {
5978                         err = -1;
5979                         goto done;
5980                 }
5981                 if (CHECK(linfo[i].file_name_off != expected_linfo->file_name_off ||
5982                           linfo[i].line_off != expected_linfo->line_off ||
5983                           linfo[i].line_col != expected_linfo->line_col,
5984                           "linfo[%u] (%u, %u, %u) != (%u, %u, %u)", i,
5985                           linfo[i].file_name_off,
5986                           linfo[i].line_off,
5987                           linfo[i].line_col,
5988                           expected_linfo->file_name_off,
5989                           expected_linfo->line_off,
5990                           expected_linfo->line_col)) {
5991                         err = -1;
5992                         goto done;
5993                 }
5994         }
5995
5996         if (!jited_cnt) {
5997                 fprintf(stderr, "not jited. skipping jited_line_info check. ");
5998                 err = 0;
5999                 goto done;
6000         }
6001
6002         if (CHECK(jited_linfo[0] != jited_ksyms[0],
6003                   "jited_linfo[0]:%lx != jited_ksyms[0]:%lx",
6004                   (long)(jited_linfo[0]), (long)(jited_ksyms[0]))) {
6005                 err = -1;
6006                 goto done;
6007         }
6008
6009         ksyms_found = 1;
6010         cur_func_len = jited_func_lens[0];
6011         cur_func_ksyms = jited_ksyms[0];
6012         for (i = 1; i < jited_cnt; i++) {
6013                 if (ksyms_found < nr_jited_ksyms &&
6014                     jited_linfo[i] == jited_ksyms[ksyms_found]) {
6015                         cur_func_ksyms = jited_ksyms[ksyms_found];
6016                         cur_func_len = jited_ksyms[ksyms_found];
6017                         ksyms_found++;
6018                         continue;
6019                 }
6020
6021                 if (CHECK(jited_linfo[i] <= jited_linfo[i - 1],
6022                           "jited_linfo[%u]:%lx <= jited_linfo[%u]:%lx",
6023                           i, (long)jited_linfo[i],
6024                           i - 1, (long)(jited_linfo[i - 1]))) {
6025                         err = -1;
6026                         goto done;
6027                 }
6028
6029                 if (CHECK(jited_linfo[i] - cur_func_ksyms > cur_func_len,
6030                           "jited_linfo[%u]:%lx - %lx > %u",
6031                           i, (long)jited_linfo[i], (long)cur_func_ksyms,
6032                           cur_func_len)) {
6033                         err = -1;
6034                         goto done;
6035                 }
6036         }
6037
6038         if (CHECK(ksyms_found != nr_jited_ksyms,
6039                   "ksyms_found:%u != nr_jited_ksyms:%u",
6040                   ksyms_found, nr_jited_ksyms)) {
6041                 err = -1;
6042                 goto done;
6043         }
6044
6045         err = 0;
6046
6047 done:
6048         free(linfo);
6049         free(jited_linfo);
6050         free(jited_ksyms);
6051         free(jited_func_lens);
6052         return err;
6053 }
6054
6055 static int do_test_info_raw(unsigned int test_num)
6056 {
6057         const struct prog_info_raw_test *test = &info_raw_tests[test_num - 1];
6058         unsigned int raw_btf_size, linfo_str_off, linfo_size;
6059         int btf_fd = -1, prog_fd = -1, err = 0;
6060         void *raw_btf, *patched_linfo = NULL;
6061         const char *ret_next_str;
6062         union bpf_attr attr = {};
6063
6064         fprintf(stderr, "BTF prog info raw test[%u] (%s): ", test_num, test->descr);
6065         raw_btf = btf_raw_create(&hdr_tmpl, test->raw_types,
6066                                  test->str_sec, test->str_sec_size,
6067                                  &raw_btf_size, &ret_next_str);
6068
6069         if (!raw_btf)
6070                 return -1;
6071
6072         *btf_log_buf = '\0';
6073         btf_fd = bpf_load_btf(raw_btf, raw_btf_size,
6074                               btf_log_buf, BTF_LOG_BUF_SIZE,
6075                               args.always_log);
6076         free(raw_btf);
6077
6078         if (CHECK(btf_fd == -1, "invalid btf_fd errno:%d", errno)) {
6079                 err = -1;
6080                 goto done;
6081         }
6082
6083         if (*btf_log_buf && args.always_log)
6084                 fprintf(stderr, "\n%s", btf_log_buf);
6085         *btf_log_buf = '\0';
6086
6087         linfo_str_off = ret_next_str - test->str_sec;
6088         patched_linfo = patch_name_tbd(test->line_info,
6089                                        test->str_sec, linfo_str_off,
6090                                        test->str_sec_size, &linfo_size);
6091         if (IS_ERR(patched_linfo)) {
6092                 fprintf(stderr, "error in creating raw bpf_line_info");
6093                 err = -1;
6094                 goto done;
6095         }
6096
6097         attr.prog_type = test->prog_type;
6098         attr.insns = ptr_to_u64(test->insns);
6099         attr.insn_cnt = probe_prog_length(test->insns);
6100         attr.license = ptr_to_u64("GPL");
6101         attr.prog_btf_fd = btf_fd;
6102         attr.func_info_rec_size = test->func_info_rec_size;
6103         attr.func_info_cnt = test->func_info_cnt;
6104         attr.func_info = ptr_to_u64(test->func_info);
6105         attr.log_buf = ptr_to_u64(btf_log_buf);
6106         attr.log_size = BTF_LOG_BUF_SIZE;
6107         attr.log_level = 1;
6108         if (linfo_size) {
6109                 attr.line_info_rec_size = test->line_info_rec_size;
6110                 attr.line_info = ptr_to_u64(patched_linfo);
6111                 attr.line_info_cnt = linfo_size / attr.line_info_rec_size;
6112         }
6113
6114         prog_fd = syscall(__NR_bpf, BPF_PROG_LOAD, &attr, sizeof(attr));
6115         err = ((prog_fd == -1) != test->expected_prog_load_failure);
6116         if (CHECK(err, "prog_fd:%d expected_prog_load_failure:%u errno:%d",
6117                   prog_fd, test->expected_prog_load_failure, errno) ||
6118             CHECK(test->err_str && !strstr(btf_log_buf, test->err_str),
6119                   "expected err_str:%s", test->err_str)) {
6120                 err = -1;
6121                 goto done;
6122         }
6123
6124         if (prog_fd == -1)
6125                 goto done;
6126
6127         err = test_get_finfo(test, prog_fd);
6128         if (err)
6129                 goto done;
6130
6131         err = test_get_linfo(test, patched_linfo,
6132                              attr.line_info_cnt - test->dead_code_cnt,
6133                              prog_fd);
6134         if (err)
6135                 goto done;
6136
6137 done:
6138         if (!err)
6139                 fprintf(stderr, "OK");
6140
6141         if (*btf_log_buf && (err || args.always_log))
6142                 fprintf(stderr, "\n%s", btf_log_buf);
6143
6144         if (btf_fd != -1)
6145                 close(btf_fd);
6146         if (prog_fd != -1)
6147                 close(prog_fd);
6148
6149         if (!IS_ERR(patched_linfo))
6150                 free(patched_linfo);
6151
6152         return err;
6153 }
6154
6155 static int test_info_raw(void)
6156 {
6157         unsigned int i;
6158         int err = 0;
6159
6160         if (args.info_raw_test_num)
6161                 return count_result(do_test_info_raw(args.info_raw_test_num));
6162
6163         for (i = 1; i <= ARRAY_SIZE(info_raw_tests); i++)
6164                 err |= count_result(do_test_info_raw(i));
6165
6166         return err;
6167 }
6168
6169 struct btf_raw_data {
6170         __u32 raw_types[MAX_NR_RAW_U32];
6171         const char *str_sec;
6172         __u32 str_sec_size;
6173 };
6174
6175 struct btf_dedup_test {
6176         const char *descr;
6177         struct btf_raw_data input;
6178         struct btf_raw_data expect;
6179         struct btf_dedup_opts opts;
6180 };
6181
6182 const struct btf_dedup_test dedup_tests[] = {
6183
6184 {
6185         .descr = "dedup: unused strings filtering",
6186         .input = {
6187                 .raw_types = {
6188                         BTF_TYPE_INT_ENC(NAME_NTH(2), BTF_INT_SIGNED, 0, 32, 4),
6189                         BTF_TYPE_INT_ENC(NAME_NTH(5), BTF_INT_SIGNED, 0, 64, 8),
6190                         BTF_END_RAW,
6191                 },
6192                 BTF_STR_SEC("\0unused\0int\0foo\0bar\0long"),
6193         },
6194         .expect = {
6195                 .raw_types = {
6196                         BTF_TYPE_INT_ENC(NAME_NTH(1), BTF_INT_SIGNED, 0, 32, 4),
6197                         BTF_TYPE_INT_ENC(NAME_NTH(2), BTF_INT_SIGNED, 0, 64, 8),
6198                         BTF_END_RAW,
6199                 },
6200                 BTF_STR_SEC("\0int\0long"),
6201         },
6202         .opts = {
6203                 .dont_resolve_fwds = false,
6204         },
6205 },
6206 {
6207         .descr = "dedup: strings deduplication",
6208         .input = {
6209                 .raw_types = {
6210                         BTF_TYPE_INT_ENC(NAME_NTH(1), BTF_INT_SIGNED, 0, 32, 4),
6211                         BTF_TYPE_INT_ENC(NAME_NTH(2), BTF_INT_SIGNED, 0, 64, 8),
6212                         BTF_TYPE_INT_ENC(NAME_NTH(3), BTF_INT_SIGNED, 0, 32, 4),
6213                         BTF_TYPE_INT_ENC(NAME_NTH(4), BTF_INT_SIGNED, 0, 64, 8),
6214                         BTF_TYPE_INT_ENC(NAME_NTH(5), BTF_INT_SIGNED, 0, 32, 4),
6215                         BTF_END_RAW,
6216                 },
6217                 BTF_STR_SEC("\0int\0long int\0int\0long int\0int"),
6218         },
6219         .expect = {
6220                 .raw_types = {
6221                         BTF_TYPE_INT_ENC(NAME_NTH(1), BTF_INT_SIGNED, 0, 32, 4),
6222                         BTF_TYPE_INT_ENC(NAME_NTH(2), BTF_INT_SIGNED, 0, 64, 8),
6223                         BTF_END_RAW,
6224                 },
6225                 BTF_STR_SEC("\0int\0long int"),
6226         },
6227         .opts = {
6228                 .dont_resolve_fwds = false,
6229         },
6230 },
6231 {
6232         .descr = "dedup: struct example #1",
6233         /*
6234          * struct s {
6235          *      struct s *next;
6236          *      const int *a;
6237          *      int b[16];
6238          *      int c;
6239          * }
6240          */
6241         .input = {
6242                 .raw_types = {
6243                         /* int */
6244                         BTF_TYPE_INT_ENC(NAME_NTH(1), BTF_INT_SIGNED, 0, 32, 4),        /* [1] */
6245                         /* int[16] */
6246                         BTF_TYPE_ARRAY_ENC(1, 1, 16),                                   /* [2] */
6247                         /* struct s { */
6248                         BTF_STRUCT_ENC(NAME_NTH(2), 4, 84),                             /* [3] */
6249                                 BTF_MEMBER_ENC(NAME_NTH(3), 4, 0),      /* struct s *next;      */
6250                                 BTF_MEMBER_ENC(NAME_NTH(4), 5, 64),     /* const int *a;        */
6251                                 BTF_MEMBER_ENC(NAME_NTH(5), 2, 128),    /* int b[16];           */
6252                                 BTF_MEMBER_ENC(NAME_NTH(6), 1, 640),    /* int c;               */
6253                         /* ptr -> [3] struct s */
6254                         BTF_PTR_ENC(3),                                                 /* [4] */
6255                         /* ptr -> [6] const int */
6256                         BTF_PTR_ENC(6),                                                 /* [5] */
6257                         /* const -> [1] int */
6258                         BTF_CONST_ENC(1),                                               /* [6] */
6259
6260                         /* full copy of the above */
6261                         BTF_TYPE_INT_ENC(NAME_NTH(1), BTF_INT_SIGNED, 0, 32, 4),        /* [7] */
6262                         BTF_TYPE_ARRAY_ENC(7, 7, 16),                                   /* [8] */
6263                         BTF_STRUCT_ENC(NAME_NTH(2), 4, 84),                             /* [9] */
6264                                 BTF_MEMBER_ENC(NAME_NTH(3), 10, 0),
6265                                 BTF_MEMBER_ENC(NAME_NTH(4), 11, 64),
6266                                 BTF_MEMBER_ENC(NAME_NTH(5), 8, 128),
6267                                 BTF_MEMBER_ENC(NAME_NTH(6), 7, 640),
6268                         BTF_PTR_ENC(9),                                                 /* [10] */
6269                         BTF_PTR_ENC(12),                                                /* [11] */
6270                         BTF_CONST_ENC(7),                                               /* [12] */
6271                         BTF_END_RAW,
6272                 },
6273                 BTF_STR_SEC("\0int\0s\0next\0a\0b\0c\0"),
6274         },
6275         .expect = {
6276                 .raw_types = {
6277                         /* int */
6278                         BTF_TYPE_INT_ENC(NAME_NTH(4), BTF_INT_SIGNED, 0, 32, 4),        /* [1] */
6279                         /* int[16] */
6280                         BTF_TYPE_ARRAY_ENC(1, 1, 16),                                   /* [2] */
6281                         /* struct s { */
6282                         BTF_STRUCT_ENC(NAME_NTH(6), 4, 84),                             /* [3] */
6283                                 BTF_MEMBER_ENC(NAME_NTH(5), 4, 0),      /* struct s *next;      */
6284                                 BTF_MEMBER_ENC(NAME_NTH(1), 5, 64),     /* const int *a;        */
6285                                 BTF_MEMBER_ENC(NAME_NTH(2), 2, 128),    /* int b[16];           */
6286                                 BTF_MEMBER_ENC(NAME_NTH(3), 1, 640),    /* int c;               */
6287                         /* ptr -> [3] struct s */
6288                         BTF_PTR_ENC(3),                                                 /* [4] */
6289                         /* ptr -> [6] const int */
6290                         BTF_PTR_ENC(6),                                                 /* [5] */
6291                         /* const -> [1] int */
6292                         BTF_CONST_ENC(1),                                               /* [6] */
6293                         BTF_END_RAW,
6294                 },
6295                 BTF_STR_SEC("\0a\0b\0c\0int\0next\0s"),
6296         },
6297         .opts = {
6298                 .dont_resolve_fwds = false,
6299         },
6300 },
6301 {
6302         .descr = "dedup: struct <-> fwd resolution w/ hash collision",
6303         /*
6304          * // CU 1:
6305          * struct x;
6306          * struct s {
6307          *      struct x *x;
6308          * };
6309          * // CU 2:
6310          * struct x {};
6311          * struct s {
6312          *      struct x *x;
6313          * };
6314          */
6315         .input = {
6316                 .raw_types = {
6317                         /* CU 1 */
6318                         BTF_FWD_ENC(NAME_TBD, 0 /* struct fwd */),      /* [1] fwd x      */
6319                         BTF_PTR_ENC(1),                                 /* [2] ptr -> [1] */
6320                         BTF_STRUCT_ENC(NAME_TBD, 1, 8),                 /* [3] struct s   */
6321                                 BTF_MEMBER_ENC(NAME_TBD, 2, 0),
6322                         /* CU 2 */
6323                         BTF_STRUCT_ENC(NAME_TBD, 0, 0),                 /* [4] struct x   */
6324                         BTF_PTR_ENC(4),                                 /* [5] ptr -> [4] */
6325                         BTF_STRUCT_ENC(NAME_TBD, 1, 8),                 /* [6] struct s   */
6326                                 BTF_MEMBER_ENC(NAME_TBD, 5, 0),
6327                         BTF_END_RAW,
6328                 },
6329                 BTF_STR_SEC("\0x\0s\0x\0x\0s\0x\0"),
6330         },
6331         .expect = {
6332                 .raw_types = {
6333                         BTF_PTR_ENC(3),                                 /* [1] ptr -> [3] */
6334                         BTF_STRUCT_ENC(NAME_TBD, 1, 8),                 /* [2] struct s   */
6335                                 BTF_MEMBER_ENC(NAME_TBD, 1, 0),
6336                         BTF_STRUCT_ENC(NAME_NTH(2), 0, 0),              /* [3] struct x   */
6337                         BTF_END_RAW,
6338                 },
6339                 BTF_STR_SEC("\0s\0x"),
6340         },
6341         .opts = {
6342                 .dont_resolve_fwds = false,
6343                 .dedup_table_size = 1, /* force hash collisions */
6344         },
6345 },
6346 {
6347         .descr = "dedup: void equiv check",
6348         /*
6349          * // CU 1:
6350          * struct s {
6351          *      struct {} *x;
6352          * };
6353          * // CU 2:
6354          * struct s {
6355          *      int *x;
6356          * };
6357          */
6358         .input = {
6359                 .raw_types = {
6360                         /* CU 1 */
6361                         BTF_STRUCT_ENC(0, 0, 1),                                /* [1] struct {}  */
6362                         BTF_PTR_ENC(1),                                         /* [2] ptr -> [1] */
6363                         BTF_STRUCT_ENC(NAME_NTH(1), 1, 8),                      /* [3] struct s   */
6364                                 BTF_MEMBER_ENC(NAME_NTH(2), 2, 0),
6365                         /* CU 2 */
6366                         BTF_PTR_ENC(0),                                         /* [4] ptr -> void */
6367                         BTF_STRUCT_ENC(NAME_NTH(1), 1, 8),                      /* [5] struct s   */
6368                                 BTF_MEMBER_ENC(NAME_NTH(2), 4, 0),
6369                         BTF_END_RAW,
6370                 },
6371                 BTF_STR_SEC("\0s\0x"),
6372         },
6373         .expect = {
6374                 .raw_types = {
6375                         /* CU 1 */
6376                         BTF_STRUCT_ENC(0, 0, 1),                                /* [1] struct {}  */
6377                         BTF_PTR_ENC(1),                                         /* [2] ptr -> [1] */
6378                         BTF_STRUCT_ENC(NAME_NTH(1), 1, 8),                      /* [3] struct s   */
6379                                 BTF_MEMBER_ENC(NAME_NTH(2), 2, 0),
6380                         /* CU 2 */
6381                         BTF_PTR_ENC(0),                                         /* [4] ptr -> void */
6382                         BTF_STRUCT_ENC(NAME_NTH(1), 1, 8),                      /* [5] struct s   */
6383                                 BTF_MEMBER_ENC(NAME_NTH(2), 4, 0),
6384                         BTF_END_RAW,
6385                 },
6386                 BTF_STR_SEC("\0s\0x"),
6387         },
6388         .opts = {
6389                 .dont_resolve_fwds = false,
6390                 .dedup_table_size = 1, /* force hash collisions */
6391         },
6392 },
6393 {
6394         .descr = "dedup: all possible kinds (no duplicates)",
6395         .input = {
6396                 .raw_types = {
6397                         BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 8),           /* [1] int */
6398                         BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_ENUM, 0, 2), 4),   /* [2] enum */
6399                                 BTF_ENUM_ENC(NAME_TBD, 0),
6400                                 BTF_ENUM_ENC(NAME_TBD, 1),
6401                         BTF_FWD_ENC(NAME_TBD, 1 /* union kind_flag */),                 /* [3] fwd */
6402                         BTF_TYPE_ARRAY_ENC(2, 1, 7),                                    /* [4] array */
6403                         BTF_STRUCT_ENC(NAME_TBD, 1, 4),                                 /* [5] struct */
6404                                 BTF_MEMBER_ENC(NAME_TBD, 1, 0),
6405                         BTF_UNION_ENC(NAME_TBD, 1, 4),                                  /* [6] union */
6406                                 BTF_MEMBER_ENC(NAME_TBD, 1, 0),
6407                         BTF_TYPEDEF_ENC(NAME_TBD, 1),                                   /* [7] typedef */
6408                         BTF_PTR_ENC(0),                                                 /* [8] ptr */
6409                         BTF_CONST_ENC(8),                                               /* [9] const */
6410                         BTF_VOLATILE_ENC(8),                                            /* [10] volatile */
6411                         BTF_RESTRICT_ENC(8),                                            /* [11] restrict */
6412                         BTF_FUNC_PROTO_ENC(1, 2),                                       /* [12] func_proto */
6413                                 BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
6414                                 BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 8),
6415                         BTF_FUNC_ENC(NAME_TBD, 12),                                     /* [13] func */
6416                         BTF_END_RAW,
6417                 },
6418                 BTF_STR_SEC("\0A\0B\0C\0D\0E\0F\0G\0H\0I\0J\0K\0L\0M"),
6419         },
6420         .expect = {
6421                 .raw_types = {
6422                         BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 8),           /* [1] int */
6423                         BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_ENUM, 0, 2), 4),   /* [2] enum */
6424                                 BTF_ENUM_ENC(NAME_TBD, 0),
6425                                 BTF_ENUM_ENC(NAME_TBD, 1),
6426                         BTF_FWD_ENC(NAME_TBD, 1 /* union kind_flag */),                 /* [3] fwd */
6427                         BTF_TYPE_ARRAY_ENC(2, 1, 7),                                    /* [4] array */
6428                         BTF_STRUCT_ENC(NAME_TBD, 1, 4),                                 /* [5] struct */
6429                                 BTF_MEMBER_ENC(NAME_TBD, 1, 0),
6430                         BTF_UNION_ENC(NAME_TBD, 1, 4),                                  /* [6] union */
6431                                 BTF_MEMBER_ENC(NAME_TBD, 1, 0),
6432                         BTF_TYPEDEF_ENC(NAME_TBD, 1),                                   /* [7] typedef */
6433                         BTF_PTR_ENC(0),                                                 /* [8] ptr */
6434                         BTF_CONST_ENC(8),                                               /* [9] const */
6435                         BTF_VOLATILE_ENC(8),                                            /* [10] volatile */
6436                         BTF_RESTRICT_ENC(8),                                            /* [11] restrict */
6437                         BTF_FUNC_PROTO_ENC(1, 2),                                       /* [12] func_proto */
6438                                 BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
6439                                 BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 8),
6440                         BTF_FUNC_ENC(NAME_TBD, 12),                                     /* [13] func */
6441                         BTF_END_RAW,
6442                 },
6443                 BTF_STR_SEC("\0A\0B\0C\0D\0E\0F\0G\0H\0I\0J\0K\0L\0M"),
6444         },
6445         .opts = {
6446                 .dont_resolve_fwds = false,
6447         },
6448 },
6449 {
6450         .descr = "dedup: no int duplicates",
6451         .input = {
6452                 .raw_types = {
6453                         BTF_TYPE_INT_ENC(NAME_NTH(1), BTF_INT_SIGNED, 0, 32, 8),
6454                         /* different name */
6455                         BTF_TYPE_INT_ENC(NAME_NTH(2), BTF_INT_SIGNED, 0, 32, 8),
6456                         /* different encoding */
6457                         BTF_TYPE_INT_ENC(NAME_NTH(1), BTF_INT_CHAR, 0, 32, 8),
6458                         BTF_TYPE_INT_ENC(NAME_NTH(1), BTF_INT_BOOL, 0, 32, 8),
6459                         /* different bit offset */
6460                         BTF_TYPE_INT_ENC(NAME_NTH(1), BTF_INT_SIGNED, 8, 32, 8),
6461                         /* different bit size */
6462                         BTF_TYPE_INT_ENC(NAME_NTH(1), BTF_INT_SIGNED, 0, 27, 8),
6463                         /* different byte size */
6464                         BTF_TYPE_INT_ENC(NAME_NTH(1), BTF_INT_SIGNED, 0, 32, 4),
6465                         BTF_END_RAW,
6466                 },
6467                 BTF_STR_SEC("\0int\0some other int"),
6468         },
6469         .expect = {
6470                 .raw_types = {
6471                         BTF_TYPE_INT_ENC(NAME_NTH(1), BTF_INT_SIGNED, 0, 32, 8),
6472                         /* different name */
6473                         BTF_TYPE_INT_ENC(NAME_NTH(2), BTF_INT_SIGNED, 0, 32, 8),
6474                         /* different encoding */
6475                         BTF_TYPE_INT_ENC(NAME_NTH(1), BTF_INT_CHAR, 0, 32, 8),
6476                         BTF_TYPE_INT_ENC(NAME_NTH(1), BTF_INT_BOOL, 0, 32, 8),
6477                         /* different bit offset */
6478                         BTF_TYPE_INT_ENC(NAME_NTH(1), BTF_INT_SIGNED, 8, 32, 8),
6479                         /* different bit size */
6480                         BTF_TYPE_INT_ENC(NAME_NTH(1), BTF_INT_SIGNED, 0, 27, 8),
6481                         /* different byte size */
6482                         BTF_TYPE_INT_ENC(NAME_NTH(1), BTF_INT_SIGNED, 0, 32, 4),
6483                         BTF_END_RAW,
6484                 },
6485                 BTF_STR_SEC("\0int\0some other int"),
6486         },
6487         .opts = {
6488                 .dont_resolve_fwds = false,
6489         },
6490 },
6491 {
6492         .descr = "dedup: enum fwd resolution",
6493         .input = {
6494                 .raw_types = {
6495                         /* [1] fwd enum 'e1' before full enum */
6496                         BTF_TYPE_ENC(NAME_NTH(1), BTF_INFO_ENC(BTF_KIND_ENUM, 0, 0), 4),
6497                         /* [2] full enum 'e1' after fwd */
6498                         BTF_TYPE_ENC(NAME_NTH(1), BTF_INFO_ENC(BTF_KIND_ENUM, 0, 1), 4),
6499                                 BTF_ENUM_ENC(NAME_NTH(2), 123),
6500                         /* [3] full enum 'e2' before fwd */
6501                         BTF_TYPE_ENC(NAME_NTH(3), BTF_INFO_ENC(BTF_KIND_ENUM, 0, 1), 4),
6502                                 BTF_ENUM_ENC(NAME_NTH(4), 456),
6503                         /* [4] fwd enum 'e2' after full enum */
6504                         BTF_TYPE_ENC(NAME_NTH(3), BTF_INFO_ENC(BTF_KIND_ENUM, 0, 0), 4),
6505                         /* [5] incompatible fwd enum with different size */
6506                         BTF_TYPE_ENC(NAME_NTH(1), BTF_INFO_ENC(BTF_KIND_ENUM, 0, 0), 1),
6507                         /* [6] incompatible full enum with different value */
6508                         BTF_TYPE_ENC(NAME_NTH(1), BTF_INFO_ENC(BTF_KIND_ENUM, 0, 1), 4),
6509                                 BTF_ENUM_ENC(NAME_NTH(2), 321),
6510                         BTF_END_RAW,
6511                 },
6512                 BTF_STR_SEC("\0e1\0e1_val\0e2\0e2_val"),
6513         },
6514         .expect = {
6515                 .raw_types = {
6516                         /* [1] full enum 'e1' */
6517                         BTF_TYPE_ENC(NAME_NTH(1), BTF_INFO_ENC(BTF_KIND_ENUM, 0, 1), 4),
6518                                 BTF_ENUM_ENC(NAME_NTH(2), 123),
6519                         /* [2] full enum 'e2' */
6520                         BTF_TYPE_ENC(NAME_NTH(3), BTF_INFO_ENC(BTF_KIND_ENUM, 0, 1), 4),
6521                                 BTF_ENUM_ENC(NAME_NTH(4), 456),
6522                         /* [3] incompatible fwd enum with different size */
6523                         BTF_TYPE_ENC(NAME_NTH(1), BTF_INFO_ENC(BTF_KIND_ENUM, 0, 0), 1),
6524                         /* [4] incompatible full enum with different value */
6525                         BTF_TYPE_ENC(NAME_NTH(1), BTF_INFO_ENC(BTF_KIND_ENUM, 0, 1), 4),
6526                                 BTF_ENUM_ENC(NAME_NTH(2), 321),
6527                         BTF_END_RAW,
6528                 },
6529                 BTF_STR_SEC("\0e1\0e1_val\0e2\0e2_val"),
6530         },
6531         .opts = {
6532                 .dont_resolve_fwds = false,
6533         },
6534 },
6535 {
6536         .descr = "dedup: datasec and vars pass-through",
6537         .input = {
6538                 .raw_types = {
6539                         /* int */
6540                         BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),  /* [1] */
6541                         /* static int t */
6542                         BTF_VAR_ENC(NAME_NTH(2), 1, 0),                 /* [2] */
6543                         /* .bss section */                              /* [3] */
6544                         BTF_TYPE_ENC(NAME_NTH(1), BTF_INFO_ENC(BTF_KIND_DATASEC, 0, 1), 4),
6545                         BTF_VAR_SECINFO_ENC(2, 0, 4),
6546                         /* int, referenced from [5] */
6547                         BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),  /* [4] */
6548                         /* another static int t */
6549                         BTF_VAR_ENC(NAME_NTH(2), 4, 0),                 /* [5] */
6550                         /* another .bss section */                      /* [6] */
6551                         BTF_TYPE_ENC(NAME_NTH(1), BTF_INFO_ENC(BTF_KIND_DATASEC, 0, 1), 4),
6552                         BTF_VAR_SECINFO_ENC(5, 0, 4),
6553                         BTF_END_RAW,
6554                 },
6555                 BTF_STR_SEC("\0.bss\0t"),
6556         },
6557         .expect = {
6558                 .raw_types = {
6559                         /* int */
6560                         BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),  /* [1] */
6561                         /* static int t */
6562                         BTF_VAR_ENC(NAME_NTH(2), 1, 0),                 /* [2] */
6563                         /* .bss section */                              /* [3] */
6564                         BTF_TYPE_ENC(NAME_NTH(1), BTF_INFO_ENC(BTF_KIND_DATASEC, 0, 1), 4),
6565                         BTF_VAR_SECINFO_ENC(2, 0, 4),
6566                         /* another static int t */
6567                         BTF_VAR_ENC(NAME_NTH(2), 1, 0),                 /* [4] */
6568                         /* another .bss section */                      /* [5] */
6569                         BTF_TYPE_ENC(NAME_NTH(1), BTF_INFO_ENC(BTF_KIND_DATASEC, 0, 1), 4),
6570                         BTF_VAR_SECINFO_ENC(4, 0, 4),
6571                         BTF_END_RAW,
6572                 },
6573                 BTF_STR_SEC("\0.bss\0t"),
6574         },
6575         .opts = {
6576                 .dont_resolve_fwds = false,
6577                 .dedup_table_size = 1
6578         },
6579 },
6580
6581 };
6582
6583 static int btf_type_size(const struct btf_type *t)
6584 {
6585         int base_size = sizeof(struct btf_type);
6586         __u16 vlen = BTF_INFO_VLEN(t->info);
6587         __u16 kind = BTF_INFO_KIND(t->info);
6588
6589         switch (kind) {
6590         case BTF_KIND_FWD:
6591         case BTF_KIND_CONST:
6592         case BTF_KIND_VOLATILE:
6593         case BTF_KIND_RESTRICT:
6594         case BTF_KIND_PTR:
6595         case BTF_KIND_TYPEDEF:
6596         case BTF_KIND_FUNC:
6597                 return base_size;
6598         case BTF_KIND_INT:
6599                 return base_size + sizeof(__u32);
6600         case BTF_KIND_ENUM:
6601                 return base_size + vlen * sizeof(struct btf_enum);
6602         case BTF_KIND_ARRAY:
6603                 return base_size + sizeof(struct btf_array);
6604         case BTF_KIND_STRUCT:
6605         case BTF_KIND_UNION:
6606                 return base_size + vlen * sizeof(struct btf_member);
6607         case BTF_KIND_FUNC_PROTO:
6608                 return base_size + vlen * sizeof(struct btf_param);
6609         case BTF_KIND_VAR:
6610                 return base_size + sizeof(struct btf_var);
6611         case BTF_KIND_DATASEC:
6612                 return base_size + vlen * sizeof(struct btf_var_secinfo);
6613         default:
6614                 fprintf(stderr, "Unsupported BTF_KIND:%u\n", kind);
6615                 return -EINVAL;
6616         }
6617 }
6618
6619 static void dump_btf_strings(const char *strs, __u32 len)
6620 {
6621         const char *cur = strs;
6622         int i = 0;
6623
6624         while (cur < strs + len) {
6625                 fprintf(stderr, "string #%d: '%s'\n", i, cur);
6626                 cur += strlen(cur) + 1;
6627                 i++;
6628         }
6629 }
6630
6631 static int do_test_dedup(unsigned int test_num)
6632 {
6633         const struct btf_dedup_test *test = &dedup_tests[test_num - 1];
6634         __u32 test_nr_types, expect_nr_types, test_btf_size, expect_btf_size;
6635         const struct btf_header *test_hdr, *expect_hdr;
6636         struct btf *test_btf = NULL, *expect_btf = NULL;
6637         const void *test_btf_data, *expect_btf_data;
6638         const char *ret_test_next_str, *ret_expect_next_str;
6639         const char *test_strs, *expect_strs;
6640         const char *test_str_cur, *test_str_end;
6641         const char *expect_str_cur, *expect_str_end;
6642         unsigned int raw_btf_size;
6643         void *raw_btf;
6644         int err = 0, i;
6645
6646         fprintf(stderr, "BTF dedup test[%u] (%s):", test_num, test->descr);
6647
6648         raw_btf = btf_raw_create(&hdr_tmpl, test->input.raw_types,
6649                                  test->input.str_sec, test->input.str_sec_size,
6650                                  &raw_btf_size, &ret_test_next_str);
6651         if (!raw_btf)
6652                 return -1;
6653         test_btf = btf__new((__u8 *)raw_btf, raw_btf_size);
6654         free(raw_btf);
6655         if (CHECK(IS_ERR(test_btf), "invalid test_btf errno:%ld",
6656                   PTR_ERR(test_btf))) {
6657                 err = -1;
6658                 goto done;
6659         }
6660
6661         raw_btf = btf_raw_create(&hdr_tmpl, test->expect.raw_types,
6662                                  test->expect.str_sec,
6663                                  test->expect.str_sec_size,
6664                                  &raw_btf_size, &ret_expect_next_str);
6665         if (!raw_btf)
6666                 return -1;
6667         expect_btf = btf__new((__u8 *)raw_btf, raw_btf_size);
6668         free(raw_btf);
6669         if (CHECK(IS_ERR(expect_btf), "invalid expect_btf errno:%ld",
6670                   PTR_ERR(expect_btf))) {
6671                 err = -1;
6672                 goto done;
6673         }
6674
6675         err = btf__dedup(test_btf, NULL, &test->opts);
6676         if (CHECK(err, "btf_dedup failed errno:%d", err)) {
6677                 err = -1;
6678                 goto done;
6679         }
6680
6681         test_btf_data = btf__get_raw_data(test_btf, &test_btf_size);
6682         expect_btf_data = btf__get_raw_data(expect_btf, &expect_btf_size);
6683         if (CHECK(test_btf_size != expect_btf_size,
6684                   "test_btf_size:%u != expect_btf_size:%u",
6685                   test_btf_size, expect_btf_size)) {
6686                 err = -1;
6687                 goto done;
6688         }
6689
6690         test_hdr = test_btf_data;
6691         test_strs = test_btf_data + sizeof(*test_hdr) + test_hdr->str_off;
6692         expect_hdr = expect_btf_data;
6693         expect_strs = expect_btf_data + sizeof(*test_hdr) + expect_hdr->str_off;
6694         if (CHECK(test_hdr->str_len != expect_hdr->str_len,
6695                   "test_hdr->str_len:%u != expect_hdr->str_len:%u",
6696                   test_hdr->str_len, expect_hdr->str_len)) {
6697                 fprintf(stderr, "\ntest strings:\n");
6698                 dump_btf_strings(test_strs, test_hdr->str_len);
6699                 fprintf(stderr, "\nexpected strings:\n");
6700                 dump_btf_strings(expect_strs, expect_hdr->str_len);
6701                 err = -1;
6702                 goto done;
6703         }
6704
6705         test_str_cur = test_strs;
6706         test_str_end = test_strs + test_hdr->str_len;
6707         expect_str_cur = expect_strs;
6708         expect_str_end = expect_strs + expect_hdr->str_len;
6709         while (test_str_cur < test_str_end && expect_str_cur < expect_str_end) {
6710                 size_t test_len, expect_len;
6711
6712                 test_len = strlen(test_str_cur);
6713                 expect_len = strlen(expect_str_cur);
6714                 if (CHECK(test_len != expect_len,
6715                           "test_len:%zu != expect_len:%zu "
6716                           "(test_str:%s, expect_str:%s)",
6717                           test_len, expect_len, test_str_cur, expect_str_cur)) {
6718                         err = -1;
6719                         goto done;
6720                 }
6721                 if (CHECK(strcmp(test_str_cur, expect_str_cur),
6722                           "test_str:%s != expect_str:%s",
6723                           test_str_cur, expect_str_cur)) {
6724                         err = -1;
6725                         goto done;
6726                 }
6727                 test_str_cur += test_len + 1;
6728                 expect_str_cur += expect_len + 1;
6729         }
6730         if (CHECK(test_str_cur != test_str_end,
6731                   "test_str_cur:%p != test_str_end:%p",
6732                   test_str_cur, test_str_end)) {
6733                 err = -1;
6734                 goto done;
6735         }
6736
6737         test_nr_types = btf__get_nr_types(test_btf);
6738         expect_nr_types = btf__get_nr_types(expect_btf);
6739         if (CHECK(test_nr_types != expect_nr_types,
6740                   "test_nr_types:%u != expect_nr_types:%u",
6741                   test_nr_types, expect_nr_types)) {
6742                 err = -1;
6743                 goto done;
6744         }
6745
6746         for (i = 1; i <= test_nr_types; i++) {
6747                 const struct btf_type *test_type, *expect_type;
6748                 int test_size, expect_size;
6749
6750                 test_type = btf__type_by_id(test_btf, i);
6751                 expect_type = btf__type_by_id(expect_btf, i);
6752                 test_size = btf_type_size(test_type);
6753                 expect_size = btf_type_size(expect_type);
6754
6755                 if (CHECK(test_size != expect_size,
6756                           "type #%d: test_size:%d != expect_size:%u",
6757                           i, test_size, expect_size)) {
6758                         err = -1;
6759                         goto done;
6760                 }
6761                 if (CHECK(memcmp((void *)test_type,
6762                                  (void *)expect_type,
6763                                  test_size),
6764                           "type #%d: contents differ", i)) {
6765                         err = -1;
6766                         goto done;
6767                 }
6768         }
6769
6770 done:
6771         if (!err)
6772                 fprintf(stderr, "OK");
6773         if (!IS_ERR(test_btf))
6774                 btf__free(test_btf);
6775         if (!IS_ERR(expect_btf))
6776                 btf__free(expect_btf);
6777
6778         return err;
6779 }
6780
6781 static int test_dedup(void)
6782 {
6783         unsigned int i;
6784         int err = 0;
6785
6786         if (args.dedup_test_num)
6787                 return count_result(do_test_dedup(args.dedup_test_num));
6788
6789         for (i = 1; i <= ARRAY_SIZE(dedup_tests); i++)
6790                 err |= count_result(do_test_dedup(i));
6791
6792         return err;
6793 }
6794
6795 static void usage(const char *cmd)
6796 {
6797         fprintf(stderr, "Usage: %s [-l] [[-r btf_raw_test_num (1 - %zu)] |\n"
6798                         "\t[-g btf_get_info_test_num (1 - %zu)] |\n"
6799                         "\t[-f btf_file_test_num (1 - %zu)] |\n"
6800                         "\t[-k btf_prog_info_raw_test_num (1 - %zu)] |\n"
6801                         "\t[-p (pretty print test)] |\n"
6802                         "\t[-d btf_dedup_test_num (1 - %zu)]]\n",
6803                 cmd, ARRAY_SIZE(raw_tests), ARRAY_SIZE(get_info_tests),
6804                 ARRAY_SIZE(file_tests), ARRAY_SIZE(info_raw_tests),
6805                 ARRAY_SIZE(dedup_tests));
6806 }
6807
6808 static int parse_args(int argc, char **argv)
6809 {
6810         const char *optstr = "hlpk:f:r:g:d:";
6811         int opt;
6812
6813         while ((opt = getopt(argc, argv, optstr)) != -1) {
6814                 switch (opt) {
6815                 case 'l':
6816                         args.always_log = true;
6817                         break;
6818                 case 'f':
6819                         args.file_test_num = atoi(optarg);
6820                         args.file_test = true;
6821                         break;
6822                 case 'r':
6823                         args.raw_test_num = atoi(optarg);
6824                         args.raw_test = true;
6825                         break;
6826                 case 'g':
6827                         args.get_info_test_num = atoi(optarg);
6828                         args.get_info_test = true;
6829                         break;
6830                 case 'p':
6831                         args.pprint_test = true;
6832                         break;
6833                 case 'k':
6834                         args.info_raw_test_num = atoi(optarg);
6835                         args.info_raw_test = true;
6836                         break;
6837                 case 'd':
6838                         args.dedup_test_num = atoi(optarg);
6839                         args.dedup_test = true;
6840                         break;
6841                 case 'h':
6842                         usage(argv[0]);
6843                         exit(0);
6844                 default:
6845                         usage(argv[0]);
6846                         return -1;
6847                 }
6848         }
6849
6850         if (args.raw_test_num &&
6851             (args.raw_test_num < 1 ||
6852              args.raw_test_num > ARRAY_SIZE(raw_tests))) {
6853                 fprintf(stderr, "BTF raw test number must be [1 - %zu]\n",
6854                         ARRAY_SIZE(raw_tests));
6855                 return -1;
6856         }
6857
6858         if (args.file_test_num &&
6859             (args.file_test_num < 1 ||
6860              args.file_test_num > ARRAY_SIZE(file_tests))) {
6861                 fprintf(stderr, "BTF file test number must be [1 - %zu]\n",
6862                         ARRAY_SIZE(file_tests));
6863                 return -1;
6864         }
6865
6866         if (args.get_info_test_num &&
6867             (args.get_info_test_num < 1 ||
6868              args.get_info_test_num > ARRAY_SIZE(get_info_tests))) {
6869                 fprintf(stderr, "BTF get info test number must be [1 - %zu]\n",
6870                         ARRAY_SIZE(get_info_tests));
6871                 return -1;
6872         }
6873
6874         if (args.info_raw_test_num &&
6875             (args.info_raw_test_num < 1 ||
6876              args.info_raw_test_num > ARRAY_SIZE(info_raw_tests))) {
6877                 fprintf(stderr, "BTF prog info raw test number must be [1 - %zu]\n",
6878                         ARRAY_SIZE(info_raw_tests));
6879                 return -1;
6880         }
6881
6882         if (args.dedup_test_num &&
6883             (args.dedup_test_num < 1 ||
6884              args.dedup_test_num > ARRAY_SIZE(dedup_tests))) {
6885                 fprintf(stderr, "BTF dedup test number must be [1 - %zu]\n",
6886                         ARRAY_SIZE(dedup_tests));
6887                 return -1;
6888         }
6889
6890         return 0;
6891 }
6892
6893 static void print_summary(void)
6894 {
6895         fprintf(stderr, "PASS:%u SKIP:%u FAIL:%u\n",
6896                 pass_cnt - skip_cnt, skip_cnt, error_cnt);
6897 }
6898
6899 int main(int argc, char **argv)
6900 {
6901         int err = 0;
6902
6903         err = parse_args(argc, argv);
6904         if (err)
6905                 return err;
6906
6907         if (args.always_log)
6908                 libbpf_set_print(__base_pr);
6909
6910         if (args.raw_test)
6911                 err |= test_raw();
6912
6913         if (args.get_info_test)
6914                 err |= test_get_info();
6915
6916         if (args.file_test)
6917                 err |= test_file();
6918
6919         if (args.pprint_test)
6920                 err |= test_pprint();
6921
6922         if (args.info_raw_test)
6923                 err |= test_info_raw();
6924
6925         if (args.dedup_test)
6926                 err |= test_dedup();
6927
6928         if (args.raw_test || args.get_info_test || args.file_test ||
6929             args.pprint_test || args.info_raw_test || args.dedup_test)
6930                 goto done;
6931
6932         err |= test_raw();
6933         err |= test_get_info();
6934         err |= test_file();
6935         err |= test_info_raw();
6936         err |= test_dedup();
6937
6938 done:
6939         print_summary();
6940         return err;
6941 }