root/tools/testing/selftests/bpf/test_btf.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. count_result
  2. __base_pr
  3. get_next_str
  4. get_raw_sec_size
  5. btf_raw_create
  6. do_test_raw
  7. test_raw
  8. ptr_to_u64
  9. test_big_btf_info
  10. test_btf_id
  11. do_test_get_info
  12. test_get_info
  13. do_test_file
  14. test_file
  15. get_pprint_mapv_size
  16. set_pprint_mapv
  17. get_pprint_expected_line
  18. check_line
  19. do_test_pprint
  20. test_pprint
  21. probe_prog_length
  22. patch_name_tbd
  23. test_get_finfo
  24. test_get_linfo
  25. do_test_info_raw
  26. test_info_raw
  27. btf_type_size
  28. dump_btf_strings
  29. do_test_dedup
  30. test_dedup
  31. usage
  32. parse_args
  33. print_summary
  34. main

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

/* [<][>][^][v][top][bottom][index][help] */