~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/tools/testing/selftests/bpf/test_btf.c

Version: ~ [ linux-5.17-rc1 ] ~ [ linux-5.16.2 ] ~ [ linux-5.15.16 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.93 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.173 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.225 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.262 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.297 ] ~ [ linux-4.8.17 ] ~ [ linux-4.7.10 ] ~ [ linux-4.6.7 ] ~ [ linux-4.5.7 ] ~ [ linux-4.4.299 ] ~ [ linux-4.3.6 ] ~ [ linux-4.2.8 ] ~ [ linux-4.1.52 ] ~ [ linux-4.0.9 ] ~ [ linux-3.18.140 ] ~ [ linux-3.16.85 ] ~ [ linux-3.14.79 ] ~ [ linux-3.12.74 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.5 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  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 {
4020         .file = "test_btf_haskv.o",
4021 },
4022 {
4023         .file = "test_btf_nokv.o",
4024         .btf_kv_notfound = true,
4025 },
4026 };
4027 
4028 static int file_has_btf_elf(const char *fn, bool *has_btf_ext)
4029 {
4030         Elf_Scn *scn = NULL;
4031         GElf_Ehdr ehdr;
4032         int ret = 0;
4033         int elf_fd;
4034         Elf *elf;
4035 
4036         if (CHECK(elf_version(EV_CURRENT) == EV_NONE,
4037                   "elf_version(EV_CURRENT) == EV_NONE"))
4038                 return -1;
4039 
4040         elf_fd = open(fn, O_RDONLY);
4041         if (CHECK(elf_fd == -1, "open(%s): errno:%d", fn, errno))
4042                 return -1;
4043 
4044         elf = elf_begin(elf_fd, ELF_C_READ, NULL);
4045         if (CHECK(!elf, "elf_begin(%s): %s", fn, elf_errmsg(elf_errno()))) {
4046                 ret = -1;
4047                 goto done;
4048         }
4049 
4050         if (CHECK(!gelf_getehdr(elf, &ehdr), "!gelf_getehdr(%s)", fn)) {
4051                 ret = -1;
4052                 goto done;
4053         }
4054 
4055         while ((scn = elf_nextscn(elf, scn))) {
4056                 const char *sh_name;
4057                 GElf_Shdr sh;
4058 
4059                 if (CHECK(gelf_getshdr(scn, &sh) != &sh,
4060                           "file:%s gelf_getshdr != &sh", fn)) {
4061                         ret = -1;
4062                         goto done;
4063                 }
4064 
4065                 sh_name = elf_strptr(elf, ehdr.e_shstrndx, sh.sh_name);
4066                 if (!strcmp(sh_name, BTF_ELF_SEC))
4067                         ret = 1;
4068                 if (!strcmp(sh_name, BTF_EXT_ELF_SEC))
4069                         *has_btf_ext = true;
4070         }
4071 
4072 done:
4073         close(elf_fd);
4074         elf_end(elf);
4075         return ret;
4076 }
4077 
4078 static int do_test_file(unsigned int test_num)
4079 {
4080         const struct btf_file_test *test = &file_tests[test_num - 1];
4081         const char *expected_fnames[] = {"_dummy_tracepoint",
4082                                          "test_long_fname_1",
4083                                          "test_long_fname_2"};
4084         struct bpf_prog_info info = {};
4085         struct bpf_object *obj = NULL;
4086         struct bpf_func_info *finfo;
4087         struct bpf_program *prog;
4088         __u32 info_len, rec_size;
4089         bool has_btf_ext = false;
4090         struct btf *btf = NULL;
4091         void *func_info = NULL;
4092         struct bpf_map *map;
4093         int i, err, prog_fd;
4094 
4095         fprintf(stderr, "BTF libbpf test[%u] (%s): ", test_num,
4096                 test->file);
4097 
4098         err = file_has_btf_elf(test->file, &has_btf_ext);
4099         if (err == -1)
4100                 return err;
4101 
4102         if (err == 0) {
4103                 fprintf(stderr, "SKIP. No ELF %s found", BTF_ELF_SEC);
4104                 skip_cnt++;
4105                 return 0;
4106         }
4107 
4108         obj = bpf_object__open(test->file);
4109         if (CHECK(IS_ERR(obj), "obj: %ld", PTR_ERR(obj)))
4110                 return PTR_ERR(obj);
4111 
4112         err = bpf_object__btf_fd(obj);
4113         if (CHECK(err == -1, "bpf_object__btf_fd: -1"))
4114                 goto done;
4115 
4116         prog = bpf_program__next(NULL, obj);
4117         if (CHECK(!prog, "Cannot find bpf_prog")) {
4118                 err = -1;
4119                 goto done;
4120         }
4121 
4122         bpf_program__set_type(prog, BPF_PROG_TYPE_TRACEPOINT);
4123         err = bpf_object__load(obj);
4124         if (CHECK(err < 0, "bpf_object__load: %d", err))
4125                 goto done;
4126         prog_fd = bpf_program__fd(prog);
4127 
4128         map = bpf_object__find_map_by_name(obj, "btf_map");
4129         if (CHECK(!map, "btf_map not found")) {
4130                 err = -1;
4131                 goto done;
4132         }
4133 
4134         err = (bpf_map__btf_key_type_id(map) == 0 || bpf_map__btf_value_type_id(map) == 0)
4135                 != test->btf_kv_notfound;
4136         if (CHECK(err, "btf_key_type_id:%u btf_value_type_id:%u test->btf_kv_notfound:%u",
4137                   bpf_map__btf_key_type_id(map), bpf_map__btf_value_type_id(map),
4138                   test->btf_kv_notfound))
4139                 goto done;
4140 
4141         if (!has_btf_ext)
4142                 goto skip;
4143 
4144         /* get necessary program info */
4145         info_len = sizeof(struct bpf_prog_info);
4146         err = bpf_obj_get_info_by_fd(prog_fd, &info, &info_len);
4147 
4148         if (CHECK(err == -1, "invalid get info (1st) errno:%d", errno)) {
4149                 fprintf(stderr, "%s\n", btf_log_buf);
4150                 err = -1;
4151                 goto done;
4152         }
4153         if (CHECK(info.nr_func_info != 3,
4154                   "incorrect info.nr_func_info (1st) %d",
4155                   info.nr_func_info)) {
4156                 err = -1;
4157                 goto done;
4158         }
4159         rec_size = info.func_info_rec_size;
4160         if (CHECK(rec_size != sizeof(struct bpf_func_info),
4161                   "incorrect info.func_info_rec_size (1st) %d\n", rec_size)) {
4162                 err = -1;
4163                 goto done;
4164         }
4165 
4166         func_info = malloc(info.nr_func_info * rec_size);
4167         if (CHECK(!func_info, "out of memory")) {
4168                 err = -1;
4169                 goto done;
4170         }
4171 
4172         /* reset info to only retrieve func_info related data */
4173         memset(&info, 0, sizeof(info));
4174         info.nr_func_info = 3;
4175         info.func_info_rec_size = rec_size;
4176         info.func_info = ptr_to_u64(func_info);
4177 
4178         err = bpf_obj_get_info_by_fd(prog_fd, &info, &info_len);
4179 
4180         if (CHECK(err == -1, "invalid get info (2nd) errno:%d", errno)) {
4181                 fprintf(stderr, "%s\n", btf_log_buf);
4182                 err = -1;
4183                 goto done;
4184         }
4185         if (CHECK(info.nr_func_info != 3,
4186                   "incorrect info.nr_func_info (2nd) %d",
4187                   info.nr_func_info)) {
4188                 err = -1;
4189                 goto done;
4190         }
4191         if (CHECK(info.func_info_rec_size != rec_size,
4192                   "incorrect info.func_info_rec_size (2nd) %d",
4193                   info.func_info_rec_size)) {
4194                 err = -1;
4195                 goto done;
4196         }
4197 
4198         err = btf__get_from_id(info.btf_id, &btf);
4199         if (CHECK(err, "cannot get btf from kernel, err: %d", err))
4200                 goto done;
4201 
4202         /* check three functions */
4203         finfo = func_info;
4204         for (i = 0; i < 3; i++) {
4205                 const struct btf_type *t;
4206                 const char *fname;
4207 
4208                 t = btf__type_by_id(btf, finfo->type_id);
4209                 if (CHECK(!t, "btf__type_by_id failure: id %u",
4210                           finfo->type_id)) {
4211                         err = -1;
4212                         goto done;
4213                 }
4214 
4215                 fname = btf__name_by_offset(btf, t->name_off);
4216                 err = strcmp(fname, expected_fnames[i]);
4217                 /* for the second and third functions in .text section,
4218                  * the compiler may order them either way.
4219                  */
4220                 if (i && err)
4221                         err = strcmp(fname, expected_fnames[3 - i]);
4222                 if (CHECK(err, "incorrect fname %s", fname ? : "")) {
4223                         err = -1;
4224                         goto done;
4225                 }
4226 
4227                 finfo = (void *)finfo + rec_size;
4228         }
4229 
4230 skip:
4231         fprintf(stderr, "OK");
4232 
4233 done:
4234         free(func_info);
4235         bpf_object__close(obj);
4236         return err;
4237 }
4238 
4239 static int test_file(void)
4240 {
4241         unsigned int i;
4242         int err = 0;
4243 
4244         if (args.file_test_num)
4245                 return count_result(do_test_file(args.file_test_num));
4246 
4247         for (i = 1; i <= ARRAY_SIZE(file_tests); i++)
4248                 err |= count_result(do_test_file(i));
4249 
4250         return err;
4251 }
4252 
4253 const char *pprint_enum_str[] = {
4254         "ENUM_ZERO",
4255         "ENUM_ONE",
4256         "ENUM_TWO",
4257         "ENUM_THREE",
4258 };
4259 
4260 struct pprint_mapv {
4261         uint32_t ui32;
4262         uint16_t ui16;
4263         /* 2 bytes hole */
4264         int32_t si32;
4265         uint32_t unused_bits2a:2,
4266                 bits28:28,
4267                 unused_bits2b:2;
4268         union {
4269                 uint64_t ui64;
4270                 uint8_t ui8a[8];
4271         };
4272         enum {
4273                 ENUM_ZERO,
4274                 ENUM_ONE,
4275                 ENUM_TWO,
4276                 ENUM_THREE,
4277         } aenum;
4278         uint32_t ui32b;
4279         uint32_t bits2c:2;
4280         uint8_t si8_4[2][2];
4281 };
4282 
4283 #ifdef __SIZEOF_INT128__
4284 struct pprint_mapv_int128 {
4285         __int128 si128a;
4286         __int128 si128b;
4287         unsigned __int128 bits3:3;
4288         unsigned __int128 bits80:80;
4289         unsigned __int128 ui128;
4290 };
4291 #endif
4292 
4293 static struct btf_raw_test pprint_test_template[] = {
4294 {
4295         .raw_types = {
4296                 /* unsighed char */                     /* [1] */
4297                 BTF_TYPE_INT_ENC(NAME_TBD, 0, 0, 8, 1),
4298                 /* unsigned short */                    /* [2] */
4299                 BTF_TYPE_INT_ENC(NAME_TBD, 0, 0, 16, 2),
4300                 /* unsigned int */                      /* [3] */
4301                 BTF_TYPE_INT_ENC(NAME_TBD, 0, 0, 32, 4),
4302                 /* int */                               /* [4] */
4303                 BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),
4304                 /* unsigned long long */                /* [5] */
4305                 BTF_TYPE_INT_ENC(NAME_TBD, 0, 0, 64, 8),
4306                 /* 2 bits */                            /* [6] */
4307                 BTF_TYPE_INT_ENC(0, 0, 0, 2, 2),
4308                 /* 28 bits */                           /* [7] */
4309                 BTF_TYPE_INT_ENC(0, 0, 0, 28, 4),
4310                 /* uint8_t[8] */                        /* [8] */
4311                 BTF_TYPE_ARRAY_ENC(9, 1, 8),
4312                 /* typedef unsigned char uint8_t */     /* [9] */
4313                 BTF_TYPEDEF_ENC(NAME_TBD, 1),
4314                 /* typedef unsigned short uint16_t */   /* [10] */
4315                 BTF_TYPEDEF_ENC(NAME_TBD, 2),
4316                 /* typedef unsigned int uint32_t */     /* [11] */
4317                 BTF_TYPEDEF_ENC(NAME_TBD, 3),
4318                 /* typedef int int32_t */               /* [12] */
4319                 BTF_TYPEDEF_ENC(NAME_TBD, 4),
4320                 /* typedef unsigned long long uint64_t *//* [13] */
4321                 BTF_TYPEDEF_ENC(NAME_TBD, 5),
4322                 /* union (anon) */                      /* [14] */
4323                 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_UNION, 0, 2), 8),
4324                 BTF_MEMBER_ENC(NAME_TBD, 13, 0),/* uint64_t ui64; */
4325                 BTF_MEMBER_ENC(NAME_TBD, 8, 0), /* uint8_t ui8a[8]; */
4326                 /* enum (anon) */                       /* [15] */
4327                 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_ENUM, 0, 4), 4),
4328                 BTF_ENUM_ENC(NAME_TBD, 0),
4329                 BTF_ENUM_ENC(NAME_TBD, 1),
4330                 BTF_ENUM_ENC(NAME_TBD, 2),
4331                 BTF_ENUM_ENC(NAME_TBD, 3),
4332                 /* struct pprint_mapv */                /* [16] */
4333                 BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 11), 40),
4334                 BTF_MEMBER_ENC(NAME_TBD, 11, 0),        /* uint32_t ui32 */
4335                 BTF_MEMBER_ENC(NAME_TBD, 10, 32),       /* uint16_t ui16 */
4336                 BTF_MEMBER_ENC(NAME_TBD, 12, 64),       /* int32_t si32 */
4337                 BTF_MEMBER_ENC(NAME_TBD, 6, 96),        /* unused_bits2a */
4338                 BTF_MEMBER_ENC(NAME_TBD, 7, 98),        /* bits28 */
4339                 BTF_MEMBER_ENC(NAME_TBD, 6, 126),       /* unused_bits2b */
4340                 BTF_MEMBER_ENC(0, 14, 128),             /* union (anon) */
4341                 BTF_MEMBER_ENC(NAME_TBD, 15, 192),      /* aenum */
4342                 BTF_MEMBER_ENC(NAME_TBD, 11, 224),      /* uint32_t ui32b */
4343                 BTF_MEMBER_ENC(NAME_TBD, 6, 256),       /* bits2c */
4344                 BTF_MEMBER_ENC(NAME_TBD, 17, 264),      /* si8_4 */
4345                 BTF_TYPE_ARRAY_ENC(18, 1, 2),           /* [17] */
4346                 BTF_TYPE_ARRAY_ENC(1, 1, 2),            /* [18] */
4347                 BTF_END_RAW,
4348         },
4349         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"),
4350         .key_size = sizeof(unsigned int),
4351         .value_size = sizeof(struct pprint_mapv),
4352         .key_type_id = 3,       /* unsigned int */
4353         .value_type_id = 16,    /* struct pprint_mapv */
4354         .max_entries = 128 * 1024,
4355 },
4356 
4357 {
4358         /* this type will have the same type as the
4359          * first .raw_types definition, but struct type will
4360          * be encoded with kind_flag set.
4361          */
4362         .raw_types = {
4363                 /* unsighed char */                     /* [1] */
4364                 BTF_TYPE_INT_ENC(NAME_TBD, 0, 0, 8, 1),
4365                 /* unsigned short */                    /* [2] */
4366                 BTF_TYPE_INT_ENC(NAME_TBD, 0, 0, 16, 2),
4367                 /* unsigned int */                      /* [3] */
4368                 BTF_TYPE_INT_ENC(NAME_TBD, 0, 0, 32, 4),
4369                 /* int */                               /* [4] */
4370                 BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),
4371                 /* unsigned long long */                /* [5] */
4372                 BTF_TYPE_INT_ENC(NAME_TBD, 0, 0, 64, 8),
4373                 BTF_TYPE_INT_ENC(0, 0, 0, 32, 4),       /* [6] */
4374                 BTF_TYPE_INT_ENC(0, 0, 0, 32, 4),       /* [7] */
4375                 /* uint8_t[8] */                        /* [8] */
4376                 BTF_TYPE_ARRAY_ENC(9, 1, 8),
4377                 /* typedef unsigned char uint8_t */     /* [9] */
4378                 BTF_TYPEDEF_ENC(NAME_TBD, 1),
4379                 /* typedef unsigned short uint16_t */   /* [10] */
4380                 BTF_TYPEDEF_ENC(NAME_TBD, 2),
4381                 /* typedef unsigned int uint32_t */     /* [11] */
4382                 BTF_TYPEDEF_ENC(NAME_TBD, 3),
4383                 /* typedef int int32_t */               /* [12] */
4384                 BTF_TYPEDEF_ENC(NAME_TBD, 4),
4385                 /* typedef unsigned long long uint64_t *//* [13] */
4386                 BTF_TYPEDEF_ENC(NAME_TBD, 5),
4387                 /* union (anon) */                      /* [14] */
4388                 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_UNION, 0, 2), 8),
4389                 BTF_MEMBER_ENC(NAME_TBD, 13, 0),/* uint64_t ui64; */
4390                 BTF_MEMBER_ENC(NAME_TBD, 8, 0), /* uint8_t ui8a[8]; */
4391                 /* enum (anon) */                       /* [15] */
4392                 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_ENUM, 0, 4), 4),
4393                 BTF_ENUM_ENC(NAME_TBD, 0),
4394                 BTF_ENUM_ENC(NAME_TBD, 1),
4395                 BTF_ENUM_ENC(NAME_TBD, 2),
4396                 BTF_ENUM_ENC(NAME_TBD, 3),
4397                 /* struct pprint_mapv */                /* [16] */
4398                 BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 1, 11), 40),
4399                 BTF_MEMBER_ENC(NAME_TBD, 11, BTF_MEMBER_OFFSET(0, 0)),  /* uint32_t ui32 */
4400                 BTF_MEMBER_ENC(NAME_TBD, 10, BTF_MEMBER_OFFSET(0, 32)), /* uint16_t ui16 */
4401                 BTF_MEMBER_ENC(NAME_TBD, 12, BTF_MEMBER_OFFSET(0, 64)), /* int32_t si32 */
4402                 BTF_MEMBER_ENC(NAME_TBD, 6, BTF_MEMBER_OFFSET(2, 96)),  /* unused_bits2a */
4403                 BTF_MEMBER_ENC(NAME_TBD, 7, BTF_MEMBER_OFFSET(28, 98)), /* bits28 */
4404                 BTF_MEMBER_ENC(NAME_TBD, 6, BTF_MEMBER_OFFSET(2, 126)), /* unused_bits2b */
4405                 BTF_MEMBER_ENC(0, 14, BTF_MEMBER_OFFSET(0, 128)),       /* union (anon) */
4406                 BTF_MEMBER_ENC(NAME_TBD, 15, BTF_MEMBER_OFFSET(0, 192)),        /* aenum */
4407                 BTF_MEMBER_ENC(NAME_TBD, 11, BTF_MEMBER_OFFSET(0, 224)),        /* uint32_t ui32b */
4408                 BTF_MEMBER_ENC(NAME_TBD, 6, BTF_MEMBER_OFFSET(2, 256)), /* bits2c */
4409                 BTF_MEMBER_ENC(NAME_TBD, 17, 264),      /* si8_4 */
4410                 BTF_TYPE_ARRAY_ENC(18, 1, 2),           /* [17] */
4411                 BTF_TYPE_ARRAY_ENC(1, 1, 2),            /* [18] */
4412                 BTF_END_RAW,
4413         },
4414         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"),
4415         .key_size = sizeof(unsigned int),
4416         .value_size = sizeof(struct pprint_mapv),
4417         .key_type_id = 3,       /* unsigned int */
4418         .value_type_id = 16,    /* struct pprint_mapv */
4419         .max_entries = 128 * 1024,
4420 },
4421 
4422 {
4423         /* this type will have the same layout as the
4424          * first .raw_types definition. The struct type will
4425          * be encoded with kind_flag set, bitfield members
4426          * are added typedef/const/volatile, and bitfield members
4427          * will have both int and enum types.
4428          */
4429         .raw_types = {
4430                 /* unsighed char */                     /* [1] */
4431                 BTF_TYPE_INT_ENC(NAME_TBD, 0, 0, 8, 1),
4432                 /* unsigned short */                    /* [2] */
4433                 BTF_TYPE_INT_ENC(NAME_TBD, 0, 0, 16, 2),
4434                 /* unsigned int */                      /* [3] */
4435                 BTF_TYPE_INT_ENC(NAME_TBD, 0, 0, 32, 4),
4436                 /* int */                               /* [4] */
4437                 BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),
4438                 /* unsigned long long */                /* [5] */
4439                 BTF_TYPE_INT_ENC(NAME_TBD, 0, 0, 64, 8),
4440                 BTF_TYPE_INT_ENC(0, 0, 0, 32, 4),       /* [6] */
4441                 BTF_TYPE_INT_ENC(0, 0, 0, 32, 4),       /* [7] */
4442                 /* uint8_t[8] */                        /* [8] */
4443                 BTF_TYPE_ARRAY_ENC(9, 1, 8),
4444                 /* typedef unsigned char uint8_t */     /* [9] */
4445                 BTF_TYPEDEF_ENC(NAME_TBD, 1),
4446                 /* typedef unsigned short uint16_t */   /* [10] */
4447                 BTF_TYPEDEF_ENC(NAME_TBD, 2),
4448                 /* typedef unsigned int uint32_t */     /* [11] */
4449                 BTF_TYPEDEF_ENC(NAME_TBD, 3),
4450                 /* typedef int int32_t */               /* [12] */
4451                 BTF_TYPEDEF_ENC(NAME_TBD, 4),
4452                 /* typedef unsigned long long uint64_t *//* [13] */
4453                 BTF_TYPEDEF_ENC(NAME_TBD, 5),
4454                 /* union (anon) */                      /* [14] */
4455                 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_UNION, 0, 2), 8),
4456                 BTF_MEMBER_ENC(NAME_TBD, 13, 0),/* uint64_t ui64; */
4457                 BTF_MEMBER_ENC(NAME_TBD, 8, 0), /* uint8_t ui8a[8]; */
4458                 /* enum (anon) */                       /* [15] */
4459                 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_ENUM, 0, 4), 4),
4460                 BTF_ENUM_ENC(NAME_TBD, 0),
4461                 BTF_ENUM_ENC(NAME_TBD, 1),
4462                 BTF_ENUM_ENC(NAME_TBD, 2),
4463                 BTF_ENUM_ENC(NAME_TBD, 3),
4464                 /* struct pprint_mapv */                /* [16] */
4465                 BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 1, 11), 40),
4466                 BTF_MEMBER_ENC(NAME_TBD, 11, BTF_MEMBER_OFFSET(0, 0)),  /* uint32_t ui32 */
4467                 BTF_MEMBER_ENC(NAME_TBD, 10, BTF_MEMBER_OFFSET(0, 32)), /* uint16_t ui16 */
4468                 BTF_MEMBER_ENC(NAME_TBD, 12, BTF_MEMBER_OFFSET(0, 64)), /* int32_t si32 */
4469                 BTF_MEMBER_ENC(NAME_TBD, 17, BTF_MEMBER_OFFSET(2, 96)), /* unused_bits2a */
4470                 BTF_MEMBER_ENC(NAME_TBD, 7, BTF_MEMBER_OFFSET(28, 98)), /* bits28 */
4471                 BTF_MEMBER_ENC(NAME_TBD, 19, BTF_MEMBER_OFFSET(2, 126)),/* unused_bits2b */
4472                 BTF_MEMBER_ENC(0, 14, BTF_MEMBER_OFFSET(0, 128)),       /* union (anon) */
4473                 BTF_MEMBER_ENC(NAME_TBD, 15, BTF_MEMBER_OFFSET(0, 192)),        /* aenum */
4474                 BTF_MEMBER_ENC(NAME_TBD, 11, BTF_MEMBER_OFFSET(0, 224)),        /* uint32_t ui32b */
4475                 BTF_MEMBER_ENC(NAME_TBD, 17, BTF_MEMBER_OFFSET(2, 256)),        /* bits2c */
4476                 BTF_MEMBER_ENC(NAME_TBD, 20, BTF_MEMBER_OFFSET(0, 264)),        /* si8_4 */
4477                 /* typedef unsigned int ___int */       /* [17] */
4478                 BTF_TYPEDEF_ENC(NAME_TBD, 18),
4479                 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_VOLATILE, 0, 0), 6),      /* [18] */
4480                 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_CONST, 0, 0), 15),        /* [19] */
4481                 BTF_TYPE_ARRAY_ENC(21, 1, 2),                                   /* [20] */
4482                 BTF_TYPE_ARRAY_ENC(1, 1, 2),                                    /* [21] */
4483                 BTF_END_RAW,
4484         },
4485         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"),
4486         .key_size = sizeof(unsigned int),
4487         .value_size = sizeof(struct pprint_mapv),
4488         .key_type_id = 3,       /* unsigned int */
4489         .value_type_id = 16,    /* struct pprint_mapv */
4490         .max_entries = 128 * 1024,
4491 },
4492 
4493 #ifdef __SIZEOF_INT128__
4494 {
4495         /* test int128 */
4496         .raw_types = {
4497                 /* unsigned int */                              /* [1] */
4498                 BTF_TYPE_INT_ENC(NAME_TBD, 0, 0, 32, 4),
4499                 /* __int128 */                                  /* [2] */
4500                 BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 128, 16),
4501                 /* unsigned __int128 */                         /* [3] */
4502                 BTF_TYPE_INT_ENC(NAME_TBD, 0, 0, 128, 16),
4503                 /* struct pprint_mapv_int128 */                 /* [4] */
4504                 BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 1, 5), 64),
4505                 BTF_MEMBER_ENC(NAME_TBD, 2, BTF_MEMBER_OFFSET(0, 0)),           /* si128a */
4506                 BTF_MEMBER_ENC(NAME_TBD, 2, BTF_MEMBER_OFFSET(0, 128)),         /* si128b */
4507                 BTF_MEMBER_ENC(NAME_TBD, 3, BTF_MEMBER_OFFSET(3, 256)),         /* bits3 */
4508                 BTF_MEMBER_ENC(NAME_TBD, 3, BTF_MEMBER_OFFSET(80, 259)),        /* bits80 */
4509                 BTF_MEMBER_ENC(NAME_TBD, 3, BTF_MEMBER_OFFSET(0, 384)),         /* ui128 */
4510                 BTF_END_RAW,
4511         },
4512         BTF_STR_SEC("\0unsigned int\0__int128\0unsigned __int128\0pprint_mapv_int128\0si128a\0si128b\0bits3\0bits80\0ui128"),
4513         .key_size = sizeof(unsigned int),
4514         .value_size = sizeof(struct pprint_mapv_int128),
4515         .key_type_id = 1,
4516         .value_type_id = 4,
4517         .max_entries = 128 * 1024,
4518         .mapv_kind = PPRINT_MAPV_KIND_INT128,
4519 },
4520 #endif
4521 
4522 };
4523 
4524 static struct btf_pprint_test_meta {
4525         const char *descr;
4526         enum bpf_map_type map_type;
4527         const char *map_name;
4528         bool ordered_map;
4529         bool lossless_map;
4530         bool percpu_map;
4531 } pprint_tests_meta[] = {
4532 {
4533         .descr = "BTF pretty print array",
4534         .map_type = BPF_MAP_TYPE_ARRAY,
4535         .map_name = "pprint_test_array",
4536         .ordered_map = true,
4537         .lossless_map = true,
4538         .percpu_map = false,
4539 },
4540 
4541 {
4542         .descr = "BTF pretty print hash",
4543         .map_type = BPF_MAP_TYPE_HASH,
4544         .map_name = "pprint_test_hash",
4545         .ordered_map = false,
4546         .lossless_map = true,
4547         .percpu_map = false,
4548 },
4549 
4550 {
4551         .descr = "BTF pretty print lru hash",
4552         .map_type = BPF_MAP_TYPE_LRU_HASH,
4553         .map_name = "pprint_test_lru_hash",
4554         .ordered_map = false,
4555         .lossless_map = false,
4556         .percpu_map = false,
4557 },
4558 
4559 {
4560         .descr = "BTF pretty print percpu array",
4561         .map_type = BPF_MAP_TYPE_PERCPU_ARRAY,
4562         .map_name = "pprint_test_percpu_array",
4563         .ordered_map = true,
4564         .lossless_map = true,
4565         .percpu_map = true,
4566 },
4567 
4568 {
4569         .descr = "BTF pretty print percpu hash",
4570         .map_type = BPF_MAP_TYPE_PERCPU_HASH,
4571         .map_name = "pprint_test_percpu_hash",
4572         .ordered_map = false,
4573         .lossless_map = true,
4574         .percpu_map = true,
4575 },
4576 
4577 {
4578         .descr = "BTF pretty print lru percpu hash",
4579         .map_type = BPF_MAP_TYPE_LRU_PERCPU_HASH,
4580         .map_name = "pprint_test_lru_percpu_hash",
4581         .ordered_map = false,
4582         .lossless_map = false,
4583         .percpu_map = true,
4584 },
4585 
4586 };
4587 
4588 static size_t get_pprint_mapv_size(enum pprint_mapv_kind_t mapv_kind)
4589 {
4590         if (mapv_kind == PPRINT_MAPV_KIND_BASIC)
4591                 return sizeof(struct pprint_mapv);
4592 
4593 #ifdef __SIZEOF_INT128__
4594         if (mapv_kind == PPRINT_MAPV_KIND_INT128)
4595                 return sizeof(struct pprint_mapv_int128);
4596 #endif
4597 
4598         assert(0);
4599 }
4600 
4601 static void set_pprint_mapv(enum pprint_mapv_kind_t mapv_kind,
4602                             void *mapv, uint32_t i,
4603                             int num_cpus, int rounded_value_size)
4604 {
4605         int cpu;
4606 
4607         if (mapv_kind == PPRINT_MAPV_KIND_BASIC) {
4608                 struct pprint_mapv *v = mapv;
4609 
4610                 for (cpu = 0; cpu < num_cpus; cpu++) {
4611                         v->ui32 = i + cpu;
4612                         v->si32 = -i;
4613                         v->unused_bits2a = 3;
4614                         v->bits28 = i;
4615                         v->unused_bits2b = 3;
4616                         v->ui64 = i;
4617                         v->aenum = i & 0x03;
4618                         v->ui32b = 4;
4619                         v->bits2c = 1;
4620                         v->si8_4[0][0] = (cpu + i) & 0xff;
4621                         v->si8_4[0][1] = (cpu + i + 1) & 0xff;
4622                         v->si8_4[1][0] = (cpu + i + 2) & 0xff;
4623                         v->si8_4[1][1] = (cpu + i + 3) & 0xff;
4624                         v = (void *)v + rounded_value_size;
4625                 }
4626         }
4627 
4628 #ifdef __SIZEOF_INT128__
4629         if (mapv_kind == PPRINT_MAPV_KIND_INT128) {
4630                 struct pprint_mapv_int128 *v = mapv;
4631 
4632                 for (cpu = 0; cpu < num_cpus; cpu++) {
4633                         v->si128a = i;
4634                         v->si128b = -i;
4635                         v->bits3 = i & 0x07;
4636                         v->bits80 = (((unsigned __int128)1) << 64) + i;
4637                         v->ui128 = (((unsigned __int128)2) << 64) + i;
4638                         v = (void *)v + rounded_value_size;
4639                 }
4640         }
4641 #endif
4642 }
4643 
4644 ssize_t get_pprint_expected_line(enum pprint_mapv_kind_t mapv_kind,
4645                                  char *expected_line, ssize_t line_size,
4646                                  bool percpu_map, unsigned int next_key,
4647                                  int cpu, void *mapv)
4648 {
4649         ssize_t nexpected_line = -1;
4650 
4651         if (mapv_kind == PPRINT_MAPV_KIND_BASIC) {
4652                 struct pprint_mapv *v = mapv;
4653 
4654                 nexpected_line = snprintf(expected_line, line_size,
4655                                           "%s%u: {%u,0,%d,0x%x,0x%x,0x%x,"
4656                                           "{%lu|[%u,%u,%u,%u,%u,%u,%u,%u]},%s,"
4657                                           "%u,0x%x,[[%d,%d],[%d,%d]]}\n",
4658                                           percpu_map ? "\tcpu" : "",
4659                                           percpu_map ? cpu : next_key,
4660                                           v->ui32, v->si32,
4661                                           v->unused_bits2a,
4662                                           v->bits28,
4663                                           v->unused_bits2b,
4664                                           v->ui64,
4665                                           v->ui8a[0], v->ui8a[1],
4666                                           v->ui8a[2], v->ui8a[3],
4667                                           v->ui8a[4], v->ui8a[5],
4668                                           v->ui8a[6], v->ui8a[7],
4669                                           pprint_enum_str[v->aenum],
4670                                           v->ui32b,
4671                                           v->bits2c,
4672                                           v->si8_4[0][0], v->si8_4[0][1],
4673                                           v->si8_4[1][0], v->si8_4[1][1]);
4674         }
4675 
4676 #ifdef __SIZEOF_INT128__
4677         if (mapv_kind == PPRINT_MAPV_KIND_INT128) {
4678                 struct pprint_mapv_int128 *v = mapv;
4679 
4680                 nexpected_line = snprintf(expected_line, line_size,
4681                                           "%s%u: {0x%lx,0x%lx,0x%lx,"
4682                                           "0x%lx%016lx,0x%lx%016lx}\n",
4683                                           percpu_map ? "\tcpu" : "",
4684                                           percpu_map ? cpu : next_key,
4685                                           (uint64_t)v->si128a,
4686                                           (uint64_t)v->si128b,
4687                                           (uint64_t)v->bits3,
4688                                           (uint64_t)(v->bits80 >> 64),
4689                                           (uint64_t)v->bits80,
4690                                           (uint64_t)(v->ui128 >> 64),
4691                                           (uint64_t)v->ui128);
4692         }
4693 #endif
4694 
4695         return nexpected_line;
4696 }
4697 
4698 static int check_line(const char *expected_line, int nexpected_line,
4699                       int expected_line_len, const char *line)
4700 {
4701         if (CHECK(nexpected_line == expected_line_len,
4702                   "expected_line is too long"))
4703                 return -1;
4704 
4705         if (strcmp(expected_line, line)) {
4706                 fprintf(stderr, "unexpected pprint output\n");
4707                 fprintf(stderr, "expected: %s", expected_line);
4708                 fprintf(stderr, "    read: %s", line);
4709                 return -1;
4710         }
4711 
4712         return 0;
4713 }
4714 
4715 
4716 static int do_test_pprint(int test_num)
4717 {
4718         const struct btf_raw_test *test = &pprint_test_template[test_num];
4719         enum pprint_mapv_kind_t mapv_kind = test->mapv_kind;
4720         struct bpf_create_map_attr create_attr = {};
4721         bool ordered_map, lossless_map, percpu_map;
4722         int err, ret, num_cpus, rounded_value_size;
4723         unsigned int key, nr_read_elems;
4724         int map_fd = -1, btf_fd = -1;
4725         unsigned int raw_btf_size;
4726         char expected_line[255];
4727         FILE *pin_file = NULL;
4728         char pin_path[255];
4729         size_t line_len = 0;
4730         char *line = NULL;
4731         void *mapv = NULL;
4732         uint8_t *raw_btf;
4733         ssize_t nread;
4734 
4735         fprintf(stderr, "%s(#%d)......", test->descr, test_num);
4736         raw_btf = btf_raw_create(&hdr_tmpl, test->raw_types,
4737                                  test->str_sec, test->str_sec_size,
4738                                  &raw_btf_size, NULL);
4739 
4740         if (!raw_btf)
4741                 return -1;
4742 
4743         *btf_log_buf = '\0';
4744         btf_fd = bpf_load_btf(raw_btf, raw_btf_size,
4745                               btf_log_buf, BTF_LOG_BUF_SIZE,
4746                               args.always_log);
4747         free(raw_btf);
4748 
4749         if (CHECK(btf_fd == -1, "errno:%d", errno)) {
4750                 err = -1;
4751                 goto done;
4752         }
4753 
4754         create_attr.name = test->map_name;
4755         create_attr.map_type = test->map_type;
4756         create_attr.key_size = test->key_size;
4757         create_attr.value_size = test->value_size;
4758         create_attr.max_entries = test->max_entries;
4759         create_attr.btf_fd = btf_fd;
4760         create_attr.btf_key_type_id = test->key_type_id;
4761         create_attr.btf_value_type_id = test->value_type_id;
4762 
4763         map_fd = bpf_create_map_xattr(&create_attr);
4764         if (CHECK(map_fd == -1, "errno:%d", errno)) {
4765                 err = -1;
4766                 goto done;
4767         }
4768 
4769         ret = snprintf(pin_path, sizeof(pin_path), "%s/%s",
4770                        "/sys/fs/bpf", test->map_name);
4771 
4772         if (CHECK(ret == sizeof(pin_path), "pin_path %s/%s is too long",
4773                   "/sys/fs/bpf", test->map_name)) {
4774                 err = -1;
4775                 goto done;
4776         }
4777 
4778         err = bpf_obj_pin(map_fd, pin_path);
4779         if (CHECK(err, "bpf_obj_pin(%s): errno:%d.", pin_path, errno))
4780                 goto done;
4781 
4782         percpu_map = test->percpu_map;
4783         num_cpus = percpu_map ? bpf_num_possible_cpus() : 1;
4784         rounded_value_size = round_up(get_pprint_mapv_size(mapv_kind), 8);
4785         mapv = calloc(num_cpus, rounded_value_size);
4786         if (CHECK(!mapv, "mapv allocation failure")) {
4787                 err = -1;
4788                 goto done;
4789         }
4790 
4791         for (key = 0; key < test->max_entries; key++) {
4792                 set_pprint_mapv(mapv_kind, mapv, key, num_cpus, rounded_value_size);
4793                 bpf_map_update_elem(map_fd, &key, mapv, 0);
4794         }
4795 
4796         pin_file = fopen(pin_path, "r");
4797         if (CHECK(!pin_file, "fopen(%s): errno:%d", pin_path, errno)) {
4798                 err = -1;
4799                 goto done;
4800         }
4801 
4802         /* Skip lines start with '#' */
4803         while ((nread = getline(&line, &line_len, pin_file)) > 0 &&
4804                *line == '#')
4805                 ;
4806 
4807         if (CHECK(nread <= 0, "Unexpected EOF")) {
4808                 err = -1;
4809                 goto done;
4810         }
4811 
4812         nr_read_elems = 0;
4813         ordered_map = test->ordered_map;
4814         lossless_map = test->lossless_map;
4815         do {
4816                 ssize_t nexpected_line;
4817                 unsigned int next_key;
4818                 void *cmapv;
4819                 int cpu;
4820 
4821                 next_key = ordered_map ? nr_read_elems : atoi(line);
4822                 set_pprint_mapv(mapv_kind, mapv, next_key, num_cpus, rounded_value_size);
4823                 cmapv = mapv;
4824 
4825                 for (cpu = 0; cpu < num_cpus; cpu++) {
4826                         if (percpu_map) {
4827                                 /* for percpu map, the format looks like:
4828                                  * <key>: {
4829                                  *      cpu0: <value_on_cpu0>
4830                                  *      cpu1: <value_on_cpu1>
4831                                  *      ...
4832                                  *      cpun: <value_on_cpun>
4833                                  * }
4834                                  *
4835                                  * let us verify the line containing the key here.
4836                                  */
4837                                 if (cpu == 0) {
4838                                         nexpected_line = snprintf(expected_line,
4839                                                                   sizeof(expected_line),
4840                                                                   "%u: {\n",
4841                                                                   next_key);
4842 
4843                                         err = check_line(expected_line, nexpected_line,
4844                                                          sizeof(expected_line), line);
4845                                         if (err == -1)
4846                                                 goto done;
4847                                 }
4848 
4849                                 /* read value@cpu */
4850                                 nread = getline(&line, &line_len, pin_file);
4851                                 if (nread < 0)
4852                                         break;
4853                         }
4854 
4855                         nexpected_line = get_pprint_expected_line(mapv_kind, expected_line,
4856                                                                   sizeof(expected_line),
4857                                                                   percpu_map, next_key,
4858                                                                   cpu, cmapv);
4859                         err = check_line(expected_line, nexpected_line,
4860                                          sizeof(expected_line), line);
4861                         if (err == -1)
4862                                 goto done;
4863 
4864                         cmapv = cmapv + rounded_value_size;
4865                 }
4866 
4867                 if (percpu_map) {
4868                         /* skip the last bracket for the percpu map */
4869                         nread = getline(&line, &line_len, pin_file);
4870                         if (nread < 0)
4871                                 break;
4872                 }
4873 
4874                 nread = getline(&line, &line_len, pin_file);
4875         } while (++nr_read_elems < test->max_entries && nread > 0);
4876 
4877         if (lossless_map &&
4878             CHECK(nr_read_elems < test->max_entries,
4879                   "Unexpected EOF. nr_read_elems:%u test->max_entries:%u",
4880                   nr_read_elems, test->max_entries)) {
4881                 err = -1;
4882                 goto done;
4883         }
4884 
4885         if (CHECK(nread > 0, "Unexpected extra pprint output: %s", line)) {
4886                 err = -1;
4887                 goto done;
4888         }
4889 
4890         err = 0;
4891 
4892 done:
4893         if (mapv)
4894                 free(mapv);
4895         if (!err)
4896                 fprintf(stderr, "OK");
4897         if (*btf_log_buf && (err || args.always_log))
4898                 fprintf(stderr, "\n%s", btf_log_buf);
4899         if (btf_fd != -1)
4900                 close(btf_fd);
4901         if (map_fd != -1)
4902                 close(map_fd);
4903         if (pin_file)
4904                 fclose(pin_file);
4905         unlink(pin_path);
4906         free(line);
4907 
4908         return err;
4909 }
4910 
4911 static int test_pprint(void)
4912 {
4913         unsigned int i;
4914         int err = 0;
4915 
4916         /* test various maps with the first test template */
4917         for (i = 0; i < ARRAY_SIZE(pprint_tests_meta); i++) {
4918                 pprint_test_template[0].descr = pprint_tests_meta[i].descr;
4919                 pprint_test_template[0].map_type = pprint_tests_meta[i].map_type;
4920                 pprint_test_template[0].map_name = pprint_tests_meta[i].map_name;
4921                 pprint_test_template[0].ordered_map = pprint_tests_meta[i].ordered_map;
4922                 pprint_test_template[0].lossless_map = pprint_tests_meta[i].lossless_map;
4923                 pprint_test_template[0].percpu_map = pprint_tests_meta[i].percpu_map;
4924 
4925                 err |= count_result(do_test_pprint(0));
4926         }
4927 
4928         /* test rest test templates with the first map */
4929         for (i = 1; i < ARRAY_SIZE(pprint_test_template); i++) {
4930                 pprint_test_template[i].descr = pprint_tests_meta[0].descr;
4931                 pprint_test_template[i].map_type = pprint_tests_meta[0].map_type;
4932                 pprint_test_template[i].map_name = pprint_tests_meta[0].map_name;
4933                 pprint_test_template[i].ordered_map = pprint_tests_meta[0].ordered_map;
4934                 pprint_test_template[i].lossless_map = pprint_tests_meta[0].lossless_map;
4935                 pprint_test_template[i].percpu_map = pprint_tests_meta[0].percpu_map;
4936                 err |= count_result(do_test_pprint(i));
4937         }
4938 
4939         return err;
4940 }
4941 
4942 #define BPF_LINE_INFO_ENC(insn_off, file_off, line_off, line_num, line_col) \
4943         (insn_off), (file_off), (line_off), ((line_num) << 10 | ((line_col) & 0x3ff))
4944 
4945 static struct prog_info_raw_test {
4946         const char *descr;
4947         const char *str_sec;
4948         const char *err_str;
4949         __u32 raw_types[MAX_NR_RAW_U32];
4950         __u32 str_sec_size;
4951         struct bpf_insn insns[MAX_INSNS];
4952         __u32 prog_type;
4953         __u32 func_info[MAX_SUBPROGS][2];
4954         __u32 func_info_rec_size;
4955         __u32 func_info_cnt;
4956         __u32 line_info[MAX_NR_RAW_U32];
4957         __u32 line_info_rec_size;
4958         __u32 nr_jited_ksyms;
4959         bool expected_prog_load_failure;
4960         __u32 dead_code_cnt;
4961         __u32 dead_code_mask;
4962         __u32 dead_func_cnt;
4963         __u32 dead_func_mask;
4964 } info_raw_tests[] = {
4965 {
4966         .descr = "func_type (main func + one sub)",
4967         .raw_types = {
4968                 BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),   /* [1] */
4969                 BTF_TYPE_INT_ENC(NAME_TBD, 0, 0, 32, 4),        /* [2] */
4970                 BTF_FUNC_PROTO_ENC(1, 2),                       /* [3] */
4971                         BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
4972                         BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 2),
4973                 BTF_FUNC_PROTO_ENC(1, 2),                       /* [4] */
4974                         BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 2),
4975                         BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
4976                 BTF_FUNC_ENC(NAME_TBD, 3),                      /* [5] */
4977                 BTF_FUNC_ENC(NAME_TBD, 4),                      /* [6] */
4978                 BTF_END_RAW,
4979         },
4980         .str_sec = "\0int\0unsigned int\0a\0b\0c\0d\0funcA\0funcB",
4981         .str_sec_size = sizeof("\0int\0unsigned int\0a\0b\0c\0d\0funcA\0funcB"),
4982         .insns = {
4983                 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2),
4984                 BPF_MOV64_IMM(BPF_REG_0, 1),
4985                 BPF_EXIT_INSN(),
4986                 BPF_MOV64_IMM(BPF_REG_0, 2),
4987                 BPF_EXIT_INSN(),
4988         },
4989         .prog_type = BPF_PROG_TYPE_TRACEPOINT,
4990         .func_info = { {0, 5}, {3, 6} },
4991         .func_info_rec_size = 8,
4992         .func_info_cnt = 2,
4993         .line_info = { BTF_END_RAW },
4994 },
4995 
4996 {
4997         .descr = "func_type (Incorrect func_info_rec_size)",
4998         .raw_types = {
4999                 BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),   /* [1] */
5000                 BTF_TYPE_INT_ENC(NAME_TBD, 0, 0, 32, 4),        /* [2] */
5001                 BTF_FUNC_PROTO_ENC(1, 2),                       /* [3] */
5002                         BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
5003                         BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 2),
5004                 BTF_FUNC_PROTO_ENC(1, 2),                       /* [4] */
5005                         BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 2),
5006                         BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
5007                 BTF_FUNC_ENC(NAME_TBD, 3),                      /* [5] */
5008                 BTF_FUNC_ENC(NAME_TBD, 4),                      /* [6] */
5009                 BTF_END_RAW,
5010         },
5011         .str_sec = "\0int\0unsigned int\0a\0b\0c\0d\0funcA\0funcB",
5012         .str_sec_size = sizeof("\0int\0unsigned int\0a\0b\0c\0d\0funcA\0funcB"),
5013         .insns = {
5014                 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2),
5015                 BPF_MOV64_IMM(BPF_REG_0, 1),
5016                 BPF_EXIT_INSN(),
5017                 BPF_MOV64_IMM(BPF_REG_0, 2),
5018                 BPF_EXIT_INSN(),
5019         },
5020         .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5021         .func_info = { {0, 5}, {3, 6} },
5022         .func_info_rec_size = 4,
5023         .func_info_cnt = 2,
5024         .line_info = { BTF_END_RAW },
5025         .expected_prog_load_failure = true,
5026 },
5027 
5028 {
5029         .descr = "func_type (Incorrect func_info_cnt)",
5030         .raw_types = {
5031                 BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),   /* [1] */
5032                 BTF_TYPE_INT_ENC(NAME_TBD, 0, 0, 32, 4),        /* [2] */
5033                 BTF_FUNC_PROTO_ENC(1, 2),                       /* [3] */
5034                         BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
5035                         BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 2),
5036                 BTF_FUNC_PROTO_ENC(1, 2),                       /* [4] */
5037                         BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 2),
5038                         BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
5039                 BTF_FUNC_ENC(NAME_TBD, 3),                      /* [5] */
5040                 BTF_FUNC_ENC(NAME_TBD, 4),                      /* [6] */
5041                 BTF_END_RAW,
5042         },
5043         .str_sec = "\0int\0unsigned int\0a\0b\0c\0d\0funcA\0funcB",
5044         .str_sec_size = sizeof("\0int\0unsigned int\0a\0b\0c\0d\0funcA\0funcB"),
5045         .insns = {
5046                 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2),
5047                 BPF_MOV64_IMM(BPF_REG_0, 1),
5048                 BPF_EXIT_INSN(),
5049                 BPF_MOV64_IMM(BPF_REG_0, 2),
5050                 BPF_EXIT_INSN(),
5051         },
5052         .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5053         .func_info = { {0, 5}, {3, 6} },
5054         .func_info_rec_size = 8,
5055         .func_info_cnt = 1,
5056         .line_info = { BTF_END_RAW },
5057         .expected_prog_load_failure = true,
5058 },
5059 
5060 {
5061         .descr = "func_type (Incorrect bpf_func_info.insn_off)",
5062         .raw_types = {
5063                 BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),   /* [1] */
5064                 BTF_TYPE_INT_ENC(NAME_TBD, 0, 0, 32, 4),        /* [2] */
5065                 BTF_FUNC_PROTO_ENC(1, 2),                       /* [3] */
5066                         BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
5067                         BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 2),
5068                 BTF_FUNC_PROTO_ENC(1, 2),                       /* [4] */
5069                         BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 2),
5070                         BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
5071                 BTF_FUNC_ENC(NAME_TBD, 3),                      /* [5] */
5072                 BTF_FUNC_ENC(NAME_TBD, 4),                      /* [6] */
5073                 BTF_END_RAW,
5074         },
5075         .str_sec = "\0int\0unsigned int\0a\0b\0c\0d\0funcA\0funcB",
5076         .str_sec_size = sizeof("\0int\0unsigned int\0a\0b\0c\0d\0funcA\0funcB"),
5077         .insns = {
5078                 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2),
5079                 BPF_MOV64_IMM(BPF_REG_0, 1),
5080                 BPF_EXIT_INSN(),
5081                 BPF_MOV64_IMM(BPF_REG_0, 2),
5082                 BPF_EXIT_INSN(),
5083         },
5084         .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5085         .func_info = { {0, 5}, {2, 6} },
5086         .func_info_rec_size = 8,
5087         .func_info_cnt = 2,
5088         .line_info = { BTF_END_RAW },
5089         .expected_prog_load_failure = true,
5090 },
5091 
5092 {
5093         .descr = "line_info (No subprog)",
5094         .raw_types = {
5095                 BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),   /* [1] */
5096                 BTF_END_RAW,
5097         },
5098         BTF_STR_SEC("\0int\0int a=1;\0int b=2;\0return a + b;\0return a + b;"),
5099         .insns = {
5100                 BPF_MOV64_IMM(BPF_REG_0, 1),
5101                 BPF_MOV64_IMM(BPF_REG_1, 2),
5102                 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
5103                 BPF_EXIT_INSN(),
5104         },
5105         .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5106         .func_info_cnt = 0,
5107         .line_info = {
5108                 BPF_LINE_INFO_ENC(0, 0, NAME_TBD, 1, 10),
5109                 BPF_LINE_INFO_ENC(1, 0, NAME_TBD, 2, 9),
5110                 BPF_LINE_INFO_ENC(2, 0, NAME_TBD, 3, 8),
5111                 BPF_LINE_INFO_ENC(3, 0, NAME_TBD, 4, 7),
5112                 BTF_END_RAW,
5113         },
5114         .line_info_rec_size = sizeof(struct bpf_line_info),
5115         .nr_jited_ksyms = 1,
5116 },
5117 
5118 {
5119         .descr = "line_info (No subprog. insn_off >= prog->len)",
5120         .raw_types = {
5121                 BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),   /* [1] */
5122                 BTF_END_RAW,
5123         },
5124         BTF_STR_SEC("\0int\0int a=1;\0int b=2;\0return a + b;\0return a + b;"),
5125         .insns = {
5126                 BPF_MOV64_IMM(BPF_REG_0, 1),
5127                 BPF_MOV64_IMM(BPF_REG_1, 2),
5128                 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
5129                 BPF_EXIT_INSN(),
5130         },
5131         .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5132         .func_info_cnt = 0,
5133         .line_info = {
5134                 BPF_LINE_INFO_ENC(0, 0, NAME_TBD, 1, 10),
5135                 BPF_LINE_INFO_ENC(1, 0, NAME_TBD, 2, 9),
5136                 BPF_LINE_INFO_ENC(2, 0, NAME_TBD, 3, 8),
5137                 BPF_LINE_INFO_ENC(3, 0, NAME_TBD, 4, 7),
5138                 BPF_LINE_INFO_ENC(4, 0, 0, 5, 6),
5139                 BTF_END_RAW,
5140         },
5141         .line_info_rec_size = sizeof(struct bpf_line_info),
5142         .nr_jited_ksyms = 1,
5143         .err_str = "line_info[4].insn_off",
5144         .expected_prog_load_failure = true,
5145 },
5146 
5147 {
5148         .descr = "line_info (Zero bpf insn code)",
5149         .raw_types = {
5150                 BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),   /* [1] */
5151                 BTF_TYPE_INT_ENC(NAME_TBD, 0, 0, 64, 8),        /* [2] */
5152                 BTF_TYPEDEF_ENC(NAME_TBD, 2),                   /* [3] */
5153                 BTF_END_RAW,
5154         },
5155         BTF_STR_SEC("\0int\0unsigned long\0u64\0u64 a=1;\0return a;"),
5156         .insns = {
5157                 BPF_LD_IMM64(BPF_REG_0, 1),
5158                 BPF_EXIT_INSN(),
5159         },
5160         .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5161         .func_info_cnt = 0,
5162         .line_info = {
5163                 BPF_LINE_INFO_ENC(0, 0, NAME_TBD, 1, 10),
5164                 BPF_LINE_INFO_ENC(1, 0, 0, 2, 9),
5165                 BPF_LINE_INFO_ENC(2, 0, NAME_TBD, 3, 8),
5166                 BTF_END_RAW,
5167         },
5168         .line_info_rec_size = sizeof(struct bpf_line_info),
5169         .nr_jited_ksyms = 1,
5170         .err_str = "Invalid insn code at line_info[1]",
5171         .expected_prog_load_failure = true,
5172 },
5173 
5174 {
5175         .descr = "line_info (No subprog. zero tailing line_info",
5176         .raw_types = {
5177                 BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),   /* [1] */
5178                 BTF_END_RAW,
5179         },
5180         BTF_STR_SEC("\0int\0int a=1;\0int b=2;\0return a + b;\0return a + b;"),
5181         .insns = {
5182                 BPF_MOV64_IMM(BPF_REG_0, 1),
5183                 BPF_MOV64_IMM(BPF_REG_1, 2),
5184                 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
5185                 BPF_EXIT_INSN(),
5186         },
5187         .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5188         .func_info_cnt = 0,
5189         .line_info = {
5190                 BPF_LINE_INFO_ENC(0, 0, NAME_TBD, 1, 10), 0,
5191                 BPF_LINE_INFO_ENC(1, 0, NAME_TBD, 2, 9), 0,
5192                 BPF_LINE_INFO_ENC(2, 0, NAME_TBD, 3, 8), 0,
5193                 BPF_LINE_INFO_ENC(3, 0, NAME_TBD, 4, 7), 0,
5194                 BTF_END_RAW,
5195         },
5196         .line_info_rec_size = sizeof(struct bpf_line_info) + sizeof(__u32),
5197         .nr_jited_ksyms = 1,
5198 },
5199 
5200 {
5201         .descr = "line_info (No subprog. nonzero tailing line_info)",
5202         .raw_types = {
5203                 BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),   /* [1] */
5204                 BTF_END_RAW,
5205         },
5206         BTF_STR_SEC("\0int\0int a=1;\0int b=2;\0return a + b;\0return a + b;"),
5207         .insns = {
5208                 BPF_MOV64_IMM(BPF_REG_0, 1),
5209                 BPF_MOV64_IMM(BPF_REG_1, 2),
5210                 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
5211                 BPF_EXIT_INSN(),
5212         },
5213         .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5214         .func_info_cnt = 0,
5215         .line_info = {
5216                 BPF_LINE_INFO_ENC(0, 0, NAME_TBD, 1, 10), 0,
5217                 BPF_LINE_INFO_ENC(1, 0, NAME_TBD, 2, 9), 0,
5218                 BPF_LINE_INFO_ENC(2, 0, NAME_TBD, 3, 8), 0,
5219                 BPF_LINE_INFO_ENC(3, 0, NAME_TBD, 4, 7), 1,
5220                 BTF_END_RAW,
5221         },
5222         .line_info_rec_size = sizeof(struct bpf_line_info) + sizeof(__u32),
5223         .nr_jited_ksyms = 1,
5224         .err_str = "nonzero tailing record in line_info",
5225         .expected_prog_load_failure = true,
5226 },
5227 
5228 {
5229         .descr = "line_info (subprog)",
5230         .raw_types = {
5231                 BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),   /* [1] */
5232                 BTF_END_RAW,
5233         },
5234         BTF_STR_SEC("\0int\0int a=1+1;\0return func(a);\0b+=1;\0return b;"),
5235         .insns = {
5236                 BPF_MOV64_IMM(BPF_REG_2, 1),
5237                 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, 1),
5238                 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
5239                 BPF_CALL_REL(1),
5240                 BPF_EXIT_INSN(),
5241                 BPF_MOV64_REG(BPF_REG_0, BPF_REG_1),
5242                 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 1),
5243                 BPF_EXIT_INSN(),
5244         },
5245         .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5246         .func_info_cnt = 0,
5247         .line_info = {
5248                 BPF_LINE_INFO_ENC(0, 0, NAME_TBD, 1, 10),
5249                 BPF_LINE_INFO_ENC(2, 0, NAME_TBD, 2, 9),
5250                 BPF_LINE_INFO_ENC(5, 0, NAME_TBD, 3, 8),
5251                 BPF_LINE_INFO_ENC(7, 0, NAME_TBD, 4, 7),
5252                 BTF_END_RAW,
5253         },
5254         .line_info_rec_size = sizeof(struct bpf_line_info),
5255         .nr_jited_ksyms = 2,
5256 },
5257 
5258 {
5259         .descr = "line_info (subprog + func_info)",
5260         .raw_types = {
5261                 BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),   /* [1] */
5262                 BTF_FUNC_PROTO_ENC(1, 1),                       /* [2] */
5263                         BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
5264                 BTF_FUNC_ENC(NAME_TBD, 2),                      /* [3] */
5265                 BTF_FUNC_ENC(NAME_TBD, 2),                      /* [4] */
5266                 BTF_END_RAW,
5267         },
5268         BTF_STR_SEC("\0int\0x\0sub\0main\0int a=1+1;\0return func(a);\0b+=1;\0return b;"),
5269         .insns = {
5270                 BPF_MOV64_IMM(BPF_REG_2, 1),
5271                 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, 1),
5272                 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
5273                 BPF_CALL_REL(1),
5274                 BPF_EXIT_INSN(),
5275                 BPF_MOV64_REG(BPF_REG_0, BPF_REG_1),
5276                 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 1),
5277                 BPF_EXIT_INSN(),
5278         },
5279         .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5280         .func_info_cnt = 2,
5281         .func_info_rec_size = 8,
5282         .func_info = { {0, 4}, {5, 3} },
5283         .line_info = {
5284                 BPF_LINE_INFO_ENC(0, 0, NAME_TBD, 1, 10),
5285                 BPF_LINE_INFO_ENC(2, 0, NAME_TBD, 2, 9),
5286                 BPF_LINE_INFO_ENC(5, 0, NAME_TBD, 3, 8),
5287                 BPF_LINE_INFO_ENC(7, 0, NAME_TBD, 4, 7),
5288                 BTF_END_RAW,
5289         },
5290         .line_info_rec_size = sizeof(struct bpf_line_info),
5291         .nr_jited_ksyms = 2,
5292 },
5293 
5294 {
5295         .descr = "line_info (subprog. missing 1st func line info)",
5296         .raw_types = {
5297                 BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),   /* [1] */
5298                 BTF_END_RAW,
5299         },
5300         BTF_STR_SEC("\0int\0int a=1+1;\0return func(a);\0b+=1;\0return b;"),
5301         .insns = {
5302                 BPF_MOV64_IMM(BPF_REG_2, 1),
5303                 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, 1),
5304                 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
5305                 BPF_CALL_REL(1),
5306                 BPF_EXIT_INSN(),
5307                 BPF_MOV64_REG(BPF_REG_0, BPF_REG_1),
5308                 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 1),
5309                 BPF_EXIT_INSN(),
5310         },
5311         .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5312         .func_info_cnt = 0,
5313         .line_info = {
5314                 BPF_LINE_INFO_ENC(1, 0, NAME_TBD, 1, 10),
5315                 BPF_LINE_INFO_ENC(2, 0, NAME_TBD, 2, 9),
5316                 BPF_LINE_INFO_ENC(5, 0, NAME_TBD, 3, 8),
5317                 BPF_LINE_INFO_ENC(7, 0, NAME_TBD, 4, 7),
5318                 BTF_END_RAW,
5319         },
5320         .line_info_rec_size = sizeof(struct bpf_line_info),
5321         .nr_jited_ksyms = 2,
5322         .err_str = "missing bpf_line_info for func#0",
5323         .expected_prog_load_failure = true,
5324 },
5325 
5326 {
5327         .descr = "line_info (subprog. missing 2nd func line info)",
5328         .raw_types = {
5329                 BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),   /* [1] */
5330                 BTF_END_RAW,
5331         },
5332         BTF_STR_SEC("\0int\0int a=1+1;\0return func(a);\0b+=1;\0return b;"),
5333         .insns = {
5334                 BPF_MOV64_IMM(BPF_REG_2, 1),
5335                 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, 1),
5336                 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
5337                 BPF_CALL_REL(1),
5338                 BPF_EXIT_INSN(),
5339                 BPF_MOV64_REG(BPF_REG_0, BPF_REG_1),
5340                 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 1),
5341                 BPF_EXIT_INSN(),
5342         },
5343         .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5344         .func_info_cnt = 0,
5345         .line_info = {
5346                 BPF_LINE_INFO_ENC(0, 0, NAME_TBD, 1, 10),
5347                 BPF_LINE_INFO_ENC(2, 0, NAME_TBD, 2, 9),
5348                 BPF_LINE_INFO_ENC(6, 0, NAME_TBD, 3, 8),