Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: GPL-2.0 */
0002 /* Copyright (c) 2018 Facebook */
0003 
0004 #include <linux/bpf.h>
0005 #include <linux/btf.h>
0006 #include <linux/err.h>
0007 #include <linux/kernel.h>
0008 #include <linux/filter.h>
0009 #include <linux/unistd.h>
0010 #include <bpf/bpf.h>
0011 #include <libelf.h>
0012 #include <gelf.h>
0013 #include <string.h>
0014 #include <stdlib.h>
0015 #include <stdio.h>
0016 #include <stdarg.h>
0017 #include <unistd.h>
0018 #include <fcntl.h>
0019 #include <errno.h>
0020 #include <assert.h>
0021 #include <bpf/libbpf.h>
0022 #include <bpf/btf.h>
0023 
0024 #include "bpf_util.h"
0025 #include "../test_btf.h"
0026 #include "test_progs.h"
0027 
0028 #define MAX_INSNS   512
0029 #define MAX_SUBPROGS    16
0030 
0031 static int duration = 0;
0032 static bool always_log;
0033 
0034 #undef CHECK
0035 #define CHECK(condition, format...) _CHECK(condition, "check", duration, format)
0036 
0037 #define NAME_TBD 0xdeadb33f
0038 
0039 #define NAME_NTH(N) (0xfffe0000 | N)
0040 #define IS_NAME_NTH(X) ((X & 0xffff0000) == 0xfffe0000)
0041 #define GET_NAME_NTH_IDX(X) (X & 0x0000ffff)
0042 
0043 #define MAX_NR_RAW_U32 1024
0044 #define BTF_LOG_BUF_SIZE 65535
0045 
0046 static char btf_log_buf[BTF_LOG_BUF_SIZE];
0047 
0048 static struct btf_header hdr_tmpl = {
0049     .magic = BTF_MAGIC,
0050     .version = BTF_VERSION,
0051     .hdr_len = sizeof(struct btf_header),
0052 };
0053 
0054 /* several different mapv kinds(types) supported by pprint */
0055 enum pprint_mapv_kind_t {
0056     PPRINT_MAPV_KIND_BASIC = 0,
0057     PPRINT_MAPV_KIND_INT128,
0058 };
0059 
0060 struct btf_raw_test {
0061     const char *descr;
0062     const char *str_sec;
0063     const char *map_name;
0064     const char *err_str;
0065     __u32 raw_types[MAX_NR_RAW_U32];
0066     __u32 str_sec_size;
0067     enum bpf_map_type map_type;
0068     __u32 key_size;
0069     __u32 value_size;
0070     __u32 key_type_id;
0071     __u32 value_type_id;
0072     __u32 max_entries;
0073     bool btf_load_err;
0074     bool map_create_err;
0075     bool ordered_map;
0076     bool lossless_map;
0077     bool percpu_map;
0078     int hdr_len_delta;
0079     int type_off_delta;
0080     int str_off_delta;
0081     int str_len_delta;
0082     enum pprint_mapv_kind_t mapv_kind;
0083 };
0084 
0085 #define BTF_STR_SEC(str) \
0086     .str_sec = str, .str_sec_size = sizeof(str)
0087 
0088 static struct btf_raw_test raw_tests[] = {
0089 /* enum E {
0090  *     E0,
0091  *     E1,
0092  * };
0093  *
0094  * struct A {
0095  *  unsigned long long m;
0096  *  int n;
0097  *  char o;
0098  *  [3 bytes hole]
0099  *  int p[8];
0100  *  int q[4][8];
0101  *  enum E r;
0102  * };
0103  */
0104 {
0105     .descr = "struct test #1",
0106     .raw_types = {
0107         /* int */
0108         BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),  /* [1] */
0109         /* unsigned long long */
0110         BTF_TYPE_INT_ENC(0, 0, 0, 64, 8),       /* [2] */
0111         /* char */
0112         BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 8, 1),   /* [3] */
0113         /* int[8] */
0114         BTF_TYPE_ARRAY_ENC(1, 1, 8),            /* [4] */
0115         /* struct A { */                /* [5] */
0116         BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 6), 180),
0117         BTF_MEMBER_ENC(NAME_TBD, 2, 0), /* unsigned long long m;*/
0118         BTF_MEMBER_ENC(NAME_TBD, 1, 64),/* int n;       */
0119         BTF_MEMBER_ENC(NAME_TBD, 3, 96),/* char o;      */
0120         BTF_MEMBER_ENC(NAME_TBD, 4, 128),/* int p[8]        */
0121         BTF_MEMBER_ENC(NAME_TBD, 6, 384),/* int q[4][8]     */
0122         BTF_MEMBER_ENC(NAME_TBD, 7, 1408), /* enum E r      */
0123         /* } */
0124         /* int[4][8] */
0125         BTF_TYPE_ARRAY_ENC(4, 1, 4),            /* [6] */
0126         /* enum E */                    /* [7] */
0127         BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_ENUM, 0, 2), sizeof(int)),
0128         BTF_ENUM_ENC(NAME_TBD, 0),
0129         BTF_ENUM_ENC(NAME_TBD, 1),
0130         BTF_END_RAW,
0131     },
0132     .str_sec = "\0A\0m\0n\0o\0p\0q\0r\0E\0E0\0E1",
0133     .str_sec_size = sizeof("\0A\0m\0n\0o\0p\0q\0r\0E\0E0\0E1"),
0134     .map_type = BPF_MAP_TYPE_ARRAY,
0135     .map_name = "struct_test1_map",
0136     .key_size = sizeof(int),
0137     .value_size = 180,
0138     .key_type_id = 1,
0139     .value_type_id = 5,
0140     .max_entries = 4,
0141 },
0142 
0143 /* typedef struct b Struct_B;
0144  *
0145  * struct A {
0146  *     int m;
0147  *     struct b n[4];
0148  *     const Struct_B o[4];
0149  * };
0150  *
0151  * struct B {
0152  *     int m;
0153  *     int n;
0154  * };
0155  */
0156 {
0157     .descr = "struct test #2",
0158     .raw_types = {
0159         /* int */                   /* [1] */
0160         BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
0161         /* struct b [4] */              /* [2] */
0162         BTF_TYPE_ARRAY_ENC(4, 1, 4),
0163 
0164         /* struct A { */                /* [3] */
0165         BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 3), 68),
0166         BTF_MEMBER_ENC(NAME_TBD, 1, 0), /* int m;       */
0167         BTF_MEMBER_ENC(NAME_TBD, 2, 32),/* struct B n[4]    */
0168         BTF_MEMBER_ENC(NAME_TBD, 8, 288),/* const Struct_B o[4];*/
0169         /* } */
0170 
0171         /* struct B { */                /* [4] */
0172         BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 2), 8),
0173         BTF_MEMBER_ENC(NAME_TBD, 1, 0), /* int m; */
0174         BTF_MEMBER_ENC(NAME_TBD, 1, 32),/* int n; */
0175         /* } */
0176 
0177         /* const int */                 /* [5] */
0178         BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_CONST, 0, 0), 1),
0179         /* typedef struct b Struct_B */ /* [6] */
0180         BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_TYPEDEF, 0, 0), 4),
0181         /* const Struct_B */                /* [7] */
0182         BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_CONST, 0, 0), 6),
0183         /* const Struct_B [4] */            /* [8] */
0184         BTF_TYPE_ARRAY_ENC(7, 1, 4),
0185         BTF_END_RAW,
0186     },
0187     .str_sec = "\0A\0m\0n\0o\0B\0m\0n\0Struct_B",
0188     .str_sec_size = sizeof("\0A\0m\0n\0o\0B\0m\0n\0Struct_B"),
0189     .map_type = BPF_MAP_TYPE_ARRAY,
0190     .map_name = "struct_test2_map",
0191     .key_size = sizeof(int),
0192     .value_size = 68,
0193     .key_type_id = 1,
0194     .value_type_id = 3,
0195     .max_entries = 4,
0196 },
0197 {
0198     .descr = "struct test #3 Invalid member offset",
0199     .raw_types = {
0200         /* int */                   /* [1] */
0201         BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
0202         /* int64 */                 /* [2] */
0203         BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 64, 8),
0204 
0205         /* struct A { */                /* [3] */
0206         BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 2), 16),
0207         BTF_MEMBER_ENC(NAME_TBD, 1, 64),    /* int m;       */
0208         BTF_MEMBER_ENC(NAME_TBD, 2, 0),     /* int64 n; */
0209         /* } */
0210         BTF_END_RAW,
0211     },
0212     .str_sec = "\0A\0m\0n\0",
0213     .str_sec_size = sizeof("\0A\0m\0n\0"),
0214     .map_type = BPF_MAP_TYPE_ARRAY,
0215     .map_name = "struct_test3_map",
0216     .key_size = sizeof(int),
0217     .value_size = 16,
0218     .key_type_id = 1,
0219     .value_type_id = 3,
0220     .max_entries = 4,
0221     .btf_load_err = true,
0222     .err_str = "Invalid member bits_offset",
0223 },
0224 /*
0225  * struct A {
0226  *  unsigned long long m;
0227  *  int n;
0228  *  char o;
0229  *  [3 bytes hole]
0230  *  int p[8];
0231  * };
0232  */
0233 {
0234     .descr = "global data test #1",
0235     .raw_types = {
0236         /* int */
0237         BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),  /* [1] */
0238         /* unsigned long long */
0239         BTF_TYPE_INT_ENC(0, 0, 0, 64, 8),       /* [2] */
0240         /* char */
0241         BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 8, 1),   /* [3] */
0242         /* int[8] */
0243         BTF_TYPE_ARRAY_ENC(1, 1, 8),            /* [4] */
0244         /* struct A { */                /* [5] */
0245         BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 4), 48),
0246         BTF_MEMBER_ENC(NAME_TBD, 2, 0), /* unsigned long long m;*/
0247         BTF_MEMBER_ENC(NAME_TBD, 1, 64),/* int n;       */
0248         BTF_MEMBER_ENC(NAME_TBD, 3, 96),/* char o;      */
0249         BTF_MEMBER_ENC(NAME_TBD, 4, 128),/* int p[8]        */
0250         /* } */
0251         BTF_END_RAW,
0252     },
0253     .str_sec = "\0A\0m\0n\0o\0p",
0254     .str_sec_size = sizeof("\0A\0m\0n\0o\0p"),
0255     .map_type = BPF_MAP_TYPE_ARRAY,
0256     .map_name = "struct_test1_map",
0257     .key_size = sizeof(int),
0258     .value_size = 48,
0259     .key_type_id = 1,
0260     .value_type_id = 5,
0261     .max_entries = 4,
0262 },
0263 /*
0264  * struct A {
0265  *  unsigned long long m;
0266  *  int n;
0267  *  char o;
0268  *  [3 bytes hole]
0269  *  int p[8];
0270  * };
0271  * static struct A t; <- in .bss
0272  */
0273 {
0274     .descr = "global data test #2",
0275     .raw_types = {
0276         /* int */
0277         BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),  /* [1] */
0278         /* unsigned long long */
0279         BTF_TYPE_INT_ENC(0, 0, 0, 64, 8),       /* [2] */
0280         /* char */
0281         BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 8, 1),   /* [3] */
0282         /* int[8] */
0283         BTF_TYPE_ARRAY_ENC(1, 1, 8),            /* [4] */
0284         /* struct A { */                /* [5] */
0285         BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 4), 48),
0286         BTF_MEMBER_ENC(NAME_TBD, 2, 0), /* unsigned long long m;*/
0287         BTF_MEMBER_ENC(NAME_TBD, 1, 64),/* int n;       */
0288         BTF_MEMBER_ENC(NAME_TBD, 3, 96),/* char o;      */
0289         BTF_MEMBER_ENC(NAME_TBD, 4, 128),/* int p[8]        */
0290         /* } */
0291         /* static struct A t */
0292         BTF_VAR_ENC(NAME_TBD, 5, 0),            /* [6] */
0293         /* .bss section */              /* [7] */
0294         BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_DATASEC, 0, 1), 48),
0295         BTF_VAR_SECINFO_ENC(6, 0, 48),
0296         BTF_END_RAW,
0297     },
0298     .str_sec = "\0A\0m\0n\0o\0p\0t\0.bss",
0299     .str_sec_size = sizeof("\0A\0m\0n\0o\0p\0t\0.bss"),
0300     .map_type = BPF_MAP_TYPE_ARRAY,
0301     .map_name = ".bss",
0302     .key_size = sizeof(int),
0303     .value_size = 48,
0304     .key_type_id = 0,
0305     .value_type_id = 7,
0306     .max_entries = 1,
0307 },
0308 {
0309     .descr = "global data test #3",
0310     .raw_types = {
0311         /* int */
0312         BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),  /* [1] */
0313         /* static int t */
0314         BTF_VAR_ENC(NAME_TBD, 1, 0),            /* [2] */
0315         /* .bss section */              /* [3] */
0316         BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_DATASEC, 0, 1), 4),
0317         BTF_VAR_SECINFO_ENC(2, 0, 4),
0318         BTF_END_RAW,
0319     },
0320     .str_sec = "\0t\0.bss",
0321     .str_sec_size = sizeof("\0t\0.bss"),
0322     .map_type = BPF_MAP_TYPE_ARRAY,
0323     .map_name = ".bss",
0324     .key_size = sizeof(int),
0325     .value_size = 4,
0326     .key_type_id = 0,
0327     .value_type_id = 3,
0328     .max_entries = 1,
0329 },
0330 {
0331     .descr = "global data test #4, unsupported linkage",
0332     .raw_types = {
0333         /* int */
0334         BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),  /* [1] */
0335         /* static int t */
0336         BTF_VAR_ENC(NAME_TBD, 1, 2),            /* [2] */
0337         /* .bss section */              /* [3] */
0338         BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_DATASEC, 0, 1), 4),
0339         BTF_VAR_SECINFO_ENC(2, 0, 4),
0340         BTF_END_RAW,
0341     },
0342     .str_sec = "\0t\0.bss",
0343     .str_sec_size = sizeof("\0t\0.bss"),
0344     .map_type = BPF_MAP_TYPE_ARRAY,
0345     .map_name = ".bss",
0346     .key_size = sizeof(int),
0347     .value_size = 4,
0348     .key_type_id = 0,
0349     .value_type_id = 3,
0350     .max_entries = 1,
0351     .btf_load_err = true,
0352     .err_str = "Linkage not supported",
0353 },
0354 {
0355     .descr = "global data test #5, invalid var type",
0356     .raw_types = {
0357         /* static void t */
0358         BTF_VAR_ENC(NAME_TBD, 0, 0),            /* [1] */
0359         /* .bss section */              /* [2] */
0360         BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_DATASEC, 0, 1), 4),
0361         BTF_VAR_SECINFO_ENC(1, 0, 4),
0362         BTF_END_RAW,
0363     },
0364     .str_sec = "\0t\0.bss",
0365     .str_sec_size = sizeof("\0t\0.bss"),
0366     .map_type = BPF_MAP_TYPE_ARRAY,
0367     .map_name = ".bss",
0368     .key_size = sizeof(int),
0369     .value_size = 4,
0370     .key_type_id = 0,
0371     .value_type_id = 2,
0372     .max_entries = 1,
0373     .btf_load_err = true,
0374     .err_str = "Invalid type_id",
0375 },
0376 {
0377     .descr = "global data test #6, invalid var type (fwd type)",
0378     .raw_types = {
0379         /* union A */
0380         BTF_TYPE_ENC(NAME_TBD,
0381                  BTF_INFO_ENC(BTF_KIND_FWD, 1, 0), 0), /* [1] */
0382         /* static union A t */
0383         BTF_VAR_ENC(NAME_TBD, 1, 0),            /* [2] */
0384         /* .bss section */              /* [3] */
0385         BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_DATASEC, 0, 1), 4),
0386         BTF_VAR_SECINFO_ENC(2, 0, 4),
0387         BTF_END_RAW,
0388     },
0389     .str_sec = "\0A\0t\0.bss",
0390     .str_sec_size = sizeof("\0A\0t\0.bss"),
0391     .map_type = BPF_MAP_TYPE_ARRAY,
0392     .map_name = ".bss",
0393     .key_size = sizeof(int),
0394     .value_size = 4,
0395     .key_type_id = 0,
0396     .value_type_id = 2,
0397     .max_entries = 1,
0398     .btf_load_err = true,
0399     .err_str = "Invalid type",
0400 },
0401 {
0402     .descr = "global data test #7, invalid var type (fwd type)",
0403     .raw_types = {
0404         /* union A */
0405         BTF_TYPE_ENC(NAME_TBD,
0406                  BTF_INFO_ENC(BTF_KIND_FWD, 1, 0), 0), /* [1] */
0407         /* static union A t */
0408         BTF_VAR_ENC(NAME_TBD, 1, 0),            /* [2] */
0409         /* .bss section */              /* [3] */
0410         BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_DATASEC, 0, 1), 4),
0411         BTF_VAR_SECINFO_ENC(1, 0, 4),
0412         BTF_END_RAW,
0413     },
0414     .str_sec = "\0A\0t\0.bss",
0415     .str_sec_size = sizeof("\0A\0t\0.bss"),
0416     .map_type = BPF_MAP_TYPE_ARRAY,
0417     .map_name = ".bss",
0418     .key_size = sizeof(int),
0419     .value_size = 4,
0420     .key_type_id = 0,
0421     .value_type_id = 2,
0422     .max_entries = 1,
0423     .btf_load_err = true,
0424     .err_str = "Invalid type",
0425 },
0426 {
0427     .descr = "global data test #8, invalid var size",
0428     .raw_types = {
0429         /* int */
0430         BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),  /* [1] */
0431         /* unsigned long long */
0432         BTF_TYPE_INT_ENC(0, 0, 0, 64, 8),       /* [2] */
0433         /* char */
0434         BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 8, 1),   /* [3] */
0435         /* int[8] */
0436         BTF_TYPE_ARRAY_ENC(1, 1, 8),            /* [4] */
0437         /* struct A { */                /* [5] */
0438         BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 4), 48),
0439         BTF_MEMBER_ENC(NAME_TBD, 2, 0), /* unsigned long long m;*/
0440         BTF_MEMBER_ENC(NAME_TBD, 1, 64),/* int n;       */
0441         BTF_MEMBER_ENC(NAME_TBD, 3, 96),/* char o;      */
0442         BTF_MEMBER_ENC(NAME_TBD, 4, 128),/* int p[8]        */
0443         /* } */
0444         /* static struct A t */
0445         BTF_VAR_ENC(NAME_TBD, 5, 0),            /* [6] */
0446         /* .bss section */              /* [7] */
0447         BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_DATASEC, 0, 1), 48),
0448         BTF_VAR_SECINFO_ENC(6, 0, 47),
0449         BTF_END_RAW,
0450     },
0451     .str_sec = "\0A\0m\0n\0o\0p\0t\0.bss",
0452     .str_sec_size = sizeof("\0A\0m\0n\0o\0p\0t\0.bss"),
0453     .map_type = BPF_MAP_TYPE_ARRAY,
0454     .map_name = ".bss",
0455     .key_size = sizeof(int),
0456     .value_size = 48,
0457     .key_type_id = 0,
0458     .value_type_id = 7,
0459     .max_entries = 1,
0460     .btf_load_err = true,
0461     .err_str = "Invalid size",
0462 },
0463 {
0464     .descr = "global data test #9, invalid var size",
0465     .raw_types = {
0466         /* int */
0467         BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),  /* [1] */
0468         /* unsigned long long */
0469         BTF_TYPE_INT_ENC(0, 0, 0, 64, 8),       /* [2] */
0470         /* char */
0471         BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 8, 1),   /* [3] */
0472         /* int[8] */
0473         BTF_TYPE_ARRAY_ENC(1, 1, 8),            /* [4] */
0474         /* struct A { */                /* [5] */
0475         BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 4), 48),
0476         BTF_MEMBER_ENC(NAME_TBD, 2, 0), /* unsigned long long m;*/
0477         BTF_MEMBER_ENC(NAME_TBD, 1, 64),/* int n;       */
0478         BTF_MEMBER_ENC(NAME_TBD, 3, 96),/* char o;      */
0479         BTF_MEMBER_ENC(NAME_TBD, 4, 128),/* int p[8]        */
0480         /* } */
0481         /* static struct A t */
0482         BTF_VAR_ENC(NAME_TBD, 5, 0),            /* [6] */
0483         /* .bss section */              /* [7] */
0484         BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_DATASEC, 0, 1), 46),
0485         BTF_VAR_SECINFO_ENC(6, 0, 48),
0486         BTF_END_RAW,
0487     },
0488     .str_sec = "\0A\0m\0n\0o\0p\0t\0.bss",
0489     .str_sec_size = sizeof("\0A\0m\0n\0o\0p\0t\0.bss"),
0490     .map_type = BPF_MAP_TYPE_ARRAY,
0491     .map_name = ".bss",
0492     .key_size = sizeof(int),
0493     .value_size = 48,
0494     .key_type_id = 0,
0495     .value_type_id = 7,
0496     .max_entries = 1,
0497     .btf_load_err = true,
0498     .err_str = "Invalid size",
0499 },
0500 {
0501     .descr = "global data test #10, invalid var size",
0502     .raw_types = {
0503         /* int */
0504         BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),  /* [1] */
0505         /* unsigned long long */
0506         BTF_TYPE_INT_ENC(0, 0, 0, 64, 8),       /* [2] */
0507         /* char */
0508         BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 8, 1),   /* [3] */
0509         /* int[8] */
0510         BTF_TYPE_ARRAY_ENC(1, 1, 8),            /* [4] */
0511         /* struct A { */                /* [5] */
0512         BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 4), 48),
0513         BTF_MEMBER_ENC(NAME_TBD, 2, 0), /* unsigned long long m;*/
0514         BTF_MEMBER_ENC(NAME_TBD, 1, 64),/* int n;       */
0515         BTF_MEMBER_ENC(NAME_TBD, 3, 96),/* char o;      */
0516         BTF_MEMBER_ENC(NAME_TBD, 4, 128),/* int p[8]        */
0517         /* } */
0518         /* static struct A t */
0519         BTF_VAR_ENC(NAME_TBD, 5, 0),            /* [6] */
0520         /* .bss section */              /* [7] */
0521         BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_DATASEC, 0, 1), 46),
0522         BTF_VAR_SECINFO_ENC(6, 0, 46),
0523         BTF_END_RAW,
0524     },
0525     .str_sec = "\0A\0m\0n\0o\0p\0t\0.bss",
0526     .str_sec_size = sizeof("\0A\0m\0n\0o\0p\0t\0.bss"),
0527     .map_type = BPF_MAP_TYPE_ARRAY,
0528     .map_name = ".bss",
0529     .key_size = sizeof(int),
0530     .value_size = 48,
0531     .key_type_id = 0,
0532     .value_type_id = 7,
0533     .max_entries = 1,
0534     .btf_load_err = true,
0535     .err_str = "Invalid size",
0536 },
0537 {
0538     .descr = "global data test #11, multiple section members",
0539     .raw_types = {
0540         /* int */
0541         BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),  /* [1] */
0542         /* unsigned long long */
0543         BTF_TYPE_INT_ENC(0, 0, 0, 64, 8),       /* [2] */
0544         /* char */
0545         BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 8, 1),   /* [3] */
0546         /* int[8] */
0547         BTF_TYPE_ARRAY_ENC(1, 1, 8),            /* [4] */
0548         /* struct A { */                /* [5] */
0549         BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 4), 48),
0550         BTF_MEMBER_ENC(NAME_TBD, 2, 0), /* unsigned long long m;*/
0551         BTF_MEMBER_ENC(NAME_TBD, 1, 64),/* int n;       */
0552         BTF_MEMBER_ENC(NAME_TBD, 3, 96),/* char o;      */
0553         BTF_MEMBER_ENC(NAME_TBD, 4, 128),/* int p[8]        */
0554         /* } */
0555         /* static struct A t */
0556         BTF_VAR_ENC(NAME_TBD, 5, 0),            /* [6] */
0557         /* static int u */
0558         BTF_VAR_ENC(NAME_TBD, 1, 0),            /* [7] */
0559         /* .bss section */              /* [8] */
0560         BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_DATASEC, 0, 2), 62),
0561         BTF_VAR_SECINFO_ENC(6, 10, 48),
0562         BTF_VAR_SECINFO_ENC(7, 58, 4),
0563         BTF_END_RAW,
0564     },
0565     .str_sec = "\0A\0m\0n\0o\0p\0t\0u\0.bss",
0566     .str_sec_size = sizeof("\0A\0m\0n\0o\0p\0t\0u\0.bss"),
0567     .map_type = BPF_MAP_TYPE_ARRAY,
0568     .map_name = ".bss",
0569     .key_size = sizeof(int),
0570     .value_size = 62,
0571     .key_type_id = 0,
0572     .value_type_id = 8,
0573     .max_entries = 1,
0574 },
0575 {
0576     .descr = "global data test #12, invalid offset",
0577     .raw_types = {
0578         /* int */
0579         BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),  /* [1] */
0580         /* unsigned long long */
0581         BTF_TYPE_INT_ENC(0, 0, 0, 64, 8),       /* [2] */
0582         /* char */
0583         BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 8, 1),   /* [3] */
0584         /* int[8] */
0585         BTF_TYPE_ARRAY_ENC(1, 1, 8),            /* [4] */
0586         /* struct A { */                /* [5] */
0587         BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 4), 48),
0588         BTF_MEMBER_ENC(NAME_TBD, 2, 0), /* unsigned long long m;*/
0589         BTF_MEMBER_ENC(NAME_TBD, 1, 64),/* int n;       */
0590         BTF_MEMBER_ENC(NAME_TBD, 3, 96),/* char o;      */
0591         BTF_MEMBER_ENC(NAME_TBD, 4, 128),/* int p[8]        */
0592         /* } */
0593         /* static struct A t */
0594         BTF_VAR_ENC(NAME_TBD, 5, 0),            /* [6] */
0595         /* static int u */
0596         BTF_VAR_ENC(NAME_TBD, 1, 0),            /* [7] */
0597         /* .bss section */              /* [8] */
0598         BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_DATASEC, 0, 2), 62),
0599         BTF_VAR_SECINFO_ENC(6, 10, 48),
0600         BTF_VAR_SECINFO_ENC(7, 60, 4),
0601         BTF_END_RAW,
0602     },
0603     .str_sec = "\0A\0m\0n\0o\0p\0t\0u\0.bss",
0604     .str_sec_size = sizeof("\0A\0m\0n\0o\0p\0t\0u\0.bss"),
0605     .map_type = BPF_MAP_TYPE_ARRAY,
0606     .map_name = ".bss",
0607     .key_size = sizeof(int),
0608     .value_size = 62,
0609     .key_type_id = 0,
0610     .value_type_id = 8,
0611     .max_entries = 1,
0612     .btf_load_err = true,
0613     .err_str = "Invalid offset+size",
0614 },
0615 {
0616     .descr = "global data test #13, invalid offset",
0617     .raw_types = {
0618         /* int */
0619         BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),  /* [1] */
0620         /* unsigned long long */
0621         BTF_TYPE_INT_ENC(0, 0, 0, 64, 8),       /* [2] */
0622         /* char */
0623         BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 8, 1),   /* [3] */
0624         /* int[8] */
0625         BTF_TYPE_ARRAY_ENC(1, 1, 8),            /* [4] */
0626         /* struct A { */                /* [5] */
0627         BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 4), 48),
0628         BTF_MEMBER_ENC(NAME_TBD, 2, 0), /* unsigned long long m;*/
0629         BTF_MEMBER_ENC(NAME_TBD, 1, 64),/* int n;       */
0630         BTF_MEMBER_ENC(NAME_TBD, 3, 96),/* char o;      */
0631         BTF_MEMBER_ENC(NAME_TBD, 4, 128),/* int p[8]        */
0632         /* } */
0633         /* static struct A t */
0634         BTF_VAR_ENC(NAME_TBD, 5, 0),            /* [6] */
0635         /* static int u */
0636         BTF_VAR_ENC(NAME_TBD, 1, 0),            /* [7] */
0637         /* .bss section */              /* [8] */
0638         BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_DATASEC, 0, 2), 62),
0639         BTF_VAR_SECINFO_ENC(6, 10, 48),
0640         BTF_VAR_SECINFO_ENC(7, 12, 4),
0641         BTF_END_RAW,
0642     },
0643     .str_sec = "\0A\0m\0n\0o\0p\0t\0u\0.bss",
0644     .str_sec_size = sizeof("\0A\0m\0n\0o\0p\0t\0u\0.bss"),
0645     .map_type = BPF_MAP_TYPE_ARRAY,
0646     .map_name = ".bss",
0647     .key_size = sizeof(int),
0648     .value_size = 62,
0649     .key_type_id = 0,
0650     .value_type_id = 8,
0651     .max_entries = 1,
0652     .btf_load_err = true,
0653     .err_str = "Invalid offset",
0654 },
0655 {
0656     .descr = "global data test #14, invalid offset",
0657     .raw_types = {
0658         /* int */
0659         BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),  /* [1] */
0660         /* unsigned long long */
0661         BTF_TYPE_INT_ENC(0, 0, 0, 64, 8),       /* [2] */
0662         /* char */
0663         BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 8, 1),   /* [3] */
0664         /* int[8] */
0665         BTF_TYPE_ARRAY_ENC(1, 1, 8),            /* [4] */
0666         /* struct A { */                /* [5] */
0667         BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 4), 48),
0668         BTF_MEMBER_ENC(NAME_TBD, 2, 0), /* unsigned long long m;*/
0669         BTF_MEMBER_ENC(NAME_TBD, 1, 64),/* int n;       */
0670         BTF_MEMBER_ENC(NAME_TBD, 3, 96),/* char o;      */
0671         BTF_MEMBER_ENC(NAME_TBD, 4, 128),/* int p[8]        */
0672         /* } */
0673         /* static struct A t */
0674         BTF_VAR_ENC(NAME_TBD, 5, 0),            /* [6] */
0675         /* static int u */
0676         BTF_VAR_ENC(NAME_TBD, 1, 0),            /* [7] */
0677         /* .bss section */              /* [8] */
0678         BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_DATASEC, 0, 2), 62),
0679         BTF_VAR_SECINFO_ENC(7, 58, 4),
0680         BTF_VAR_SECINFO_ENC(6, 10, 48),
0681         BTF_END_RAW,
0682     },
0683     .str_sec = "\0A\0m\0n\0o\0p\0t\0u\0.bss",
0684     .str_sec_size = sizeof("\0A\0m\0n\0o\0p\0t\0u\0.bss"),
0685     .map_type = BPF_MAP_TYPE_ARRAY,
0686     .map_name = ".bss",
0687     .key_size = sizeof(int),
0688     .value_size = 62,
0689     .key_type_id = 0,
0690     .value_type_id = 8,
0691     .max_entries = 1,
0692     .btf_load_err = true,
0693     .err_str = "Invalid offset",
0694 },
0695 {
0696     .descr = "global data test #15, not var kind",
0697     .raw_types = {
0698         /* int */
0699         BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),  /* [1] */
0700         BTF_VAR_ENC(NAME_TBD, 1, 0),            /* [2] */
0701         /* .bss section */              /* [3] */
0702         BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_DATASEC, 0, 1), 4),
0703         BTF_VAR_SECINFO_ENC(1, 0, 4),
0704         BTF_END_RAW,
0705     },
0706     .str_sec = "\0A\0t\0.bss",
0707     .str_sec_size = sizeof("\0A\0t\0.bss"),
0708     .map_type = BPF_MAP_TYPE_ARRAY,
0709     .map_name = ".bss",
0710     .key_size = sizeof(int),
0711     .value_size = 4,
0712     .key_type_id = 0,
0713     .value_type_id = 3,
0714     .max_entries = 1,
0715     .btf_load_err = true,
0716     .err_str = "Not a VAR kind member",
0717 },
0718 {
0719     .descr = "global data test #16, invalid var referencing sec",
0720     .raw_types = {
0721         /* int */
0722         BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),  /* [1] */
0723         BTF_VAR_ENC(NAME_TBD, 5, 0),            /* [2] */
0724         BTF_VAR_ENC(NAME_TBD, 2, 0),            /* [3] */
0725         /* a section */                 /* [4] */
0726         BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_DATASEC, 0, 1), 4),
0727         BTF_VAR_SECINFO_ENC(3, 0, 4),
0728         /* a section */                 /* [5] */
0729         BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_DATASEC, 0, 1), 4),
0730         BTF_VAR_SECINFO_ENC(6, 0, 4),
0731         BTF_VAR_ENC(NAME_TBD, 1, 0),            /* [6] */
0732         BTF_END_RAW,
0733     },
0734     .str_sec = "\0A\0t\0s\0a\0a",
0735     .str_sec_size = sizeof("\0A\0t\0s\0a\0a"),
0736     .map_type = BPF_MAP_TYPE_ARRAY,
0737     .map_name = ".bss",
0738     .key_size = sizeof(int),
0739     .value_size = 4,
0740     .key_type_id = 0,
0741     .value_type_id = 4,
0742     .max_entries = 1,
0743     .btf_load_err = true,
0744     .err_str = "Invalid type_id",
0745 },
0746 {
0747     .descr = "global data test #17, invalid var referencing var",
0748     .raw_types = {
0749         /* int */
0750         BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),  /* [1] */
0751         BTF_VAR_ENC(NAME_TBD, 1, 0),            /* [2] */
0752         BTF_VAR_ENC(NAME_TBD, 2, 0),            /* [3] */
0753         /* a section */                 /* [4] */
0754         BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_DATASEC, 0, 1), 4),
0755         BTF_VAR_SECINFO_ENC(3, 0, 4),
0756         BTF_END_RAW,
0757     },
0758     .str_sec = "\0A\0t\0s\0a\0a",
0759     .str_sec_size = sizeof("\0A\0t\0s\0a\0a"),
0760     .map_type = BPF_MAP_TYPE_ARRAY,
0761     .map_name = ".bss",
0762     .key_size = sizeof(int),
0763     .value_size = 4,
0764     .key_type_id = 0,
0765     .value_type_id = 4,
0766     .max_entries = 1,
0767     .btf_load_err = true,
0768     .err_str = "Invalid type_id",
0769 },
0770 {
0771     .descr = "global data test #18, invalid var loop",
0772     .raw_types = {
0773         /* int */
0774         BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),  /* [1] */
0775         BTF_VAR_ENC(NAME_TBD, 2, 0),            /* [2] */
0776         /* .bss section */              /* [3] */
0777         BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_DATASEC, 0, 1), 4),
0778         BTF_VAR_SECINFO_ENC(2, 0, 4),
0779         BTF_END_RAW,
0780     },
0781     .str_sec = "\0A\0t\0aaa",
0782     .str_sec_size = sizeof("\0A\0t\0aaa"),
0783     .map_type = BPF_MAP_TYPE_ARRAY,
0784     .map_name = ".bss",
0785     .key_size = sizeof(int),
0786     .value_size = 4,
0787     .key_type_id = 0,
0788     .value_type_id = 4,
0789     .max_entries = 1,
0790     .btf_load_err = true,
0791     .err_str = "Invalid type_id",
0792 },
0793 {
0794     .descr = "global data test #19, invalid var referencing var",
0795     .raw_types = {
0796         /* int */
0797         BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),  /* [1] */
0798         BTF_VAR_ENC(NAME_TBD, 3, 0),            /* [2] */
0799         BTF_VAR_ENC(NAME_TBD, 1, 0),            /* [3] */
0800         BTF_END_RAW,
0801     },
0802     .str_sec = "\0A\0t\0s\0a\0a",
0803     .str_sec_size = sizeof("\0A\0t\0s\0a\0a"),
0804     .map_type = BPF_MAP_TYPE_ARRAY,
0805     .map_name = ".bss",
0806     .key_size = sizeof(int),
0807     .value_size = 4,
0808     .key_type_id = 0,
0809     .value_type_id = 4,
0810     .max_entries = 1,
0811     .btf_load_err = true,
0812     .err_str = "Invalid type_id",
0813 },
0814 {
0815     .descr = "global data test #20, invalid ptr referencing var",
0816     .raw_types = {
0817         /* int */
0818         BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),  /* [1] */
0819         /* PTR type_id=3    */          /* [2] */
0820         BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_PTR, 0, 0), 3),
0821         BTF_VAR_ENC(NAME_TBD, 1, 0),            /* [3] */
0822         BTF_END_RAW,
0823     },
0824     .str_sec = "\0A\0t\0s\0a\0a",
0825     .str_sec_size = sizeof("\0A\0t\0s\0a\0a"),
0826     .map_type = BPF_MAP_TYPE_ARRAY,
0827     .map_name = ".bss",
0828     .key_size = sizeof(int),
0829     .value_size = 4,
0830     .key_type_id = 0,
0831     .value_type_id = 4,
0832     .max_entries = 1,
0833     .btf_load_err = true,
0834     .err_str = "Invalid type_id",
0835 },
0836 {
0837     .descr = "global data test #21, var included in struct",
0838     .raw_types = {
0839         /* int */
0840         BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),  /* [1] */
0841         /* struct A { */                /* [2] */
0842         BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 2), sizeof(int) * 2),
0843         BTF_MEMBER_ENC(NAME_TBD, 1, 0), /* int m; */
0844         BTF_MEMBER_ENC(NAME_TBD, 3, 32),/* VAR type_id=3; */
0845         /* } */
0846         BTF_VAR_ENC(NAME_TBD, 1, 0),            /* [3] */
0847         BTF_END_RAW,
0848     },
0849     .str_sec = "\0A\0t\0s\0a\0a",
0850     .str_sec_size = sizeof("\0A\0t\0s\0a\0a"),
0851     .map_type = BPF_MAP_TYPE_ARRAY,
0852     .map_name = ".bss",
0853     .key_size = sizeof(int),
0854     .value_size = 4,
0855     .key_type_id = 0,
0856     .value_type_id = 4,
0857     .max_entries = 1,
0858     .btf_load_err = true,
0859     .err_str = "Invalid member",
0860 },
0861 {
0862     .descr = "global data test #22, array of var",
0863     .raw_types = {
0864         /* int */
0865         BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),  /* [1] */
0866         BTF_TYPE_ARRAY_ENC(3, 1, 4),            /* [2] */
0867         BTF_VAR_ENC(NAME_TBD, 1, 0),            /* [3] */
0868         BTF_END_RAW,
0869     },
0870     .str_sec = "\0A\0t\0s\0a\0a",
0871     .str_sec_size = sizeof("\0A\0t\0s\0a\0a"),
0872     .map_type = BPF_MAP_TYPE_ARRAY,
0873     .map_name = ".bss",
0874     .key_size = sizeof(int),
0875     .value_size = 4,
0876     .key_type_id = 0,
0877     .value_type_id = 4,
0878     .max_entries = 1,
0879     .btf_load_err = true,
0880     .err_str = "Invalid elem",
0881 },
0882 /* Test member exceeds the size of struct.
0883  *
0884  * struct A {
0885  *     int m;
0886  *     int n;
0887  * };
0888  */
0889 {
0890     .descr = "size check test #1",
0891     .raw_types = {
0892         /* int */                   /* [1] */
0893         BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
0894         /* struct A { */                /* [2] */
0895         BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 2), sizeof(int) * 2 -  1),
0896         BTF_MEMBER_ENC(NAME_TBD, 1, 0), /* int m; */
0897         BTF_MEMBER_ENC(NAME_TBD, 1, 32),/* int n; */
0898         /* } */
0899         BTF_END_RAW,
0900     },
0901     .str_sec = "\0A\0m\0n",
0902     .str_sec_size = sizeof("\0A\0m\0n"),
0903     .map_type = BPF_MAP_TYPE_ARRAY,
0904     .map_name = "size_check1_map",
0905     .key_size = sizeof(int),
0906     .value_size = 1,
0907     .key_type_id = 1,
0908     .value_type_id = 2,
0909     .max_entries = 4,
0910     .btf_load_err = true,
0911     .err_str = "Member exceeds struct_size",
0912 },
0913 
0914 /* Test member exceeds the size of struct
0915  *
0916  * struct A {
0917  *     int m;
0918  *     int n[2];
0919  * };
0920  */
0921 {
0922     .descr = "size check test #2",
0923     .raw_types = {
0924         /* int */                   /* [1] */
0925         BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, sizeof(int)),
0926         /* int[2] */                    /* [2] */
0927         BTF_TYPE_ARRAY_ENC(1, 1, 2),
0928         /* struct A { */                /* [3] */
0929         BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 2), sizeof(int) * 3 - 1),
0930         BTF_MEMBER_ENC(NAME_TBD, 1, 0), /* int m; */
0931         BTF_MEMBER_ENC(NAME_TBD, 2, 32),/* int n[2]; */
0932         /* } */
0933         BTF_END_RAW,
0934     },
0935     .str_sec = "\0A\0m\0n",
0936     .str_sec_size = sizeof("\0A\0m\0n"),
0937     .map_type = BPF_MAP_TYPE_ARRAY,
0938     .map_name = "size_check2_map",
0939     .key_size = sizeof(int),
0940     .value_size = 1,
0941     .key_type_id = 1,
0942     .value_type_id = 3,
0943     .max_entries = 4,
0944     .btf_load_err = true,
0945     .err_str = "Member exceeds struct_size",
0946 },
0947 
0948 /* Test member exceeds the size of struct
0949  *
0950  * struct A {
0951  *     int m;
0952  *     void *n;
0953  * };
0954  */
0955 {
0956     .descr = "size check test #3",
0957     .raw_types = {
0958         /* int */                   /* [1] */
0959         BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, sizeof(int)),
0960         /* void* */                 /* [2] */
0961         BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_PTR, 0, 0), 0),
0962         /* struct A { */                /* [3] */
0963         BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 2), sizeof(int) + sizeof(void *) - 1),
0964         BTF_MEMBER_ENC(NAME_TBD, 1, 0), /* int m; */
0965         BTF_MEMBER_ENC(NAME_TBD, 2, 32),/* void *n; */
0966         /* } */
0967         BTF_END_RAW,
0968     },
0969     .str_sec = "\0A\0m\0n",
0970     .str_sec_size = sizeof("\0A\0m\0n"),
0971     .map_type = BPF_MAP_TYPE_ARRAY,
0972     .map_name = "size_check3_map",
0973     .key_size = sizeof(int),
0974     .value_size = 1,
0975     .key_type_id = 1,
0976     .value_type_id = 3,
0977     .max_entries = 4,
0978     .btf_load_err = true,
0979     .err_str = "Member exceeds struct_size",
0980 },
0981 
0982 /* Test member exceeds the size of struct
0983  *
0984  * enum E {
0985  *     E0,
0986  *     E1,
0987  * };
0988  *
0989  * struct A {
0990  *     int m;
0991  *     enum E n;
0992  * };
0993  */
0994 {
0995     .descr = "size check test #4",
0996     .raw_types = {
0997         /* int */           /* [1] */
0998         BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, sizeof(int)),
0999         /* enum E { */          /* [2] */
1000         BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_ENUM, 0, 2), sizeof(int)),
1001         BTF_ENUM_ENC(NAME_TBD, 0),
1002         BTF_ENUM_ENC(NAME_TBD, 1),
1003         /* } */
1004         /* struct A { */        /* [3] */
1005         BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 2), sizeof(int) * 2 - 1),
1006         BTF_MEMBER_ENC(NAME_TBD, 1, 0), /* int m; */
1007         BTF_MEMBER_ENC(NAME_TBD, 2, 32),/* enum E n; */
1008         /* } */
1009         BTF_END_RAW,
1010     },
1011     .str_sec = "\0E\0E0\0E1\0A\0m\0n",
1012     .str_sec_size = sizeof("\0E\0E0\0E1\0A\0m\0n"),
1013     .map_type = BPF_MAP_TYPE_ARRAY,
1014     .map_name = "size_check4_map",
1015     .key_size = sizeof(int),
1016     .value_size = 1,
1017     .key_type_id = 1,
1018     .value_type_id = 3,
1019     .max_entries = 4,
1020     .btf_load_err = true,
1021     .err_str = "Member exceeds struct_size",
1022 },
1023 
1024 /* Test member unexceeds the size of struct
1025  *
1026  * enum E {
1027  *     E0,
1028  *     E1,
1029  * };
1030  *
1031  * struct A {
1032  *     char m;
1033  *     enum E __attribute__((packed)) n;
1034  * };
1035  */
1036 {
1037     .descr = "size check test #5",
1038     .raw_types = {
1039         /* int */           /* [1] */
1040         BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, sizeof(int)),
1041         /* char */          /* [2] */
1042         BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 8, 1),
1043         /* enum E { */          /* [3] */
1044         BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_ENUM, 0, 2), 1),
1045         BTF_ENUM_ENC(NAME_TBD, 0),
1046         BTF_ENUM_ENC(NAME_TBD, 1),
1047         /* } */
1048         /* struct A { */        /* [4] */
1049         BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 2), 2),
1050         BTF_MEMBER_ENC(NAME_TBD, 2, 0), /* char m; */
1051         BTF_MEMBER_ENC(NAME_TBD, 3, 8),/* enum E __attribute__((packed)) n; */
1052         /* } */
1053         BTF_END_RAW,
1054     },
1055     .str_sec = "\0E\0E0\0E1\0A\0m\0n",
1056     .str_sec_size = sizeof("\0E\0E0\0E1\0A\0m\0n"),
1057     .map_type = BPF_MAP_TYPE_ARRAY,
1058     .map_name = "size_check5_map",
1059     .key_size = sizeof(int),
1060     .value_size = 2,
1061     .key_type_id = 1,
1062     .value_type_id = 4,
1063     .max_entries = 4,
1064 },
1065 
1066 /* typedef const void * const_void_ptr;
1067  * struct A {
1068  *  const_void_ptr m;
1069  * };
1070  */
1071 {
1072     .descr = "void test #1",
1073     .raw_types = {
1074         /* int */       /* [1] */
1075         BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
1076         /* const void */    /* [2] */
1077         BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_CONST, 0, 0), 0),
1078         /* const void* */   /* [3] */
1079         BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_PTR, 0, 0), 2),
1080         /* typedef const void * const_void_ptr */
1081         BTF_TYPEDEF_ENC(NAME_TBD, 3),   /* [4] */
1082         /* struct A { */    /* [5] */
1083         BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 1), sizeof(void *)),
1084         /* const_void_ptr m; */
1085         BTF_MEMBER_ENC(NAME_TBD, 4, 0),
1086         /* } */
1087         BTF_END_RAW,
1088     },
1089     .str_sec = "\0const_void_ptr\0A\0m",
1090     .str_sec_size = sizeof("\0const_void_ptr\0A\0m"),
1091     .map_type = BPF_MAP_TYPE_ARRAY,
1092     .map_name = "void_test1_map",
1093     .key_size = sizeof(int),
1094     .value_size = sizeof(void *),
1095     .key_type_id = 1,
1096     .value_type_id = 4,
1097     .max_entries = 4,
1098 },
1099 
1100 /* struct A {
1101  *     const void m;
1102  * };
1103  */
1104 {
1105     .descr = "void test #2",
1106     .raw_types = {
1107         /* int */       /* [1] */
1108         BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
1109         /* const void */    /* [2] */
1110         BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_CONST, 0, 0), 0),
1111         /* struct A { */    /* [3] */
1112         BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 1), 8),
1113         /* const void m; */
1114         BTF_MEMBER_ENC(NAME_TBD, 2, 0),
1115         /* } */
1116         BTF_END_RAW,
1117     },
1118     .str_sec = "\0A\0m",
1119     .str_sec_size = sizeof("\0A\0m"),
1120     .map_type = BPF_MAP_TYPE_ARRAY,
1121     .map_name = "void_test2_map",
1122     .key_size = sizeof(int),
1123     .value_size = sizeof(void *),
1124     .key_type_id = 1,
1125     .value_type_id = 3,
1126     .max_entries = 4,
1127     .btf_load_err = true,
1128     .err_str = "Invalid member",
1129 },
1130 
1131 /* typedef const void * const_void_ptr;
1132  * const_void_ptr[4]
1133  */
1134 {
1135     .descr = "void test #3",
1136     .raw_types = {
1137         /* int */       /* [1] */
1138         BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
1139         /* const void */    /* [2] */
1140         BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_CONST, 0, 0), 0),
1141         /* const void* */   /* [3] */
1142         BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_PTR, 0, 0), 2),
1143         /* typedef const void * const_void_ptr */
1144         BTF_TYPEDEF_ENC(NAME_TBD, 3),   /* [4] */
1145         /* const_void_ptr[4] */
1146         BTF_TYPE_ARRAY_ENC(4, 1, 4),    /* [5] */
1147         BTF_END_RAW,
1148     },
1149     .str_sec = "\0const_void_ptr",
1150     .str_sec_size = sizeof("\0const_void_ptr"),
1151     .map_type = BPF_MAP_TYPE_ARRAY,
1152     .map_name = "void_test3_map",
1153     .key_size = sizeof(int),
1154     .value_size = sizeof(void *) * 4,
1155     .key_type_id = 1,
1156     .value_type_id = 5,
1157     .max_entries = 4,
1158 },
1159 
1160 /* const void[4]  */
1161 {
1162     .descr = "void test #4",
1163     .raw_types = {
1164         /* int */       /* [1] */
1165         BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
1166         /* const void */    /* [2] */
1167         BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_CONST, 0, 0), 0),
1168         /* const void[4] */ /* [3] */
1169         BTF_TYPE_ARRAY_ENC(2, 1, 4),
1170         BTF_END_RAW,
1171     },
1172     .str_sec = "\0A\0m",
1173     .str_sec_size = sizeof("\0A\0m"),
1174     .map_type = BPF_MAP_TYPE_ARRAY,
1175     .map_name = "void_test4_map",
1176     .key_size = sizeof(int),
1177     .value_size = sizeof(void *) * 4,
1178     .key_type_id = 1,
1179     .value_type_id = 3,
1180     .max_entries = 4,
1181     .btf_load_err = true,
1182     .err_str = "Invalid elem",
1183 },
1184 
1185 /* Array_A  <------------------+
1186  *     elem_type == Array_B    |
1187  *                    |        |
1188  *                    |        |
1189  * Array_B  <-------- +        |
1190  *      elem_type == Array A --+
1191  */
1192 {
1193     .descr = "loop test #1",
1194     .raw_types = {
1195         /* int */           /* [1] */
1196         BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
1197         /* Array_A */           /* [2] */
1198         BTF_TYPE_ARRAY_ENC(3, 1, 8),
1199         /* Array_B */           /* [3] */
1200         BTF_TYPE_ARRAY_ENC(2, 1, 8),
1201         BTF_END_RAW,
1202     },
1203     .str_sec = "",
1204     .str_sec_size = sizeof(""),
1205     .map_type = BPF_MAP_TYPE_ARRAY,
1206     .map_name = "loop_test1_map",
1207     .key_size = sizeof(int),
1208     .value_size = sizeof(sizeof(int) * 8),
1209     .key_type_id = 1,
1210     .value_type_id = 2,
1211     .max_entries = 4,
1212     .btf_load_err = true,
1213     .err_str = "Loop detected",
1214 },
1215 
1216 /* typedef is _before_ the BTF type of Array_A and Array_B
1217  *
1218  * typedef Array_B int_array;
1219  *
1220  * Array_A  <------------------+
1221  *     elem_type == int_array  |
1222  *                    |        |
1223  *                    |        |
1224  * Array_B  <-------- +        |
1225  *      elem_type == Array_A --+
1226  */
1227 {
1228     .descr = "loop test #2",
1229     .raw_types = {
1230         /* int */
1231         BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),  /* [1] */
1232         /* typedef Array_B int_array */
1233         BTF_TYPEDEF_ENC(1, 4),              /* [2] */
1234         /* Array_A */
1235         BTF_TYPE_ARRAY_ENC(2, 1, 8),            /* [3] */
1236         /* Array_B */
1237         BTF_TYPE_ARRAY_ENC(3, 1, 8),            /* [4] */
1238         BTF_END_RAW,
1239     },
1240     .str_sec = "\0int_array\0",
1241     .str_sec_size = sizeof("\0int_array"),
1242     .map_type = BPF_MAP_TYPE_ARRAY,
1243     .map_name = "loop_test2_map",
1244     .key_size = sizeof(int),
1245     .value_size = sizeof(sizeof(int) * 8),
1246     .key_type_id = 1,
1247     .value_type_id = 2,
1248     .max_entries = 4,
1249     .btf_load_err = true,
1250     .err_str = "Loop detected",
1251 },
1252 
1253 /* Array_A  <------------------+
1254  *     elem_type == Array_B    |
1255  *                    |        |
1256  *                    |        |
1257  * Array_B  <-------- +        |
1258  *      elem_type == Array_A --+
1259  */
1260 {
1261     .descr = "loop test #3",
1262     .raw_types = {
1263         /* int */               /* [1] */
1264         BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
1265         /* Array_A */               /* [2] */
1266         BTF_TYPE_ARRAY_ENC(3, 1, 8),
1267         /* Array_B */               /* [3] */
1268         BTF_TYPE_ARRAY_ENC(2, 1, 8),
1269         BTF_END_RAW,
1270     },
1271     .str_sec = "",
1272     .str_sec_size = sizeof(""),
1273     .map_type = BPF_MAP_TYPE_ARRAY,
1274     .map_name = "loop_test3_map",
1275     .key_size = sizeof(int),
1276     .value_size = sizeof(sizeof(int) * 8),
1277     .key_type_id = 1,
1278     .value_type_id = 2,
1279     .max_entries = 4,
1280     .btf_load_err = true,
1281     .err_str = "Loop detected",
1282 },
1283 
1284 /* typedef is _between_ the BTF type of Array_A and Array_B
1285  *
1286  * typedef Array_B int_array;
1287  *
1288  * Array_A  <------------------+
1289  *     elem_type == int_array  |
1290  *                    |        |
1291  *                    |        |
1292  * Array_B  <-------- +        |
1293  *      elem_type == Array_A --+
1294  */
1295 {
1296     .descr = "loop test #4",
1297     .raw_types = {
1298         /* int */               /* [1] */
1299         BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
1300         /* Array_A */               /* [2] */
1301         BTF_TYPE_ARRAY_ENC(3, 1, 8),
1302         /* typedef Array_B int_array */     /* [3] */
1303         BTF_TYPEDEF_ENC(NAME_TBD, 4),
1304         /* Array_B */               /* [4] */
1305         BTF_TYPE_ARRAY_ENC(2, 1, 8),
1306         BTF_END_RAW,
1307     },
1308     .str_sec = "\0int_array\0",
1309     .str_sec_size = sizeof("\0int_array"),
1310     .map_type = BPF_MAP_TYPE_ARRAY,
1311     .map_name = "loop_test4_map",
1312     .key_size = sizeof(int),
1313     .value_size = sizeof(sizeof(int) * 8),
1314     .key_type_id = 1,
1315     .value_type_id = 2,
1316     .max_entries = 4,
1317     .btf_load_err = true,
1318     .err_str = "Loop detected",
1319 },
1320 
1321 /* typedef struct B Struct_B
1322  *
1323  * struct A {
1324  *     int x;
1325  *     Struct_B y;
1326  * };
1327  *
1328  * struct B {
1329  *     int x;
1330  *     struct A y;
1331  * };
1332  */
1333 {
1334     .descr = "loop test #5",
1335     .raw_types = {
1336         /* int */
1337         BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),  /* [1] */
1338         /* struct A */                  /* [2] */
1339         BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 2), 8),
1340         BTF_MEMBER_ENC(NAME_TBD, 1, 0), /* int x;   */
1341         BTF_MEMBER_ENC(NAME_TBD, 3, 32),/* Struct_B y;  */
1342         /* typedef struct B Struct_B */
1343         BTF_TYPEDEF_ENC(NAME_TBD, 4),           /* [3] */
1344         /* struct B */                  /* [4] */
1345         BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 2), 8),
1346         BTF_MEMBER_ENC(NAME_TBD, 1, 0), /* int x;   */
1347         BTF_MEMBER_ENC(NAME_TBD, 2, 32),/* struct A y;  */
1348         BTF_END_RAW,
1349     },
1350     .str_sec = "\0A\0x\0y\0Struct_B\0B\0x\0y",
1351     .str_sec_size = sizeof("\0A\0x\0y\0Struct_B\0B\0x\0y"),
1352     .map_type = BPF_MAP_TYPE_ARRAY,
1353     .map_name = "loop_test5_map",
1354     .key_size = sizeof(int),
1355     .value_size = 8,
1356     .key_type_id = 1,
1357     .value_type_id = 2,
1358     .max_entries = 4,
1359     .btf_load_err = true,
1360     .err_str = "Loop detected",
1361 },
1362 
1363 /* struct A {
1364  *     int x;
1365  *     struct A array_a[4];
1366  * };
1367  */
1368 {
1369     .descr = "loop test #6",
1370     .raw_types = {
1371         /* int */
1372         BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),  /* [1] */
1373         BTF_TYPE_ARRAY_ENC(3, 1, 4),            /* [2] */
1374         /* struct A */                  /* [3] */
1375         BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 2), 8),
1376         BTF_MEMBER_ENC(NAME_TBD, 1, 0), /* int x;       */
1377         BTF_MEMBER_ENC(NAME_TBD, 2, 32),/* struct A array_a[4]; */
1378         BTF_END_RAW,
1379     },
1380     .str_sec = "\0A\0x\0y",
1381     .str_sec_size = sizeof("\0A\0x\0y"),
1382     .map_type = BPF_MAP_TYPE_ARRAY,
1383     .map_name = "loop_test6_map",
1384     .key_size = sizeof(int),
1385     .value_size = 8,
1386     .key_type_id = 1,
1387     .value_type_id = 2,
1388     .max_entries = 4,
1389     .btf_load_err = true,
1390     .err_str = "Loop detected",
1391 },
1392 
1393 {
1394     .descr = "loop test #7",
1395     .raw_types = {
1396         /* int */               /* [1] */
1397         BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
1398         /* struct A { */            /* [2] */
1399         BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 1), sizeof(void *)),
1400         /*     const void *m;   */
1401         BTF_MEMBER_ENC(NAME_TBD, 3, 0),
1402         /* CONST type_id=3  */      /* [3] */
1403         BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_CONST, 0, 0), 4),
1404         /* PTR type_id=2    */      /* [4] */
1405         BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_PTR, 0, 0), 3),
1406         BTF_END_RAW,
1407     },
1408     .str_sec = "\0A\0m",
1409     .str_sec_size = sizeof("\0A\0m"),
1410     .map_type = BPF_MAP_TYPE_ARRAY,
1411     .map_name = "loop_test7_map",
1412     .key_size = sizeof(int),
1413     .value_size = sizeof(void *),
1414     .key_type_id = 1,
1415     .value_type_id = 2,
1416     .max_entries = 4,
1417     .btf_load_err = true,
1418     .err_str = "Loop detected",
1419 },
1420 
1421 {
1422     .descr = "loop test #8",
1423     .raw_types = {
1424         /* int */               /* [1] */
1425         BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
1426         /* struct A { */            /* [2] */
1427         BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 1), sizeof(void *)),
1428         /*     const void *m;   */
1429         BTF_MEMBER_ENC(NAME_TBD, 4, 0),
1430         /* struct B { */            /* [3] */
1431         BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 1), sizeof(void *)),
1432         /*     const void *n;   */
1433         BTF_MEMBER_ENC(NAME_TBD, 6, 0),
1434         /* CONST type_id=5  */      /* [4] */
1435         BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_CONST, 0, 0), 5),
1436         /* PTR type_id=6    */      /* [5] */
1437         BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_PTR, 0, 0), 6),
1438         /* CONST type_id=7  */      /* [6] */
1439         BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_CONST, 0, 0), 7),
1440         /* PTR type_id=4    */      /* [7] */
1441         BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_PTR, 0, 0), 4),
1442         BTF_END_RAW,
1443     },
1444     .str_sec = "\0A\0m\0B\0n",
1445     .str_sec_size = sizeof("\0A\0m\0B\0n"),
1446     .map_type = BPF_MAP_TYPE_ARRAY,
1447     .map_name = "loop_test8_map",
1448     .key_size = sizeof(int),
1449     .value_size = sizeof(void *),
1450     .key_type_id = 1,
1451     .value_type_id = 2,
1452     .max_entries = 4,
1453     .btf_load_err = true,
1454     .err_str = "Loop detected",
1455 },
1456 
1457 {
1458     .descr = "string section does not end with null",
1459     .raw_types = {
1460         /* int */               /* [1] */
1461         BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),
1462         BTF_END_RAW,
1463     },
1464     .str_sec = "\0int",
1465     .str_sec_size = sizeof("\0int") - 1,
1466     .map_type = BPF_MAP_TYPE_ARRAY,
1467     .map_name = "hdr_test_map",
1468     .key_size = sizeof(int),
1469     .value_size = sizeof(int),
1470     .key_type_id = 1,
1471     .value_type_id = 1,
1472     .max_entries = 4,
1473     .btf_load_err = true,
1474     .err_str = "Invalid string section",
1475 },
1476 
1477 {
1478     .descr = "empty string section",
1479     .raw_types = {
1480         /* int */               /* [1] */
1481         BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
1482         BTF_END_RAW,
1483     },
1484     .str_sec = "",
1485     .str_sec_size = 0,
1486     .map_type = BPF_MAP_TYPE_ARRAY,
1487     .map_name = "hdr_test_map",
1488     .key_size = sizeof(int),
1489     .value_size = sizeof(int),
1490     .key_type_id = 1,
1491     .value_type_id = 1,
1492     .max_entries = 4,
1493     .btf_load_err = true,
1494     .err_str = "Invalid string section",
1495 },
1496 
1497 {
1498     .descr = "empty type section",
1499     .raw_types = {
1500         BTF_END_RAW,
1501     },
1502     .str_sec = "\0int",
1503     .str_sec_size = sizeof("\0int"),
1504     .map_type = BPF_MAP_TYPE_ARRAY,
1505     .map_name = "hdr_test_map",
1506     .key_size = sizeof(int),
1507     .value_size = sizeof(int),
1508     .key_type_id = 1,
1509     .value_type_id = 1,
1510     .max_entries = 4,
1511     .btf_load_err = true,
1512     .err_str = "No type found",
1513 },
1514 
1515 {
1516     .descr = "btf_header test. Longer hdr_len",
1517     .raw_types = {
1518         /* int */               /* [1] */
1519         BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),
1520         BTF_END_RAW,
1521     },
1522     .str_sec = "\0int",
1523     .str_sec_size = sizeof("\0int"),
1524     .map_type = BPF_MAP_TYPE_ARRAY,
1525     .map_name = "hdr_test_map",
1526     .key_size = sizeof(int),
1527     .value_size = sizeof(int),
1528     .key_type_id = 1,
1529     .value_type_id = 1,
1530     .max_entries = 4,
1531     .btf_load_err = true,
1532     .hdr_len_delta = 4,
1533     .err_str = "Unsupported btf_header",
1534 },
1535 
1536 {
1537     .descr = "btf_header test. Gap between hdr and type",
1538     .raw_types = {
1539         /* int */               /* [1] */
1540         BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),
1541         BTF_END_RAW,
1542     },
1543     .str_sec = "\0int",
1544     .str_sec_size = sizeof("\0int"),
1545     .map_type = BPF_MAP_TYPE_ARRAY,
1546     .map_name = "hdr_test_map",
1547     .key_size = sizeof(int),
1548     .value_size = sizeof(int),
1549     .key_type_id = 1,
1550     .value_type_id = 1,
1551     .max_entries = 4,
1552     .btf_load_err = true,
1553     .type_off_delta = 4,
1554     .err_str = "Unsupported section found",
1555 },
1556 
1557 {
1558     .descr = "btf_header test. Gap between type and str",
1559     .raw_types = {
1560         /* int */               /* [1] */
1561         BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),
1562         BTF_END_RAW,
1563     },
1564     .str_sec = "\0int",
1565     .str_sec_size = sizeof("\0int"),
1566     .map_type = BPF_MAP_TYPE_ARRAY,
1567     .map_name = "hdr_test_map",
1568     .key_size = sizeof(int),
1569     .value_size = sizeof(int),
1570     .key_type_id = 1,
1571     .value_type_id = 1,
1572     .max_entries = 4,
1573     .btf_load_err = true,
1574     .str_off_delta = 4,
1575     .err_str = "Unsupported section found",
1576 },
1577 
1578 {
1579     .descr = "btf_header test. Overlap between type and str",
1580     .raw_types = {
1581         /* int */               /* [1] */
1582         BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),
1583         BTF_END_RAW,
1584     },
1585     .str_sec = "\0int",
1586     .str_sec_size = sizeof("\0int"),
1587     .map_type = BPF_MAP_TYPE_ARRAY,
1588     .map_name = "hdr_test_map",
1589     .key_size = sizeof(int),
1590     .value_size = sizeof(int),
1591     .key_type_id = 1,
1592     .value_type_id = 1,
1593     .max_entries = 4,
1594     .btf_load_err = true,
1595     .str_off_delta = -4,
1596     .err_str = "Section overlap found",
1597 },
1598 
1599 {
1600     .descr = "btf_header test. Larger BTF size",
1601     .raw_types = {
1602         /* int */               /* [1] */
1603         BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),
1604         BTF_END_RAW,
1605     },
1606     .str_sec = "\0int",
1607     .str_sec_size = sizeof("\0int"),
1608     .map_type = BPF_MAP_TYPE_ARRAY,
1609     .map_name = "hdr_test_map",
1610     .key_size = sizeof(int),
1611     .value_size = sizeof(int),
1612     .key_type_id = 1,
1613     .value_type_id = 1,
1614     .max_entries = 4,
1615     .btf_load_err = true,
1616     .str_len_delta = -4,
1617     .err_str = "Unsupported section found",
1618 },
1619 
1620 {
1621     .descr = "btf_header test. Smaller BTF size",
1622     .raw_types = {
1623         /* int */               /* [1] */
1624         BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),
1625         BTF_END_RAW,
1626     },
1627     .str_sec = "\0int",
1628     .str_sec_size = sizeof("\0int"),
1629     .map_type = BPF_MAP_TYPE_ARRAY,
1630     .map_name = "hdr_test_map",
1631     .key_size = sizeof(int),
1632     .value_size = sizeof(int),
1633     .key_type_id = 1,
1634     .value_type_id = 1,
1635     .max_entries = 4,
1636     .btf_load_err = true,
1637     .str_len_delta = 4,
1638     .err_str = "Total section length too long",
1639 },
1640 
1641 {
1642     .descr = "array test. index_type/elem_type \"int\"",
1643     .raw_types = {
1644         /* int */               /* [1] */
1645         BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
1646         /* int[16] */               /* [2] */
1647         BTF_TYPE_ARRAY_ENC(1, 1, 16),
1648         BTF_END_RAW,
1649     },
1650     .str_sec = "",
1651     .str_sec_size = sizeof(""),
1652     .map_type = BPF_MAP_TYPE_ARRAY,
1653     .map_name = "array_test_map",
1654     .key_size = sizeof(int),
1655     .value_size = sizeof(int),
1656     .key_type_id = 1,
1657     .value_type_id = 1,
1658     .max_entries = 4,
1659 },
1660 
1661 {
1662     .descr = "array test. index_type/elem_type \"const int\"",
1663     .raw_types = {
1664         /* int */               /* [1] */
1665         BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
1666         /* int[16] */               /* [2] */
1667         BTF_TYPE_ARRAY_ENC(3, 3, 16),
1668         /* CONST type_id=1 */           /* [3] */
1669         BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_CONST, 0, 0), 1),
1670         BTF_END_RAW,
1671     },
1672     .str_sec = "",
1673     .str_sec_size = sizeof(""),
1674     .map_type = BPF_MAP_TYPE_ARRAY,
1675     .map_name = "array_test_map",
1676     .key_size = sizeof(int),
1677     .value_size = sizeof(int),
1678     .key_type_id = 1,
1679     .value_type_id = 1,
1680     .max_entries = 4,
1681 },
1682 
1683 {
1684     .descr = "array test. index_type \"const int:31\"",
1685     .raw_types = {
1686         /* int */               /* [1] */
1687         BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
1688         /* int:31 */                /* [2] */
1689         BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 31, 4),
1690         /* int[16] */               /* [3] */
1691         BTF_TYPE_ARRAY_ENC(1, 4, 16),
1692         /* CONST type_id=2 */           /* [4] */
1693         BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_CONST, 0, 0), 2),
1694         BTF_END_RAW,
1695     },
1696     .str_sec = "",
1697     .str_sec_size = sizeof(""),
1698     .map_type = BPF_MAP_TYPE_ARRAY,
1699     .map_name = "array_test_map",
1700     .key_size = sizeof(int),
1701     .value_size = sizeof(int),
1702     .key_type_id = 1,
1703     .value_type_id = 1,
1704     .max_entries = 4,
1705     .btf_load_err = true,
1706     .err_str = "Invalid index",
1707 },
1708 
1709 {
1710     .descr = "array test. elem_type \"const int:31\"",
1711     .raw_types = {
1712         /* int */               /* [1] */
1713         BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
1714         /* int:31 */                /* [2] */
1715         BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 31, 4),
1716         /* int[16] */               /* [3] */
1717         BTF_TYPE_ARRAY_ENC(4, 1, 16),
1718         /* CONST type_id=2 */           /* [4] */
1719         BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_CONST, 0, 0), 2),
1720         BTF_END_RAW,
1721     },
1722     .str_sec = "",
1723     .str_sec_size = sizeof(""),
1724     .map_type = BPF_MAP_TYPE_ARRAY,
1725     .map_name = "array_test_map",
1726     .key_size = sizeof(int),
1727     .value_size = sizeof(int),
1728     .key_type_id = 1,
1729     .value_type_id = 1,
1730     .max_entries = 4,
1731     .btf_load_err = true,
1732     .err_str = "Invalid array of int",
1733 },
1734 
1735 {
1736     .descr = "array test. index_type \"void\"",
1737     .raw_types = {
1738         /* int */               /* [1] */
1739         BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
1740         /* int[16] */               /* [2] */
1741         BTF_TYPE_ARRAY_ENC(1, 0, 16),
1742         BTF_END_RAW,
1743     },
1744     .str_sec = "",
1745     .str_sec_size = sizeof(""),
1746     .map_type = BPF_MAP_TYPE_ARRAY,
1747     .map_name = "array_test_map",
1748     .key_size = sizeof(int),
1749     .value_size = sizeof(int),
1750     .key_type_id = 1,
1751     .value_type_id = 1,
1752     .max_entries = 4,
1753     .btf_load_err = true,
1754     .err_str = "Invalid index",
1755 },
1756 
1757 {
1758     .descr = "array test. index_type \"const void\"",
1759     .raw_types = {
1760         /* int */               /* [1] */
1761         BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
1762         /* int[16] */               /* [2] */
1763         BTF_TYPE_ARRAY_ENC(1, 3, 16),
1764         /* CONST type_id=0 (void) */        /* [3] */
1765         BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_CONST, 0, 0), 0),
1766         BTF_END_RAW,
1767     },
1768     .str_sec = "",
1769     .str_sec_size = sizeof(""),
1770     .map_type = BPF_MAP_TYPE_ARRAY,
1771     .map_name = "array_test_map",
1772     .key_size = sizeof(int),
1773     .value_size = sizeof(int),
1774     .key_type_id = 1,
1775     .value_type_id = 1,
1776     .max_entries = 4,
1777     .btf_load_err = true,
1778     .err_str = "Invalid index",
1779 },
1780 
1781 {
1782     .descr = "array test. elem_type \"const void\"",
1783     .raw_types = {
1784         /* int */               /* [1] */
1785         BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
1786         /* int[16] */               /* [2] */
1787         BTF_TYPE_ARRAY_ENC(3, 1, 16),
1788         /* CONST type_id=0 (void) */        /* [3] */
1789         BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_CONST, 0, 0), 0),
1790         BTF_END_RAW,
1791     },
1792     .str_sec = "",
1793     .str_sec_size = sizeof(""),
1794     .map_type = BPF_MAP_TYPE_ARRAY,
1795     .map_name = "array_test_map",
1796     .key_size = sizeof(int),
1797     .value_size = sizeof(int),
1798     .key_type_id = 1,
1799     .value_type_id = 1,
1800     .max_entries = 4,
1801     .btf_load_err = true,
1802     .err_str = "Invalid elem",
1803 },
1804 
1805 {
1806     .descr = "array test. elem_type \"const void *\"",
1807     .raw_types = {
1808         /* int */               /* [1] */
1809         BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
1810         /* const void *[16] */          /* [2] */
1811         BTF_TYPE_ARRAY_ENC(3, 1, 16),
1812         /* CONST type_id=4 */           /* [3] */
1813         BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_CONST, 0, 0), 4),
1814         /* void* */             /* [4] */
1815         BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_PTR, 0, 0), 0),
1816         BTF_END_RAW,
1817     },
1818     .str_sec = "",
1819     .str_sec_size = sizeof(""),
1820     .map_type = BPF_MAP_TYPE_ARRAY,
1821     .map_name = "array_test_map",
1822     .key_size = sizeof(int),
1823     .value_size = sizeof(int),
1824     .key_type_id = 1,
1825     .value_type_id = 1,
1826     .max_entries = 4,
1827 },
1828 
1829 {
1830     .descr = "array test. index_type \"const void *\"",
1831     .raw_types = {
1832         /* int */               /* [1] */
1833         BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
1834         /* const void *[16] */          /* [2] */
1835         BTF_TYPE_ARRAY_ENC(3, 3, 16),
1836         /* CONST type_id=4 */           /* [3] */
1837         BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_CONST, 0, 0), 4),
1838         /* void* */             /* [4] */
1839         BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_PTR, 0, 0), 0),
1840         BTF_END_RAW,
1841     },
1842     .str_sec = "",
1843     .str_sec_size = sizeof(""),
1844     .map_type = BPF_MAP_TYPE_ARRAY,
1845     .map_name = "array_test_map",
1846     .key_size = sizeof(int),
1847     .value_size = sizeof(int),
1848     .key_type_id = 1,
1849     .value_type_id = 1,
1850     .max_entries = 4,
1851     .btf_load_err = true,
1852     .err_str = "Invalid index",
1853 },
1854 
1855 {
1856     .descr = "array test. t->size != 0\"",
1857     .raw_types = {
1858         /* int */               /* [1] */
1859         BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
1860         /* int[16] */               /* [2] */
1861         BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_ARRAY, 0, 0), 1),
1862         BTF_ARRAY_ENC(1, 1, 16),
1863         BTF_END_RAW,
1864     },
1865     .str_sec = "",
1866     .str_sec_size = sizeof(""),
1867     .map_type = BPF_MAP_TYPE_ARRAY,
1868     .map_name = "array_test_map",
1869     .key_size = sizeof(int),
1870     .value_size = sizeof(int),
1871     .key_type_id = 1,
1872     .value_type_id = 1,
1873     .max_entries = 4,
1874     .btf_load_err = true,
1875     .err_str = "size != 0",
1876 },
1877 
1878 {
1879     .descr = "int test. invalid int_data",
1880     .raw_types = {
1881         BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_INT, 0, 0), 4),
1882         0x10000000,
1883         BTF_END_RAW,
1884     },
1885     .str_sec = "",
1886     .str_sec_size = sizeof(""),
1887     .map_type = BPF_MAP_TYPE_ARRAY,
1888     .map_name = "array_test_map",
1889     .key_size = sizeof(int),
1890     .value_size = sizeof(int),
1891     .key_type_id = 1,
1892     .value_type_id = 1,
1893     .max_entries = 4,
1894     .btf_load_err = true,
1895     .err_str = "Invalid int_data",
1896 },
1897 
1898 {
1899     .descr = "invalid BTF_INFO",
1900     .raw_types = {
1901         /* int */               /* [1] */
1902         BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
1903         BTF_TYPE_ENC(0, 0x20000000, 4),
1904         BTF_END_RAW,
1905     },
1906     .str_sec = "",
1907     .str_sec_size = sizeof(""),
1908     .map_type = BPF_MAP_TYPE_ARRAY,
1909     .map_name = "array_test_map",
1910     .key_size = sizeof(int),
1911     .value_size = sizeof(int),
1912     .key_type_id = 1,
1913     .value_type_id = 1,
1914     .max_entries = 4,
1915     .btf_load_err = true,
1916     .err_str = "Invalid btf_info",
1917 },
1918 
1919 {
1920     .descr = "fwd test. t->type != 0\"",
1921     .raw_types = {
1922         /* int */               /* [1] */
1923         BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
1924         /* fwd type */              /* [2] */
1925         BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_FWD, 0, 0), 1),
1926         BTF_END_RAW,
1927     },
1928     .str_sec = "",
1929     .str_sec_size = sizeof(""),
1930     .map_type = BPF_MAP_TYPE_ARRAY,
1931     .map_name = "fwd_test_map",
1932     .key_size = sizeof(int),
1933     .value_size = sizeof(int),
1934     .key_type_id = 1,
1935     .value_type_id = 1,
1936     .max_entries = 4,
1937     .btf_load_err = true,
1938     .err_str = "type != 0",
1939 },
1940 
1941 {
1942     .descr = "typedef (invalid name, name_off = 0)",
1943     .raw_types = {
1944         BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),  /* [1] */
1945         BTF_TYPEDEF_ENC(0, 1),              /* [2] */
1946         BTF_END_RAW,
1947     },
1948     .str_sec = "\0__int",
1949     .str_sec_size = sizeof("\0__int"),
1950     .map_type = BPF_MAP_TYPE_ARRAY,
1951     .map_name = "typedef_check_btf",
1952     .key_size = sizeof(int),
1953     .value_size = sizeof(int),
1954     .key_type_id = 1,
1955     .value_type_id = 1,
1956     .max_entries = 4,
1957     .btf_load_err = true,
1958     .err_str = "Invalid name",
1959 },
1960 
1961 {
1962     .descr = "typedef (invalid name, invalid identifier)",
1963     .raw_types = {
1964         BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),  /* [1] */
1965         BTF_TYPEDEF_ENC(NAME_TBD, 1),           /* [2] */
1966         BTF_END_RAW,
1967     },
1968     .str_sec = "\0__!int",
1969     .str_sec_size = sizeof("\0__!int"),
1970     .map_type = BPF_MAP_TYPE_ARRAY,
1971     .map_name = "typedef_check_btf",
1972     .key_size = sizeof(int),
1973     .value_size = sizeof(int),
1974     .key_type_id = 1,
1975     .value_type_id = 1,
1976     .max_entries = 4,
1977     .btf_load_err = true,
1978     .err_str = "Invalid name",
1979 },
1980 
1981 {
1982     .descr = "ptr type (invalid name, name_off <> 0)",
1983     .raw_types = {
1984         BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),      /* [1] */
1985         BTF_TYPE_ENC(NAME_TBD,
1986                  BTF_INFO_ENC(BTF_KIND_PTR, 0, 0), 1),  /* [2] */
1987         BTF_END_RAW,
1988     },
1989     .str_sec = "\0__int",
1990     .str_sec_size = sizeof("\0__int"),
1991     .map_type = BPF_MAP_TYPE_ARRAY,
1992     .map_name = "ptr_type_check_btf",
1993     .key_size = sizeof(int),
1994     .value_size = sizeof(int),
1995     .key_type_id = 1,
1996     .value_type_id = 1,
1997     .max_entries = 4,
1998     .btf_load_err = true,
1999     .err_str = "Invalid name",
2000 },
2001 
2002 {
2003     .descr = "volatile type (invalid name, name_off <> 0)",
2004     .raw_types = {
2005         BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),      /* [1] */
2006         BTF_TYPE_ENC(NAME_TBD,
2007                  BTF_INFO_ENC(BTF_KIND_VOLATILE, 0, 0), 1), /* [2] */
2008         BTF_END_RAW,
2009     },
2010     .str_sec = "\0__int",
2011     .str_sec_size = sizeof("\0__int"),
2012     .map_type = BPF_MAP_TYPE_ARRAY,
2013     .map_name = "volatile_type_check_btf",
2014     .key_size = sizeof(int),
2015     .value_size = sizeof(int),
2016     .key_type_id = 1,
2017     .value_type_id = 1,
2018     .max_entries = 4,
2019     .btf_load_err = true,
2020     .err_str = "Invalid name",
2021 },
2022 
2023 {
2024     .descr = "const type (invalid name, name_off <> 0)",
2025     .raw_types = {
2026         BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),      /* [1] */
2027         BTF_TYPE_ENC(NAME_TBD,
2028                  BTF_INFO_ENC(BTF_KIND_CONST, 0, 0), 1),    /* [2] */
2029         BTF_END_RAW,
2030     },
2031     .str_sec = "\0__int",
2032     .str_sec_size = sizeof("\0__int"),
2033     .map_type = BPF_MAP_TYPE_ARRAY,
2034     .map_name = "const_type_check_btf",
2035     .key_size = sizeof(int),
2036     .value_size = sizeof(int),
2037     .key_type_id = 1,
2038     .value_type_id = 1,
2039     .max_entries = 4,
2040     .btf_load_err = true,
2041     .err_str = "Invalid name",
2042 },
2043 
2044 {
2045     .descr = "restrict type (invalid name, name_off <> 0)",
2046     .raw_types = {
2047         BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),      /* [1] */
2048         BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_PTR, 0, 0), 1),   /* [2] */
2049         BTF_TYPE_ENC(NAME_TBD,
2050                  BTF_INFO_ENC(BTF_KIND_RESTRICT, 0, 0), 2), /* [3] */
2051         BTF_END_RAW,
2052     },
2053     .str_sec = "\0__int",
2054     .str_sec_size = sizeof("\0__int"),
2055     .map_type = BPF_MAP_TYPE_ARRAY,
2056     .map_name = "restrict_type_check_btf",
2057     .key_size = sizeof(int),
2058     .value_size = sizeof(int),
2059     .key_type_id = 1,
2060     .value_type_id = 1,
2061     .max_entries = 4,
2062     .btf_load_err = true,
2063     .err_str = "Invalid name",
2064 },
2065 
2066 {
2067     .descr = "fwd type (invalid name, name_off = 0)",
2068     .raw_types = {
2069         BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),      /* [1] */
2070         BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_FWD, 0, 0), 0),   /* [2] */
2071         BTF_END_RAW,
2072     },
2073     .str_sec = "\0__skb",
2074     .str_sec_size = sizeof("\0__skb"),
2075     .map_type = BPF_MAP_TYPE_ARRAY,
2076     .map_name = "fwd_type_check_btf",
2077     .key_size = sizeof(int),
2078     .value_size = sizeof(int),
2079     .key_type_id = 1,
2080     .value_type_id = 1,
2081     .max_entries = 4,
2082     .btf_load_err = true,
2083     .err_str = "Invalid name",
2084 },
2085 
2086 {
2087     .descr = "fwd type (invalid name, invalid identifier)",
2088     .raw_types = {
2089         BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),      /* [1] */
2090         BTF_TYPE_ENC(NAME_TBD,
2091                  BTF_INFO_ENC(BTF_KIND_FWD, 0, 0), 0),  /* [2] */
2092         BTF_END_RAW,
2093     },
2094     .str_sec = "\0__!skb",
2095     .str_sec_size = sizeof("\0__!skb"),
2096     .map_type = BPF_MAP_TYPE_ARRAY,
2097     .map_name = "fwd_type_check_btf",
2098     .key_size = sizeof(int),
2099     .value_size = sizeof(int),
2100     .key_type_id = 1,
2101     .value_type_id = 1,
2102     .max_entries = 4,
2103     .btf_load_err = true,
2104     .err_str = "Invalid name",
2105 },
2106 
2107 {
2108     .descr = "array type (invalid name, name_off <> 0)",
2109     .raw_types = {
2110         BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),      /* [1] */
2111         BTF_TYPE_ENC(NAME_TBD,
2112                  BTF_INFO_ENC(BTF_KIND_ARRAY, 0, 0), 0),    /* [2] */
2113         BTF_ARRAY_ENC(1, 1, 4),
2114         BTF_END_RAW,
2115     },
2116     .str_sec = "\0__skb",
2117     .str_sec_size = sizeof("\0__skb"),
2118     .map_type = BPF_MAP_TYPE_ARRAY,
2119     .map_name = "array_type_check_btf",
2120     .key_size = sizeof(int),
2121     .value_size = sizeof(int),
2122     .key_type_id = 1,
2123     .value_type_id = 1,
2124     .max_entries = 4,
2125     .btf_load_err = true,
2126     .err_str = "Invalid name",
2127 },
2128 
2129 {
2130     .descr = "struct type (name_off = 0)",
2131     .raw_types = {
2132         BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),      /* [1] */
2133         BTF_TYPE_ENC(0,
2134                  BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 1), 4),   /* [2] */
2135         BTF_MEMBER_ENC(NAME_TBD, 1, 0),
2136         BTF_END_RAW,
2137     },
2138     .str_sec = "\0A",
2139     .str_sec_size = sizeof("\0A"),
2140     .map_type = BPF_MAP_TYPE_ARRAY,
2141     .map_name = "struct_type_check_btf",
2142     .key_size = sizeof(int),
2143     .value_size = sizeof(int),
2144     .key_type_id = 1,
2145     .value_type_id = 1,
2146     .max_entries = 4,
2147 },
2148 
2149 {
2150     .descr = "struct type (invalid name, invalid identifier)",
2151     .raw_types = {
2152         BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),      /* [1] */
2153         BTF_TYPE_ENC(NAME_TBD,
2154                  BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 1), 4),   /* [2] */
2155         BTF_MEMBER_ENC(NAME_TBD, 1, 0),
2156         BTF_END_RAW,
2157     },
2158     .str_sec = "\0A!\0B",
2159     .str_sec_size = sizeof("\0A!\0B"),
2160     .map_type = BPF_MAP_TYPE_ARRAY,
2161     .map_name = "struct_type_check_btf",
2162     .key_size = sizeof(int),
2163     .value_size = sizeof(int),
2164     .key_type_id = 1,
2165     .value_type_id = 1,
2166     .max_entries = 4,
2167     .btf_load_err = true,
2168     .err_str = "Invalid name",
2169 },
2170 
2171 {
2172     .descr = "struct member (name_off = 0)",
2173     .raw_types = {
2174         BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),      /* [1] */
2175         BTF_TYPE_ENC(0,
2176                  BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 1), 4),   /* [2] */
2177         BTF_MEMBER_ENC(NAME_TBD, 1, 0),
2178         BTF_END_RAW,
2179     },
2180     .str_sec = "\0A",
2181     .str_sec_size = sizeof("\0A"),
2182     .map_type = BPF_MAP_TYPE_ARRAY,
2183     .map_name = "struct_type_check_btf",
2184     .key_size = sizeof(int),
2185     .value_size = sizeof(int),
2186     .key_type_id = 1,
2187     .value_type_id = 1,
2188     .max_entries = 4,
2189 },
2190 
2191 {
2192     .descr = "struct member (invalid name, invalid identifier)",
2193     .raw_types = {
2194         BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),      /* [1] */
2195         BTF_TYPE_ENC(NAME_TBD,
2196                  BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 1), 4),   /* [2] */
2197         BTF_MEMBER_ENC(NAME_TBD, 1, 0),
2198         BTF_END_RAW,
2199     },
2200     .str_sec = "\0A\0B*",
2201     .str_sec_size = sizeof("\0A\0B*"),
2202     .map_type = BPF_MAP_TYPE_ARRAY,
2203     .map_name = "struct_type_check_btf",
2204     .key_size = sizeof(int),
2205     .value_size = sizeof(int),
2206     .key_type_id = 1,
2207     .value_type_id = 1,
2208     .max_entries = 4,
2209     .btf_load_err = true,
2210     .err_str = "Invalid name",
2211 },
2212 
2213 {
2214     .descr = "enum type (name_off = 0)",
2215     .raw_types = {
2216         BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),      /* [1] */
2217         BTF_TYPE_ENC(0,
2218                  BTF_INFO_ENC(BTF_KIND_ENUM, 0, 1),
2219                  sizeof(int)),              /* [2] */
2220         BTF_ENUM_ENC(NAME_TBD, 0),
2221         BTF_END_RAW,
2222     },
2223     .str_sec = "\0A\0B",
2224     .str_sec_size = sizeof("\0A\0B"),
2225     .map_type = BPF_MAP_TYPE_ARRAY,
2226     .map_name = "enum_type_check_btf",
2227     .key_size = sizeof(int),
2228     .value_size = sizeof(int),
2229     .key_type_id = 1,
2230     .value_type_id = 1,
2231     .max_entries = 4,
2232 },
2233 
2234 {
2235     .descr = "enum type (invalid name, invalid identifier)",
2236     .raw_types = {
2237         BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),      /* [1] */
2238         BTF_TYPE_ENC(NAME_TBD,
2239                  BTF_INFO_ENC(BTF_KIND_ENUM, 0, 1),
2240                  sizeof(int)),              /* [2] */
2241         BTF_ENUM_ENC(NAME_TBD, 0),
2242         BTF_END_RAW,
2243     },
2244     .str_sec = "\0A!\0B",
2245     .str_sec_size = sizeof("\0A!\0B"),
2246     .map_type = BPF_MAP_TYPE_ARRAY,
2247     .map_name = "enum_type_check_btf",
2248     .key_size = sizeof(int),
2249     .value_size = sizeof(int),
2250     .key_type_id = 1,
2251     .value_type_id = 1,
2252     .max_entries = 4,
2253     .btf_load_err = true,
2254     .err_str = "Invalid name",
2255 },
2256 
2257 {
2258     .descr = "enum member (invalid name, name_off = 0)",
2259     .raw_types = {
2260         BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),      /* [1] */
2261         BTF_TYPE_ENC(0,
2262                  BTF_INFO_ENC(BTF_KIND_ENUM, 0, 1),
2263                  sizeof(int)),              /* [2] */
2264         BTF_ENUM_ENC(0, 0),
2265         BTF_END_RAW,
2266     },
2267     .str_sec = "",
2268     .str_sec_size = sizeof(""),
2269     .map_type = BPF_MAP_TYPE_ARRAY,
2270     .map_name = "enum_type_check_btf",
2271     .key_size = sizeof(int),
2272     .value_size = sizeof(int),
2273     .key_type_id = 1,
2274     .value_type_id = 1,
2275     .max_entries = 4,
2276     .btf_load_err = true,
2277     .err_str = "Invalid name",
2278 },
2279 
2280 {
2281     .descr = "enum member (invalid name, invalid identifier)",
2282     .raw_types = {
2283         BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),      /* [1] */
2284         BTF_TYPE_ENC(0,
2285                  BTF_INFO_ENC(BTF_KIND_ENUM, 0, 1),
2286                  sizeof(int)),              /* [2] */
2287         BTF_ENUM_ENC(NAME_TBD, 0),
2288         BTF_END_RAW,
2289     },
2290     .str_sec = "\0A!",
2291     .str_sec_size = sizeof("\0A!"),
2292     .map_type = BPF_MAP_TYPE_ARRAY,
2293     .map_name = "enum_type_check_btf",
2294     .key_size = sizeof(int),
2295     .value_size = sizeof(int),
2296     .key_type_id = 1,
2297     .value_type_id = 1,
2298     .max_entries = 4,
2299     .btf_load_err = true,
2300     .err_str = "Invalid name",
2301 },
2302 {
2303     .descr = "arraymap invalid btf key (a bit field)",
2304     .raw_types = {
2305         /* int */               /* [1] */
2306         BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
2307         /* 32 bit int with 32 bit offset */ /* [2] */
2308         BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 32, 32, 8),
2309         BTF_END_RAW,
2310     },
2311     .str_sec = "",
2312     .str_sec_size = sizeof(""),
2313     .map_type = BPF_MAP_TYPE_ARRAY,
2314     .map_name = "array_map_check_btf",
2315     .key_size = sizeof(int),
2316     .value_size = sizeof(int),
2317     .key_type_id = 2,
2318     .value_type_id = 1,
2319     .max_entries = 4,
2320     .map_create_err = true,
2321 },
2322 
2323 {
2324     .descr = "arraymap invalid btf key (!= 32 bits)",
2325     .raw_types = {
2326         /* int */               /* [1] */
2327         BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
2328         /* 16 bit int with 0 bit offset */  /* [2] */
2329         BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 16, 2),
2330         BTF_END_RAW,
2331     },
2332     .str_sec = "",
2333     .str_sec_size = sizeof(""),
2334     .map_type = BPF_MAP_TYPE_ARRAY,
2335     .map_name = "array_map_check_btf",
2336     .key_size = sizeof(int),
2337     .value_size = sizeof(int),
2338     .key_type_id = 2,
2339     .value_type_id = 1,
2340     .max_entries = 4,
2341     .map_create_err = true,
2342 },
2343 
2344 {
2345     .descr = "arraymap invalid btf value (too small)",
2346     .raw_types = {
2347         /* int */               /* [1] */
2348         BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
2349         BTF_END_RAW,
2350     },
2351     .str_sec = "",
2352     .str_sec_size = sizeof(""),
2353     .map_type = BPF_MAP_TYPE_ARRAY,
2354     .map_name = "array_map_check_btf",
2355     .key_size = sizeof(int),
2356     /* btf_value_size < map->value_size */
2357     .value_size = sizeof(__u64),
2358     .key_type_id = 1,
2359     .value_type_id = 1,
2360     .max_entries = 4,
2361     .map_create_err = true,
2362 },
2363 
2364 {
2365     .descr = "arraymap invalid btf value (too big)",
2366     .raw_types = {
2367         /* int */               /* [1] */
2368         BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
2369         BTF_END_RAW,
2370     },
2371     .str_sec = "",
2372     .str_sec_size = sizeof(""),
2373     .map_type = BPF_MAP_TYPE_ARRAY,
2374     .map_name = "array_map_check_btf",
2375     .key_size = sizeof(int),
2376     /* btf_value_size > map->value_size */
2377     .value_size = sizeof(__u16),
2378     .key_type_id = 1,
2379     .value_type_id = 1,
2380     .max_entries = 4,
2381     .map_create_err = true,
2382 },
2383 
2384 {
2385     .descr = "func proto (int (*)(int, unsigned int))",
2386     .raw_types = {
2387         BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
2388         BTF_TYPE_INT_ENC(0, 0, 0, 32, 4),       /* [2] */
2389         /* int (*)(int, unsigned int) */
2390         BTF_FUNC_PROTO_ENC(1, 2),           /* [3] */
2391             BTF_FUNC_PROTO_ARG_ENC(0, 1),
2392             BTF_FUNC_PROTO_ARG_ENC(0, 2),
2393         BTF_END_RAW,
2394     },
2395     .str_sec = "",
2396     .str_sec_size = sizeof(""),
2397     .map_type = BPF_MAP_TYPE_ARRAY,
2398     .map_name = "func_proto_type_check_btf",
2399     .key_size = sizeof(int),
2400     .value_size = sizeof(int),
2401     .key_type_id = 1,
2402     .value_type_id = 1,
2403     .max_entries = 4,
2404 },
2405 
2406 {
2407     .descr = "func proto (vararg)",
2408     .raw_types = {
2409         BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),  /* [1] */
2410         BTF_TYPE_INT_ENC(0, 0, 0, 32, 4),       /* [2] */
2411         /* void (*)(int, unsigned int, ...) */
2412         BTF_FUNC_PROTO_ENC(0, 3),           /* [3] */
2413             BTF_FUNC_PROTO_ARG_ENC(0, 1),
2414             BTF_FUNC_PROTO_ARG_ENC(0, 2),
2415             BTF_FUNC_PROTO_ARG_ENC(0, 0),
2416         BTF_END_RAW,
2417     },
2418     .str_sec = "",
2419     .str_sec_size = sizeof(""),
2420     .map_type = BPF_MAP_TYPE_ARRAY,
2421     .map_name = "func_proto_type_check_btf",
2422     .key_size = sizeof(int),
2423     .value_size = sizeof(int),
2424     .key_type_id = 1,
2425     .value_type_id = 1,
2426     .max_entries = 4,
2427 },
2428 
2429 {
2430     .descr = "func proto (vararg with name)",
2431     .raw_types = {
2432         BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),  /* [1] */
2433         BTF_TYPE_INT_ENC(0, 0, 0, 32, 4),       /* [2] */
2434         /* void (*)(int a, unsigned int b, ... c) */
2435         BTF_FUNC_PROTO_ENC(0, 3),           /* [3] */
2436             BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
2437             BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 2),
2438             BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 0),
2439         BTF_END_RAW,
2440     },
2441     .str_sec = "\0a\0b\0c",
2442     .str_sec_size = sizeof("\0a\0b\0c"),
2443     .map_type = BPF_MAP_TYPE_ARRAY,
2444     .map_name = "func_proto_type_check_btf",
2445     .key_size = sizeof(int),
2446     .value_size = sizeof(int),
2447     .key_type_id = 1,
2448     .value_type_id = 1,
2449     .max_entries = 4,
2450     .btf_load_err = true,
2451     .err_str = "Invalid arg#3",
2452 },
2453 
2454 {
2455     .descr = "func proto (arg after vararg)",
2456     .raw_types = {
2457         BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),  /* [1] */
2458         BTF_TYPE_INT_ENC(0, 0, 0, 32, 4),       /* [2] */
2459         /* void (*)(int a, ..., unsigned int b) */
2460         BTF_FUNC_PROTO_ENC(0, 3),           /* [3] */
2461             BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
2462             BTF_FUNC_PROTO_ARG_ENC(0, 0),
2463             BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 2),
2464         BTF_END_RAW,
2465     },
2466     .str_sec = "\0a\0b",
2467     .str_sec_size = sizeof("\0a\0b"),
2468     .map_type = BPF_MAP_TYPE_ARRAY,
2469     .map_name = "func_proto_type_check_btf",
2470     .key_size = sizeof(int),
2471     .value_size = sizeof(int),
2472     .key_type_id = 1,
2473     .value_type_id = 1,
2474     .max_entries = 4,
2475     .btf_load_err = true,
2476     .err_str = "Invalid arg#2",
2477 },
2478 
2479 {
2480     .descr = "func proto (CONST=>TYPEDEF=>PTR=>FUNC_PROTO)",
2481     .raw_types = {
2482         BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),  /* [1] */
2483         BTF_TYPE_INT_ENC(0, 0, 0, 32, 4),       /* [2] */
2484         /* typedef void (*func_ptr)(int, unsigned int) */
2485         BTF_TYPEDEF_ENC(NAME_TBD, 5),           /* [3] */
2486         /* const func_ptr */
2487         BTF_CONST_ENC(3),               /* [4] */
2488         BTF_PTR_ENC(6),                 /* [5] */
2489         BTF_FUNC_PROTO_ENC(0, 2),           /* [6] */
2490             BTF_FUNC_PROTO_ARG_ENC(0, 1),
2491             BTF_FUNC_PROTO_ARG_ENC(0, 2),
2492         BTF_END_RAW,
2493     },
2494     .str_sec = "\0func_ptr",
2495     .str_sec_size = sizeof("\0func_ptr"),
2496     .map_type = BPF_MAP_TYPE_ARRAY,
2497     .map_name = "func_proto_type_check_btf",
2498     .key_size = sizeof(int),
2499     .value_size = sizeof(int),
2500     .key_type_id = 1,
2501     .value_type_id = 1,
2502     .max_entries = 4,
2503 },
2504 
2505 {
2506     .descr = "func proto (TYPEDEF=>FUNC_PROTO)",
2507     .raw_types = {
2508         BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),  /* [1] */
2509         BTF_TYPE_INT_ENC(0, 0, 0, 32, 4),       /* [2] */
2510         BTF_TYPEDEF_ENC(NAME_TBD, 4),           /* [3] */
2511         BTF_FUNC_PROTO_ENC(0, 2),           /* [4] */
2512             BTF_FUNC_PROTO_ARG_ENC(0, 1),
2513             BTF_FUNC_PROTO_ARG_ENC(0, 2),
2514         BTF_END_RAW,
2515     },
2516     .str_sec = "\0func_typedef",
2517     .str_sec_size = sizeof("\0func_typedef"),
2518     .map_type = BPF_MAP_TYPE_ARRAY,
2519     .map_name = "func_proto_type_check_btf",
2520     .key_size = sizeof(int),
2521     .value_size = sizeof(int),
2522     .key_type_id = 1,
2523     .value_type_id = 1,
2524     .max_entries = 4,
2525 },
2526 
2527 {
2528     .descr = "func proto (btf_resolve(arg))",
2529     .raw_types = {
2530         BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),  /* [1] */
2531         /* void (*)(const void *) */
2532         BTF_FUNC_PROTO_ENC(0, 1),           /* [2] */
2533             BTF_FUNC_PROTO_ARG_ENC(0, 3),
2534         BTF_CONST_ENC(4),               /* [3] */
2535         BTF_PTR_ENC(0),                 /* [4] */
2536         BTF_END_RAW,
2537     },
2538     .str_sec = "",
2539     .str_sec_size = sizeof(""),
2540     .map_type = BPF_MAP_TYPE_ARRAY,
2541     .map_name = "func_proto_type_check_btf",
2542     .key_size = sizeof(int),
2543     .value_size = sizeof(int),
2544     .key_type_id = 1,
2545     .value_type_id = 1,
2546     .max_entries = 4,
2547 },
2548 
2549 {
2550     .descr = "func proto (Not all arg has name)",
2551     .raw_types = {
2552         BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),  /* [1] */
2553         BTF_TYPE_INT_ENC(0, 0, 0, 32, 4),       /* [2] */
2554         /* void (*)(int, unsigned int b) */
2555         BTF_FUNC_PROTO_ENC(0, 2),           /* [3] */
2556             BTF_FUNC_PROTO_ARG_ENC(0, 1),
2557             BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 2),
2558         BTF_END_RAW,
2559     },
2560     .str_sec = "\0b",
2561     .str_sec_size = sizeof("\0b"),
2562     .map_type = BPF_MAP_TYPE_ARRAY,
2563     .map_name = "func_proto_type_check_btf",
2564     .key_size = sizeof(int),
2565     .value_size = sizeof(int),
2566     .key_type_id = 1,
2567     .value_type_id = 1,
2568     .max_entries = 4,
2569 },
2570 
2571 {
2572     .descr = "func proto (Bad arg name_off)",
2573     .raw_types = {
2574         BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),  /* [1] */
2575         BTF_TYPE_INT_ENC(0, 0, 0, 32, 4),       /* [2] */
2576         /* void (*)(int a, unsigned int <bad_name_off>) */
2577         BTF_FUNC_PROTO_ENC(0, 2),           /* [3] */
2578             BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
2579             BTF_FUNC_PROTO_ARG_ENC(0x0fffffff, 2),
2580         BTF_END_RAW,
2581     },
2582     .str_sec = "\0a",
2583     .str_sec_size = sizeof("\0a"),
2584     .map_type = BPF_MAP_TYPE_ARRAY,
2585     .map_name = "func_proto_type_check_btf",
2586     .key_size = sizeof(int),
2587     .value_size = sizeof(int),
2588     .key_type_id = 1,
2589     .value_type_id = 1,
2590     .max_entries = 4,
2591     .btf_load_err = true,
2592     .err_str = "Invalid arg#2",
2593 },
2594 
2595 {
2596     .descr = "func proto (Bad arg name)",
2597     .raw_types = {
2598         BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),  /* [1] */
2599         BTF_TYPE_INT_ENC(0, 0, 0, 32, 4),       /* [2] */
2600         /* void (*)(int a, unsigned int !!!) */
2601         BTF_FUNC_PROTO_ENC(0, 2),           /* [3] */
2602             BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
2603             BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 2),
2604         BTF_END_RAW,
2605     },
2606     .str_sec = "\0a\0!!!",
2607     .str_sec_size = sizeof("\0a\0!!!"),
2608     .map_type = BPF_MAP_TYPE_ARRAY,
2609     .map_name = "func_proto_type_check_btf",
2610     .key_size = sizeof(int),
2611     .value_size = sizeof(int),
2612     .key_type_id = 1,
2613     .value_type_id = 1,
2614     .max_entries = 4,
2615     .btf_load_err = true,
2616     .err_str = "Invalid arg#2",
2617 },
2618 
2619 {
2620     .descr = "func proto (Invalid return type)",
2621     .raw_types = {
2622         BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),  /* [1] */
2623         BTF_TYPE_INT_ENC(0, 0, 0, 32, 4),       /* [2] */
2624         /* <bad_ret_type> (*)(int, unsigned int) */
2625         BTF_FUNC_PROTO_ENC(100, 2),         /* [3] */
2626             BTF_FUNC_PROTO_ARG_ENC(0, 1),
2627             BTF_FUNC_PROTO_ARG_ENC(0, 2),
2628         BTF_END_RAW,
2629     },
2630     .str_sec = "",
2631     .str_sec_size = sizeof(""),
2632     .map_type = BPF_MAP_TYPE_ARRAY,
2633     .map_name = "func_proto_type_check_btf",
2634     .key_size = sizeof(int),
2635     .value_size = sizeof(int),
2636     .key_type_id = 1,
2637     .value_type_id = 1,
2638     .max_entries = 4,
2639     .btf_load_err = true,
2640     .err_str = "Invalid return type",
2641 },
2642 
2643 {
2644     .descr = "func proto (with func name)",
2645     .raw_types = {
2646         BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),  /* [1] */
2647         BTF_TYPE_INT_ENC(0, 0, 0, 32, 4),       /* [2] */
2648         /* void func_proto(int, unsigned int) */
2649         BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_FUNC_PROTO, 0, 2), 0), /* [3] */
2650             BTF_FUNC_PROTO_ARG_ENC(0, 1),
2651             BTF_FUNC_PROTO_ARG_ENC(0, 2),
2652         BTF_END_RAW,
2653     },
2654     .str_sec = "\0func_proto",
2655     .str_sec_size = sizeof("\0func_proto"),
2656     .map_type = BPF_MAP_TYPE_ARRAY,
2657     .map_name = "func_proto_type_check_btf",
2658     .key_size = sizeof(int),
2659     .value_size = sizeof(int),
2660     .key_type_id = 1,
2661     .value_type_id = 1,
2662     .max_entries = 4,
2663     .btf_load_err = true,
2664     .err_str = "Invalid name",
2665 },
2666 
2667 {
2668     .descr = "func proto (const void arg)",
2669     .raw_types = {
2670         BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),  /* [1] */
2671         BTF_TYPE_INT_ENC(0, 0, 0, 32, 4),       /* [2] */
2672         /* void (*)(const void) */
2673         BTF_FUNC_PROTO_ENC(0, 1),           /* [3] */
2674             BTF_FUNC_PROTO_ARG_ENC(0, 4),
2675         BTF_CONST_ENC(0),               /* [4] */
2676         BTF_END_RAW,
2677     },
2678     .str_sec = "",
2679     .str_sec_size = sizeof(""),
2680     .map_type = BPF_MAP_TYPE_ARRAY,
2681     .map_name = "func_proto_type_check_btf",
2682     .key_size = sizeof(int),
2683     .value_size = sizeof(int),
2684     .key_type_id = 1,
2685     .value_type_id = 1,
2686     .max_entries = 4,
2687     .btf_load_err = true,
2688     .err_str = "Invalid arg#1",
2689 },
2690 
2691 {
2692     .descr = "func (void func(int a, unsigned int b))",
2693     .raw_types = {
2694         BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),  /* [1] */
2695         BTF_TYPE_INT_ENC(0, 0, 0, 32, 4),       /* [2] */
2696         /* void (*)(int a, unsigned int b) */
2697         BTF_FUNC_PROTO_ENC(0, 2),           /* [3] */
2698             BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
2699             BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 2),
2700         /* void func(int a, unsigned int b) */
2701         BTF_FUNC_ENC(NAME_TBD, 3),          /* [4] */
2702         BTF_END_RAW,
2703     },
2704     .str_sec = "\0a\0b\0func",
2705     .str_sec_size = sizeof("\0a\0b\0func"),
2706     .map_type = BPF_MAP_TYPE_ARRAY,
2707     .map_name = "func_type_check_btf",
2708     .key_size = sizeof(int),
2709     .value_size = sizeof(int),
2710     .key_type_id = 1,
2711     .value_type_id = 1,
2712     .max_entries = 4,
2713 },
2714 
2715 {
2716     .descr = "func (No func name)",
2717     .raw_types = {
2718         BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),  /* [1] */
2719         BTF_TYPE_INT_ENC(0, 0, 0, 32, 4),       /* [2] */
2720         /* void (*)(int a, unsigned int b) */
2721         BTF_FUNC_PROTO_ENC(0, 2),           /* [3] */
2722             BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
2723             BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 2),
2724         /* void <no_name>(int a, unsigned int b) */
2725         BTF_FUNC_ENC(0, 3),             /* [4] */
2726         BTF_END_RAW,
2727     },
2728     .str_sec = "\0a\0b",
2729     .str_sec_size = sizeof("\0a\0b"),
2730     .map_type = BPF_MAP_TYPE_ARRAY,
2731     .map_name = "func_type_check_btf",
2732     .key_size = sizeof(int),
2733     .value_size = sizeof(int),
2734     .key_type_id = 1,
2735     .value_type_id = 1,
2736     .max_entries = 4,
2737     .btf_load_err = true,
2738     .err_str = "Invalid name",
2739 },
2740 
2741 {
2742     .descr = "func (Invalid func name)",
2743     .raw_types = {
2744         BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),  /* [1] */
2745         BTF_TYPE_INT_ENC(0, 0, 0, 32, 4),       /* [2] */
2746         /* void (*)(int a, unsigned int b) */
2747         BTF_FUNC_PROTO_ENC(0, 2),           /* [3] */
2748             BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
2749             BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 2),
2750         /* void !!!(int a, unsigned int b) */
2751         BTF_FUNC_ENC(NAME_TBD, 3),          /* [4] */
2752         BTF_END_RAW,
2753     },
2754     .str_sec = "\0a\0b\0!!!",
2755     .str_sec_size = sizeof("\0a\0b\0!!!"),
2756     .map_type = BPF_MAP_TYPE_ARRAY,
2757     .map_name = "func_type_check_btf",
2758     .key_size = sizeof(int),
2759     .value_size = sizeof(int),
2760     .key_type_id = 1,
2761     .value_type_id = 1,
2762     .max_entries = 4,
2763     .btf_load_err = true,
2764     .err_str = "Invalid name",
2765 },
2766 
2767 {
2768     .descr = "func (Some arg has no name)",
2769     .raw_types = {
2770         BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),  /* [1] */
2771         BTF_TYPE_INT_ENC(0, 0, 0, 32, 4),       /* [2] */
2772         /* void (*)(int a, unsigned int) */
2773         BTF_FUNC_PROTO_ENC(0, 2),           /* [3] */
2774             BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
2775             BTF_FUNC_PROTO_ARG_ENC(0, 2),
2776         /* void func(int a, unsigned int) */
2777         BTF_FUNC_ENC(NAME_TBD, 3),          /* [4] */
2778         BTF_END_RAW,
2779     },
2780     .str_sec = "\0a\0func",
2781     .str_sec_size = sizeof("\0a\0func"),
2782     .map_type = BPF_MAP_TYPE_ARRAY,
2783     .map_name = "func_type_check_btf",
2784     .key_size = sizeof(int),
2785     .value_size = sizeof(int),
2786     .key_type_id = 1,
2787     .value_type_id = 1,
2788     .max_entries = 4,
2789     .btf_load_err = true,
2790     .err_str = "Invalid arg#2",
2791 },
2792 
2793 {
2794     .descr = "func (Non zero vlen)",
2795     .raw_types = {
2796         BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),  /* [1] */
2797         BTF_TYPE_INT_ENC(0, 0, 0, 32, 4),       /* [2] */
2798         /* void (*)(int a, unsigned int b) */
2799         BTF_FUNC_PROTO_ENC(0, 2),           /* [3] */
2800             BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
2801             BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 2),
2802         /* void func(int a, unsigned int b) */
2803         BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_FUNC, 0, 2), 3),   /* [4] */
2804         BTF_END_RAW,
2805     },
2806     .str_sec = "\0a\0b\0func",
2807     .str_sec_size = sizeof("\0a\0b\0func"),
2808     .map_type = BPF_MAP_TYPE_ARRAY,
2809     .map_name = "func_type_check_btf",
2810     .key_size = sizeof(int),
2811     .value_size = sizeof(int),
2812     .key_type_id = 1,
2813     .value_type_id = 1,
2814     .max_entries = 4,
2815     .btf_load_err = true,
2816     .err_str = "Invalid func linkage",
2817 },
2818 
2819 {
2820     .descr = "func (Not referring to FUNC_PROTO)",
2821     .raw_types = {
2822         BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),  /* [1] */
2823         BTF_FUNC_ENC(NAME_TBD, 1),          /* [2] */
2824         BTF_END_RAW,
2825     },
2826     .str_sec = "\0func",
2827     .str_sec_size = sizeof("\0func"),
2828     .map_type = BPF_MAP_TYPE_ARRAY,
2829     .map_name = "func_type_check_btf",
2830     .key_size = sizeof(int),
2831     .value_size = sizeof(int),
2832     .key_type_id = 1,
2833     .value_type_id = 1,
2834     .max_entries = 4,
2835     .btf_load_err = true,
2836     .err_str = "Invalid type_id",
2837 },
2838 
2839 {
2840     .descr = "invalid int kind_flag",
2841     .raw_types = {
2842         BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),      /* [1] */
2843         BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_INT, 1, 0), 4),   /* [2] */
2844         BTF_INT_ENC(0, 0, 32),
2845         BTF_END_RAW,
2846     },
2847     BTF_STR_SEC(""),
2848     .map_type = BPF_MAP_TYPE_ARRAY,
2849     .map_name = "int_type_check_btf",
2850     .key_size = sizeof(int),
2851     .value_size = sizeof(int),
2852     .key_type_id = 1,
2853     .value_type_id = 1,
2854     .max_entries = 4,
2855     .btf_load_err = true,
2856     .err_str = "Invalid btf_info kind_flag",
2857 },
2858 
2859 {
2860     .descr = "invalid ptr kind_flag",
2861     .raw_types = {
2862         BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),      /* [1] */
2863         BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_PTR, 1, 0), 1),   /* [2] */
2864         BTF_END_RAW,
2865     },
2866     BTF_STR_SEC(""),
2867     .map_type = BPF_MAP_TYPE_ARRAY,
2868     .map_name = "ptr_type_check_btf",
2869     .key_size = sizeof(int),
2870     .value_size = sizeof(int),
2871     .key_type_id = 1,
2872     .value_type_id = 1,
2873     .max_entries = 4,
2874     .btf_load_err = true,
2875     .err_str = "Invalid btf_info kind_flag",
2876 },
2877 
2878 {
2879     .descr = "invalid array kind_flag",
2880     .raw_types = {
2881         BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),      /* [1] */
2882         BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_ARRAY, 1, 0), 0), /* [2] */
2883         BTF_ARRAY_ENC(1, 1, 1),
2884         BTF_END_RAW,
2885     },
2886     BTF_STR_SEC(""),
2887     .map_type = BPF_MAP_TYPE_ARRAY,
2888     .map_name = "array_type_check_btf",
2889     .key_size = sizeof(int),
2890     .value_size = sizeof(int),
2891     .key_type_id = 1,
2892     .value_type_id = 1,
2893     .max_entries = 4,
2894     .btf_load_err = true,
2895     .err_str = "Invalid btf_info kind_flag",
2896 },
2897 
2898 {
2899     .descr = "valid fwd kind_flag",
2900     .raw_types = {
2901         BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),      /* [1] */
2902         BTF_TYPE_ENC(NAME_TBD,
2903                  BTF_INFO_ENC(BTF_KIND_FWD, 1, 0), 0),  /* [2] */
2904         BTF_END_RAW,
2905     },
2906     BTF_STR_SEC("\0A"),
2907     .map_type = BPF_MAP_TYPE_ARRAY,
2908     .map_name = "fwd_type_check_btf",
2909     .key_size = sizeof(int),
2910     .value_size = sizeof(int),
2911     .key_type_id = 1,
2912     .value_type_id = 1,
2913     .max_entries = 4,
2914 },
2915 
2916 {
2917     .descr = "invalid typedef kind_flag",
2918     .raw_types = {
2919         BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),      /* [1] */
2920         BTF_TYPE_ENC(NAME_TBD,
2921                  BTF_INFO_ENC(BTF_KIND_TYPEDEF, 1, 0), 1),  /* [2] */
2922         BTF_END_RAW,
2923     },
2924     BTF_STR_SEC("\0A"),
2925     .map_type = BPF_MAP_TYPE_ARRAY,
2926     .map_name = "typedef_type_check_btf",
2927     .key_size = sizeof(int),
2928     .value_size = sizeof(int),
2929     .key_type_id = 1,
2930     .value_type_id = 1,
2931     .max_entries = 4,
2932     .btf_load_err = true,
2933     .err_str = "Invalid btf_info kind_flag",
2934 },
2935 
2936 {
2937     .descr = "invalid volatile kind_flag",
2938     .raw_types = {
2939         BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),          /* [1] */
2940         BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_VOLATILE, 1, 0), 1),  /* [2] */
2941         BTF_END_RAW,
2942     },
2943     BTF_STR_SEC(""),
2944     .map_type = BPF_MAP_TYPE_ARRAY,
2945     .map_name = "volatile_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 const 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_CONST, 1, 0), 1), /* [2] */
2960         BTF_END_RAW,
2961     },
2962     BTF_STR_SEC(""),
2963     .map_type = BPF_MAP_TYPE_ARRAY,
2964     .map_name = "const_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 restrict 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_RESTRICT, 1, 0), 1),  /* [2] */
2979         BTF_END_RAW,
2980     },
2981     BTF_STR_SEC(""),
2982     .map_type = BPF_MAP_TYPE_ARRAY,
2983     .map_name = "restrict_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 func 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_FUNC_PROTO, 0, 0), 0),    /* [2] */
2998         BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_FUNC, 1, 0), 2),   /* [3] */
2999         BTF_END_RAW,
3000     },
3001     BTF_STR_SEC("\0A"),
3002     .map_type = BPF_MAP_TYPE_ARRAY,
3003     .map_name = "func_type_check_btf",
3004     .key_size = sizeof(int),
3005     .value_size = sizeof(int),
3006     .key_type_id = 1,
3007     .value_type_id = 1,
3008     .max_entries = 4,
3009     .btf_load_err = true,
3010     .err_str = "Invalid btf_info kind_flag",
3011 },
3012 
3013 {
3014     .descr = "invalid func_proto kind_flag",
3015     .raw_types = {
3016         BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),          /* [1] */
3017         BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_FUNC_PROTO, 1, 0), 0),    /* [2] */
3018         BTF_END_RAW,
3019     },
3020     BTF_STR_SEC(""),
3021     .map_type = BPF_MAP_TYPE_ARRAY,
3022     .map_name = "func_proto_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 = "valid struct, kind_flag, bitfield_size = 0",
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_STRUCT, 1, 2), 8),    /* [2] */
3037         BTF_MEMBER_ENC(NAME_TBD, 1, BTF_MEMBER_OFFSET(0, 0)),
3038         BTF_MEMBER_ENC(NAME_TBD, 1, BTF_MEMBER_OFFSET(0, 32)),
3039         BTF_END_RAW,
3040     },
3041     BTF_STR_SEC("\0A\0B"),
3042     .map_type = BPF_MAP_TYPE_ARRAY,
3043     .map_name = "struct_type_check_btf",
3044     .key_size = sizeof(int),
3045     .value_size = sizeof(int),
3046     .key_type_id = 1,
3047     .value_type_id = 1,
3048     .max_entries = 4,
3049 },
3050 
3051 {
3052     .descr = "valid struct, kind_flag, int member, 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), 4),    /* [2] */
3056         BTF_MEMBER_ENC(NAME_TBD, 1, BTF_MEMBER_OFFSET(4, 0)),
3057         BTF_MEMBER_ENC(NAME_TBD, 1, BTF_MEMBER_OFFSET(4, 4)),
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 union, 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_UNION, 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, 0)),
3077         BTF_END_RAW,
3078     },
3079     BTF_STR_SEC("\0A\0B"),
3080     .map_type = BPF_MAP_TYPE_ARRAY,
3081     .map_name = "union_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 struct, kind_flag, enum 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_ENUM, 0, 1), 4),  /* [2] */
3094         BTF_ENUM_ENC(NAME_TBD, 0),
3095         BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_STRUCT, 1, 2), 4),/* [3] */
3096         BTF_MEMBER_ENC(NAME_TBD, 2, BTF_MEMBER_OFFSET(4, 0)),
3097         BTF_MEMBER_ENC(NAME_TBD, 2, BTF_MEMBER_OFFSET(4, 4)),
3098         BTF_END_RAW,
3099     },
3100     BTF_STR_SEC("\0A\0B\0C"),
3101     .map_type = BPF_MAP_TYPE_ARRAY,
3102     .map_name = "struct_type_check_btf",
3103     .key_size = sizeof(int),
3104     .value_size = sizeof(int),
3105     .key_type_id = 1,
3106     .value_type_id = 1,
3107     .max_entries = 4,
3108 },
3109 
3110 {
3111     .descr = "valid union, kind_flag, enum member, bitfield_size != 0",
3112     .raw_types = {
3113         BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),      /* [1] */
3114         BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_ENUM, 0, 1), 4),  /* [2] */
3115         BTF_ENUM_ENC(NAME_TBD, 0),
3116         BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_UNION, 1, 2), 4), /* [3] */
3117         BTF_MEMBER_ENC(NAME_TBD, 2, BTF_MEMBER_OFFSET(4, 0)),
3118         BTF_MEMBER_ENC(NAME_TBD, 2, BTF_MEMBER_OFFSET(4, 0)),
3119         BTF_END_RAW,
3120     },
3121     BTF_STR_SEC("\0A\0B\0C"),
3122     .map_type = BPF_MAP_TYPE_ARRAY,
3123     .map_name = "union_type_check_btf",
3124     .key_size = sizeof(int),
3125     .value_size = sizeof(int),
3126     .key_type_id = 1,
3127     .value_type_id = 1,
3128     .max_entries = 4,
3129 },
3130 
3131 {
3132     .descr = "valid struct, kind_flag, typedef member, bitfield_size != 0",
3133     .raw_types = {
3134         BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),      /* [1] */
3135         BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_ENUM, 0, 1), 4),  /* [2] */
3136         BTF_ENUM_ENC(NAME_TBD, 0),
3137         BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_STRUCT, 1, 2), 4),/* [3] */
3138         BTF_MEMBER_ENC(NAME_TBD, 4, BTF_MEMBER_OFFSET(4, 0)),
3139         BTF_MEMBER_ENC(NAME_TBD, 5, BTF_MEMBER_OFFSET(4, 4)),
3140         BTF_TYPEDEF_ENC(NAME_TBD, 1),               /* [4] */
3141         BTF_TYPEDEF_ENC(NAME_TBD, 2),               /* [5] */
3142         BTF_END_RAW,
3143     },
3144     BTF_STR_SEC("\0A\0B\0C\0D\0E"),
3145     .map_type = BPF_MAP_TYPE_ARRAY,
3146     .map_name = "struct_type_check_btf",
3147     .key_size = sizeof(int),
3148     .value_size = sizeof(int),
3149     .key_type_id = 1,
3150     .value_type_id = 1,
3151     .max_entries = 4,
3152 },
3153 
3154 {
3155     .descr = "valid union, kind_flag, typedef member, bitfield_size != 0",
3156     .raw_types = {
3157         BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),      /* [1] */
3158         BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_ENUM, 0, 1), 4),  /* [2] */
3159         BTF_ENUM_ENC(NAME_TBD, 0),
3160         BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_UNION, 1, 2), 4), /* [3] */
3161         BTF_MEMBER_ENC(NAME_TBD, 4, BTF_MEMBER_OFFSET(4, 0)),
3162         BTF_MEMBER_ENC(NAME_TBD, 5, BTF_MEMBER_OFFSET(4, 0)),
3163         BTF_TYPEDEF_ENC(NAME_TBD, 1),               /* [4] */
3164         BTF_TYPEDEF_ENC(NAME_TBD, 2),               /* [5] */
3165         BTF_END_RAW,
3166     },
3167     BTF_STR_SEC("\0A\0B\0C\0D\0E"),
3168     .map_type = BPF_MAP_TYPE_ARRAY,
3169     .map_name = "union_type_check_btf",
3170     .key_size = sizeof(int),
3171     .value_size = sizeof(int),
3172     .key_type_id = 1,
3173     .value_type_id = 1,
3174     .max_entries = 4,
3175 },
3176 
3177 {
3178     .descr = "invalid struct, kind_flag, bitfield_size greater than struct size",
3179     .raw_types = {
3180         BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),          /* [1] */
3181         BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_STRUCT, 1, 2), 4),    /* [2] */
3182         BTF_MEMBER_ENC(NAME_TBD, 1, BTF_MEMBER_OFFSET(20, 0)),
3183         BTF_MEMBER_ENC(NAME_TBD, 1, BTF_MEMBER_OFFSET(20, 20)),
3184         BTF_END_RAW,
3185     },
3186     BTF_STR_SEC("\0A\0B"),
3187     .map_type = BPF_MAP_TYPE_ARRAY,
3188     .map_name = "struct_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     .btf_load_err = true,
3195     .err_str = "Member exceeds struct_size",
3196 },
3197 
3198 {
3199     .descr = "invalid struct, kind_flag, bitfield base_type int not regular",
3200     .raw_types = {
3201         BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),          /* [1] */
3202         BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 20, 4),          /* [2] */
3203         BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_STRUCT, 1, 2), 4),    /* [3] */
3204         BTF_MEMBER_ENC(NAME_TBD, 2, BTF_MEMBER_OFFSET(20, 0)),
3205         BTF_MEMBER_ENC(NAME_TBD, 2, BTF_MEMBER_OFFSET(20, 20)),
3206         BTF_END_RAW,
3207     },
3208     BTF_STR_SEC("\0A\0B"),
3209     .map_type = BPF_MAP_TYPE_ARRAY,
3210     .map_name = "struct_type_check_btf",
3211     .key_size = sizeof(int),
3212     .value_size = sizeof(int),
3213     .key_type_id = 1,
3214     .value_type_id = 1,
3215     .max_entries = 4,
3216     .btf_load_err = true,
3217     .err_str = "Invalid member base type",
3218 },
3219 
3220 {
3221     .descr = "invalid struct, kind_flag, base_type int not regular",
3222     .raw_types = {
3223         BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),          /* [1] */
3224         BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 12, 4),          /* [2] */
3225         BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_STRUCT, 1, 2), 4),    /* [3] */
3226         BTF_MEMBER_ENC(NAME_TBD, 2, BTF_MEMBER_OFFSET(8, 0)),
3227         BTF_MEMBER_ENC(NAME_TBD, 2, BTF_MEMBER_OFFSET(8, 8)),
3228         BTF_END_RAW,
3229     },
3230     BTF_STR_SEC("\0A\0B"),
3231     .map_type = BPF_MAP_TYPE_ARRAY,
3232     .map_name = "struct_type_check_btf",
3233     .key_size = sizeof(int),
3234     .value_size = sizeof(int),
3235     .key_type_id = 1,
3236     .value_type_id = 1,
3237     .max_entries = 4,
3238     .btf_load_err = true,
3239     .err_str = "Invalid member base type",
3240 },
3241 
3242 {
3243     .descr = "invalid union, kind_flag, bitfield_size greater than struct size",
3244     .raw_types = {
3245         BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),      /* [1] */
3246         BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_UNION, 1, 2), 2), /* [2] */
3247         BTF_MEMBER_ENC(NAME_TBD, 1, BTF_MEMBER_OFFSET(8, 0)),
3248         BTF_MEMBER_ENC(NAME_TBD, 1, BTF_MEMBER_OFFSET(20, 0)),
3249         BTF_END_RAW,
3250     },
3251     BTF_STR_SEC("\0A\0B"),
3252     .map_type = BPF_MAP_TYPE_ARRAY,
3253     .map_name = "union_type_check_btf",
3254     .key_size = sizeof(int),
3255     .value_size = sizeof(int),
3256     .key_type_id = 1,
3257     .value_type_id = 1,
3258     .max_entries = 4,
3259     .btf_load_err = true,
3260     .err_str = "Member exceeds struct_size",
3261 },
3262 
3263 {
3264     .descr = "invalid struct, kind_flag, int member, bitfield_size = 0, wrong byte alignment",
3265     .raw_types = {
3266         BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),          /* [1] */
3267         BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),          /* [2] */
3268         BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_STRUCT, 1, 2), 12),   /* [3] */
3269         BTF_MEMBER_ENC(NAME_TBD, 2, BTF_MEMBER_OFFSET(0, 0)),
3270         BTF_MEMBER_ENC(NAME_TBD, 2, BTF_MEMBER_OFFSET(0, 36)),
3271         BTF_END_RAW,
3272     },
3273     BTF_STR_SEC("\0A\0B"),
3274     .map_type = BPF_MAP_TYPE_ARRAY,
3275     .map_name = "struct_type_check_btf",
3276     .key_size = sizeof(int),
3277     .value_size = sizeof(int),
3278     .key_type_id = 1,
3279     .value_type_id = 1,
3280     .max_entries = 4,
3281     .btf_load_err = true,
3282     .err_str = "Invalid member offset",
3283 },
3284 
3285 {
3286     .descr = "invalid struct, kind_flag, enum member, bitfield_size = 0, wrong byte alignment",
3287     .raw_types = {
3288         BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),          /* [1] */
3289         BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),          /* [2] */
3290         BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_ENUM, 0, 1), 4),  /* [2] */
3291         BTF_ENUM_ENC(NAME_TBD, 0),
3292         BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_STRUCT, 1, 2), 12),   /* [3] */
3293         BTF_MEMBER_ENC(NAME_TBD, 2, BTF_MEMBER_OFFSET(0, 0)),
3294         BTF_MEMBER_ENC(NAME_TBD, 2, BTF_MEMBER_OFFSET(0, 36)),
3295         BTF_END_RAW,
3296     },
3297     BTF_STR_SEC("\0A\0B\0C"),
3298     .map_type = BPF_MAP_TYPE_ARRAY,
3299     .map_name = "struct_type_check_btf",
3300     .key_size = sizeof(int),
3301     .value_size = sizeof(int),
3302     .key_type_id = 1,
3303     .value_type_id = 1,
3304     .max_entries = 4,
3305     .btf_load_err = true,
3306     .err_str = "Invalid member offset",
3307 },
3308 
3309 {
3310     .descr = "128-bit int",
3311     .raw_types = {
3312         BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),          /* [1] */
3313         BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 128, 16),        /* [2] */
3314         BTF_END_RAW,
3315     },
3316     BTF_STR_SEC("\0A"),
3317     .map_type = BPF_MAP_TYPE_ARRAY,
3318     .map_name = "int_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 },
3325 
3326 {
3327     .descr = "struct, 128-bit int member",
3328     .raw_types = {
3329         BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),          /* [1] */
3330         BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 128, 16),        /* [2] */
3331         BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 1), 16),   /* [3] */
3332         BTF_MEMBER_ENC(NAME_TBD, 2, 0),
3333         BTF_END_RAW,
3334     },
3335     BTF_STR_SEC("\0A"),
3336     .map_type = BPF_MAP_TYPE_ARRAY,
3337     .map_name = "struct_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, 120-bit int member bitfield",
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, 120, 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, kind_flag, 128-bit int member",
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, 128, 16),        /* [2] */
3369         BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_STRUCT, 1, 1), 16),   /* [3] */
3370         BTF_MEMBER_ENC(NAME_TBD, 2, BTF_MEMBER_OFFSET(0, 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, 120-bit int member bitfield",
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(120, 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  * typedef int arr_t[16];
3403  * struct s {
3404  *  arr_t *a;
3405  * };
3406  */
3407 {
3408     .descr = "struct->ptr->typedef->array->int size resolution",
3409     .raw_types = {
3410         BTF_STRUCT_ENC(NAME_TBD, 1, 8),         /* [1] */
3411         BTF_MEMBER_ENC(NAME_TBD, 2, 0),
3412         BTF_PTR_ENC(3),                 /* [2] */
3413         BTF_TYPEDEF_ENC(NAME_TBD, 4),           /* [3] */
3414         BTF_TYPE_ARRAY_ENC(5, 5, 16),           /* [4] */
3415         BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),  /* [5] */
3416         BTF_END_RAW,
3417     },
3418     BTF_STR_SEC("\0s\0a\0arr_t"),
3419     .map_type = BPF_MAP_TYPE_ARRAY,
3420     .map_name = "ptr_mod_chain_size_resolve_map",
3421     .key_size = sizeof(int),
3422     .value_size = sizeof(int) * 16,
3423     .key_type_id = 5 /* int */,
3424     .value_type_id = 3 /* arr_t */,
3425     .max_entries = 4,
3426 },
3427 /*
3428  * typedef int arr_t[16][8][4];
3429  * struct s {
3430  *  arr_t *a;
3431  * };
3432  */
3433 {
3434     .descr = "struct->ptr->typedef->multi-array->int size resolution",
3435     .raw_types = {
3436         BTF_STRUCT_ENC(NAME_TBD, 1, 8),         /* [1] */
3437         BTF_MEMBER_ENC(NAME_TBD, 2, 0),
3438         BTF_PTR_ENC(3),                 /* [2] */
3439         BTF_TYPEDEF_ENC(NAME_TBD, 4),           /* [3] */
3440         BTF_TYPE_ARRAY_ENC(5, 7, 16),           /* [4] */
3441         BTF_TYPE_ARRAY_ENC(6, 7, 8),            /* [5] */
3442         BTF_TYPE_ARRAY_ENC(7, 7, 4),            /* [6] */
3443         BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),  /* [7] */
3444         BTF_END_RAW,
3445     },
3446     BTF_STR_SEC("\0s\0a\0arr_t"),
3447     .map_type = BPF_MAP_TYPE_ARRAY,
3448     .map_name = "multi_arr_size_resolve_map",
3449     .key_size = sizeof(int),
3450     .value_size = sizeof(int) * 16 * 8 * 4,
3451     .key_type_id = 7 /* int */,
3452     .value_type_id = 3 /* arr_t */,
3453     .max_entries = 4,
3454 },
3455 /*
3456  * typedef int int_t;
3457  * typedef int_t arr3_t[4];
3458  * typedef arr3_t arr2_t[8];
3459  * typedef arr2_t arr1_t[16];
3460  * struct s {
3461  *  arr1_t *a;
3462  * };
3463  */
3464 {
3465     .descr = "typedef/multi-arr mix size resolution",
3466     .raw_types = {
3467         BTF_STRUCT_ENC(NAME_TBD, 1, 8),         /* [1] */
3468         BTF_MEMBER_ENC(NAME_TBD, 2, 0),
3469         BTF_PTR_ENC(3),                 /* [2] */
3470         BTF_TYPEDEF_ENC(NAME_TBD, 4),           /* [3] */
3471         BTF_TYPE_ARRAY_ENC(5, 10, 16),          /* [4] */
3472         BTF_TYPEDEF_ENC(NAME_TBD, 6),           /* [5] */
3473         BTF_TYPE_ARRAY_ENC(7, 10, 8),           /* [6] */
3474         BTF_TYPEDEF_ENC(NAME_TBD, 8),           /* [7] */
3475         BTF_TYPE_ARRAY_ENC(9, 10, 4),           /* [8] */
3476         BTF_TYPEDEF_ENC(NAME_TBD, 10),          /* [9] */
3477         BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),  /* [10] */
3478         BTF_END_RAW,
3479     },
3480     BTF_STR_SEC("\0s\0a\0arr1_t\0arr2_t\0arr3_t\0int_t"),
3481     .map_type = BPF_MAP_TYPE_ARRAY,
3482     .map_name = "typedef_arra_mix_size_resolve_map",
3483     .key_size = sizeof(int),
3484     .value_size = sizeof(int) * 16 * 8 * 4,
3485     .key_type_id = 10 /* int */,
3486     .value_type_id = 3 /* arr_t */,
3487     .max_entries = 4,
3488 },
3489 /*
3490  * elf .rodata section size 4 and btf .rodata section vlen 0.
3491  */
3492 {
3493     .descr = "datasec: vlen == 0",
3494     .raw_types = {
3495         /* int */
3496         BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),  /* [1] */
3497         /* .rodata section */
3498         BTF_TYPE_ENC(NAME_NTH(1), BTF_INFO_ENC(BTF_KIND_DATASEC, 0, 0), 4),
3499                                  /* [2] */
3500         BTF_END_RAW,
3501     },
3502     BTF_STR_SEC("\0.rodata"),
3503     .map_type = BPF_MAP_TYPE_ARRAY,
3504     .key_size = sizeof(int),
3505     .value_size = sizeof(int),
3506     .key_type_id = 1,
3507     .value_type_id = 1,
3508     .max_entries = 1,
3509 },
3510 
3511 {
3512     .descr = "float test #1, well-formed",
3513     .raw_types = {
3514         BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),
3515                                 /* [1] */
3516         BTF_TYPE_FLOAT_ENC(NAME_TBD, 2),        /* [2] */
3517         BTF_TYPE_FLOAT_ENC(NAME_TBD, 4),        /* [3] */
3518         BTF_TYPE_FLOAT_ENC(NAME_TBD, 8),        /* [4] */
3519         BTF_TYPE_FLOAT_ENC(NAME_TBD, 12),       /* [5] */
3520         BTF_TYPE_FLOAT_ENC(NAME_TBD, 16),       /* [6] */
3521         BTF_STRUCT_ENC(NAME_TBD, 5, 48),        /* [7] */
3522         BTF_MEMBER_ENC(NAME_TBD, 2, 0),
3523         BTF_MEMBER_ENC(NAME_TBD, 3, 32),
3524         BTF_MEMBER_ENC(NAME_TBD, 4, 64),
3525         BTF_MEMBER_ENC(NAME_TBD, 5, 128),
3526         BTF_MEMBER_ENC(NAME_TBD, 6, 256),
3527         BTF_END_RAW,
3528     },
3529     BTF_STR_SEC("\0int\0_Float16\0float\0double\0_Float80\0long_double"
3530             "\0floats\0a\0b\0c\0d\0e"),
3531     .map_type = BPF_MAP_TYPE_ARRAY,
3532     .map_name = "float_type_check_btf",
3533     .key_size = sizeof(int),
3534     .value_size = 48,
3535     .key_type_id = 1,
3536     .value_type_id = 7,
3537     .max_entries = 1,
3538 },
3539 {
3540     .descr = "float test #2, invalid vlen",
3541     .raw_types = {
3542         BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),
3543                                 /* [1] */
3544         BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_FLOAT, 0, 1), 4),
3545                                 /* [2] */
3546         BTF_END_RAW,
3547     },
3548     BTF_STR_SEC("\0int\0float"),
3549     .map_type = BPF_MAP_TYPE_ARRAY,
3550     .map_name = "float_type_check_btf",
3551     .key_size = sizeof(int),
3552     .value_size = 4,
3553     .key_type_id = 1,
3554     .value_type_id = 2,
3555     .max_entries = 1,
3556     .btf_load_err = true,
3557     .err_str = "vlen != 0",
3558 },
3559 {
3560     .descr = "float test #3, invalid kind_flag",
3561     .raw_types = {
3562         BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),
3563                                 /* [1] */
3564         BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_FLOAT, 1, 0), 4),
3565                                 /* [2] */
3566         BTF_END_RAW,
3567     },
3568     BTF_STR_SEC("\0int\0float"),
3569     .map_type = BPF_MAP_TYPE_ARRAY,
3570     .map_name = "float_type_check_btf",
3571     .key_size = sizeof(int),
3572     .value_size = 4,
3573     .key_type_id = 1,
3574     .value_type_id = 2,
3575     .max_entries = 1,
3576     .btf_load_err = true,
3577     .err_str = "Invalid btf_info kind_flag",
3578 },
3579 {
3580     .descr = "float test #4, member does not fit",
3581     .raw_types = {
3582         BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),
3583                                 /* [1] */
3584         BTF_TYPE_FLOAT_ENC(NAME_TBD, 4),        /* [2] */
3585         BTF_STRUCT_ENC(NAME_TBD, 1, 2),         /* [3] */
3586         BTF_MEMBER_ENC(NAME_TBD, 2, 0),
3587         BTF_END_RAW,
3588     },
3589     BTF_STR_SEC("\0int\0float\0floats\0x"),
3590     .map_type = BPF_MAP_TYPE_ARRAY,
3591     .map_name = "float_type_check_btf",
3592     .key_size = sizeof(int),
3593     .value_size = 4,
3594     .key_type_id = 1,
3595     .value_type_id = 3,
3596     .max_entries = 1,
3597     .btf_load_err = true,
3598     .err_str = "Member exceeds struct_size",
3599 },
3600 {
3601     .descr = "float test #5, member is not properly aligned",
3602     .raw_types = {
3603         BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),
3604                                 /* [1] */
3605         BTF_TYPE_FLOAT_ENC(NAME_TBD, 4),        /* [2] */
3606         BTF_STRUCT_ENC(NAME_TBD, 1, 8),         /* [3] */
3607         BTF_MEMBER_ENC(NAME_TBD, 2, 8),
3608         BTF_END_RAW,
3609     },
3610     BTF_STR_SEC("\0int\0float\0floats\0x"),
3611     .map_type = BPF_MAP_TYPE_ARRAY,
3612     .map_name = "float_type_check_btf",
3613     .key_size = sizeof(int),
3614     .value_size = 4,
3615     .key_type_id = 1,
3616     .value_type_id = 3,
3617     .max_entries = 1,
3618     .btf_load_err = true,
3619     .err_str = "Member is not properly aligned",
3620 },
3621 {
3622     .descr = "float test #6, invalid size",
3623     .raw_types = {
3624         BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),
3625                                 /* [1] */
3626         BTF_TYPE_FLOAT_ENC(NAME_TBD, 6),        /* [2] */
3627         BTF_END_RAW,
3628     },
3629     BTF_STR_SEC("\0int\0float"),
3630     .map_type = BPF_MAP_TYPE_ARRAY,
3631     .map_name = "float_type_check_btf",
3632     .key_size = sizeof(int),
3633     .value_size = 6,
3634     .key_type_id = 1,
3635     .value_type_id = 2,
3636     .max_entries = 1,
3637     .btf_load_err = true,
3638     .err_str = "Invalid type_size",
3639 },
3640 
3641 {
3642     .descr = "decl_tag test #1, struct/member, well-formed",
3643     .raw_types = {
3644         BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),  /* [1] */
3645         BTF_STRUCT_ENC(0, 2, 8),            /* [2] */
3646         BTF_MEMBER_ENC(NAME_TBD, 1, 0),
3647         BTF_MEMBER_ENC(NAME_TBD, 1, 32),
3648         BTF_DECL_TAG_ENC(NAME_TBD, 2, -1),
3649         BTF_DECL_TAG_ENC(NAME_TBD, 2, 0),
3650         BTF_DECL_TAG_ENC(NAME_TBD, 2, 1),
3651         BTF_END_RAW,
3652     },
3653     BTF_STR_SEC("\0m1\0m2\0tag1\0tag2\0tag3"),
3654     .map_type = BPF_MAP_TYPE_ARRAY,
3655     .map_name = "tag_type_check_btf",
3656     .key_size = sizeof(int),
3657     .value_size = 8,
3658     .key_type_id = 1,
3659     .value_type_id = 2,
3660     .max_entries = 1,
3661 },
3662 {
3663     .descr = "decl_tag test #2, union/member, well-formed",
3664     .raw_types = {
3665         BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),  /* [1] */
3666         BTF_UNION_ENC(NAME_TBD, 2, 4),          /* [2] */
3667         BTF_MEMBER_ENC(NAME_TBD, 1, 0),
3668         BTF_MEMBER_ENC(NAME_TBD, 1, 0),
3669         BTF_DECL_TAG_ENC(NAME_TBD, 2, -1),
3670         BTF_DECL_TAG_ENC(NAME_TBD, 2, 0),
3671         BTF_DECL_TAG_ENC(NAME_TBD, 2, 1),
3672         BTF_END_RAW,
3673     },
3674     BTF_STR_SEC("\0t\0m1\0m2\0tag1\0tag2\0tag3"),
3675     .map_type = BPF_MAP_TYPE_ARRAY,
3676     .map_name = "tag_type_check_btf",
3677     .key_size = sizeof(int),
3678     .value_size = 4,
3679     .key_type_id = 1,
3680     .value_type_id = 2,
3681     .max_entries = 1,
3682 },
3683 {
3684     .descr = "decl_tag test #3, variable, well-formed",
3685     .raw_types = {
3686         BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),  /* [1] */
3687         BTF_VAR_ENC(NAME_TBD, 1, 0),            /* [2] */
3688         BTF_VAR_ENC(NAME_TBD, 1, 1),            /* [3] */
3689         BTF_DECL_TAG_ENC(NAME_TBD, 2, -1),
3690         BTF_DECL_TAG_ENC(NAME_TBD, 3, -1),
3691         BTF_END_RAW,
3692     },
3693     BTF_STR_SEC("\0local\0global\0tag1\0tag2"),
3694     .map_type = BPF_MAP_TYPE_ARRAY,
3695     .map_name = "tag_type_check_btf",
3696     .key_size = sizeof(int),
3697     .value_size = 4,
3698     .key_type_id = 1,
3699     .value_type_id = 1,
3700     .max_entries = 1,
3701 },
3702 {
3703     .descr = "decl_tag test #4, func/parameter, well-formed",
3704     .raw_types = {
3705         BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),  /* [1] */
3706         BTF_FUNC_PROTO_ENC(0, 2),           /* [2] */
3707             BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
3708             BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
3709         BTF_FUNC_ENC(NAME_TBD, 2),          /* [3] */
3710         BTF_DECL_TAG_ENC(NAME_TBD, 3, -1),
3711         BTF_DECL_TAG_ENC(NAME_TBD, 3, 0),
3712         BTF_DECL_TAG_ENC(NAME_TBD, 3, 1),
3713         BTF_END_RAW,
3714     },
3715     BTF_STR_SEC("\0arg1\0arg2\0f\0tag1\0tag2\0tag3"),
3716     .map_type = BPF_MAP_TYPE_ARRAY,
3717     .map_name = "tag_type_check_btf",
3718     .key_size = sizeof(int),
3719     .value_size = 4,
3720     .key_type_id = 1,
3721     .value_type_id = 1,
3722     .max_entries = 1,
3723 },
3724 {
3725     .descr = "decl_tag test #5, invalid value",
3726     .raw_types = {
3727         BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),  /* [1] */
3728         BTF_VAR_ENC(NAME_TBD, 1, 0),            /* [2] */
3729         BTF_DECL_TAG_ENC(0, 2, -1),
3730         BTF_END_RAW,
3731     },
3732     BTF_STR_SEC("\0local\0tag"),
3733     .map_type = BPF_MAP_TYPE_ARRAY,
3734     .map_name = "tag_type_check_btf",
3735     .key_size = sizeof(int),
3736     .value_size = 4,
3737     .key_type_id = 1,
3738     .value_type_id = 1,
3739     .max_entries = 1,
3740     .btf_load_err = true,
3741     .err_str = "Invalid value",
3742 },
3743 {
3744     .descr = "decl_tag test #6, invalid target type",
3745     .raw_types = {
3746         BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),  /* [1] */
3747         BTF_DECL_TAG_ENC(NAME_TBD, 1, -1),
3748         BTF_END_RAW,
3749     },
3750     BTF_STR_SEC("\0tag1"),
3751     .map_type = BPF_MAP_TYPE_ARRAY,
3752     .map_name = "tag_type_check_btf",
3753     .key_size = sizeof(int),
3754     .value_size = 4,
3755     .key_type_id = 1,
3756     .value_type_id = 1,
3757     .max_entries = 1,
3758     .btf_load_err = true,
3759     .err_str = "Invalid type",
3760 },
3761 {
3762     .descr = "decl_tag test #7, invalid vlen",
3763     .raw_types = {
3764         BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),  /* [1] */
3765         BTF_VAR_ENC(NAME_TBD, 1, 0),            /* [2] */
3766         BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_DECL_TAG, 0, 1), 2), (0),
3767         BTF_END_RAW,
3768     },
3769     BTF_STR_SEC("\0local\0tag1"),
3770     .map_type = BPF_MAP_TYPE_ARRAY,
3771     .map_name = "tag_type_check_btf",
3772     .key_size = sizeof(int),
3773     .value_size = 4,
3774     .key_type_id = 1,
3775     .value_type_id = 1,
3776     .max_entries = 1,
3777     .btf_load_err = true,
3778     .err_str = "vlen != 0",
3779 },
3780 {
3781     .descr = "decl_tag test #8, invalid kflag",
3782     .raw_types = {
3783         BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),  /* [1] */
3784         BTF_VAR_ENC(NAME_TBD, 1, 0),            /* [2] */
3785         BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_DECL_TAG, 1, 0), 2), (-1),
3786         BTF_END_RAW,
3787     },
3788     BTF_STR_SEC("\0local\0tag1"),
3789     .map_type = BPF_MAP_TYPE_ARRAY,
3790     .map_name = "tag_type_check_btf",
3791     .key_size = sizeof(int),
3792     .value_size = 4,
3793     .key_type_id = 1,
3794     .value_type_id = 1,
3795     .max_entries = 1,
3796     .btf_load_err = true,
3797     .err_str = "Invalid btf_info kind_flag",
3798 },
3799 {
3800     .descr = "decl_tag test #9, var, invalid component_idx",
3801     .raw_types = {
3802         BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),  /* [1] */
3803         BTF_VAR_ENC(NAME_TBD, 1, 0),            /* [2] */
3804         BTF_DECL_TAG_ENC(NAME_TBD, 2, 0),
3805         BTF_END_RAW,
3806     },
3807     BTF_STR_SEC("\0local\0tag"),
3808     .map_type = BPF_MAP_TYPE_ARRAY,
3809     .map_name = "tag_type_check_btf",
3810     .key_size = sizeof(int),
3811     .value_size = 4,
3812     .key_type_id = 1,
3813     .value_type_id = 1,
3814     .max_entries = 1,
3815     .btf_load_err = true,
3816     .err_str = "Invalid component_idx",
3817 },
3818 {
3819     .descr = "decl_tag test #10, struct member, invalid component_idx",
3820     .raw_types = {
3821         BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),  /* [1] */
3822         BTF_STRUCT_ENC(0, 2, 8),            /* [2] */
3823         BTF_MEMBER_ENC(NAME_TBD, 1, 0),
3824         BTF_MEMBER_ENC(NAME_TBD, 1, 32),
3825         BTF_DECL_TAG_ENC(NAME_TBD, 2, 2),
3826         BTF_END_RAW,
3827     },
3828     BTF_STR_SEC("\0m1\0m2\0tag"),
3829     .map_type = BPF_MAP_TYPE_ARRAY,
3830     .map_name = "tag_type_check_btf",
3831     .key_size = sizeof(int),
3832     .value_size = 8,
3833     .key_type_id = 1,
3834     .value_type_id = 2,
3835     .max_entries = 1,
3836     .btf_load_err = true,
3837     .err_str = "Invalid component_idx",
3838 },
3839 {
3840     .descr = "decl_tag test #11, func parameter, invalid component_idx",
3841     .raw_types = {
3842         BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),  /* [1] */
3843         BTF_FUNC_PROTO_ENC(0, 2),           /* [2] */
3844             BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
3845             BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
3846         BTF_FUNC_ENC(NAME_TBD, 2),          /* [3] */
3847         BTF_DECL_TAG_ENC(NAME_TBD, 3, 2),
3848         BTF_END_RAW,
3849     },
3850     BTF_STR_SEC("\0arg1\0arg2\0f\0tag"),
3851     .map_type = BPF_MAP_TYPE_ARRAY,
3852     .map_name = "tag_type_check_btf",
3853     .key_size = sizeof(int),
3854     .value_size = 4,
3855     .key_type_id = 1,
3856     .value_type_id = 1,
3857     .max_entries = 1,
3858     .btf_load_err = true,
3859     .err_str = "Invalid component_idx",
3860 },
3861 {
3862     .descr = "decl_tag test #12, < -1 component_idx",
3863     .raw_types = {
3864         BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),  /* [1] */
3865         BTF_FUNC_PROTO_ENC(0, 2),           /* [2] */
3866             BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
3867             BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
3868         BTF_FUNC_ENC(NAME_TBD, 2),          /* [3] */
3869         BTF_DECL_TAG_ENC(NAME_TBD, 3, -2),
3870         BTF_END_RAW,
3871     },
3872     BTF_STR_SEC("\0arg1\0arg2\0f\0tag"),
3873     .map_type = BPF_MAP_TYPE_ARRAY,
3874     .map_name = "tag_type_check_btf",
3875     .key_size = sizeof(int),
3876     .value_size = 4,
3877     .key_type_id = 1,
3878     .value_type_id = 1,
3879     .max_entries = 1,
3880     .btf_load_err = true,
3881     .err_str = "Invalid component_idx",
3882 },
3883 {
3884     .descr = "decl_tag test #13, typedef, well-formed",
3885     .raw_types = {
3886         BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),  /* [1] */
3887         BTF_TYPEDEF_ENC(NAME_TBD, 1),           /* [2] */
3888         BTF_DECL_TAG_ENC(NAME_TBD, 2, -1),
3889         BTF_END_RAW,
3890     },
3891     BTF_STR_SEC("\0t\0tag"),
3892     .map_type = BPF_MAP_TYPE_ARRAY,
3893     .map_name = "tag_type_check_btf",
3894     .key_size = sizeof(int),
3895     .value_size = 4,
3896     .key_type_id = 1,
3897     .value_type_id = 1,
3898     .max_entries = 1,
3899 },
3900 {
3901     .descr = "decl_tag test #14, typedef, invalid component_idx",
3902     .raw_types = {
3903         BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),  /* [1] */
3904         BTF_TYPEDEF_ENC(NAME_TBD, 1),           /* [2] */
3905         BTF_DECL_TAG_ENC(NAME_TBD, 2, 0),
3906         BTF_END_RAW,
3907     },
3908     BTF_STR_SEC("\0local\0tag"),
3909     .map_type = BPF_MAP_TYPE_ARRAY,
3910     .map_name = "tag_type_check_btf",
3911     .key_size = sizeof(int),
3912     .value_size = 4,
3913     .key_type_id = 1,
3914     .value_type_id = 1,
3915     .max_entries = 1,
3916     .btf_load_err = true,
3917     .err_str = "Invalid component_idx",
3918 },
3919 {
3920     .descr = "decl_tag test #15, func, invalid func proto",
3921     .raw_types = {
3922         BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),  /* [1] */
3923         BTF_DECL_TAG_ENC(NAME_TBD, 3, 0),       /* [2] */
3924         BTF_FUNC_ENC(NAME_TBD, 8),          /* [3] */
3925         BTF_END_RAW,
3926     },
3927     BTF_STR_SEC("\0tag\0func"),
3928     .map_type = BPF_MAP_TYPE_ARRAY,
3929     .map_name = "tag_type_check_btf",
3930     .key_size = sizeof(int),
3931     .value_size = 4,
3932     .key_type_id = 1,
3933     .value_type_id = 1,
3934     .max_entries = 1,
3935     .btf_load_err = true,
3936     .err_str = "Invalid type_id",
3937 },
3938 {
3939     .descr = "type_tag test #1",
3940     .raw_types = {
3941         BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),  /* [1] */
3942         BTF_TYPE_TAG_ENC(NAME_TBD, 1),          /* [2] */
3943         BTF_PTR_ENC(2),                 /* [3] */
3944         BTF_END_RAW,
3945     },
3946     BTF_STR_SEC("\0tag"),
3947     .map_type = BPF_MAP_TYPE_ARRAY,
3948     .map_name = "tag_type_check_btf",
3949     .key_size = sizeof(int),
3950     .value_size = 4,
3951     .key_type_id = 1,
3952     .value_type_id = 1,
3953     .max_entries = 1,
3954 },
3955 {
3956     .descr = "type_tag test #2, type tag order",
3957     .raw_types = {
3958         BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),  /* [1] */
3959         BTF_CONST_ENC(3),               /* [2] */
3960         BTF_TYPE_TAG_ENC(NAME_TBD, 1),          /* [3] */
3961         BTF_END_RAW,
3962     },
3963     BTF_STR_SEC("\0tag"),
3964     .map_type = BPF_MAP_TYPE_ARRAY,
3965     .map_name = "tag_type_check_btf",
3966     .key_size = sizeof(int),
3967     .value_size = 4,
3968     .key_type_id = 1,
3969     .value_type_id = 1,
3970     .max_entries = 1,
3971     .btf_load_err = true,
3972     .err_str = "Type tags don't precede modifiers",
3973 },
3974 {
3975     .descr = "type_tag test #3, type tag order",
3976     .raw_types = {
3977         BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),  /* [1] */
3978         BTF_TYPE_TAG_ENC(NAME_TBD, 3),          /* [2] */
3979         BTF_CONST_ENC(4),               /* [3] */
3980         BTF_TYPE_TAG_ENC(NAME_TBD, 1),          /* [4] */
3981         BTF_END_RAW,
3982     },
3983     BTF_STR_SEC("\0tag\0tag"),
3984     .map_type = BPF_MAP_TYPE_ARRAY,
3985     .map_name = "tag_type_check_btf",
3986     .key_size = sizeof(int),
3987     .value_size = 4,
3988     .key_type_id = 1,
3989     .value_type_id = 1,
3990     .max_entries = 1,
3991     .btf_load_err = true,
3992     .err_str = "Type tags don't precede modifiers",
3993 },
3994 {
3995     .descr = "type_tag test #4, type tag order",
3996     .raw_types = {
3997         BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),  /* [1] */
3998         BTF_TYPEDEF_ENC(NAME_TBD, 3),           /* [2] */
3999         BTF_CONST_ENC(4),               /* [3] */
4000         BTF_TYPE_TAG_ENC(NAME_TBD, 1),          /* [4] */
4001         BTF_END_RAW,
4002     },
4003     BTF_STR_SEC("\0tag\0tag"),
4004     .map_type = BPF_MAP_TYPE_ARRAY,
4005     .map_name = "tag_type_check_btf",
4006     .key_size = sizeof(int),
4007     .value_size = 4,
4008     .key_type_id = 1,
4009     .value_type_id = 1,
4010     .max_entries = 1,
4011     .btf_load_err = true,
4012     .err_str = "Type tags don't precede modifiers",
4013 },
4014 {
4015     .descr = "type_tag test #5, type tag order",
4016     .raw_types = {
4017         BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),  /* [1] */
4018         BTF_TYPE_TAG_ENC(NAME_TBD, 3),          /* [2] */
4019         BTF_CONST_ENC(1),               /* [3] */
4020         BTF_TYPE_TAG_ENC(NAME_TBD, 2),          /* [4] */
4021         BTF_END_RAW,
4022     },
4023     BTF_STR_SEC("\0tag\0tag"),
4024     .map_type = BPF_MAP_TYPE_ARRAY,
4025     .map_name = "tag_type_check_btf",
4026     .key_size = sizeof(int),
4027     .value_size = 4,
4028     .key_type_id = 1,
4029     .value_type_id = 1,
4030     .max_entries = 1,
4031 },
4032 {
4033     .descr = "type_tag test #6, type tag order",
4034     .raw_types = {
4035         BTF_PTR_ENC(2),                 /* [1] */
4036         BTF_TYPE_TAG_ENC(NAME_TBD, 3),          /* [2] */
4037         BTF_CONST_ENC(4),               /* [3] */
4038         BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),  /* [4] */
4039         BTF_PTR_ENC(6),                 /* [5] */
4040         BTF_CONST_ENC(2),               /* [6] */
4041         BTF_END_RAW,
4042     },
4043     BTF_STR_SEC("\0tag"),
4044     .map_type = BPF_MAP_TYPE_ARRAY,
4045     .map_name = "tag_type_check_btf",
4046     .key_size = sizeof(int),
4047     .value_size = 4,
4048     .key_type_id = 1,
4049     .value_type_id = 1,
4050     .max_entries = 1,
4051     .btf_load_err = true,
4052     .err_str = "Type tags don't precede modifiers",
4053 },
4054 {
4055     .descr = "enum64 test #1, unsigned, size 8",
4056     .raw_types = {
4057         BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),          /* [1] */
4058         BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_ENUM64, 0, 2), 8), /* [2] */
4059         BTF_ENUM64_ENC(NAME_TBD, 0, 0),
4060         BTF_ENUM64_ENC(NAME_TBD, 1, 1),
4061         BTF_END_RAW,
4062     },
4063     BTF_STR_SEC("\0a\0b\0c"),
4064     .map_type = BPF_MAP_TYPE_ARRAY,
4065     .map_name = "tag_type_check_btf",
4066     .key_size = sizeof(int),
4067     .value_size = 8,
4068     .key_type_id = 1,
4069     .value_type_id = 2,
4070     .max_entries = 1,
4071 },
4072 {
4073     .descr = "enum64 test #2, signed, size 4",
4074     .raw_types = {
4075         BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),          /* [1] */
4076         BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_ENUM64, 1, 2), 4), /* [2] */
4077         BTF_ENUM64_ENC(NAME_TBD, -1, 0),
4078         BTF_ENUM64_ENC(NAME_TBD, 1, 0),
4079         BTF_END_RAW,
4080     },
4081     BTF_STR_SEC("\0a\0b\0c"),
4082     .map_type = BPF_MAP_TYPE_ARRAY,
4083     .map_name = "tag_type_check_btf",
4084     .key_size = sizeof(int),
4085     .value_size = 4,
4086     .key_type_id = 1,
4087     .value_type_id = 2,
4088     .max_entries = 1,
4089 },
4090 
4091 }; /* struct btf_raw_test raw_tests[] */
4092 
4093 static const char *get_next_str(const char *start, const char *end)
4094 {
4095     return start < end - 1 ? start + 1 : NULL;
4096 }
4097 
4098 static int get_raw_sec_size(const __u32 *raw_types)
4099 {
4100     int i;
4101 
4102     for (i = MAX_NR_RAW_U32 - 1;
4103          i >= 0 && raw_types[i] != BTF_END_RAW;
4104          i--)
4105         ;
4106 
4107     return i < 0 ? i : i * sizeof(raw_types[0]);
4108 }
4109 
4110 static void *btf_raw_create(const struct btf_header *hdr,
4111                 const __u32 *raw_types,
4112                 const char *str,
4113                 unsigned int str_sec_size,
4114                 unsigned int *btf_size,
4115                 const char **ret_next_str)
4116 {
4117     const char *next_str = str, *end_str = str + str_sec_size;
4118     const char **strs_idx = NULL, **tmp_strs_idx;
4119     int strs_cap = 0, strs_cnt = 0, next_str_idx = 0;
4120     unsigned int size_needed, offset;
4121     struct btf_header *ret_hdr;
4122     int i, type_sec_size, err = 0;
4123     uint32_t *ret_types;
4124     void *raw_btf = NULL;
4125 
4126     type_sec_size = get_raw_sec_size(raw_types);
4127     if (CHECK(type_sec_size < 0, "Cannot get nr_raw_types"))
4128         return NULL;
4129 
4130     size_needed = sizeof(*hdr) + type_sec_size + str_sec_size;
4131     raw_btf = malloc(size_needed);
4132     if (CHECK(!raw_btf, "Cannot allocate memory for raw_btf"))
4133         return NULL;
4134 
4135     /* Copy header */
4136     memcpy(raw_btf, hdr, sizeof(*hdr));
4137     offset = sizeof(*hdr);
4138 
4139     /* Index strings */
4140     while ((next_str = get_next_str(next_str, end_str))) {
4141         if (strs_cnt == strs_cap) {
4142             strs_cap += max(16, strs_cap / 2);
4143             tmp_strs_idx = realloc(strs_idx,
4144                            sizeof(*strs_idx) * strs_cap);
4145             if (CHECK(!tmp_strs_idx,
4146                   "Cannot allocate memory for strs_idx")) {
4147                 err = -1;
4148                 goto done;
4149             }
4150             strs_idx = tmp_strs_idx;
4151         }
4152         strs_idx[strs_cnt++] = next_str;
4153         next_str += strlen(next_str);
4154     }
4155 
4156     /* Copy type section */
4157     ret_types = raw_btf + offset;
4158     for (i = 0; i < type_sec_size / sizeof(raw_types[0]); i++) {
4159         if (raw_types[i] == NAME_TBD) {
4160             if (CHECK(next_str_idx == strs_cnt,
4161                   "Error in getting next_str #%d",
4162                   next_str_idx)) {
4163                 err = -1;
4164                 goto done;
4165             }
4166             ret_types[i] = strs_idx[next_str_idx++] - str;
4167         } else if (IS_NAME_NTH(raw_types[i])) {
4168             int idx = GET_NAME_NTH_IDX(raw_types[i]);
4169 
4170             if (CHECK(idx <= 0 || idx > strs_cnt,
4171                   "Error getting string #%d, strs_cnt:%d",
4172                   idx, strs_cnt)) {
4173                 err = -1;
4174                 goto done;
4175             }
4176             ret_types[i] = strs_idx[idx-1] - str;
4177         } else {
4178             ret_types[i] = raw_types[i];
4179         }
4180     }
4181     offset += type_sec_size;
4182 
4183     /* Copy string section */
4184     memcpy(raw_btf + offset, str, str_sec_size);
4185 
4186     ret_hdr = (struct btf_header *)raw_btf;
4187     ret_hdr->type_len = type_sec_size;
4188     ret_hdr->str_off = type_sec_size;
4189     ret_hdr->str_len = str_sec_size;
4190 
4191     *btf_size = size_needed;
4192     if (ret_next_str)
4193         *ret_next_str =
4194             next_str_idx < strs_cnt ? strs_idx[next_str_idx] : NULL;
4195 
4196 done:
4197     free(strs_idx);
4198     if (err) {
4199         free(raw_btf);
4200         return NULL;
4201     }
4202     return raw_btf;
4203 }
4204 
4205 static int load_raw_btf(const void *raw_data, size_t raw_size)
4206 {
4207     LIBBPF_OPTS(bpf_btf_load_opts, opts);
4208     int btf_fd;
4209 
4210     if (always_log) {
4211         opts.log_buf = btf_log_buf,
4212         opts.log_size = BTF_LOG_BUF_SIZE,
4213         opts.log_level = 1;
4214     }
4215 
4216     btf_fd = bpf_btf_load(raw_data, raw_size, &opts);
4217     if (btf_fd < 0 && !always_log) {
4218         opts.log_buf = btf_log_buf,
4219         opts.log_size = BTF_LOG_BUF_SIZE,
4220         opts.log_level = 1;
4221         btf_fd = bpf_btf_load(raw_data, raw_size, &opts);
4222     }
4223 
4224     return btf_fd;
4225 }
4226 
4227 static void do_test_raw(unsigned int test_num)
4228 {
4229     struct btf_raw_test *test = &raw_tests[test_num - 1];
4230     LIBBPF_OPTS(bpf_map_create_opts, opts);
4231     int map_fd = -1, btf_fd = -1;
4232     unsigned int raw_btf_size;
4233     struct btf_header *hdr;
4234     void *raw_btf;
4235     int err;
4236 
4237     if (!test__start_subtest(test->descr))
4238         return;
4239 
4240     raw_btf = btf_raw_create(&hdr_tmpl,
4241                  test->raw_types,
4242                  test->str_sec,
4243                  test->str_sec_size,
4244                  &raw_btf_size, NULL);
4245     if (!raw_btf)
4246         return;
4247 
4248     hdr = raw_btf;
4249 
4250     hdr->hdr_len = (int)hdr->hdr_len + test->hdr_len_delta;
4251     hdr->type_off = (int)hdr->type_off + test->type_off_delta;
4252     hdr->str_off = (int)hdr->str_off + test->str_off_delta;
4253     hdr->str_len = (int)hdr->str_len + test->str_len_delta;
4254 
4255     *btf_log_buf = '\0';
4256     btf_fd = load_raw_btf(raw_btf, raw_btf_size);
4257     free(raw_btf);
4258 
4259     err = ((btf_fd < 0) != test->btf_load_err);
4260     if (CHECK(err, "btf_fd:%d test->btf_load_err:%u",
4261           btf_fd, test->btf_load_err) ||
4262         CHECK(test->err_str && !strstr(btf_log_buf, test->err_str),
4263           "expected err_str:%s\n", test->err_str)) {
4264         err = -1;
4265         goto done;
4266     }
4267 
4268     if (err || btf_fd < 0)
4269         goto done;
4270 
4271     opts.btf_fd = btf_fd;
4272     opts.btf_key_type_id = test->key_type_id;
4273     opts.btf_value_type_id = test->value_type_id;
4274     map_fd = bpf_map_create(test->map_type, test->map_name,
4275                 test->key_size, test->value_size, test->max_entries, &opts);
4276 
4277     err = ((map_fd < 0) != test->map_create_err);
4278     CHECK(err, "map_fd:%d test->map_create_err:%u",
4279           map_fd, test->map_create_err);
4280 
4281 done:
4282     if (*btf_log_buf && (err || always_log))
4283         fprintf(stderr, "\n%s", btf_log_buf);
4284     if (btf_fd >= 0)
4285         close(btf_fd);
4286     if (map_fd >= 0)
4287         close(map_fd);
4288 }
4289 
4290 struct btf_get_info_test {
4291     const char *descr;
4292     const char *str_sec;
4293     __u32 raw_types[MAX_NR_RAW_U32];
4294     __u32 str_sec_size;
4295     int btf_size_delta;
4296     int (*special_test)(unsigned int test_num);
4297 };
4298 
4299 static int test_big_btf_info(unsigned int test_num);
4300 static int test_btf_id(unsigned int test_num);
4301 
4302 const struct btf_get_info_test get_info_tests[] = {
4303 {
4304     .descr = "== raw_btf_size+1",
4305     .raw_types = {
4306         /* int */               /* [1] */
4307         BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
4308         BTF_END_RAW,
4309     },
4310     .str_sec = "",
4311     .str_sec_size = sizeof(""),
4312     .btf_size_delta = 1,
4313 },
4314 {
4315     .descr = "== raw_btf_size-3",
4316     .raw_types = {
4317         /* int */               /* [1] */
4318         BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
4319         BTF_END_RAW,
4320     },
4321     .str_sec = "",
4322     .str_sec_size = sizeof(""),
4323     .btf_size_delta = -3,
4324 },
4325 {
4326     .descr = "Large bpf_btf_info",
4327     .raw_types = {
4328         /* int */               /* [1] */
4329         BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
4330         BTF_END_RAW,
4331     },
4332     .str_sec = "",
4333     .str_sec_size = sizeof(""),
4334     .special_test = test_big_btf_info,
4335 },
4336 {
4337     .descr = "BTF ID",
4338     .raw_types = {
4339         /* int */               /* [1] */
4340         BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
4341         /* unsigned int */          /* [2] */
4342         BTF_TYPE_INT_ENC(0, 0, 0, 32, 4),
4343         BTF_END_RAW,
4344     },
4345     .str_sec = "",
4346     .str_sec_size = sizeof(""),
4347     .special_test = test_btf_id,
4348 },
4349 };
4350 
4351 static int test_big_btf_info(unsigned int test_num)
4352 {
4353     const struct btf_get_info_test *test = &get_info_tests[test_num - 1];
4354     uint8_t *raw_btf = NULL, *user_btf = NULL;
4355     unsigned int raw_btf_size;
4356     struct {
4357         struct bpf_btf_info info;
4358         uint64_t garbage;
4359     } info_garbage;
4360     struct bpf_btf_info *info;
4361     int btf_fd = -1, err;
4362     uint32_t info_len;
4363 
4364     raw_btf = btf_raw_create(&hdr_tmpl,
4365                  test->raw_types,
4366                  test->str_sec,
4367                  test->str_sec_size,
4368                  &raw_btf_size, NULL);
4369 
4370     if (!raw_btf)
4371         return -1;
4372 
4373     *btf_log_buf = '\0';
4374 
4375     user_btf = malloc(raw_btf_size);
4376     if (CHECK(!user_btf, "!user_btf")) {
4377         err = -1;
4378         goto done;
4379     }
4380 
4381     btf_fd = load_raw_btf(raw_btf, raw_btf_size);
4382     if (CHECK(btf_fd < 0, "errno:%d", errno)) {
4383         err = -1;
4384         goto done;
4385     }
4386 
4387     /*
4388      * GET_INFO should error out if the userspace info
4389      * has non zero tailing bytes.
4390      */
4391     info = &info_garbage.info;
4392     memset(info, 0, sizeof(*info));
4393     info_garbage.garbage = 0xdeadbeef;
4394     info_len = sizeof(info_garbage);
4395     info->btf = ptr_to_u64(user_btf);
4396     info->btf_size = raw_btf_size;
4397 
4398     err = bpf_obj_get_info_by_fd(btf_fd, info, &info_len);
4399     if (CHECK(!err, "!err")) {
4400         err = -1;
4401         goto done;
4402     }
4403 
4404     /*
4405      * GET_INFO should succeed even info_len is larger than
4406      * the kernel supported as long as tailing bytes are zero.
4407      * The kernel supported info len should also be returned
4408      * to userspace.
4409      */
4410     info_garbage.garbage = 0;
4411     err = bpf_obj_get_info_by_fd(btf_fd, info, &info_len);
4412     if (CHECK(err || info_len != sizeof(*info),
4413           "err:%d errno:%d info_len:%u sizeof(*info):%zu",
4414           err, errno, info_len, sizeof(*info))) {
4415         err = -1;
4416         goto done;
4417     }
4418 
4419     fprintf(stderr, "OK");
4420 
4421 done:
4422     if (*btf_log_buf && (err || always_log))
4423         fprintf(stderr, "\n%s", btf_log_buf);
4424 
4425     free(raw_btf);
4426     free(user_btf);
4427 
4428     if (btf_fd >= 0)
4429         close(btf_fd);
4430 
4431     return err;
4432 }
4433 
4434 static int test_btf_id(unsigned int test_num)
4435 {
4436     const struct btf_get_info_test *test = &get_info_tests[test_num - 1];
4437     LIBBPF_OPTS(bpf_map_create_opts, opts);
4438     uint8_t *raw_btf = NULL, *user_btf[2] = {};
4439     int btf_fd[2] = {-1, -1}, map_fd = -1;
4440     struct bpf_map_info map_info = {};
4441     struct bpf_btf_info info[2] = {};
4442     unsigned int raw_btf_size;
4443     uint32_t info_len;
4444     int err, i, ret;
4445 
4446     raw_btf = btf_raw_create(&hdr_tmpl,
4447                  test->raw_types,
4448                  test->str_sec,
4449                  test->str_sec_size,
4450                  &raw_btf_size, NULL);
4451 
4452     if (!raw_btf)
4453         return -1;
4454 
4455     *btf_log_buf = '\0';
4456 
4457     for (i = 0; i < 2; i++) {
4458         user_btf[i] = malloc(raw_btf_size);
4459         if (CHECK(!user_btf[i], "!user_btf[%d]", i)) {
4460             err = -1;
4461             goto done;
4462         }
4463         info[i].btf = ptr_to_u64(user_btf[i]);
4464         info[i].btf_size = raw_btf_size;
4465     }
4466 
4467     btf_fd[0] = load_raw_btf(raw_btf, raw_btf_size);
4468     if (CHECK(btf_fd[0] < 0, "errno:%d", errno)) {
4469         err = -1;
4470         goto done;
4471     }
4472 
4473     /* Test BPF_OBJ_GET_INFO_BY_ID on btf_id */
4474     info_len = sizeof(info[0]);
4475     err = bpf_obj_get_info_by_fd(btf_fd[0], &info[0], &info_len);
4476     if (CHECK(err, "errno:%d", errno)) {
4477         err = -1;
4478         goto done;
4479     }
4480 
4481     btf_fd[1] = bpf_btf_get_fd_by_id(info[0].id);
4482     if (CHECK(btf_fd[1] < 0, "errno:%d", errno)) {
4483         err = -1;
4484         goto done;
4485     }
4486 
4487     ret = 0;
4488     err = bpf_obj_get_info_by_fd(btf_fd[1], &info[1], &info_len);
4489     if (CHECK(err || info[0].id != info[1].id ||
4490           info[0].btf_size != info[1].btf_size ||
4491           (ret = memcmp(user_btf[0], user_btf[1], info[0].btf_size)),
4492           "err:%d errno:%d id0:%u id1:%u btf_size0:%u btf_size1:%u memcmp:%d",
4493           err, errno, info[0].id, info[1].id,
4494           info[0].btf_size, info[1].btf_size, ret)) {
4495         err = -1;
4496         goto done;
4497     }
4498 
4499     /* Test btf members in struct bpf_map_info */
4500     opts.btf_fd = btf_fd[0];
4501     opts.btf_key_type_id = 1;
4502     opts.btf_value_type_id = 2;
4503     map_fd = bpf_map_create(BPF_MAP_TYPE_ARRAY, "test_btf_id",
4504                 sizeof(int), sizeof(int), 4, &opts);
4505     if (CHECK(map_fd < 0, "errno:%d", errno)) {
4506         err = -1;
4507         goto done;
4508     }
4509 
4510     info_len = sizeof(map_info);
4511     err = bpf_obj_get_info_by_fd(map_fd, &map_info, &info_len);
4512     if (CHECK(err || map_info.btf_id != info[0].id ||
4513           map_info.btf_key_type_id != 1 || map_info.btf_value_type_id != 2,
4514           "err:%d errno:%d info.id:%u btf_id:%u btf_key_type_id:%u btf_value_type_id:%u",
4515           err, errno, info[0].id, map_info.btf_id, map_info.btf_key_type_id,
4516           map_info.btf_value_type_id)) {
4517         err = -1;
4518         goto done;
4519     }
4520 
4521     for (i = 0; i < 2; i++) {
4522         close(btf_fd[i]);
4523         btf_fd[i] = -1;
4524     }
4525 
4526     /* Test BTF ID is removed from the kernel */
4527     btf_fd[0] = bpf_btf_get_fd_by_id(map_info.btf_id);
4528     if (CHECK(btf_fd[0] < 0, "errno:%d", errno)) {
4529         err = -1;
4530         goto done;
4531     }
4532     close(btf_fd[0]);
4533     btf_fd[0] = -1;
4534 
4535     /* The map holds the last ref to BTF and its btf_id */
4536     close(map_fd);
4537     map_fd = -1;
4538     btf_fd[0] = bpf_btf_get_fd_by_id(map_info.btf_id);
4539     if (CHECK(btf_fd[0] >= 0, "BTF lingers")) {
4540         err = -1;
4541         goto done;
4542     }
4543 
4544     fprintf(stderr, "OK");
4545 
4546 done:
4547     if (*btf_log_buf && (err || always_log))
4548         fprintf(stderr, "\n%s", btf_log_buf);
4549 
4550     free(raw_btf);
4551     if (map_fd >= 0)
4552         close(map_fd);
4553     for (i = 0; i < 2; i++) {
4554         free(user_btf[i]);
4555         if (btf_fd[i] >= 0)
4556             close(btf_fd[i]);
4557     }
4558 
4559     return err;
4560 }
4561 
4562 static void do_test_get_info(unsigned int test_num)
4563 {
4564     const struct btf_get_info_test *test = &get_info_tests[test_num - 1];
4565     unsigned int raw_btf_size, user_btf_size, expected_nbytes;
4566     uint8_t *raw_btf = NULL, *user_btf = NULL;
4567     struct bpf_btf_info info = {};
4568     int btf_fd = -1, err, ret;
4569     uint32_t info_len;
4570 
4571     if (!test__start_subtest(test->descr))
4572         return;
4573 
4574     if (test->special_test) {
4575         err = test->special_test(test_num);
4576         if (CHECK(err, "failed: %d\n", err))
4577             return;
4578     }
4579 
4580     raw_btf = btf_raw_create(&hdr_tmpl,
4581                  test->raw_types,
4582                  test->str_sec,
4583                  test->str_sec_size,
4584                  &raw_btf_size, NULL);
4585 
4586     if (!raw_btf)
4587         return;
4588 
4589     *btf_log_buf = '\0';
4590 
4591     user_btf = malloc(raw_btf_size);
4592     if (CHECK(!user_btf, "!user_btf")) {
4593         err = -1;
4594         goto done;
4595     }
4596 
4597     btf_fd = load_raw_btf(raw_btf, raw_btf_size);
4598     if (CHECK(btf_fd <= 0, "errno:%d", errno)) {
4599         err = -1;
4600         goto done;
4601     }
4602 
4603     user_btf_size = (int)raw_btf_size + test->btf_size_delta;
4604     expected_nbytes = min(raw_btf_size, user_btf_size);
4605     if (raw_btf_size > expected_nbytes)
4606         memset(user_btf + expected_nbytes, 0xff,
4607                raw_btf_size - expected_nbytes);
4608 
4609     info_len = sizeof(info);
4610     info.btf = ptr_to_u64(user_btf);
4611     info.btf_size = user_btf_size;
4612 
4613     ret = 0;
4614     err = bpf_obj_get_info_by_fd(btf_fd, &info, &info_len);
4615     if (CHECK(err || !info.id || info_len != sizeof(info) ||
4616           info.btf_size != raw_btf_size ||
4617           (ret = memcmp(raw_btf, user_btf, expected_nbytes)),
4618           "err:%d errno:%d info.id:%u info_len:%u sizeof(info):%zu raw_btf_size:%u info.btf_size:%u expected_nbytes:%u memcmp:%d",
4619           err, errno, info.id, info_len, sizeof(info),
4620           raw_btf_size, info.btf_size, expected_nbytes, ret)) {
4621         err = -1;
4622         goto done;
4623     }
4624 
4625     while (expected_nbytes < raw_btf_size) {
4626         fprintf(stderr, "%u...", expected_nbytes);
4627         if (CHECK(user_btf[expected_nbytes++] != 0xff,
4628               "user_btf[%u]:%x != 0xff", expected_nbytes - 1,
4629               user_btf[expected_nbytes - 1])) {
4630             err = -1;
4631             goto done;
4632         }
4633     }
4634 
4635     fprintf(stderr, "OK");
4636 
4637 done:
4638     if (*btf_log_buf && (err || always_log))
4639         fprintf(stderr, "\n%s", btf_log_buf);
4640 
4641     free(raw_btf);
4642     free(user_btf);
4643 
4644     if (btf_fd >= 0)
4645         close(btf_fd);
4646 }
4647 
4648 struct btf_file_test {
4649     const char *file;
4650     bool btf_kv_notfound;
4651 };
4652 
4653 static struct btf_file_test file_tests[] = {
4654     { .file = "test_btf_newkv.o", },
4655     { .file = "test_btf_nokv.o", .btf_kv_notfound = true, },
4656 };
4657 
4658 static void do_test_file(unsigned int test_num)
4659 {
4660     const struct btf_file_test *test = &file_tests[test_num - 1];
4661     const char *expected_fnames[] = {"_dummy_tracepoint",
4662                      "test_long_fname_1",
4663                      "test_long_fname_2"};
4664     struct btf_ext *btf_ext = NULL;
4665     struct bpf_prog_info info = {};
4666     struct bpf_object *obj = NULL;
4667     struct bpf_func_info *finfo;
4668     struct bpf_program *prog;
4669     __u32 info_len, rec_size;
4670     bool has_btf_ext = false;
4671     struct btf *btf = NULL;
4672     void *func_info = NULL;
4673     struct bpf_map *map;
4674     int i, err, prog_fd;
4675 
4676     if (!test__start_subtest(test->file))
4677         return;
4678 
4679     btf = btf__parse_elf(test->file, &btf_ext);
4680     err = libbpf_get_error(btf);
4681     if (err) {
4682         if (err == -ENOENT) {
4683             printf("%s:SKIP: No ELF %s found", __func__, BTF_ELF_SEC);
4684             test__skip();
4685             return;
4686         }
4687         return;
4688     }
4689     btf__free(btf);
4690 
4691     has_btf_ext = btf_ext != NULL;
4692     btf_ext__free(btf_ext);
4693 
4694     /* temporary disable LIBBPF_STRICT_MAP_DEFINITIONS to test legacy maps */
4695     libbpf_set_strict_mode(LIBBPF_STRICT_ALL & ~LIBBPF_STRICT_MAP_DEFINITIONS);
4696     obj = bpf_object__open(test->file);
4697     err = libbpf_get_error(obj);
4698     if (CHECK(err, "obj: %d", err))
4699         return;
4700 
4701     prog = bpf_object__next_program(obj, NULL);
4702     if (CHECK(!prog, "Cannot find bpf_prog")) {
4703         err = -1;
4704         goto done;
4705     }
4706 
4707     bpf_program__set_type(prog, BPF_PROG_TYPE_TRACEPOINT);
4708     err = bpf_object__load(obj);
4709     if (CHECK(err < 0, "bpf_object__load: %d", err))
4710         goto done;
4711     prog_fd = bpf_program__fd(prog);
4712 
4713     map = bpf_object__find_map_by_name(obj, "btf_map");
4714     if (CHECK(!map, "btf_map not found")) {
4715         err = -1;
4716         goto done;
4717     }
4718 
4719     err = (bpf_map__btf_key_type_id(map) == 0 || bpf_map__btf_value_type_id(map) == 0)
4720         != test->btf_kv_notfound;
4721     if (CHECK(err, "btf_key_type_id:%u btf_value_type_id:%u test->btf_kv_notfound:%u",
4722           bpf_map__btf_key_type_id(map), bpf_map__btf_value_type_id(map),
4723           test->btf_kv_notfound))
4724         goto done;
4725 
4726     if (!has_btf_ext)
4727         goto skip;
4728 
4729     /* get necessary program info */
4730     info_len = sizeof(struct bpf_prog_info);
4731     err = bpf_obj_get_info_by_fd(prog_fd, &info, &info_len);
4732 
4733     if (CHECK(err < 0, "invalid get info (1st) errno:%d", errno)) {
4734         fprintf(stderr, "%s\n", btf_log_buf);
4735         err = -1;
4736         goto done;
4737     }
4738     if (CHECK(info.nr_func_info != 3,
4739           "incorrect info.nr_func_info (1st) %d",
4740           info.nr_func_info)) {
4741         err = -1;
4742         goto done;
4743     }
4744     rec_size = info.func_info_rec_size;
4745     if (CHECK(rec_size != sizeof(struct bpf_func_info),
4746           "incorrect info.func_info_rec_size (1st) %d\n", rec_size)) {
4747         err = -1;
4748         goto done;
4749     }
4750 
4751     func_info = malloc(info.nr_func_info * rec_size);
4752     if (CHECK(!func_info, "out of memory")) {
4753         err = -1;
4754         goto done;
4755     }
4756 
4757     /* reset info to only retrieve func_info related data */
4758     memset(&info, 0, sizeof(info));
4759     info.nr_func_info = 3;
4760     info.func_info_rec_size = rec_size;
4761     info.func_info = ptr_to_u64(func_info);
4762 
4763     err = bpf_obj_get_info_by_fd(prog_fd, &info, &info_len);
4764 
4765     if (CHECK(err < 0, "invalid get info (2nd) errno:%d", errno)) {
4766         fprintf(stderr, "%s\n", btf_log_buf);
4767         err = -1;
4768         goto done;
4769     }
4770     if (CHECK(info.nr_func_info != 3,
4771           "incorrect info.nr_func_info (2nd) %d",
4772           info.nr_func_info)) {
4773         err = -1;
4774         goto done;
4775     }
4776     if (CHECK(info.func_info_rec_size != rec_size,
4777           "incorrect info.func_info_rec_size (2nd) %d",
4778           info.func_info_rec_size)) {
4779         err = -1;
4780         goto done;
4781     }
4782 
4783     btf = btf__load_from_kernel_by_id(info.btf_id);
4784     err = libbpf_get_error(btf);
4785     if (CHECK(err, "cannot get btf from kernel, err: %d", err))
4786         goto done;
4787 
4788     /* check three functions */
4789     finfo = func_info;
4790     for (i = 0; i < 3; i++) {
4791         const struct btf_type *t;
4792         const char *fname;
4793 
4794         t = btf__type_by_id(btf, finfo->type_id);
4795         if (CHECK(!t, "btf__type_by_id failure: id %u",
4796               finfo->type_id)) {
4797             err = -1;
4798             goto done;
4799         }
4800 
4801         fname = btf__name_by_offset(btf, t->name_off);
4802         err = strcmp(fname, expected_fnames[i]);
4803         /* for the second and third functions in .text section,
4804          * the compiler may order them either way.
4805          */
4806         if (i && err)
4807             err = strcmp(fname, expected_fnames[3 - i]);
4808         if (CHECK(err, "incorrect fname %s", fname ? : "")) {
4809             err = -1;
4810             goto done;
4811         }
4812 
4813         finfo = (void *)finfo + rec_size;
4814     }
4815 
4816 skip:
4817     fprintf(stderr, "OK");
4818 
4819 done:
4820     libbpf_set_strict_mode(LIBBPF_STRICT_ALL);
4821 
4822     btf__free(btf);
4823     free(func_info);
4824     bpf_object__close(obj);
4825 }
4826 
4827 const char *pprint_enum_str[] = {
4828     "ENUM_ZERO",
4829     "ENUM_ONE",
4830     "ENUM_TWO",
4831     "ENUM_THREE",
4832 };
4833 
4834 struct pprint_mapv {
4835     uint32_t ui32;
4836     uint16_t ui16;
4837     /* 2 bytes hole */
4838     int32_t si32;
4839     uint32_t unused_bits2a:2,
4840         bits28:28,
4841         unused_bits2b:2;
4842     union {
4843         uint64_t ui64;
4844         uint8_t ui8a[8];
4845     };
4846     enum {
4847         ENUM_ZERO,
4848         ENUM_ONE,
4849         ENUM_TWO,
4850         ENUM_THREE,
4851     } aenum;
4852     uint32_t ui32b;
4853     uint32_t bits2c:2;
4854     uint8_t si8_4[2][2];
4855 };
4856 
4857 #ifdef __SIZEOF_INT128__
4858 struct pprint_mapv_int128 {
4859     __int128 si128a;
4860     __int128 si128b;
4861     unsigned __int128 bits3:3;
4862     unsigned __int128 bits80:80;
4863     unsigned __int128 ui128;
4864 };
4865 #endif
4866 
4867 static struct btf_raw_test pprint_test_template[] = {
4868 {
4869     .raw_types = {
4870         /* unsighed char */         /* [1] */
4871         BTF_TYPE_INT_ENC(NAME_TBD, 0, 0, 8, 1),
4872         /* unsigned short */            /* [2] */
4873         BTF_TYPE_INT_ENC(NAME_TBD, 0, 0, 16, 2),
4874         /* unsigned int */          /* [3] */
4875         BTF_TYPE_INT_ENC(NAME_TBD, 0, 0, 32, 4),
4876         /* int */               /* [4] */
4877         BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),
4878         /* unsigned long long */        /* [5] */
4879         BTF_TYPE_INT_ENC(NAME_TBD, 0, 0, 64, 8),
4880         /* 2 bits */                /* [6] */
4881         BTF_TYPE_INT_ENC(0, 0, 0, 2, 2),
4882         /* 28 bits */               /* [7] */
4883         BTF_TYPE_INT_ENC(0, 0, 0, 28, 4),
4884         /* uint8_t[8] */            /* [8] */
4885         BTF_TYPE_ARRAY_ENC(9, 1, 8),
4886         /* typedef unsigned char uint8_t */ /* [9] */
4887         BTF_TYPEDEF_ENC(NAME_TBD, 1),
4888         /* typedef unsigned short uint16_t */   /* [10] */
4889         BTF_TYPEDEF_ENC(NAME_TBD, 2),
4890         /* typedef unsigned int uint32_t */ /* [11] */
4891         BTF_TYPEDEF_ENC(NAME_TBD, 3),
4892         /* typedef int int32_t */       /* [12] */
4893         BTF_TYPEDEF_ENC(NAME_TBD, 4),
4894         /* typedef unsigned long long uint64_t *//* [13] */
4895         BTF_TYPEDEF_ENC(NAME_TBD, 5),
4896         /* union (anon) */          /* [14] */
4897         BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_UNION, 0, 2), 8),
4898         BTF_MEMBER_ENC(NAME_TBD, 13, 0),/* uint64_t ui64; */
4899         BTF_MEMBER_ENC(NAME_TBD, 8, 0), /* uint8_t ui8a[8]; */
4900         /* enum (anon) */           /* [15] */
4901         BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_ENUM, 0, 4), 4),
4902         BTF_ENUM_ENC(NAME_TBD, 0),
4903         BTF_ENUM_ENC(NAME_TBD, 1),
4904         BTF_ENUM_ENC(NAME_TBD, 2),
4905         BTF_ENUM_ENC(NAME_TBD, 3),
4906         /* struct pprint_mapv */        /* [16] */
4907         BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 11), 40),
4908         BTF_MEMBER_ENC(NAME_TBD, 11, 0),    /* uint32_t ui32 */
4909         BTF_MEMBER_ENC(NAME_TBD, 10, 32),   /* uint16_t ui16 */
4910         BTF_MEMBER_ENC(NAME_TBD, 12, 64),   /* int32_t si32 */
4911         BTF_MEMBER_ENC(NAME_TBD, 6, 96),    /* unused_bits2a */
4912         BTF_MEMBER_ENC(NAME_TBD, 7, 98),    /* bits28 */
4913         BTF_MEMBER_ENC(NAME_TBD, 6, 126),   /* unused_bits2b */
4914         BTF_MEMBER_ENC(0, 14, 128),     /* union (anon) */
4915         BTF_MEMBER_ENC(NAME_TBD, 15, 192),  /* aenum */
4916         BTF_MEMBER_ENC(NAME_TBD, 11, 224),  /* uint32_t ui32b */
4917         BTF_MEMBER_ENC(NAME_TBD, 6, 256),   /* bits2c */
4918         BTF_MEMBER_ENC(NAME_TBD, 17, 264),  /* si8_4 */
4919         BTF_TYPE_ARRAY_ENC(18, 1, 2),       /* [17] */
4920         BTF_TYPE_ARRAY_ENC(1, 1, 2),        /* [18] */
4921         BTF_END_RAW,
4922     },
4923     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"),
4924     .key_size = sizeof(unsigned int),
4925     .value_size = sizeof(struct pprint_mapv),
4926     .key_type_id = 3,   /* unsigned int */
4927     .value_type_id = 16,    /* struct pprint_mapv */
4928     .max_entries = 128,
4929 },
4930 
4931 {
4932     /* this type will have the same type as the
4933      * first .raw_types definition, but struct type will
4934      * be encoded with kind_flag set.
4935      */
4936     .raw_types = {
4937         /* unsighed char */         /* [1] */
4938         BTF_TYPE_INT_ENC(NAME_TBD, 0, 0, 8, 1),
4939         /* unsigned short */            /* [2] */
4940         BTF_TYPE_INT_ENC(NAME_TBD, 0, 0, 16, 2),
4941         /* unsigned int */          /* [3] */
4942         BTF_TYPE_INT_ENC(NAME_TBD, 0, 0, 32, 4),
4943         /* int */               /* [4] */
4944         BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),
4945         /* unsigned long long */        /* [5] */
4946         BTF_TYPE_INT_ENC(NAME_TBD, 0, 0, 64, 8),
4947         BTF_TYPE_INT_ENC(0, 0, 0, 32, 4),   /* [6] */
4948         BTF_TYPE_INT_ENC(0, 0, 0, 32, 4),   /* [7] */
4949         /* uint8_t[8] */            /* [8] */
4950         BTF_TYPE_ARRAY_ENC(9, 1, 8),
4951         /* typedef unsigned char uint8_t */ /* [9] */
4952         BTF_TYPEDEF_ENC(NAME_TBD, 1),
4953         /* typedef unsigned short uint16_t */   /* [10] */
4954         BTF_TYPEDEF_ENC(NAME_TBD, 2),
4955         /* typedef unsigned int uint32_t */ /* [11] */
4956         BTF_TYPEDEF_ENC(NAME_TBD, 3),
4957         /* typedef int int32_t */       /* [12] */
4958         BTF_TYPEDEF_ENC(NAME_TBD, 4),
4959         /* typedef unsigned long long uint64_t *//* [13] */
4960         BTF_TYPEDEF_ENC(NAME_TBD, 5),
4961         /* union (anon) */          /* [14] */
4962         BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_UNION, 0, 2), 8),
4963         BTF_MEMBER_ENC(NAME_TBD, 13, 0),/* uint64_t ui64; */
4964         BTF_MEMBER_ENC(NAME_TBD, 8, 0), /* uint8_t ui8a[8]; */
4965         /* enum (anon) */           /* [15] */
4966         BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_ENUM, 0, 4), 4),
4967         BTF_ENUM_ENC(NAME_TBD, 0),
4968         BTF_ENUM_ENC(NAME_TBD, 1),
4969         BTF_ENUM_ENC(NAME_TBD, 2),
4970         BTF_ENUM_ENC(NAME_TBD, 3),
4971         /* struct pprint_mapv */        /* [16] */
4972         BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 1, 11), 40),
4973         BTF_MEMBER_ENC(NAME_TBD, 11, BTF_MEMBER_OFFSET(0, 0)),  /* uint32_t ui32 */
4974         BTF_MEMBER_ENC(NAME_TBD, 10, BTF_MEMBER_OFFSET(0, 32)), /* uint16_t ui16 */
4975         BTF_MEMBER_ENC(NAME_TBD, 12, BTF_MEMBER_OFFSET(0, 64)), /* int32_t si32 */
4976         BTF_MEMBER_ENC(NAME_TBD, 6, BTF_MEMBER_OFFSET(2, 96)),  /* unused_bits2a */
4977         BTF_MEMBER_ENC(NAME_TBD, 7, BTF_MEMBER_OFFSET(28, 98)), /* bits28 */
4978         BTF_MEMBER_ENC(NAME_TBD, 6, BTF_MEMBER_OFFSET(2, 126)), /* unused_bits2b */
4979         BTF_MEMBER_ENC(0, 14, BTF_MEMBER_OFFSET(0, 128)),   /* union (anon) */
4980         BTF_MEMBER_ENC(NAME_TBD, 15, BTF_MEMBER_OFFSET(0, 192)),    /* aenum */
4981         BTF_MEMBER_ENC(NAME_TBD, 11, BTF_MEMBER_OFFSET(0, 224)),    /* uint32_t ui32b */
4982         BTF_MEMBER_ENC(NAME_TBD, 6, BTF_MEMBER_OFFSET(2, 256)), /* bits2c */
4983         BTF_MEMBER_ENC(NAME_TBD, 17, 264),  /* si8_4 */
4984         BTF_TYPE_ARRAY_ENC(18, 1, 2),       /* [17] */
4985         BTF_TYPE_ARRAY_ENC(1, 1, 2),        /* [18] */
4986         BTF_END_RAW,
4987     },
4988     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"),
4989     .key_size = sizeof(unsigned int),
4990     .value_size = sizeof(struct pprint_mapv),
4991     .key_type_id = 3,   /* unsigned int */
4992     .value_type_id = 16,    /* struct pprint_mapv */
4993     .max_entries = 128,
4994 },
4995 
4996 {
4997     /* this type will have the same layout as the
4998      * first .raw_types definition. The struct type will
4999      * be encoded with kind_flag set, bitfield members
5000      * are added typedef/const/volatile, and bitfield members
5001      * will have both int and enum types.
5002      */
5003     .raw_types = {
5004         /* unsighed char */         /* [1] */
5005         BTF_TYPE_INT_ENC(NAME_TBD, 0, 0, 8, 1),
5006         /* unsigned short */            /* [2] */
5007         BTF_TYPE_INT_ENC(NAME_TBD, 0, 0, 16, 2),
5008         /* unsigned int */          /* [3] */
5009         BTF_TYPE_INT_ENC(NAME_TBD, 0, 0, 32, 4),
5010         /* int */               /* [4] */
5011         BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),
5012         /* unsigned long long */        /* [5] */
5013         BTF_TYPE_INT_ENC(NAME_TBD, 0, 0, 64, 8),
5014         BTF_TYPE_INT_ENC(0, 0, 0, 32, 4),   /* [6] */
5015         BTF_TYPE_INT_ENC(0, 0, 0, 32, 4),   /* [7] */
5016         /* uint8_t[8] */            /* [8] */
5017         BTF_TYPE_ARRAY_ENC(9, 1, 8),
5018         /* typedef unsigned char uint8_t */ /* [9] */
5019         BTF_TYPEDEF_ENC(NAME_TBD, 1),
5020         /* typedef unsigned short uint16_t */   /* [10] */
5021         BTF_TYPEDEF_ENC(NAME_TBD, 2),
5022         /* typedef unsigned int uint32_t */ /* [11] */
5023         BTF_TYPEDEF_ENC(NAME_TBD, 3),
5024         /* typedef int int32_t */       /* [12] */
5025         BTF_TYPEDEF_ENC(NAME_TBD, 4),
5026         /* typedef unsigned long long uint64_t *//* [13] */
5027         BTF_TYPEDEF_ENC(NAME_TBD, 5),
5028         /* union (anon) */          /* [14] */
5029         BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_UNION, 0, 2), 8),
5030         BTF_MEMBER_ENC(NAME_TBD, 13, 0),/* uint64_t ui64; */
5031         BTF_MEMBER_ENC(NAME_TBD, 8, 0), /* uint8_t ui8a[8]; */
5032         /* enum (anon) */           /* [15] */
5033         BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_ENUM, 0, 4), 4),
5034         BTF_ENUM_ENC(NAME_TBD, 0),
5035         BTF_ENUM_ENC(NAME_TBD, 1),
5036         BTF_ENUM_ENC(NAME_TBD, 2),
5037         BTF_ENUM_ENC(NAME_TBD, 3),
5038         /* struct pprint_mapv */        /* [16] */
5039         BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 1, 11), 40),
5040         BTF_MEMBER_ENC(NAME_TBD, 11, BTF_MEMBER_OFFSET(0, 0)),  /* uint32_t ui32 */
5041         BTF_MEMBER_ENC(NAME_TBD, 10, BTF_MEMBER_OFFSET(0, 32)), /* uint16_t ui16 */
5042         BTF_MEMBER_ENC(NAME_TBD, 12, BTF_MEMBER_OFFSET(0, 64)), /* int32_t si32 */
5043         BTF_MEMBER_ENC(NAME_TBD, 17, BTF_MEMBER_OFFSET(2, 96)), /* unused_bits2a */
5044         BTF_MEMBER_ENC(NAME_TBD, 7, BTF_MEMBER_OFFSET(28, 98)), /* bits28 */
5045         BTF_MEMBER_ENC(NAME_TBD, 19, BTF_MEMBER_OFFSET(2, 126)),/* unused_bits2b */
5046         BTF_MEMBER_ENC(0, 14, BTF_MEMBER_OFFSET(0, 128)),   /* union (anon) */
5047         BTF_MEMBER_ENC(NAME_TBD, 15, BTF_MEMBER_OFFSET(0, 192)),    /* aenum */
5048         BTF_MEMBER_ENC(NAME_TBD, 11, BTF_MEMBER_OFFSET(0, 224)),    /* uint32_t ui32b */
5049         BTF_MEMBER_ENC(NAME_TBD, 17, BTF_MEMBER_OFFSET(2, 256)),    /* bits2c */
5050         BTF_MEMBER_ENC(NAME_TBD, 20, BTF_MEMBER_OFFSET(0, 264)),    /* si8_4 */
5051         /* typedef unsigned int ___int */   /* [17] */
5052         BTF_TYPEDEF_ENC(NAME_TBD, 18),
5053         BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_VOLATILE, 0, 0), 6),  /* [18] */
5054         BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_CONST, 0, 0), 15),    /* [19] */
5055         BTF_TYPE_ARRAY_ENC(21, 1, 2),                   /* [20] */
5056         BTF_TYPE_ARRAY_ENC(1, 1, 2),                    /* [21] */
5057         BTF_END_RAW,
5058     },
5059     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"),
5060     .key_size = sizeof(unsigned int),
5061     .value_size = sizeof(struct pprint_mapv),
5062     .key_type_id = 3,   /* unsigned int */
5063     .value_type_id = 16,    /* struct pprint_mapv */
5064     .max_entries = 128,
5065 },
5066 
5067 #ifdef __SIZEOF_INT128__
5068 {
5069     /* test int128 */
5070     .raw_types = {
5071         /* unsigned int */              /* [1] */
5072         BTF_TYPE_INT_ENC(NAME_TBD, 0, 0, 32, 4),
5073         /* __int128 */                  /* [2] */
5074         BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 128, 16),
5075         /* unsigned __int128 */             /* [3] */
5076         BTF_TYPE_INT_ENC(NAME_TBD, 0, 0, 128, 16),
5077         /* struct pprint_mapv_int128 */         /* [4] */
5078         BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 1, 5), 64),
5079         BTF_MEMBER_ENC(NAME_TBD, 2, BTF_MEMBER_OFFSET(0, 0)),       /* si128a */
5080         BTF_MEMBER_ENC(NAME_TBD, 2, BTF_MEMBER_OFFSET(0, 128)),     /* si128b */
5081         BTF_MEMBER_ENC(NAME_TBD, 3, BTF_MEMBER_OFFSET(3, 256)),     /* bits3 */
5082         BTF_MEMBER_ENC(NAME_TBD, 3, BTF_MEMBER_OFFSET(80, 259)),    /* bits80 */
5083         BTF_MEMBER_ENC(NAME_TBD, 3, BTF_MEMBER_OFFSET(0, 384)),     /* ui128 */
5084         BTF_END_RAW,
5085     },
5086     BTF_STR_SEC("\0unsigned int\0__int128\0unsigned __int128\0pprint_mapv_int128\0si128a\0si128b\0bits3\0bits80\0ui128"),
5087     .key_size = sizeof(unsigned int),
5088     .value_size = sizeof(struct pprint_mapv_int128),
5089     .key_type_id = 1,
5090     .value_type_id = 4,
5091     .max_entries = 128,
5092     .mapv_kind = PPRINT_MAPV_KIND_INT128,
5093 },
5094 #endif
5095 
5096 };
5097 
5098 static struct btf_pprint_test_meta {
5099     const char *descr;
5100     enum bpf_map_type map_type;
5101     const char *map_name;
5102     bool ordered_map;
5103     bool lossless_map;
5104     bool percpu_map;
5105 } pprint_tests_meta[] = {
5106 {
5107     .descr = "BTF pretty print array",
5108     .map_type = BPF_MAP_TYPE_ARRAY,
5109     .map_name = "pprint_test_array",
5110     .ordered_map = true,
5111     .lossless_map = true,
5112     .percpu_map = false,
5113 },
5114 
5115 {
5116     .descr = "BTF pretty print hash",
5117     .map_type = BPF_MAP_TYPE_HASH,
5118     .map_name = "pprint_test_hash",
5119     .ordered_map = false,
5120     .lossless_map = true,
5121     .percpu_map = false,
5122 },
5123 
5124 {
5125     .descr = "BTF pretty print lru hash",
5126     .map_type = BPF_MAP_TYPE_LRU_HASH,
5127     .map_name = "pprint_test_lru_hash",
5128     .ordered_map = false,
5129     .lossless_map = false,
5130     .percpu_map = false,
5131 },
5132 
5133 {
5134     .descr = "BTF pretty print percpu array",
5135     .map_type = BPF_MAP_TYPE_PERCPU_ARRAY,
5136     .map_name = "pprint_test_percpu_array",
5137     .ordered_map = true,
5138     .lossless_map = true,
5139     .percpu_map = true,
5140 },
5141 
5142 {
5143     .descr = "BTF pretty print percpu hash",
5144     .map_type = BPF_MAP_TYPE_PERCPU_HASH,
5145     .map_name = "pprint_test_percpu_hash",
5146     .ordered_map = false,
5147     .lossless_map = true,
5148     .percpu_map = true,
5149 },
5150 
5151 {
5152     .descr = "BTF pretty print lru percpu hash",
5153     .map_type = BPF_MAP_TYPE_LRU_PERCPU_HASH,
5154     .map_name = "pprint_test_lru_percpu_hash",
5155     .ordered_map = false,
5156     .lossless_map = false,
5157     .percpu_map = true,
5158 },
5159 
5160 };
5161 
5162 static size_t get_pprint_mapv_size(enum pprint_mapv_kind_t mapv_kind)
5163 {
5164     if (mapv_kind == PPRINT_MAPV_KIND_BASIC)
5165         return sizeof(struct pprint_mapv);
5166 
5167 #ifdef __SIZEOF_INT128__
5168     if (mapv_kind == PPRINT_MAPV_KIND_INT128)
5169         return sizeof(struct pprint_mapv_int128);
5170 #endif
5171 
5172     assert(0);
5173 }
5174 
5175 static void set_pprint_mapv(enum pprint_mapv_kind_t mapv_kind,
5176                 void *mapv, uint32_t i,
5177                 int num_cpus, int rounded_value_size)
5178 {
5179     int cpu;
5180 
5181     if (mapv_kind == PPRINT_MAPV_KIND_BASIC) {
5182         struct pprint_mapv *v = mapv;
5183 
5184         for (cpu = 0; cpu < num_cpus; cpu++) {
5185             v->ui32 = i + cpu;
5186             v->si32 = -i;
5187             v->unused_bits2a = 3;
5188             v->bits28 = i;
5189             v->unused_bits2b = 3;
5190             v->ui64 = i;
5191             v->aenum = i & 0x03;
5192             v->ui32b = 4;
5193             v->bits2c = 1;
5194             v->si8_4[0][0] = (cpu + i) & 0xff;
5195             v->si8_4[0][1] = (cpu + i + 1) & 0xff;
5196             v->si8_4[1][0] = (cpu + i + 2) & 0xff;
5197             v->si8_4[1][1] = (cpu + i + 3) & 0xff;
5198             v = (void *)v + rounded_value_size;
5199         }
5200     }
5201 
5202 #ifdef __SIZEOF_INT128__
5203     if (mapv_kind == PPRINT_MAPV_KIND_INT128) {
5204         struct pprint_mapv_int128 *v = mapv;
5205 
5206         for (cpu = 0; cpu < num_cpus; cpu++) {
5207             v->si128a = i;
5208             v->si128b = -i;
5209             v->bits3 = i & 0x07;
5210             v->bits80 = (((unsigned __int128)1) << 64) + i;
5211             v->ui128 = (((unsigned __int128)2) << 64) + i;
5212             v = (void *)v + rounded_value_size;
5213         }
5214     }
5215 #endif
5216 }
5217 
5218 ssize_t get_pprint_expected_line(enum pprint_mapv_kind_t mapv_kind,
5219                  char *expected_line, ssize_t line_size,
5220                  bool percpu_map, unsigned int next_key,
5221                  int cpu, void *mapv)
5222 {
5223     ssize_t nexpected_line = -1;
5224 
5225     if (mapv_kind == PPRINT_MAPV_KIND_BASIC) {
5226         struct pprint_mapv *v = mapv;
5227 
5228         nexpected_line = snprintf(expected_line, line_size,
5229                       "%s%u: {%u,0,%d,0x%x,0x%x,0x%x,"
5230                       "{%llu|[%u,%u,%u,%u,%u,%u,%u,%u]},%s,"
5231                       "%u,0x%x,[[%d,%d],[%d,%d]]}\n",
5232                       percpu_map ? "\tcpu" : "",
5233                       percpu_map ? cpu : next_key,
5234                       v->ui32, v->si32,
5235                       v->unused_bits2a,
5236                       v->bits28,
5237                       v->unused_bits2b,
5238                       (__u64)v->ui64,
5239                       v->ui8a[0], v->ui8a[1],
5240                       v->ui8a[2], v->ui8a[3],
5241                       v->ui8a[4], v->ui8a[5],
5242                       v->ui8a[6], v->ui8a[7],
5243                       pprint_enum_str[v->aenum],
5244                       v->ui32b,
5245                       v->bits2c,
5246                       v->si8_4[0][0], v->si8_4[0][1],
5247                       v->si8_4[1][0], v->si8_4[1][1]);
5248     }
5249 
5250 #ifdef __SIZEOF_INT128__
5251     if (mapv_kind == PPRINT_MAPV_KIND_INT128) {
5252         struct pprint_mapv_int128 *v = mapv;
5253 
5254         nexpected_line = snprintf(expected_line, line_size,
5255                       "%s%u: {0x%lx,0x%lx,0x%lx,"
5256                       "0x%lx%016lx,0x%lx%016lx}\n",
5257                       percpu_map ? "\tcpu" : "",
5258                       percpu_map ? cpu : next_key,
5259                       (uint64_t)v->si128a,
5260                       (uint64_t)v->si128b,
5261                       (uint64_t)v->bits3,
5262                       (uint64_t)(v->bits80 >> 64),
5263                       (uint64_t)v->bits80,
5264                       (uint64_t)(v->ui128 >> 64),
5265                       (uint64_t)v->ui128);
5266     }
5267 #endif
5268 
5269     return nexpected_line;
5270 }
5271 
5272 static int check_line(const char *expected_line, int nexpected_line,
5273               int expected_line_len, const char *line)
5274 {
5275     if (CHECK(nexpected_line == expected_line_len,
5276           "expected_line is too long"))
5277         return -1;
5278 
5279     if (strcmp(expected_line, line)) {
5280         fprintf(stderr, "unexpected pprint output\n");
5281         fprintf(stderr, "expected: %s", expected_line);
5282         fprintf(stderr, "    read: %s", line);
5283         return -1;
5284     }
5285 
5286     return 0;
5287 }
5288 
5289 
5290 static void do_test_pprint(int test_num)
5291 {
5292     const struct btf_raw_test *test = &pprint_test_template[test_num];
5293     enum pprint_mapv_kind_t mapv_kind = test->mapv_kind;
5294     LIBBPF_OPTS(bpf_map_create_opts, opts);
5295     bool ordered_map, lossless_map, percpu_map;
5296     int err, ret, num_cpus, rounded_value_size;
5297     unsigned int key, nr_read_elems;
5298     int map_fd = -1, btf_fd = -1;
5299     unsigned int raw_btf_size;
5300     char expected_line[255];
5301     FILE *pin_file = NULL;
5302     char pin_path[255];
5303     size_t line_len = 0;
5304     char *line = NULL;
5305     void *mapv = NULL;
5306     uint8_t *raw_btf;
5307     ssize_t nread;
5308 
5309     if (!test__start_subtest(test->descr))
5310         return;
5311 
5312     raw_btf = btf_raw_create(&hdr_tmpl, test->raw_types,
5313                  test->str_sec, test->str_sec_size,
5314                  &raw_btf_size, NULL);
5315 
5316     if (!raw_btf)
5317         return;
5318 
5319     *btf_log_buf = '\0';
5320     btf_fd = load_raw_btf(raw_btf, raw_btf_size);
5321     free(raw_btf);
5322 
5323     if (CHECK(btf_fd < 0, "errno:%d\n", errno)) {
5324         err = -1;
5325         goto done;
5326     }
5327 
5328     opts.btf_fd = btf_fd;
5329     opts.btf_key_type_id = test->key_type_id;
5330     opts.btf_value_type_id = test->value_type_id;
5331     map_fd = bpf_map_create(test->map_type, test->map_name,
5332                 test->key_size, test->value_size, test->max_entries, &opts);
5333     if (CHECK(map_fd < 0, "errno:%d", errno)) {
5334         err = -1;
5335         goto done;
5336     }
5337 
5338     ret = snprintf(pin_path, sizeof(pin_path), "%s/%s",
5339                "/sys/fs/bpf", test->map_name);
5340 
5341     if (CHECK(ret >= sizeof(pin_path), "pin_path %s/%s is too long",
5342           "/sys/fs/bpf", test->map_name)) {
5343         err = -1;
5344         goto done;
5345     }
5346 
5347     err = bpf_obj_pin(map_fd, pin_path);
5348     if (CHECK(err, "bpf_obj_pin(%s): errno:%d.", pin_path, errno))
5349         goto done;
5350 
5351     percpu_map = test->percpu_map;
5352     num_cpus = percpu_map ? bpf_num_possible_cpus() : 1;
5353     rounded_value_size = round_up(get_pprint_mapv_size(mapv_kind), 8);
5354     mapv = calloc(num_cpus, rounded_value_size);
5355     if (CHECK(!mapv, "mapv allocation failure")) {
5356         err = -1;
5357         goto done;
5358     }
5359 
5360     for (key = 0; key < test->max_entries; key++) {
5361         set_pprint_mapv(mapv_kind, mapv, key, num_cpus, rounded_value_size);
5362         bpf_map_update_elem(map_fd, &key, mapv, 0);
5363     }
5364 
5365     pin_file = fopen(pin_path, "r");
5366     if (CHECK(!pin_file, "fopen(%s): errno:%d", pin_path, errno)) {
5367         err = -1;
5368         goto done;
5369     }
5370 
5371     /* Skip lines start with '#' */
5372     while ((nread = getline(&line, &line_len, pin_file)) > 0 &&
5373            *line == '#')
5374         ;
5375 
5376     if (CHECK(nread <= 0, "Unexpected EOF")) {
5377         err = -1;
5378         goto done;
5379     }
5380 
5381     nr_read_elems = 0;
5382     ordered_map = test->ordered_map;
5383     lossless_map = test->lossless_map;
5384     do {
5385         ssize_t nexpected_line;
5386         unsigned int next_key;
5387         void *cmapv;
5388         int cpu;
5389 
5390         next_key = ordered_map ? nr_read_elems : atoi(line);
5391         set_pprint_mapv(mapv_kind, mapv, next_key, num_cpus, rounded_value_size);
5392         cmapv = mapv;
5393 
5394         for (cpu = 0; cpu < num_cpus; cpu++) {
5395             if (percpu_map) {
5396                 /* for percpu map, the format looks like:
5397                  * <key>: {
5398                  *  cpu0: <value_on_cpu0>
5399                  *  cpu1: <value_on_cpu1>
5400                  *  ...
5401                  *  cpun: <value_on_cpun>
5402                  * }
5403                  *
5404                  * let us verify the line containing the key here.
5405                  */
5406                 if (cpu == 0) {
5407                     nexpected_line = snprintf(expected_line,
5408                                   sizeof(expected_line),
5409                                   "%u: {\n",
5410                                   next_key);
5411 
5412                     err = check_line(expected_line, nexpected_line,
5413                              sizeof(expected_line), line);
5414                     if (err < 0)
5415                         goto done;
5416                 }
5417 
5418                 /* read value@cpu */
5419                 nread = getline(&line, &line_len, pin_file);
5420                 if (nread < 0)
5421                     break;
5422             }
5423 
5424             nexpected_line = get_pprint_expected_line(mapv_kind, expected_line,
5425                                   sizeof(expected_line),
5426                                   percpu_map, next_key,
5427                                   cpu, cmapv);
5428             err = check_line(expected_line, nexpected_line,
5429                      sizeof(expected_line), line);
5430             if (err < 0)
5431                 goto done;
5432 
5433             cmapv = cmapv + rounded_value_size;
5434         }
5435 
5436         if (percpu_map) {
5437             /* skip the last bracket for the percpu map */
5438             nread = getline(&line, &line_len, pin_file);
5439             if (nread < 0)
5440                 break;
5441         }
5442 
5443         nread = getline(&line, &line_len, pin_file);
5444     } while (++nr_read_elems < test->max_entries && nread > 0);
5445 
5446     if (lossless_map &&
5447         CHECK(nr_read_elems < test->max_entries,
5448           "Unexpected EOF. nr_read_elems:%u test->max_entries:%u",
5449           nr_read_elems, test->max_entries)) {
5450         err = -1;
5451         goto done;
5452     }
5453 
5454     if (CHECK(nread > 0, "Unexpected extra pprint output: %s", line)) {
5455         err = -1;
5456         goto done;
5457     }
5458 
5459     err = 0;
5460 
5461 done:
5462     if (mapv)
5463         free(mapv);
5464     if (!err)
5465         fprintf(stderr, "OK");
5466     if (*btf_log_buf && (err || always_log))
5467         fprintf(stderr, "\n%s", btf_log_buf);
5468     if (btf_fd >= 0)
5469         close(btf_fd);
5470     if (map_fd >= 0)
5471         close(map_fd);
5472     if (pin_file)
5473         fclose(pin_file);
5474     unlink(pin_path);
5475     free(line);
5476 }
5477 
5478 static void test_pprint(void)
5479 {
5480     unsigned int i;
5481 
5482     /* test various maps with the first test template */
5483     for (i = 0; i < ARRAY_SIZE(pprint_tests_meta); i++) {
5484         pprint_test_template[0].descr = pprint_tests_meta[i].descr;
5485         pprint_test_template[0].map_type = pprint_tests_meta[i].map_type;
5486         pprint_test_template[0].map_name = pprint_tests_meta[i].map_name;
5487         pprint_test_template[0].ordered_map = pprint_tests_meta[i].ordered_map;
5488         pprint_test_template[0].lossless_map = pprint_tests_meta[i].lossless_map;
5489         pprint_test_template[0].percpu_map = pprint_tests_meta[i].percpu_map;
5490 
5491         do_test_pprint(0);
5492     }
5493 
5494     /* test rest test templates with the first map */
5495     for (i = 1; i < ARRAY_SIZE(pprint_test_template); i++) {
5496         pprint_test_template[i].descr = pprint_tests_meta[0].descr;
5497         pprint_test_template[i].map_type = pprint_tests_meta[0].map_type;
5498         pprint_test_template[i].map_name = pprint_tests_meta[0].map_name;
5499         pprint_test_template[i].ordered_map = pprint_tests_meta[0].ordered_map;
5500         pprint_test_template[i].lossless_map = pprint_tests_meta[0].lossless_map;
5501         pprint_test_template[i].percpu_map = pprint_tests_meta[0].percpu_map;
5502         do_test_pprint(i);
5503     }
5504 }
5505 
5506 #define BPF_LINE_INFO_ENC(insn_off, file_off, line_off, line_num, line_col) \
5507     (insn_off), (file_off), (line_off), ((line_num) << 10 | ((line_col) & 0x3ff))
5508 
5509 static struct prog_info_raw_test {
5510     const char *descr;
5511     const char *str_sec;
5512     const char *err_str;
5513     __u32 raw_types[MAX_NR_RAW_U32];
5514     __u32 str_sec_size;
5515     struct bpf_insn insns[MAX_INSNS];
5516     __u32 prog_type;
5517     __u32 func_info[MAX_SUBPROGS][2];
5518     __u32 func_info_rec_size;
5519     __u32 func_info_cnt;
5520     __u32 line_info[MAX_NR_RAW_U32];
5521     __u32 line_info_rec_size;
5522     __u32 nr_jited_ksyms;
5523     bool expected_prog_load_failure;
5524     __u32 dead_code_cnt;
5525     __u32 dead_code_mask;
5526     __u32 dead_func_cnt;
5527     __u32 dead_func_mask;
5528 } info_raw_tests[] = {
5529 {
5530     .descr = "func_type (main func + one sub)",
5531     .raw_types = {
5532         BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),   /* [1] */
5533         BTF_TYPE_INT_ENC(NAME_TBD, 0, 0, 32, 4),    /* [2] */
5534         BTF_FUNC_PROTO_ENC(1, 2),           /* [3] */
5535             BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
5536             BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 2),
5537         BTF_FUNC_PROTO_ENC(1, 2),           /* [4] */
5538             BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 2),
5539             BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
5540         BTF_FUNC_ENC(NAME_TBD, 3),          /* [5] */
5541         BTF_FUNC_ENC(NAME_TBD, 4),          /* [6] */
5542         BTF_END_RAW,
5543     },
5544     .str_sec = "\0int\0unsigned int\0a\0b\0c\0d\0funcA\0funcB",
5545     .str_sec_size = sizeof("\0int\0unsigned int\0a\0b\0c\0d\0funcA\0funcB"),
5546     .insns = {
5547         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2),
5548         BPF_MOV64_IMM(BPF_REG_0, 1),
5549         BPF_EXIT_INSN(),
5550         BPF_MOV64_IMM(BPF_REG_0, 2),
5551         BPF_EXIT_INSN(),
5552     },
5553     .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5554     .func_info = { {0, 5}, {3, 6} },
5555     .func_info_rec_size = 8,
5556     .func_info_cnt = 2,
5557     .line_info = { BTF_END_RAW },
5558 },
5559 
5560 {
5561     .descr = "func_type (Incorrect func_info_rec_size)",
5562     .raw_types = {
5563         BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),   /* [1] */
5564         BTF_TYPE_INT_ENC(NAME_TBD, 0, 0, 32, 4),    /* [2] */
5565         BTF_FUNC_PROTO_ENC(1, 2),           /* [3] */
5566             BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
5567             BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 2),
5568         BTF_FUNC_PROTO_ENC(1, 2),           /* [4] */
5569             BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 2),
5570             BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
5571         BTF_FUNC_ENC(NAME_TBD, 3),          /* [5] */
5572         BTF_FUNC_ENC(NAME_TBD, 4),          /* [6] */
5573         BTF_END_RAW,
5574     },
5575     .str_sec = "\0int\0unsigned int\0a\0b\0c\0d\0funcA\0funcB",
5576     .str_sec_size = sizeof("\0int\0unsigned int\0a\0b\0c\0d\0funcA\0funcB"),
5577     .insns = {
5578         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2),
5579         BPF_MOV64_IMM(BPF_REG_0, 1),
5580         BPF_EXIT_INSN(),
5581         BPF_MOV64_IMM(BPF_REG_0, 2),
5582         BPF_EXIT_INSN(),
5583     },
5584     .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5585     .func_info = { {0, 5}, {3, 6} },
5586     .func_info_rec_size = 4,
5587     .func_info_cnt = 2,
5588     .line_info = { BTF_END_RAW },
5589     .expected_prog_load_failure = true,
5590 },
5591 
5592 {
5593     .descr = "func_type (Incorrect func_info_cnt)",
5594     .raw_types = {
5595         BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),   /* [1] */
5596         BTF_TYPE_INT_ENC(NAME_TBD, 0, 0, 32, 4),    /* [2] */
5597         BTF_FUNC_PROTO_ENC(1, 2),           /* [3] */
5598             BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
5599             BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 2),
5600         BTF_FUNC_PROTO_ENC(1, 2),           /* [4] */
5601             BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 2),
5602             BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
5603         BTF_FUNC_ENC(NAME_TBD, 3),          /* [5] */
5604         BTF_FUNC_ENC(NAME_TBD, 4),          /* [6] */
5605         BTF_END_RAW,
5606     },
5607     .str_sec = "\0int\0unsigned int\0a\0b\0c\0d\0funcA\0funcB",
5608     .str_sec_size = sizeof("\0int\0unsigned int\0a\0b\0c\0d\0funcA\0funcB"),
5609     .insns = {
5610         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2),
5611         BPF_MOV64_IMM(BPF_REG_0, 1),
5612         BPF_EXIT_INSN(),
5613         BPF_MOV64_IMM(BPF_REG_0, 2),
5614         BPF_EXIT_INSN(),
5615     },
5616     .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5617     .func_info = { {0, 5}, {3, 6} },
5618     .func_info_rec_size = 8,
5619     .func_info_cnt = 1,
5620     .line_info = { BTF_END_RAW },
5621     .expected_prog_load_failure = true,
5622 },
5623 
5624 {
5625     .descr = "func_type (Incorrect bpf_func_info.insn_off)",
5626     .raw_types = {
5627         BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),   /* [1] */
5628         BTF_TYPE_INT_ENC(NAME_TBD, 0, 0, 32, 4),    /* [2] */
5629         BTF_FUNC_PROTO_ENC(1, 2),           /* [3] */
5630             BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
5631             BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 2),
5632         BTF_FUNC_PROTO_ENC(1, 2),           /* [4] */
5633             BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 2),
5634             BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
5635         BTF_FUNC_ENC(NAME_TBD, 3),          /* [5] */
5636         BTF_FUNC_ENC(NAME_TBD, 4),          /* [6] */
5637         BTF_END_RAW,
5638     },
5639     .str_sec = "\0int\0unsigned int\0a\0b\0c\0d\0funcA\0funcB",
5640     .str_sec_size = sizeof("\0int\0unsigned int\0a\0b\0c\0d\0funcA\0funcB"),
5641     .insns = {
5642         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2),
5643         BPF_MOV64_IMM(BPF_REG_0, 1),
5644         BPF_EXIT_INSN(),
5645         BPF_MOV64_IMM(BPF_REG_0, 2),
5646         BPF_EXIT_INSN(),
5647     },
5648     .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5649     .func_info = { {0, 5}, {2, 6} },
5650     .func_info_rec_size = 8,
5651     .func_info_cnt = 2,
5652     .line_info = { BTF_END_RAW },
5653     .expected_prog_load_failure = true,
5654 },
5655 
5656 {
5657     .descr = "line_info (No subprog)",
5658     .raw_types = {
5659         BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),   /* [1] */
5660         BTF_END_RAW,
5661     },
5662     BTF_STR_SEC("\0int\0int a=1;\0int b=2;\0return a + b;\0return a + b;"),
5663     .insns = {
5664         BPF_MOV64_IMM(BPF_REG_0, 1),
5665         BPF_MOV64_IMM(BPF_REG_1, 2),
5666         BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
5667         BPF_EXIT_INSN(),
5668     },
5669     .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5670     .func_info_cnt = 0,
5671     .line_info = {
5672         BPF_LINE_INFO_ENC(0, 0, NAME_TBD, 1, 10),
5673         BPF_LINE_INFO_ENC(1, 0, NAME_TBD, 2, 9),
5674         BPF_LINE_INFO_ENC(2, 0, NAME_TBD, 3, 8),
5675         BPF_LINE_INFO_ENC(3, 0, NAME_TBD, 4, 7),
5676         BTF_END_RAW,
5677     },
5678     .line_info_rec_size = sizeof(struct bpf_line_info),
5679     .nr_jited_ksyms = 1,
5680 },
5681 
5682 {
5683     .descr = "line_info (No subprog. insn_off >= prog->len)",
5684     .raw_types = {
5685         BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),   /* [1] */
5686         BTF_END_RAW,
5687     },
5688     BTF_STR_SEC("\0int\0int a=1;\0int b=2;\0return a + b;\0return a + b;"),
5689     .insns = {
5690         BPF_MOV64_IMM(BPF_REG_0, 1),
5691         BPF_MOV64_IMM(BPF_REG_1, 2),
5692         BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
5693         BPF_EXIT_INSN(),
5694     },
5695     .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5696     .func_info_cnt = 0,
5697     .line_info = {
5698         BPF_LINE_INFO_ENC(0, 0, NAME_TBD, 1, 10),
5699         BPF_LINE_INFO_ENC(1, 0, NAME_TBD, 2, 9),
5700         BPF_LINE_INFO_ENC(2, 0, NAME_TBD, 3, 8),
5701         BPF_LINE_INFO_ENC(3, 0, NAME_TBD, 4, 7),
5702         BPF_LINE_INFO_ENC(4, 0, 0, 5, 6),
5703         BTF_END_RAW,
5704     },
5705     .line_info_rec_size = sizeof(struct bpf_line_info),
5706     .nr_jited_ksyms = 1,
5707     .err_str = "line_info[4].insn_off",
5708     .expected_prog_load_failure = true,
5709 },
5710 
5711 {
5712     .descr = "line_info (Zero bpf insn code)",
5713     .raw_types = {
5714         BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),   /* [1] */
5715         BTF_TYPE_INT_ENC(NAME_TBD, 0, 0, 64, 8),    /* [2] */
5716         BTF_TYPEDEF_ENC(NAME_TBD, 2),           /* [3] */
5717         BTF_END_RAW,
5718     },
5719     BTF_STR_SEC("\0int\0unsigned long\0u64\0u64 a=1;\0return a;"),
5720     .insns = {
5721         BPF_LD_IMM64(BPF_REG_0, 1),
5722         BPF_EXIT_INSN(),
5723     },
5724     .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5725     .func_info_cnt = 0,
5726     .line_info = {
5727         BPF_LINE_INFO_ENC(0, 0, NAME_TBD, 1, 10),
5728         BPF_LINE_INFO_ENC(1, 0, 0, 2, 9),
5729         BPF_LINE_INFO_ENC(2, 0, NAME_TBD, 3, 8),
5730         BTF_END_RAW,
5731     },
5732     .line_info_rec_size = sizeof(struct bpf_line_info),
5733     .nr_jited_ksyms = 1,
5734     .err_str = "Invalid insn code at line_info[1]",
5735     .expected_prog_load_failure = true,
5736 },
5737 
5738 {
5739     .descr = "line_info (No subprog. zero tailing line_info",
5740     .raw_types = {
5741         BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),   /* [1] */
5742         BTF_END_RAW,
5743     },
5744     BTF_STR_SEC("\0int\0int a=1;\0int b=2;\0return a + b;\0return a + b;"),
5745     .insns = {
5746         BPF_MOV64_IMM(BPF_REG_0, 1),
5747         BPF_MOV64_IMM(BPF_REG_1, 2),
5748         BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
5749         BPF_EXIT_INSN(),
5750     },
5751     .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5752     .func_info_cnt = 0,
5753     .line_info = {
5754         BPF_LINE_INFO_ENC(0, 0, NAME_TBD, 1, 10), 0,
5755         BPF_LINE_INFO_ENC(1, 0, NAME_TBD, 2, 9), 0,
5756         BPF_LINE_INFO_ENC(2, 0, NAME_TBD, 3, 8), 0,
5757         BPF_LINE_INFO_ENC(3, 0, NAME_TBD, 4, 7), 0,
5758         BTF_END_RAW,
5759     },
5760     .line_info_rec_size = sizeof(struct bpf_line_info) + sizeof(__u32),
5761     .nr_jited_ksyms = 1,
5762 },
5763 
5764 {
5765     .descr = "line_info (No subprog. nonzero tailing line_info)",
5766     .raw_types = {
5767         BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),   /* [1] */
5768         BTF_END_RAW,
5769     },
5770     BTF_STR_SEC("\0int\0int a=1;\0int b=2;\0return a + b;\0return a + b;"),
5771     .insns = {
5772         BPF_MOV64_IMM(BPF_REG_0, 1),
5773         BPF_MOV64_IMM(BPF_REG_1, 2),
5774         BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
5775         BPF_EXIT_INSN(),
5776     },
5777     .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5778     .func_info_cnt = 0,
5779     .line_info = {
5780         BPF_LINE_INFO_ENC(0, 0, NAME_TBD, 1, 10), 0,
5781         BPF_LINE_INFO_ENC(1, 0, NAME_TBD, 2, 9), 0,
5782         BPF_LINE_INFO_ENC(2, 0, NAME_TBD, 3, 8), 0,
5783         BPF_LINE_INFO_ENC(3, 0, NAME_TBD, 4, 7), 1,
5784         BTF_END_RAW,
5785     },
5786     .line_info_rec_size = sizeof(struct bpf_line_info) + sizeof(__u32),
5787     .nr_jited_ksyms = 1,
5788     .err_str = "nonzero tailing record in line_info",
5789     .expected_prog_load_failure = true,
5790 },
5791 
5792 {
5793     .descr = "line_info (subprog)",
5794     .raw_types = {
5795         BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),   /* [1] */
5796         BTF_END_RAW,
5797     },
5798     BTF_STR_SEC("\0int\0int a=1+1;\0return func(a);\0b+=1;\0return b;"),
5799     .insns = {
5800         BPF_MOV64_IMM(BPF_REG_2, 1),
5801         BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, 1),
5802         BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
5803         BPF_CALL_REL(1),
5804         BPF_EXIT_INSN(),
5805         BPF_MOV64_REG(BPF_REG_0, BPF_REG_1),
5806         BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 1),
5807         BPF_EXIT_INSN(),
5808     },
5809     .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5810     .func_info_cnt = 0,
5811     .line_info = {
5812         BPF_LINE_INFO_ENC(0, 0, NAME_TBD, 1, 10),
5813         BPF_LINE_INFO_ENC(2, 0, NAME_TBD, 2, 9),
5814         BPF_LINE_INFO_ENC(5, 0, NAME_TBD, 3, 8),
5815         BPF_LINE_INFO_ENC(7, 0, NAME_TBD, 4, 7),
5816         BTF_END_RAW,
5817     },
5818     .line_info_rec_size = sizeof(struct bpf_line_info),
5819     .nr_jited_ksyms = 2,
5820 },
5821 
5822 {
5823     .descr = "line_info (subprog + func_info)",
5824     .raw_types = {
5825         BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),   /* [1] */
5826         BTF_FUNC_PROTO_ENC(1, 1),           /* [2] */
5827             BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
5828         BTF_FUNC_ENC(NAME_TBD, 2),          /* [3] */
5829         BTF_FUNC_ENC(NAME_TBD, 2),          /* [4] */
5830         BTF_END_RAW,
5831     },
5832     BTF_STR_SEC("\0int\0x\0sub\0main\0int a=1+1;\0return func(a);\0b+=1;\0return b;"),
5833     .insns = {
5834         BPF_MOV64_IMM(BPF_REG_2, 1),
5835         BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, 1),
5836         BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
5837         BPF_CALL_REL(1),
5838         BPF_EXIT_INSN(),
5839         BPF_MOV64_REG(BPF_REG_0, BPF_REG_1),
5840         BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 1),
5841         BPF_EXIT_INSN(),
5842     },
5843     .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5844     .func_info_cnt = 2,
5845     .func_info_rec_size = 8,
5846     .func_info = { {0, 4}, {5, 3} },
5847     .line_info = {
5848         BPF_LINE_INFO_ENC(0, 0, NAME_TBD, 1, 10),
5849         BPF_LINE_INFO_ENC(2, 0, NAME_TBD, 2, 9),
5850         BPF_LINE_INFO_ENC(5, 0, NAME_TBD, 3, 8),
5851         BPF_LINE_INFO_ENC(7, 0, NAME_TBD, 4, 7),
5852         BTF_END_RAW,
5853     },
5854     .line_info_rec_size = sizeof(struct bpf_line_info),
5855     .nr_jited_ksyms = 2,
5856 },
5857 
5858 {
5859     .descr = "line_info (subprog. missing 1st func line info)",
5860     .raw_types = {
5861         BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),   /* [1] */
5862         BTF_END_RAW,
5863     },
5864     BTF_STR_SEC("\0int\0int a=1+1;\0return func(a);\0b+=1;\0return b;"),
5865     .insns = {
5866         BPF_MOV64_IMM(BPF_REG_2, 1),
5867         BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, 1),
5868         BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
5869         BPF_CALL_REL(1),
5870         BPF_EXIT_INSN(),
5871         BPF_MOV64_REG(BPF_REG_0, BPF_REG_1),
5872         BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 1),
5873         BPF_EXIT_INSN(),
5874     },
5875     .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5876     .func_info_cnt = 0,
5877     .line_info = {
5878         BPF_LINE_INFO_ENC(1, 0, NAME_TBD, 1, 10),
5879         BPF_LINE_INFO_ENC(2, 0, NAME_TBD, 2, 9),
5880         BPF_LINE_INFO_ENC(5, 0, NAME_TBD, 3, 8),
5881         BPF_LINE_INFO_ENC(7, 0, NAME_TBD, 4, 7),
5882         BTF_END_RAW,
5883     },
5884     .line_info_rec_size = sizeof(struct bpf_line_info),
5885     .nr_jited_ksyms = 2,
5886     .err_str = "missing bpf_line_info for func#0",
5887     .expected_prog_load_failure = true,
5888 },
5889 
5890 {
5891     .descr = "line_info (subprog. missing 2nd func line info)",
5892     .raw_types = {
5893         BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),   /* [1] */
5894         BTF_END_RAW,
5895     },
5896     BTF_STR_SEC("\0int\0int a=1+1;\0return func(a);\0b+=1;\0return b;"),
5897     .insns = {
5898         BPF_MOV64_IMM(BPF_REG_2, 1),
5899         BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, 1),
5900         BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
5901         BPF_CALL_REL(1),
5902         BPF_EXIT_INSN(),
5903         BPF_MOV64_REG(BPF_REG_0, BPF_REG_1),
5904         BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 1),
5905         BPF_EXIT_INSN(),
5906     },
5907     .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5908     .func_info_cnt = 0,
5909     .line_info = {
5910         BPF_LINE_INFO_ENC(0, 0, NAME_TBD, 1, 10),
5911         BPF_LINE_INFO_ENC(2, 0, NAME_TBD, 2, 9),
5912         BPF_LINE_INFO_ENC(6, 0, NAME_TBD, 3, 8),
5913         BPF_LINE_INFO_ENC(7, 0, NAME_TBD, 4, 7),
5914         BTF_END_RAW,
5915     },
5916     .line_info_rec_size = sizeof(struct bpf_line_info),
5917     .nr_jited_ksyms = 2,
5918     .err_str = "missing bpf_line_info for func#1",
5919     .expected_prog_load_failure = true,
5920 },
5921 
5922 {
5923     .descr = "line_info (subprog. unordered insn offset)",
5924     .raw_types = {
5925         BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),   /* [1] */
5926         BTF_END_RAW,
5927     },
5928     BTF_STR_SEC("\0int\0int a=1+1;\0return func(a);\0b+=1;\0return b;"),
5929     .insns = {
5930         BPF_MOV64_IMM(BPF_REG_2, 1),
5931         BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, 1),
5932         BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
5933         BPF_CALL_REL(1),
5934         BPF_EXIT_INSN(),
5935         BPF_MOV64_REG(BPF_REG_0, BPF_REG_1),
5936         BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 1),
5937         BPF_EXIT_INSN(),
5938     },
5939     .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5940     .func_info_cnt = 0,
5941     .line_info = {
5942         BPF_LINE_INFO_ENC(0, 0, NAME_TBD, 1, 10),
5943         BPF_LINE_INFO_ENC(5, 0, NAME_TBD, 2, 9),
5944         BPF_LINE_INFO_ENC(2, 0, NAME_TBD, 3, 8),
5945         BPF_LINE_INFO_ENC(7, 0, NAME_TBD, 4, 7),
5946         BTF_END_RAW,
5947     },
5948     .line_info_rec_size = sizeof(struct bpf_line_info),
5949     .nr_jited_ksyms = 2,
5950     .err_str = "Invalid line_info[2].insn_off",
5951     .expected_prog_load_failure = true,
5952 },
5953 
5954 {
5955     .descr = "line_info (dead start)",
5956     .raw_types = {
5957         BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),   /* [1] */
5958         BTF_END_RAW,
5959     },
5960     BTF_STR_SEC("\0int\0/* dead jmp */\0int a=1;\0int b=2;\0return a + b;\0return a + b;"),
5961     .insns = {
5962         BPF_JMP_IMM(BPF_JA, 0, 0, 0),
5963         BPF_MOV64_IMM(BPF_REG_0, 1),
5964         BPF_MOV64_IMM(BPF_REG_1, 2),
5965         BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
5966         BPF_EXIT_INSN(),
5967     },
5968     .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5969     .func_info_cnt = 0,
5970     .line_info = {
5971         BPF_LINE_INFO_ENC(0, 0, NAME_TBD, 1, 10),
5972         BPF_LINE_INFO_ENC(1, 0, NAME_TBD, 2, 9),
5973         BPF_LINE_INFO_ENC(2, 0, NAME_TBD, 3, 8),
5974         BPF_LINE_INFO_ENC(3, 0, NAME_TBD, 4, 7),
5975         BPF_LINE_INFO_ENC(4, 0, NAME_TBD, 5, 6),
5976         BTF_END_RAW,
5977     },
5978     .line_info_rec_size = sizeof(struct bpf_line_info),
5979     .nr_jited_ksyms = 1,
5980     .dead_code_cnt = 1,
5981     .dead_code_mask = 0x01,
5982 },
5983 
5984 {
5985     .descr = "line_info (dead end)",
5986     .raw_types = {
5987         BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),   /* [1] */
5988         BTF_END_RAW,
5989     },
5990     BTF_STR_SEC("\0int\0int a=1;\0int b=2;\0return a + b;\0/* dead jmp */\0return a + b;\0/* dead exit */"),
5991     .insns = {
5992         BPF_MOV64_IMM(BPF_REG_0, 1),
5993         BPF_MOV64_IMM(BPF_REG_1, 2),
5994         BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
5995         BPF_JMP_IMM(BPF_JGE, BPF_REG_0, 10, 1),
5996         BPF_EXIT_INSN(),
5997         BPF_EXIT_INSN(),
5998     },
5999     .prog_type = BPF_PROG_TYPE_TRACEPOINT,
6000     .func_info_cnt = 0,
6001     .line_info = {
6002         BPF_LINE_INFO_ENC(0, 0, NAME_TBD, 1, 12),
6003         BPF_LINE_INFO_ENC(1, 0, NAME_TBD, 2, 11),
6004         BPF_LINE_INFO_ENC(2, 0, NAME_TBD, 3, 10),
6005         BPF_LINE_INFO_ENC(3, 0, NAME_TBD, 4, 9),
6006         BPF_LINE_INFO_ENC(4, 0, NAME_TBD, 5, 8),
6007         BPF_LINE_INFO_ENC(5, 0, NAME_TBD, 6, 7),
6008         BTF_END_RAW,
6009     },
6010     .line_info_rec_size = sizeof(struct bpf_line_info),
6011     .nr_jited_ksyms = 1,
6012     .dead_code_cnt = 2,
6013     .dead_code_mask = 0x28,
6014 },
6015 
6016 {
6017     .descr = "line_info (dead code + subprog + func_info)",
6018     .raw_types = {
6019         BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),   /* [1] */
6020         BTF_FUNC_PROTO_ENC(1, 1),           /* [2] */
6021             BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
6022         BTF_FUNC_ENC(NAME_TBD, 2),          /* [3] */
6023         BTF_FUNC_ENC(NAME_TBD, 2),          /* [4] */
6024         BTF_END_RAW,
6025     },
6026     BTF_STR_SEC("\0int\0x\0sub\0main\0int a=1+1;\0/* dead jmp */"
6027             "\0/* dead */\0/* dead */\0/* dead */\0/* dead */"
6028             "\0/* dead */\0/* dead */\0/* dead */\0/* dead */"
6029             "\0return func(a);\0b+=1;\0return b;"),
6030     .insns = {
6031         BPF_MOV64_IMM(BPF_REG_2, 1),
6032         BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, 1),
6033         BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
6034         BPF_JMP_IMM(BPF_JGE, BPF_REG_2, 0, 8),
6035         BPF_MOV64_IMM(BPF_REG_2, 1),
6036         BPF_MOV64_IMM(BPF_REG_2, 1),
6037         BPF_MOV64_IMM(BPF_REG_2, 1),
6038         BPF_MOV64_IMM(BPF_REG_2, 1),
6039         BPF_MOV64_IMM(BPF_REG_2, 1),
6040         BPF_MOV64_IMM(BPF_REG_2, 1),
6041         BPF_MOV64_IMM(BPF_REG_2, 1),
6042         BPF_MOV64_IMM(BPF_REG_2, 1),
6043         BPF_CALL_REL(1),
6044         BPF_EXIT_INSN(),
6045         BPF_MOV64_REG(BPF_REG_0, BPF_REG_1),
6046         BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 1),
6047         BPF_EXIT_INSN(),
6048     },
6049     .prog_type = BPF_PROG_TYPE_TRACEPOINT,
6050     .func_info_cnt = 2,
6051     .func_info_rec_size = 8,
6052     .func_info = { {0, 4}, {14, 3} },
6053     .line_info = {
6054         BPF_LINE_INFO_ENC(0, 0, NAME_TBD, 1, 10),
6055         BPF_LINE_INFO_ENC(3, 0, NAME_TBD, 1, 10),
6056         BPF_LINE_INFO_ENC(4, 0, NAME_TBD, 1, 10),
6057         BPF_LINE_INFO_ENC(5, 0, NAME_TBD, 1, 10),
6058         BPF_LINE_INFO_ENC(6, 0, NAME_TBD, 1, 10),
6059         BPF_LINE_INFO_ENC(7, 0, NAME_TBD, 1, 10),
6060         BPF_LINE_INFO_ENC(8, 0, NAME_TBD, 1, 10),
6061         BPF_LINE_INFO_ENC(9, 0, NAME_TBD, 1, 10),
6062         BPF_LINE_INFO_ENC(10, 0, NAME_TBD, 1, 10),
6063         BPF_LINE_INFO_ENC(11, 0, NAME_TBD, 2, 9),
6064         BPF_LINE_INFO_ENC(12, 0, NAME_TBD, 2, 9),
6065         BPF_LINE_INFO_ENC(14, 0, NAME_TBD, 3, 8),
6066         BPF_LINE_INFO_ENC(16, 0, NAME_TBD, 4, 7),
6067         BTF_END_RAW,
6068     },
6069     .line_info_rec_size = sizeof(struct bpf_line_info),
6070     .nr_jited_ksyms = 2,
6071     .dead_code_cnt = 9,
6072     .dead_code_mask = 0x3fe,
6073 },
6074 
6075 {
6076     .descr = "line_info (dead subprog)",
6077     .raw_types = {
6078         BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),   /* [1] */
6079         BTF_FUNC_PROTO_ENC(1, 1),           /* [2] */
6080             BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
6081         BTF_FUNC_ENC(NAME_TBD, 2),          /* [3] */
6082         BTF_FUNC_ENC(NAME_TBD, 2),          /* [4] */
6083         BTF_FUNC_ENC(NAME_TBD, 2),          /* [5] */
6084         BTF_END_RAW,
6085     },
6086     BTF_STR_SEC("\0int\0x\0dead\0main\0func\0int a=1+1;\0/* live call */"
6087             "\0return 0;\0return 0;\0/* dead */\0/* dead */"
6088             "\0/* dead */\0return bla + 1;\0return bla + 1;"
6089             "\0return bla + 1;\0return func(a);\0b+=1;\0return b;"),
6090     .insns = {
6091         BPF_MOV64_IMM(BPF_REG_2, 1),
6092         BPF_JMP_IMM(BPF_JGE, BPF_REG_2, 0, 1),
6093         BPF_CALL_REL(3),
6094         BPF_CALL_REL(5),
6095         BPF_MOV64_IMM(BPF_REG_0, 0),
6096         BPF_EXIT_INSN(),
6097         BPF_MOV64_IMM(BPF_REG_0, 0),
6098         BPF_CALL_REL(1),
6099         BPF_EXIT_INSN(),
6100         BPF_MOV64_REG(BPF_REG_0, 2),
6101         BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 1),
6102         BPF_EXIT_INSN(),
6103     },
6104     .prog_type = BPF_PROG_TYPE_TRACEPOINT,
6105     .func_info_cnt = 3,
6106     .func_info_rec_size = 8,
6107         .func_info = { {0, 4}, {6, 3}, {9, 5} },
6108     .line_info = {
6109         BPF_LINE_INFO_ENC(0, 0, NAME_TBD, 1, 10),
6110         BPF_LINE_INFO_ENC(3, 0, NAME_TBD, 1, 10),
6111         BPF_LINE_INFO_ENC(4, 0, NAME_TBD, 1, 10),
6112         BPF_LINE_INFO_ENC(5, 0, NAME_TBD, 1, 10),
6113         BPF_LINE_INFO_ENC(6, 0, NAME_TBD, 1, 10),
6114         BPF_LINE_INFO_ENC(7, 0, NAME_TBD, 1, 10),
6115         BPF_LINE_INFO_ENC(8, 0, NAME_TBD, 1, 10),
6116         BPF_LINE_INFO_ENC(9, 0, NAME_TBD, 1, 10),
6117         BPF_LINE_INFO_ENC(10, 0, NAME_TBD, 1, 10),
6118         BPF_LINE_INFO_ENC(11, 0, NAME_TBD, 2, 9),
6119         BTF_END_RAW,
6120     },
6121     .line_info_rec_size = sizeof(struct bpf_line_info),
6122     .nr_jited_ksyms = 2,
6123     .dead_code_cnt = 3,
6124     .dead_code_mask = 0x70,
6125     .dead_func_cnt = 1,
6126     .dead_func_mask = 0x2,
6127 },
6128 
6129 {
6130     .descr = "line_info (dead last subprog)",
6131     .raw_types = {
6132         BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),   /* [1] */
6133         BTF_FUNC_PROTO_ENC(1, 1),           /* [2] */
6134             BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
6135         BTF_FUNC_ENC(NAME_TBD, 2),          /* [3] */
6136         BTF_FUNC_ENC(NAME_TBD, 2),          /* [5] */
6137         BTF_END_RAW,
6138     },
6139     BTF_STR_SEC("\0int\0x\0dead\0main\0int a=1+1;\0/* live call */"
6140             "\0return 0;\0/* dead */\0/* dead */"),
6141     .insns = {
6142         BPF_MOV64_IMM(BPF_REG_2, 1),
6143         BPF_JMP_IMM(BPF_JGE, BPF_REG_2, 0, 1),
6144         BPF_CALL_REL(2),
6145         BPF_MOV64_IMM(BPF_REG_0, 0),
6146         BPF_EXIT_INSN(),
6147         BPF_MOV64_IMM(BPF_REG_0, 0),
6148         BPF_EXIT_INSN(),
6149     },
6150     .prog_type = BPF_PROG_TYPE_TRACEPOINT,
6151     .func_info_cnt = 2,
6152     .func_info_rec_size = 8,
6153         .func_info = { {0, 4}, {5, 3} },
6154     .line_info = {
6155         BPF_LINE_INFO_ENC(0, 0, NAME_TBD, 1, 10),
6156         BPF_LINE_INFO_ENC(3, 0, NAME_TBD, 1, 10),
6157         BPF_LINE_INFO_ENC(4, 0, NAME_TBD, 1, 10),
6158         BPF_LINE_INFO_ENC(5, 0, NAME_TBD, 1, 10),
6159         BPF_LINE_INFO_ENC(6, 0, NAME_TBD, 1, 10),
6160         BTF_END_RAW,
6161     },
6162     .line_info_rec_size = sizeof(struct bpf_line_info),
6163     .nr_jited_ksyms = 1,
6164     .dead_code_cnt = 2,
6165     .dead_code_mask = 0x18,
6166     .dead_func_cnt = 1,
6167     .dead_func_mask = 0x2,
6168 },
6169 
6170 {
6171     .descr = "line_info (dead subprog + dead start)",
6172     .raw_types = {
6173         BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),   /* [1] */
6174         BTF_FUNC_PROTO_ENC(1, 1),           /* [2] */
6175             BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
6176         BTF_FUNC_ENC(NAME_TBD, 2),          /* [3] */
6177         BTF_FUNC_ENC(NAME_TBD, 2),          /* [4] */
6178         BTF_FUNC_ENC(NAME_TBD, 2),          /* [5] */
6179         BTF_END_RAW,
6180     },
6181     BTF_STR_SEC("\0int\0x\0dead\0main\0func\0int a=1+1;\0/* dead */"
6182             "\0return 0;\0return 0;\0return 0;"
6183             "\0/* dead */\0/* dead */\0/* dead */\0/* dead */"
6184             "\0return b + 1;\0return b + 1;\0return b + 1;"),
6185     .insns = {
6186         BPF_JMP_IMM(BPF_JA, 0, 0, 0),
6187         BPF_MOV64_IMM(BPF_REG_2, 1),
6188         BPF_JMP_IMM(BPF_JGE, BPF_REG_2, 0, 1),
6189         BPF_CALL_REL(3),
6190         BPF_CALL_REL(5),
6191         BPF_MOV64_IMM(BPF_REG_0, 0),
6192         BPF_EXIT_INSN(),
6193         BPF_MOV64_IMM(BPF_REG_0, 0),
6194         BPF_CALL_REL(1),
6195         BPF_EXIT_INSN(),
6196         BPF_JMP_IMM(BPF_JA, 0, 0, 0),
6197         BPF_MOV64_REG(BPF_REG_0, 2),
6198         BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 1),
6199         BPF_EXIT_INSN(),
6200     },
6201     .prog_type = BPF_PROG_TYPE_TRACEPOINT,
6202     .func_info_cnt = 3,
6203     .func_info_rec_size = 8,
6204         .func_info = { {0, 4}, {7, 3}, {10, 5} },
6205     .line_info = {
6206         BPF_LINE_INFO_ENC(0, 0, NAME_TBD, 1, 10),
6207         BPF_LINE_INFO_ENC(3, 0, NAME_TBD, 1, 10),
6208         BPF_LINE_INFO_ENC(4, 0, NAME_TBD, 1, 10),
6209         BPF_LINE_INFO_ENC(5, 0, NAME_TBD, 1, 10),
6210         BPF_LINE_INFO_ENC(6, 0, NAME_TBD, 1, 10),
6211         BPF_LINE_INFO_ENC(7, 0, NAME_TBD, 1, 10),
6212         BPF_LINE_INFO_ENC(8, 0, NAME_TBD, 1, 10),
6213         BPF_LINE_INFO_ENC(9, 0, NAME_TBD, 1, 10),
6214         BPF_LINE_INFO_ENC(10, 0, NAME_TBD, 1, 10),
6215         BPF_LINE_INFO_ENC(11, 0, NAME_TBD, 2, 9),
6216         BPF_LINE_INFO_ENC(12, 0, NAME_TBD, 2, 9),
6217         BPF_LINE_INFO_ENC(13, 0, NAME_TBD, 2, 9),
6218         BTF_END_RAW,
6219     },
6220     .line_info_rec_size = sizeof(struct bpf_line_info),
6221     .nr_jited_ksyms = 2,
6222     .dead_code_cnt = 5,
6223     .dead_code_mask = 0x1e2,
6224     .dead_func_cnt = 1,
6225     .dead_func_mask = 0x2,
6226 },
6227 
6228 {
6229     .descr = "line_info (dead subprog + dead start w/ move)",
6230     .raw_types = {
6231         BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),   /* [1] */
6232         BTF_FUNC_PROTO_ENC(1, 1),           /* [2] */
6233             BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
6234         BTF_FUNC_ENC(NAME_TBD, 2),          /* [3] */
6235         BTF_FUNC_ENC(NAME_TBD, 2),          /* [4] */
6236         BTF_FUNC_ENC(NAME_TBD, 2),          /* [5] */
6237         BTF_END_RAW,
6238     },
6239     BTF_STR_SEC("\0int\0x\0dead\0main\0func\0int a=1+1;\0/* live call */"
6240             "\0return 0;\0return 0;\0/* dead */\0/* dead */"
6241             "\0/* dead */\0return bla + 1;\0return bla + 1;"
6242             "\0return bla + 1;\0return func(a);\0b+=1;\0return b;"),
6243     .insns = {
6244         BPF_MOV64_IMM(BPF_REG_2, 1),
6245         BPF_JMP_IMM(BPF_JGE, BPF_REG_2, 0, 1),
6246         BPF_CALL_REL(3),
6247         BPF_CALL_REL(5),
6248         BPF_MOV64_IMM(BPF_REG_0, 0),
6249         BPF_EXIT_INSN(),
6250         BPF_MOV64_IMM(BPF_REG_0, 0),
6251         BPF_CALL_REL(1),
6252         BPF_EXIT_INSN(),
6253         BPF_JMP_IMM(BPF_JA, 0, 0, 0),
6254         BPF_MOV64_REG(BPF_REG_0, 2),
6255         BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 1),
6256         BPF_EXIT_INSN(),
6257     },
6258     .prog_type = BPF_PROG_TYPE_TRACEPOINT,
6259     .func_info_cnt = 3,
6260     .func_info_rec_size = 8,
6261         .func_info = { {0, 4}, {6, 3}, {9, 5} },
6262     .line_info = {
6263         BPF_LINE_INFO_ENC(0, 0, NAME_TBD, 1, 10),
6264         BPF_LINE_INFO_ENC(3, 0, NAME_TBD, 1, 10),
6265         BPF_LINE_INFO_ENC(4, 0, NAME_TBD, 1, 10),
6266         BPF_LINE_INFO_ENC(5, 0, NAME_TBD, 1, 10),
6267         BPF_LINE_INFO_ENC(6, 0, NAME_TBD, 1, 10),
6268         BPF_LINE_INFO_ENC(7, 0, NAME_TBD, 1, 10),
6269         BPF_LINE_INFO_ENC(8, 0, NAME_TBD, 1, 10),
6270         BPF_LINE_INFO_ENC(9, 0, NAME_TBD, 1, 10),
6271         BPF_LINE_INFO_ENC(11, 0, NAME_TBD, 1, 10),
6272         BPF_LINE_INFO_ENC(12, 0, NAME_TBD, 2, 9),
6273         BTF_END_RAW,
6274     },
6275     .line_info_rec_size = sizeof(struct bpf_line_info),
6276     .nr_jited_ksyms = 2,
6277     .dead_code_cnt = 3,
6278     .dead_code_mask = 0x70,
6279     .dead_func_cnt = 1,
6280     .dead_func_mask = 0x2,
6281 },
6282 
6283 {
6284     .descr = "line_info (dead end + subprog start w/ no linfo)",
6285     .raw_types = {
6286         BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),   /* [1] */
6287         BTF_FUNC_PROTO_ENC(1, 1),           /* [2] */
6288             BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
6289         BTF_FUNC_ENC(NAME_TBD, 2),          /* [3] */
6290         BTF_FUNC_ENC(NAME_TBD, 2),          /* [4] */
6291         BTF_END_RAW,
6292     },
6293     BTF_STR_SEC("\0int\0x\0main\0func\0/* main linfo */\0/* func linfo */"),
6294     .insns = {
6295         BPF_MOV64_IMM(BPF_REG_0, 0),
6296         BPF_JMP_IMM(BPF_JGE, BPF_REG_0, 1, 3),
6297         BPF_CALL_REL(3),
6298         BPF_MOV64_IMM(BPF_REG_0, 0),
6299         BPF_EXIT_INSN(),
6300         BPF_EXIT_INSN(),
6301         BPF_JMP_IMM(BPF_JA, 0, 0, 0),
6302         BPF_EXIT_INSN(),
6303     },
6304     .prog_type = BPF_PROG_TYPE_TRACEPOINT,
6305     .func_info_cnt = 2,
6306     .func_info_rec_size = 8,
6307     .func_info = { {0, 3}, {6, 4}, },
6308     .line_info = {
6309         BPF_LINE_INFO_ENC(0, 0, NAME_TBD, 1, 10),
6310         BPF_LINE_INFO_ENC(6, 0, NAME_TBD, 1, 10),
6311         BTF_END_RAW,
6312     },
6313     .line_info_rec_size = sizeof(struct bpf_line_info),
6314     .nr_jited_ksyms = 2,
6315 },
6316 
6317 };
6318 
6319 static size_t probe_prog_length(const struct bpf_insn *fp)
6320 {
6321     size_t len;
6322 
6323     for (len = MAX_INSNS - 1; len > 0; --len)
6324         if (fp[len].code != 0 || fp[len].imm != 0)
6325             break;
6326     return len + 1;
6327 }
6328 
6329 static __u32 *patch_name_tbd(const __u32 *raw_u32,
6330                  const char *str, __u32 str_off,
6331                  unsigned int str_sec_size,
6332                  unsigned int *ret_size)
6333 {
6334     int i, raw_u32_size = get_raw_sec_size(raw_u32);
6335     const char *end_str = str + str_sec_size;
6336     const char *next_str = str + str_off;
6337     __u32 *new_u32 = NULL;
6338 
6339     if (raw_u32_size == -1)
6340         return ERR_PTR(-EINVAL);
6341 
6342     if (!raw_u32_size) {
6343         *ret_size = 0;
6344         return NULL;
6345     }
6346 
6347     new_u32 = malloc(raw_u32_size);
6348     if (!new_u32)
6349         return ERR_PTR(-ENOMEM);
6350 
6351     for (i = 0; i < raw_u32_size / sizeof(raw_u32[0]); i++) {
6352         if (raw_u32[i] == NAME_TBD) {
6353             next_str = get_next_str(next_str, end_str);
6354             if (CHECK(!next_str, "Error in getting next_str\n")) {
6355                 free(new_u32);
6356                 return ERR_PTR(-EINVAL);
6357             }
6358             new_u32[i] = next_str - str;
6359             next_str += strlen(next_str);
6360         } else {
6361             new_u32[i] = raw_u32[i];
6362         }
6363     }
6364 
6365     *ret_size = raw_u32_size;
6366     return new_u32;
6367 }
6368 
6369 static int test_get_finfo(const struct prog_info_raw_test *test,
6370               int prog_fd)
6371 {
6372     struct bpf_prog_info info = {};
6373     struct bpf_func_info *finfo;
6374     __u32 info_len, rec_size, i;
6375     void *func_info = NULL;
6376     __u32 nr_func_info;
6377     int err;
6378 
6379     /* get necessary lens */
6380     info_len = sizeof(struct bpf_prog_info);
6381     err = bpf_obj_get_info_by_fd(prog_fd, &info, &info_len);
6382     if (CHECK(err < 0, "invalid get info (1st) errno:%d", errno)) {
6383         fprintf(stderr, "%s\n", btf_log_buf);
6384         return -1;
6385     }
6386     nr_func_info = test->func_info_cnt - test->dead_func_cnt;
6387     if (CHECK(info.nr_func_info != nr_func_info,
6388           "incorrect info.nr_func_info (1st) %d",
6389           info.nr_func_info)) {
6390         return -1;
6391     }
6392 
6393     rec_size = info.func_info_rec_size;
6394     if (CHECK(rec_size != sizeof(struct bpf_func_info),
6395           "incorrect info.func_info_rec_size (1st) %d", rec_size)) {
6396         return -1;
6397     }
6398 
6399     if (!info.nr_func_info)
6400         return 0;
6401 
6402     func_info = malloc(info.nr_func_info * rec_size);
6403     if (CHECK(!func_info, "out of memory"))
6404         return -1;
6405 
6406     /* reset info to only retrieve func_info related data */
6407     memset(&info, 0, sizeof(info));
6408     info.nr_func_info = nr_func_info;
6409     info.func_info_rec_size = rec_size;
6410     info.func_info = ptr_to_u64(func_info);
6411     err = bpf_obj_get_info_by_fd(prog_fd, &info, &info_len);
6412     if (CHECK(err < 0, "invalid get info (2nd) errno:%d", errno)) {
6413         fprintf(stderr, "%s\n", btf_log_buf);
6414         err = -1;
6415         goto done;
6416     }
6417     if (CHECK(info.nr_func_info != nr_func_info,
6418           "incorrect info.nr_func_info (2nd) %d",
6419           info.nr_func_info)) {
6420         err = -1;
6421         goto done;
6422     }
6423     if (CHECK(info.func_info_rec_size != rec_size,
6424           "incorrect info.func_info_rec_size (2nd) %d",
6425           info.func_info_rec_size)) {
6426         err = -1;
6427         goto done;
6428     }
6429 
6430     finfo = func_info;
6431     for (i = 0; i < nr_func_info; i++) {
6432         if (test->dead_func_mask & (1 << i))
6433             continue;
6434         if (CHECK(finfo->type_id != test->func_info[i][1],
6435               "incorrect func_type %u expected %u",
6436               finfo->type_id, test->func_info[i][1])) {
6437             err = -1;
6438             goto done;
6439         }
6440         finfo = (void *)finfo + rec_size;
6441     }
6442 
6443     err = 0;
6444 
6445 done:
6446     free(func_info);
6447     return err;
6448 }
6449 
6450 static int test_get_linfo(const struct prog_info_raw_test *test,
6451               const void *patched_linfo,
6452               __u32 cnt, int prog_fd)
6453 {
6454     __u32 i, info_len, nr_jited_ksyms, nr_jited_func_lens;
6455     __u64 *jited_linfo = NULL, *jited_ksyms = NULL;
6456     __u32 rec_size, jited_rec_size, jited_cnt;
6457     struct bpf_line_info *linfo = NULL;
6458     __u32 cur_func_len, ksyms_found;
6459     struct bpf_prog_info info = {};
6460     __u32 *jited_func_lens = NULL;
6461     __u64 cur_func_ksyms;
6462     __u32 dead_insns;
6463     int err;
6464 
6465     jited_cnt = cnt;
6466     rec_size = sizeof(*linfo);
6467     jited_rec_size = sizeof(*jited_linfo);
6468     if (test->nr_jited_ksyms)
6469         nr_jited_ksyms = test->nr_jited_ksyms;
6470     else
6471         nr_jited_ksyms = test->func_info_cnt - test->dead_func_cnt;
6472     nr_jited_func_lens = nr_jited_ksyms;
6473 
6474     info_len = sizeof(struct bpf_prog_info);
6475     err = bpf_obj_get_info_by_fd(prog_fd, &info, &info_len);
6476     if (CHECK(err < 0, "err:%d errno:%d", err, errno)) {
6477         err = -1;
6478         goto done;
6479     }
6480 
6481     if (!info.jited_prog_len) {
6482         /* prog is not jited */
6483         jited_cnt = 0;
6484         nr_jited_ksyms = 1;
6485         nr_jited_func_lens = 1;
6486     }
6487 
6488     if (CHECK(info.nr_line_info != cnt ||
6489           info.nr_jited_line_info != jited_cnt ||
6490           info.nr_jited_ksyms != nr_jited_ksyms ||
6491           info.nr_jited_func_lens != nr_jited_func_lens ||
6492           (!info.nr_line_info && info.nr_jited_line_info),
6493           "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)",
6494           info.nr_line_info, cnt,
6495           info.nr_jited_line_info, jited_cnt,
6496           info.nr_jited_ksyms, nr_jited_ksyms,
6497           info.nr_jited_func_lens, nr_jited_func_lens)) {
6498         err = -1;
6499         goto done;
6500     }
6501 
6502     if (CHECK(info.line_info_rec_size != sizeof(struct bpf_line_info) ||
6503           info.jited_line_info_rec_size != sizeof(__u64),
6504           "info: line_info_rec_size:%u(userspace expected:%u) jited_line_info_rec_size:%u(userspace expected:%u)",
6505           info.line_info_rec_size, rec_size,
6506           info.jited_line_info_rec_size, jited_rec_size)) {
6507         err = -1;
6508         goto done;
6509     }
6510 
6511     if (!cnt)
6512         return 0;
6513 
6514     rec_size = info.line_info_rec_size;
6515     jited_rec_size = info.jited_line_info_rec_size;
6516 
6517     memset(&info, 0, sizeof(info));
6518 
6519     linfo = calloc(cnt, rec_size);
6520     if (CHECK(!linfo, "!linfo")) {
6521         err = -1;
6522         goto done;
6523     }
6524     info.nr_line_info = cnt;
6525     info.line_info_rec_size = rec_size;
6526     info.line_info = ptr_to_u64(linfo);
6527 
6528     if (jited_cnt) {
6529         jited_linfo = calloc(jited_cnt, jited_rec_size);
6530         jited_ksyms = calloc(nr_jited_ksyms, sizeof(*jited_ksyms));
6531         jited_func_lens = calloc(nr_jited_func_lens,
6532                      sizeof(*jited_func_lens));
6533         if (CHECK(!jited_linfo || !jited_ksyms || !jited_func_lens,
6534               "jited_linfo:%p jited_ksyms:%p jited_func_lens:%p",
6535               jited_linfo, jited_ksyms, jited_func_lens)) {
6536             err = -1;
6537             goto done;
6538         }
6539 
6540         info.nr_jited_line_info = jited_cnt;
6541         info.jited_line_info_rec_size = jited_rec_size;
6542         info.jited_line_info = ptr_to_u64(jited_linfo);
6543         info.nr_jited_ksyms = nr_jited_ksyms;
6544         info.jited_ksyms = ptr_to_u64(jited_ksyms);
6545         info.nr_jited_func_lens = nr_jited_func_lens;
6546         info.jited_func_lens = ptr_to_u64(jited_func_lens);
6547     }
6548 
6549     err = bpf_obj_get_info_by_fd(prog_fd, &info, &info_len);
6550 
6551     /*
6552      * Only recheck the info.*line_info* fields.
6553      * Other fields are not the concern of this test.
6554      */
6555     if (CHECK(err < 0 ||
6556           info.nr_line_info != cnt ||
6557           (jited_cnt && !info.jited_line_info) ||
6558           info.nr_jited_line_info != jited_cnt ||
6559           info.line_info_rec_size != rec_size ||
6560           info.jited_line_info_rec_size != jited_rec_size,
6561           "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",
6562           err, errno,
6563           info.nr_line_info, cnt,
6564           info.nr_jited_line_info, jited_cnt,
6565           info.line_info_rec_size, rec_size,
6566           info.jited_line_info_rec_size, jited_rec_size,
6567           (void *)(long)info.line_info,
6568           (void *)(long)info.jited_line_info)) {
6569         err = -1;
6570         goto done;
6571     }
6572 
6573     dead_insns = 0;
6574     while (test->dead_code_mask & (1 << dead_insns))
6575         dead_insns++;
6576 
6577     CHECK(linfo[0].insn_off, "linfo[0].insn_off:%u",
6578           linfo[0].insn_off);
6579     for (i = 1; i < cnt; i++) {
6580         const struct bpf_line_info *expected_linfo;
6581 
6582         while (test->dead_code_mask & (1 << (i + dead_insns)))
6583             dead_insns++;
6584 
6585         expected_linfo = patched_linfo +
6586             ((i + dead_insns) * test->line_info_rec_size);
6587         if (CHECK(linfo[i].insn_off <= linfo[i - 1].insn_off,
6588               "linfo[%u].insn_off:%u <= linfo[%u].insn_off:%u",
6589               i, linfo[i].insn_off,
6590               i - 1, linfo[i - 1].insn_off)) {
6591             err = -1;
6592             goto done;
6593         }
6594         if (CHECK(linfo[i].file_name_off != expected_linfo->file_name_off ||
6595               linfo[i].line_off != expected_linfo->line_off ||
6596               linfo[i].line_col != expected_linfo->line_col,
6597               "linfo[%u] (%u, %u, %u) != (%u, %u, %u)", i,
6598               linfo[i].file_name_off,
6599               linfo[i].line_off,
6600               linfo[i].line_col,
6601               expected_linfo->file_name_off,
6602               expected_linfo->line_off,
6603               expected_linfo->line_col)) {
6604             err = -1;
6605             goto done;
6606         }
6607     }
6608 
6609     if (!jited_cnt) {
6610         fprintf(stderr, "not jited. skipping jited_line_info check. ");
6611         err = 0;
6612         goto done;
6613     }
6614 
6615     if (CHECK(jited_linfo[0] != jited_ksyms[0],
6616           "jited_linfo[0]:%lx != jited_ksyms[0]:%lx",
6617           (long)(jited_linfo[0]), (long)(jited_ksyms[0]))) {
6618         err = -1;
6619         goto done;
6620     }
6621 
6622     ksyms_found = 1;
6623     cur_func_len = jited_func_lens[0];
6624     cur_func_ksyms = jited_ksyms[0];
6625     for (i = 1; i < jited_cnt; i++) {
6626         if (ksyms_found < nr_jited_ksyms &&
6627             jited_linfo[i] == jited_ksyms[ksyms_found]) {
6628             cur_func_ksyms = jited_ksyms[ksyms_found];
6629             cur_func_len = jited_ksyms[ksyms_found];
6630             ksyms_found++;
6631             continue;
6632         }
6633 
6634         if (CHECK(jited_linfo[i] <= jited_linfo[i - 1],
6635               "jited_linfo[%u]:%lx <= jited_linfo[%u]:%lx",
6636               i, (long)jited_linfo[i],
6637               i - 1, (long)(jited_linfo[i - 1]))) {
6638             err = -1;
6639             goto done;
6640         }
6641 
6642         if (CHECK(jited_linfo[i] - cur_func_ksyms > cur_func_len,
6643               "jited_linfo[%u]:%lx - %lx > %u",
6644               i, (long)jited_linfo[i], (long)cur_func_ksyms,
6645               cur_func_len)) {
6646             err = -1;
6647             goto done;
6648         }
6649     }
6650 
6651     if (CHECK(ksyms_found != nr_jited_ksyms,
6652           "ksyms_found:%u != nr_jited_ksyms:%u",
6653           ksyms_found, nr_jited_ksyms)) {
6654         err = -1;
6655         goto done;
6656     }
6657 
6658     err = 0;
6659 
6660 done:
6661     free(linfo);
6662     free(jited_linfo);
6663     free(jited_ksyms);
6664     free(jited_func_lens);
6665     return err;
6666 }
6667 
6668 static void do_test_info_raw(unsigned int test_num)
6669 {
6670     const struct prog_info_raw_test *test = &info_raw_tests[test_num - 1];
6671     unsigned int raw_btf_size, linfo_str_off, linfo_size = 0;
6672     int btf_fd = -1, prog_fd = -1, err = 0;
6673     void *raw_btf, *patched_linfo = NULL;
6674     const char *ret_next_str;
6675     union bpf_attr attr = {};
6676 
6677     if (!test__start_subtest(test->descr))
6678         return;
6679 
6680     raw_btf = btf_raw_create(&hdr_tmpl, test->raw_types,
6681                  test->str_sec, test->str_sec_size,
6682                  &raw_btf_size, &ret_next_str);
6683     if (!raw_btf)
6684         return;
6685 
6686     *btf_log_buf = '\0';
6687     btf_fd = load_raw_btf(raw_btf, raw_btf_size);
6688     free(raw_btf);
6689 
6690     if (CHECK(btf_fd < 0, "invalid btf_fd errno:%d", errno)) {
6691         err = -1;
6692         goto done;
6693     }
6694 
6695     if (*btf_log_buf && always_log)
6696         fprintf(stderr, "\n%s", btf_log_buf);
6697     *btf_log_buf = '\0';
6698 
6699     linfo_str_off = ret_next_str - test->str_sec;
6700     patched_linfo = patch_name_tbd(test->line_info,
6701                        test->str_sec, linfo_str_off,
6702                        test->str_sec_size, &linfo_size);
6703     err = libbpf_get_error(patched_linfo);
6704     if (err) {
6705         fprintf(stderr, "error in creating raw bpf_line_info");
6706         err = -1;
6707         goto done;
6708     }
6709 
6710     attr.prog_type = test->prog_type;
6711     attr.insns = ptr_to_u64(test->insns);
6712     attr.insn_cnt = probe_prog_length(test->insns);
6713     attr.license = ptr_to_u64("GPL");
6714     attr.prog_btf_fd = btf_fd;
6715     attr.func_info_rec_size = test->func_info_rec_size;
6716     attr.func_info_cnt = test->func_info_cnt;
6717     attr.func_info = ptr_to_u64(test->func_info);
6718     attr.log_buf = ptr_to_u64(btf_log_buf);
6719     attr.log_size = BTF_LOG_BUF_SIZE;
6720     attr.log_level = 1;
6721     if (linfo_size) {
6722         attr.line_info_rec_size = test->line_info_rec_size;
6723         attr.line_info = ptr_to_u64(patched_linfo);
6724         attr.line_info_cnt = linfo_size / attr.line_info_rec_size;
6725     }
6726 
6727     prog_fd = syscall(__NR_bpf, BPF_PROG_LOAD, &attr, sizeof(attr));
6728     err = ((prog_fd < 0) != test->expected_prog_load_failure);
6729     if (CHECK(err, "prog_fd:%d expected_prog_load_failure:%u errno:%d",
6730           prog_fd, test->expected_prog_load_failure, errno) ||
6731         CHECK(test->err_str && !strstr(btf_log_buf, test->err_str),
6732           "expected err_str:%s", test->err_str)) {
6733         err = -1;
6734         goto done;
6735     }
6736 
6737     if (prog_fd < 0)
6738         goto done;
6739 
6740     err = test_get_finfo(test, prog_fd);
6741     if (err)
6742         goto done;
6743 
6744     err = test_get_linfo(test, patched_linfo,
6745                  attr.line_info_cnt - test->dead_code_cnt,
6746                  prog_fd);
6747     if (err)
6748         goto done;
6749 
6750 done:
6751     if (*btf_log_buf && (err || always_log))
6752         fprintf(stderr, "\n%s", btf_log_buf);
6753 
6754     if (btf_fd >= 0)
6755         close(btf_fd);
6756     if (prog_fd >= 0)
6757         close(prog_fd);
6758 
6759     if (!libbpf_get_error(patched_linfo))
6760         free(patched_linfo);
6761 }
6762 
6763 struct btf_raw_data {
6764     __u32 raw_types[MAX_NR_RAW_U32];
6765     const char *str_sec;
6766     __u32 str_sec_size;
6767 };
6768 
6769 struct btf_dedup_test {
6770     const char *descr;
6771     struct btf_raw_data input;
6772     struct btf_raw_data expect;
6773     struct btf_dedup_opts opts;
6774 };
6775 
6776 static struct btf_dedup_test dedup_tests[] = {
6777 
6778 {
6779     .descr = "dedup: unused strings filtering",
6780     .input = {
6781         .raw_types = {
6782             BTF_TYPE_INT_ENC(NAME_NTH(2), BTF_INT_SIGNED, 0, 32, 4),
6783             BTF_TYPE_INT_ENC(NAME_NTH(5), BTF_INT_SIGNED, 0, 64, 8),
6784             BTF_END_RAW,
6785         },
6786         BTF_STR_SEC("\0unused\0int\0foo\0bar\0long"),
6787     },
6788     .expect = {
6789         .raw_types = {
6790             BTF_TYPE_INT_ENC(NAME_NTH(1), BTF_INT_SIGNED, 0, 32, 4),
6791             BTF_TYPE_INT_ENC(NAME_NTH(2), BTF_INT_SIGNED, 0, 64, 8),
6792             BTF_END_RAW,
6793         },
6794         BTF_STR_SEC("\0int\0long"),
6795     },
6796 },
6797 {
6798     .descr = "dedup: strings deduplication",
6799     .input = {
6800         .raw_types = {
6801             BTF_TYPE_INT_ENC(NAME_NTH(1), BTF_INT_SIGNED, 0, 32, 4),
6802             BTF_TYPE_INT_ENC(NAME_NTH(2), BTF_INT_SIGNED, 0, 64, 8),
6803             BTF_TYPE_INT_ENC(NAME_NTH(3), BTF_INT_SIGNED, 0, 32, 4),
6804             BTF_TYPE_INT_ENC(NAME_NTH(4), BTF_INT_SIGNED, 0, 64, 8),
6805             BTF_TYPE_INT_ENC(NAME_NTH(5), BTF_INT_SIGNED, 0, 32, 4),
6806             BTF_END_RAW,
6807         },
6808         BTF_STR_SEC("\0int\0long int\0int\0long int\0int"),
6809     },
6810     .expect = {
6811         .raw_types = {
6812             BTF_TYPE_INT_ENC(NAME_NTH(1), BTF_INT_SIGNED, 0, 32, 4),
6813             BTF_TYPE_INT_ENC(NAME_NTH(2), BTF_INT_SIGNED, 0, 64, 8),
6814             BTF_END_RAW,
6815         },
6816         BTF_STR_SEC("\0int\0long int"),
6817     },
6818 },
6819 {
6820     .descr = "dedup: struct example #1",
6821     /*
6822      * struct s {
6823      *  struct s *next;
6824      *  const int *a;
6825      *  int b[16];
6826      *  int c;
6827      * }
6828      */
6829     .input = {
6830         .raw_types = {
6831             /* int */
6832             BTF_TYPE_INT_ENC(NAME_NTH(1), BTF_INT_SIGNED, 0, 32, 4),    /* [1] */
6833             /* int[16] */
6834             BTF_TYPE_ARRAY_ENC(1, 1, 16),                   /* [2] */
6835             /* struct s { */
6836             BTF_STRUCT_ENC(NAME_NTH(2), 5, 88),             /* [3] */
6837                 BTF_MEMBER_ENC(NAME_NTH(3), 4, 0),  /* struct s *next;  */
6838                 BTF_MEMBER_ENC(NAME_NTH(4), 5, 64), /* const int *a;    */
6839                 BTF_MEMBER_ENC(NAME_NTH(5), 2, 128),    /* int b[16];       */
6840                 BTF_MEMBER_ENC(NAME_NTH(6), 1, 640),    /* int c;       */
6841                 BTF_MEMBER_ENC(NAME_NTH(8), 15, 672),   /* float d;     */
6842             /* ptr -> [3] struct s */
6843             BTF_PTR_ENC(3),                         /* [4] */
6844             /* ptr -> [6] const int */
6845             BTF_PTR_ENC(6),                         /* [5] */
6846             /* const -> [1] int */
6847             BTF_CONST_ENC(1),                       /* [6] */
6848             /* tag -> [3] struct s */
6849             BTF_DECL_TAG_ENC(NAME_NTH(2), 3, -1),               /* [7] */
6850             /* tag -> [3] struct s, member 1 */
6851             BTF_DECL_TAG_ENC(NAME_NTH(2), 3, 1),                /* [8] */
6852 
6853             /* full copy of the above */
6854             BTF_TYPE_INT_ENC(NAME_NTH(1), BTF_INT_SIGNED, 0, 32, 4),    /* [9] */
6855             BTF_TYPE_ARRAY_ENC(9, 9, 16),                   /* [10] */
6856             BTF_STRUCT_ENC(NAME_NTH(2), 5, 88),             /* [11] */
6857                 BTF_MEMBER_ENC(NAME_NTH(3), 12, 0),
6858                 BTF_MEMBER_ENC(NAME_NTH(4), 13, 64),
6859                 BTF_MEMBER_ENC(NAME_NTH(5), 10, 128),
6860                 BTF_MEMBER_ENC(NAME_NTH(6), 9, 640),
6861                 BTF_MEMBER_ENC(NAME_NTH(8), 15, 672),
6862             BTF_PTR_ENC(11),                        /* [12] */
6863             BTF_PTR_ENC(14),                        /* [13] */
6864             BTF_CONST_ENC(9),                       /* [14] */
6865             BTF_TYPE_FLOAT_ENC(NAME_NTH(7), 4),             /* [15] */
6866             BTF_DECL_TAG_ENC(NAME_NTH(2), 11, -1),              /* [16] */
6867             BTF_DECL_TAG_ENC(NAME_NTH(2), 11, 1),               /* [17] */
6868             BTF_END_RAW,
6869         },
6870         BTF_STR_SEC("\0int\0s\0next\0a\0b\0c\0float\0d"),
6871     },
6872     .expect = {
6873         .raw_types = {
6874             /* int */
6875             BTF_TYPE_INT_ENC(NAME_NTH(5), BTF_INT_SIGNED, 0, 32, 4),    /* [1] */
6876             /* int[16] */
6877             BTF_TYPE_ARRAY_ENC(1, 1, 16),                   /* [2] */
6878             /* struct s { */
6879             BTF_STRUCT_ENC(NAME_NTH(8), 5, 88),             /* [3] */
6880                 BTF_MEMBER_ENC(NAME_NTH(7), 4, 0),  /* struct s *next;  */
6881                 BTF_MEMBER_ENC(NAME_NTH(1), 5, 64), /* const int *a;    */
6882                 BTF_MEMBER_ENC(NAME_NTH(2), 2, 128),    /* int b[16];       */
6883                 BTF_MEMBER_ENC(NAME_NTH(3), 1, 640),    /* int c;       */
6884                 BTF_MEMBER_ENC(NAME_NTH(4), 9, 672),    /* float d;     */
6885             /* ptr -> [3] struct s */
6886             BTF_PTR_ENC(3),                         /* [4] */
6887             /* ptr -> [6] const int */
6888             BTF_PTR_ENC(6),                         /* [5] */
6889             /* const -> [1] int */
6890             BTF_CONST_ENC(1),                       /* [6] */
6891             BTF_DECL_TAG_ENC(NAME_NTH(2), 3, -1),               /* [7] */
6892             BTF_DECL_TAG_ENC(NAME_NTH(2), 3, 1),                /* [8] */
6893             BTF_TYPE_FLOAT_ENC(NAME_NTH(7), 4),             /* [9] */
6894             BTF_END_RAW,
6895         },
6896         BTF_STR_SEC("\0a\0b\0c\0d\0int\0float\0next\0s"),
6897     },
6898 },
6899 {
6900     .descr = "dedup: struct <-> fwd resolution w/ hash collision",
6901     /*
6902      * // CU 1:
6903      * struct x;
6904      * struct s {
6905      *  struct x *x;
6906      * };
6907      * // CU 2:
6908      * struct x {};
6909      * struct s {
6910      *  struct x *x;
6911      * };
6912      */
6913     .input = {
6914         .raw_types = {
6915             /* CU 1 */
6916             BTF_FWD_ENC(NAME_TBD, 0 /* struct fwd */),  /* [1] fwd x      */
6917             BTF_PTR_ENC(1),                 /* [2] ptr -> [1] */
6918             BTF_STRUCT_ENC(NAME_TBD, 1, 8),         /* [3] struct s   */
6919                 BTF_MEMBER_ENC(NAME_TBD, 2, 0),
6920             /* CU 2 */
6921             BTF_STRUCT_ENC(NAME_TBD, 0, 0),         /* [4] struct x   */
6922             BTF_PTR_ENC(4),                 /* [5] ptr -> [4] */
6923             BTF_STRUCT_ENC(NAME_TBD, 1, 8),         /* [6] struct s   */
6924                 BTF_MEMBER_ENC(NAME_TBD, 5, 0),
6925             BTF_END_RAW,
6926         },
6927         BTF_STR_SEC("\0x\0s\0x\0x\0s\0x\0"),
6928     },
6929     .expect = {
6930         .raw_types = {
6931             BTF_PTR_ENC(3),                 /* [1] ptr -> [3] */
6932             BTF_STRUCT_ENC(NAME_TBD, 1, 8),         /* [2] struct s   */
6933                 BTF_MEMBER_ENC(NAME_TBD, 1, 0),
6934             BTF_STRUCT_ENC(NAME_NTH(2), 0, 0),      /* [3] struct x   */
6935             BTF_END_RAW,
6936         },
6937         BTF_STR_SEC("\0s\0x"),
6938     },
6939     .opts = {
6940         .force_collisions = true, /* force hash collisions */
6941     },
6942 },
6943 {
6944     .descr = "dedup: void equiv check",
6945     /*
6946      * // CU 1:
6947      * struct s {
6948      *  struct {} *x;
6949      * };
6950      * // CU 2:
6951      * struct s {
6952      *  int *x;
6953      * };
6954      */
6955     .input = {
6956         .raw_types = {
6957             /* CU 1 */
6958             BTF_STRUCT_ENC(0, 0, 1),                /* [1] struct {}  */
6959             BTF_PTR_ENC(1),                     /* [2] ptr -> [1] */
6960             BTF_STRUCT_ENC(NAME_NTH(1), 1, 8),          /* [3] struct s   */
6961                 BTF_MEMBER_ENC(NAME_NTH(2), 2, 0),
6962             /* CU 2 */
6963             BTF_PTR_ENC(0),                     /* [4] ptr -> void */
6964             BTF_STRUCT_ENC(NAME_NTH(1), 1, 8),          /* [5] struct s   */
6965                 BTF_MEMBER_ENC(NAME_NTH(2), 4, 0),
6966             BTF_END_RAW,
6967         },
6968         BTF_STR_SEC("\0s\0x"),
6969     },
6970     .expect = {
6971         .raw_types = {
6972             /* CU 1 */
6973             BTF_STRUCT_ENC(0, 0, 1),                /* [1] struct {}  */
6974             BTF_PTR_ENC(1),                     /* [2] ptr -> [1] */
6975             BTF_STRUCT_ENC(NAME_NTH(1), 1, 8),          /* [3] struct s   */
6976                 BTF_MEMBER_ENC(NAME_NTH(2), 2, 0),
6977             /* CU 2 */
6978             BTF_PTR_ENC(0),                     /* [4] ptr -> void */
6979             BTF_STRUCT_ENC(NAME_NTH(1), 1, 8),          /* [5] struct s   */
6980                 BTF_MEMBER_ENC(NAME_NTH(2), 4, 0),
6981             BTF_END_RAW,
6982         },
6983         BTF_STR_SEC("\0s\0x"),
6984     },
6985     .opts = {
6986         .force_collisions = true, /* force hash collisions */
6987     },
6988 },
6989 {
6990     .descr = "dedup: all possible kinds (no duplicates)",
6991     .input = {
6992         .raw_types = {
6993             BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 8),       /* [1] int */
6994             BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_ENUM, 0, 2), 4),   /* [2] enum */
6995                 BTF_ENUM_ENC(NAME_TBD, 0),
6996                 BTF_ENUM_ENC(NAME_TBD, 1),
6997             BTF_FWD_ENC(NAME_TBD, 1 /* union kind_flag */),         /* [3] fwd */
6998             BTF_TYPE_ARRAY_ENC(2, 1, 7),                    /* [4] array */
6999             BTF_STRUCT_ENC(NAME_TBD, 1, 4),                 /* [5] struct */
7000                 BTF_MEMBER_ENC(NAME_TBD, 1, 0),
7001             BTF_UNION_ENC(NAME_TBD, 1, 4),                  /* [6] union */
7002                 BTF_MEMBER_ENC(NAME_TBD, 1, 0),
7003             BTF_TYPEDEF_ENC(NAME_TBD, 1),                   /* [7] typedef */
7004             BTF_PTR_ENC(0),                         /* [8] ptr */
7005             BTF_CONST_ENC(8),                       /* [9] const */
7006             BTF_VOLATILE_ENC(8),                        /* [10] volatile */
7007             BTF_RESTRICT_ENC(8),                        /* [11] restrict */
7008             BTF_FUNC_PROTO_ENC(1, 2),                   /* [12] func_proto */
7009                 BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
7010                 BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 18),
7011             BTF_FUNC_ENC(NAME_TBD, 12),                 /* [13] func */
7012             BTF_TYPE_FLOAT_ENC(NAME_TBD, 2),                /* [14] float */
7013             BTF_DECL_TAG_ENC(NAME_TBD, 13, -1),             /* [15] decl_tag */
7014             BTF_DECL_TAG_ENC(NAME_TBD, 13, 1),              /* [16] decl_tag */
7015             BTF_DECL_TAG_ENC(NAME_TBD, 7, -1),              /* [17] decl_tag */
7016             BTF_TYPE_TAG_ENC(NAME_TBD, 8),                  /* [18] type_tag */
7017             BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_ENUM64, 0, 2), 8), /* [19] enum64 */
7018                 BTF_ENUM64_ENC(NAME_TBD, 0, 0),
7019                 BTF_ENUM64_ENC(NAME_TBD, 1, 1),
7020             BTF_END_RAW,
7021         },
7022         BTF_STR_SEC("\0A\0B\0C\0D\0E\0F\0G\0H\0I\0J\0K\0L\0M\0N\0O\0P\0Q\0R\0S\0T\0U"),
7023     },
7024     .expect = {
7025         .raw_types = {
7026             BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 8),       /* [1] int */
7027             BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_ENUM, 0, 2), 4),   /* [2] enum */
7028                 BTF_ENUM_ENC(NAME_TBD, 0),
7029                 BTF_ENUM_ENC(NAME_TBD, 1),
7030             BTF_FWD_ENC(NAME_TBD, 1 /* union kind_flag */),         /* [3] fwd */
7031             BTF_TYPE_ARRAY_ENC(2, 1, 7),                    /* [4] array */
7032             BTF_STRUCT_ENC(NAME_TBD, 1, 4),                 /* [5] struct */
7033                 BTF_MEMBER_ENC(NAME_TBD, 1, 0),
7034             BTF_UNION_ENC(NAME_TBD, 1, 4),                  /* [6] union */
7035                 BTF_MEMBER_ENC(NAME_TBD, 1, 0),
7036             BTF_TYPEDEF_ENC(NAME_TBD, 1),                   /* [7] typedef */
7037             BTF_PTR_ENC(0),                         /* [8] ptr */
7038             BTF_CONST_ENC(8),                       /* [9] const */
7039             BTF_VOLATILE_ENC(8),                        /* [10] volatile */
7040             BTF_RESTRICT_ENC(8),                        /* [11] restrict */
7041             BTF_FUNC_PROTO_ENC(1, 2),                   /* [12] func_proto */
7042                 BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
7043                 BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 18),
7044             BTF_FUNC_ENC(NAME_TBD, 12),                 /* [13] func */
7045             BTF_TYPE_FLOAT_ENC(NAME_TBD, 2),                /* [14] float */
7046             BTF_DECL_TAG_ENC(NAME_TBD, 13, -1),             /* [15] decl_tag */
7047             BTF_DECL_TAG_ENC(NAME_TBD, 13, 1),              /* [16] decl_tag */
7048             BTF_DECL_TAG_ENC(NAME_TBD, 7, -1),              /* [17] decl_tag */
7049             BTF_TYPE_TAG_ENC(NAME_TBD, 8),                  /* [18] type_tag */
7050             BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_ENUM64, 0, 2), 8), /* [19] enum64 */
7051                 BTF_ENUM64_ENC(NAME_TBD, 0, 0),
7052                 BTF_ENUM64_ENC(NAME_TBD, 1, 1),
7053             BTF_END_RAW,
7054         },
7055         BTF_STR_SEC("\0A\0B\0C\0D\0E\0F\0G\0H\0I\0J\0K\0L\0M\0N\0O\0P\0Q\0R\0S\0T\0U"),
7056     },
7057 },
7058 {
7059     .descr = "dedup: no int/float duplicates",
7060     .input = {
7061         .raw_types = {
7062             BTF_TYPE_INT_ENC(NAME_NTH(1), BTF_INT_SIGNED, 0, 32, 8),
7063             /* different name */
7064             BTF_TYPE_INT_ENC(NAME_NTH(2), BTF_INT_SIGNED, 0, 32, 8),
7065             /* different encoding */
7066             BTF_TYPE_INT_ENC(NAME_NTH(1), BTF_INT_CHAR, 0, 32, 8),
7067             BTF_TYPE_INT_ENC(NAME_NTH(1), BTF_INT_BOOL, 0, 32, 8),
7068             /* different bit offset */
7069             BTF_TYPE_INT_ENC(NAME_NTH(1), BTF_INT_SIGNED, 8, 32, 8),
7070             /* different bit size */
7071             BTF_TYPE_INT_ENC(NAME_NTH(1), BTF_INT_SIGNED, 0, 27, 8),
7072             /* different byte size */
7073             BTF_TYPE_INT_ENC(NAME_NTH(1), BTF_INT_SIGNED, 0, 32, 4),
7074             /* all allowed sizes */
7075             BTF_TYPE_FLOAT_ENC(NAME_NTH(3), 2),
7076             BTF_TYPE_FLOAT_ENC(NAME_NTH(3), 4),
7077             BTF_TYPE_FLOAT_ENC(NAME_NTH(3), 8),
7078             BTF_TYPE_FLOAT_ENC(NAME_NTH(3), 12),
7079             BTF_TYPE_FLOAT_ENC(NAME_NTH(3), 16),
7080             BTF_END_RAW,
7081         },
7082         BTF_STR_SEC("\0int\0some other int\0float"),
7083     },
7084     .expect = {
7085         .raw_types = {
7086             BTF_TYPE_INT_ENC(NAME_NTH(1), BTF_INT_SIGNED, 0, 32, 8),
7087             /* different name */
7088             BTF_TYPE_INT_ENC(NAME_NTH(2), BTF_INT_SIGNED, 0, 32, 8),
7089             /* different encoding */
7090             BTF_TYPE_INT_ENC(NAME_NTH(1), BTF_INT_CHAR, 0, 32, 8),
7091             BTF_TYPE_INT_ENC(NAME_NTH(1), BTF_INT_BOOL, 0, 32, 8),
7092             /* different bit offset */
7093             BTF_TYPE_INT_ENC(NAME_NTH(1), BTF_INT_SIGNED, 8, 32, 8),
7094             /* different bit size */
7095             BTF_TYPE_INT_ENC(NAME_NTH(1), BTF_INT_SIGNED, 0, 27, 8),
7096             /* different byte size */
7097             BTF_TYPE_INT_ENC(NAME_NTH(1), BTF_INT_SIGNED, 0, 32, 4),
7098             /* all allowed sizes */
7099             BTF_TYPE_FLOAT_ENC(NAME_NTH(3), 2),
7100             BTF_TYPE_FLOAT_ENC(NAME_NTH(3), 4),
7101             BTF_TYPE_FLOAT_ENC(NAME_NTH(3), 8),
7102             BTF_TYPE_FLOAT_ENC(NAME_NTH(3), 12),
7103             BTF_TYPE_FLOAT_ENC(NAME_NTH(3), 16),
7104             BTF_END_RAW,
7105         },
7106         BTF_STR_SEC("\0int\0some other int\0float"),
7107     },
7108 },
7109 {
7110     .descr = "dedup: enum fwd resolution",
7111     .input = {
7112         .raw_types = {
7113             /* [1] fwd enum 'e1' before full enum */
7114             BTF_TYPE_ENC(NAME_NTH(1), BTF_INFO_ENC(BTF_KIND_ENUM, 0, 0), 4),
7115             /* [2] full enum 'e1' after fwd */
7116             BTF_TYPE_ENC(NAME_NTH(1), BTF_INFO_ENC(BTF_KIND_ENUM, 0, 1), 4),
7117                 BTF_ENUM_ENC(NAME_NTH(2), 123),
7118             /* [3] full enum 'e2' before fwd */
7119             BTF_TYPE_ENC(NAME_NTH(3), BTF_INFO_ENC(BTF_KIND_ENUM, 0, 1), 4),
7120                 BTF_ENUM_ENC(NAME_NTH(4), 456),
7121             /* [4] fwd enum 'e2' after full enum */
7122             BTF_TYPE_ENC(NAME_NTH(3), BTF_INFO_ENC(BTF_KIND_ENUM, 0, 0), 4),
7123             /* [5] incompatible fwd enum with different size */
7124             BTF_TYPE_ENC(NAME_NTH(1), BTF_INFO_ENC(BTF_KIND_ENUM, 0, 0), 1),
7125             /* [6] incompatible full enum with different value */
7126             BTF_TYPE_ENC(NAME_NTH(1), BTF_INFO_ENC(BTF_KIND_ENUM, 0, 1), 4),
7127                 BTF_ENUM_ENC(NAME_NTH(2), 321),
7128             BTF_END_RAW,
7129         },
7130         BTF_STR_SEC("\0e1\0e1_val\0e2\0e2_val"),
7131     },
7132     .expect = {
7133         .raw_types = {
7134             /* [1] full enum 'e1' */
7135             BTF_TYPE_ENC(NAME_NTH(1), BTF_INFO_ENC(BTF_KIND_ENUM, 0, 1), 4),
7136                 BTF_ENUM_ENC(NAME_NTH(2), 123),
7137             /* [2] full enum 'e2' */
7138             BTF_TYPE_ENC(NAME_NTH(3), BTF_INFO_ENC(BTF_KIND_ENUM, 0, 1), 4),
7139                 BTF_ENUM_ENC(NAME_NTH(4), 456),
7140             /* [3] incompatible fwd enum with different size */
7141             BTF_TYPE_ENC(NAME_NTH(1), BTF_INFO_ENC(BTF_KIND_ENUM, 0, 0), 1),
7142             /* [4] incompatible full enum with different value */
7143             BTF_TYPE_ENC(NAME_NTH(1), BTF_INFO_ENC(BTF_KIND_ENUM, 0, 1), 4),
7144                 BTF_ENUM_ENC(NAME_NTH(2), 321),
7145             BTF_END_RAW,
7146         },
7147         BTF_STR_SEC("\0e1\0e1_val\0e2\0e2_val"),
7148     },
7149 },
7150 {
7151     .descr = "dedup: datasec and vars pass-through",
7152     .input = {
7153         .raw_types = {
7154             /* int */
7155             BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),  /* [1] */
7156             /* static int t */
7157             BTF_VAR_ENC(NAME_NTH(2), 1, 0),         /* [2] */
7158             /* .bss section */              /* [3] */
7159             BTF_TYPE_ENC(NAME_NTH(1), BTF_INFO_ENC(BTF_KIND_DATASEC, 0, 1), 4),
7160             BTF_VAR_SECINFO_ENC(2, 0, 4),
7161             /* int, referenced from [5] */
7162             BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),  /* [4] */
7163             /* another static int t */
7164             BTF_VAR_ENC(NAME_NTH(2), 4, 0),         /* [5] */
7165             /* another .bss section */          /* [6] */
7166             BTF_TYPE_ENC(NAME_NTH(1), BTF_INFO_ENC(BTF_KIND_DATASEC, 0, 1), 4),
7167             BTF_VAR_SECINFO_ENC(5, 0, 4),
7168             BTF_END_RAW,
7169         },
7170         BTF_STR_SEC("\0.bss\0t"),
7171     },
7172     .expect = {
7173         .raw_types = {
7174             /* int */
7175             BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),  /* [1] */
7176             /* static int t */
7177             BTF_VAR_ENC(NAME_NTH(2), 1, 0),         /* [2] */
7178             /* .bss section */              /* [3] */
7179             BTF_TYPE_ENC(NAME_NTH(1), BTF_INFO_ENC(BTF_KIND_DATASEC, 0, 1), 4),
7180             BTF_VAR_SECINFO_ENC(2, 0, 4),
7181             /* another static int t */
7182             BTF_VAR_ENC(NAME_NTH(2), 1, 0),         /* [4] */
7183             /* another .bss section */          /* [5] */
7184             BTF_TYPE_ENC(NAME_NTH(1), BTF_INFO_ENC(BTF_KIND_DATASEC, 0, 1), 4),
7185             BTF_VAR_SECINFO_ENC(4, 0, 4),
7186             BTF_END_RAW,
7187         },
7188         BTF_STR_SEC("\0.bss\0t"),
7189     },
7190     .opts = {
7191         .force_collisions = true
7192     },
7193 },
7194 {
7195     .descr = "dedup: func/func_arg/var tags",
7196     .input = {
7197         .raw_types = {
7198             /* int */
7199             BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),  /* [1] */
7200             /* static int t */
7201             BTF_VAR_ENC(NAME_NTH(1), 1, 0),         /* [2] */
7202             /* void f(int a1, int a2) */
7203             BTF_FUNC_PROTO_ENC(0, 2),           /* [3] */
7204                 BTF_FUNC_PROTO_ARG_ENC(NAME_NTH(2), 1),
7205                 BTF_FUNC_PROTO_ARG_ENC(NAME_NTH(3), 1),
7206             BTF_FUNC_ENC(NAME_NTH(4), 2),           /* [4] */
7207             /* tag -> t */
7208             BTF_DECL_TAG_ENC(NAME_NTH(5), 2, -1),       /* [5] */
7209             BTF_DECL_TAG_ENC(NAME_NTH(5), 2, -1),       /* [6] */
7210             /* tag -> func */
7211             BTF_DECL_TAG_ENC(NAME_NTH(5), 4, -1),       /* [7] */
7212             BTF_DECL_TAG_ENC(NAME_NTH(5), 4, -1),       /* [8] */
7213             /* tag -> func arg a1 */
7214             BTF_DECL_TAG_ENC(NAME_NTH(5), 4, 1),        /* [9] */
7215             BTF_DECL_TAG_ENC(NAME_NTH(5), 4, 1),        /* [10] */
7216             BTF_END_RAW,
7217         },
7218         BTF_STR_SEC("\0t\0a1\0a2\0f\0tag"),
7219     },
7220     .expect = {
7221         .raw_types = {
7222             BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),  /* [1] */
7223             BTF_VAR_ENC(NAME_NTH(1), 1, 0),         /* [2] */
7224             BTF_FUNC_PROTO_ENC(0, 2),           /* [3] */
7225                 BTF_FUNC_PROTO_ARG_ENC(NAME_NTH(2), 1),
7226                 BTF_FUNC_PROTO_ARG_ENC(NAME_NTH(3), 1),
7227             BTF_FUNC_ENC(NAME_NTH(4), 2),           /* [4] */
7228             BTF_DECL_TAG_ENC(NAME_NTH(5), 2, -1),       /* [5] */
7229             BTF_DECL_TAG_ENC(NAME_NTH(5), 4, -1),       /* [6] */
7230             BTF_DECL_TAG_ENC(NAME_NTH(5), 4, 1),        /* [7] */
7231             BTF_END_RAW,
7232         },
7233         BTF_STR_SEC("\0t\0a1\0a2\0f\0tag"),
7234     },
7235 },
7236 {
7237     .descr = "dedup: func/func_param tags",
7238     .input = {
7239         .raw_types = {
7240             /* int */
7241             BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),  /* [1] */
7242             /* void f(int a1, int a2) */
7243             BTF_FUNC_PROTO_ENC(0, 2),           /* [2] */
7244                 BTF_FUNC_PROTO_ARG_ENC(NAME_NTH(1), 1),
7245                 BTF_FUNC_PROTO_ARG_ENC(NAME_NTH(2), 1),
7246             BTF_FUNC_ENC(NAME_NTH(3), 2),           /* [3] */
7247             /* void f(int a1, int a2) */
7248             BTF_FUNC_PROTO_ENC(0, 2),           /* [4] */
7249                 BTF_FUNC_PROTO_ARG_ENC(NAME_NTH(1), 1),
7250                 BTF_FUNC_PROTO_ARG_ENC(NAME_NTH(2), 1),
7251             BTF_FUNC_ENC(NAME_NTH(3), 4),           /* [5] */
7252             /* tag -> f: tag1, tag2 */
7253             BTF_DECL_TAG_ENC(NAME_NTH(4), 3, -1),       /* [6] */
7254             BTF_DECL_TAG_ENC(NAME_NTH(5), 3, -1),       /* [7] */
7255             /* tag -> f/a2: tag1, tag2 */
7256             BTF_DECL_TAG_ENC(NAME_NTH(4), 3, 1),        /* [8] */
7257             BTF_DECL_TAG_ENC(NAME_NTH(5), 3, 1),        /* [9] */
7258             /* tag -> f: tag1, tag3 */
7259             BTF_DECL_TAG_ENC(NAME_NTH(4), 5, -1),       /* [10] */
7260             BTF_DECL_TAG_ENC(NAME_NTH(6), 5, -1),       /* [11] */
7261             /* tag -> f/a2: tag1, tag3 */
7262             BTF_DECL_TAG_ENC(NAME_NTH(4), 5, 1),        /* [12] */
7263             BTF_DECL_TAG_ENC(NAME_NTH(6), 5, 1),        /* [13] */
7264             BTF_END_RAW,
7265         },
7266         BTF_STR_SEC("\0a1\0a2\0f\0tag1\0tag2\0tag3"),
7267     },
7268     .expect = {
7269         .raw_types = {
7270             BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),  /* [1] */
7271             BTF_FUNC_PROTO_ENC(0, 2),           /* [2] */
7272                 BTF_FUNC_PROTO_ARG_ENC(NAME_NTH(1), 1),
7273                 BTF_FUNC_PROTO_ARG_ENC(NAME_NTH(2), 1),
7274             BTF_FUNC_ENC(NAME_NTH(3), 2),           /* [3] */
7275             BTF_DECL_TAG_ENC(NAME_NTH(4), 3, -1),       /* [4] */
7276             BTF_DECL_TAG_ENC(NAME_NTH(5), 3, -1),       /* [5] */
7277             BTF_DECL_TAG_ENC(NAME_NTH(6), 3, -1),       /* [6] */
7278             BTF_DECL_TAG_ENC(NAME_NTH(4), 3, 1),        /* [7] */
7279             BTF_DECL_TAG_ENC(NAME_NTH(5), 3, 1),        /* [8] */
7280             BTF_DECL_TAG_ENC(NAME_NTH(6), 3, 1),        /* [9] */
7281             BTF_END_RAW,
7282         },
7283         BTF_STR_SEC("\0a1\0a2\0f\0tag1\0tag2\0tag3"),
7284     },
7285 },
7286 {
7287     .descr = "dedup: struct/struct_member tags",
7288     .input = {
7289         .raw_types = {
7290             /* int */
7291             BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),  /* [1] */
7292             BTF_STRUCT_ENC(NAME_NTH(1), 2, 8),      /* [2] */
7293                 BTF_MEMBER_ENC(NAME_NTH(2), 1, 0),
7294                 BTF_MEMBER_ENC(NAME_NTH(3), 1, 32),
7295             BTF_STRUCT_ENC(NAME_NTH(1), 2, 8),      /* [3] */
7296                 BTF_MEMBER_ENC(NAME_NTH(2), 1, 0),
7297                 BTF_MEMBER_ENC(NAME_NTH(3), 1, 32),
7298             /* tag -> t: tag1, tag2 */
7299             BTF_DECL_TAG_ENC(NAME_NTH(4), 2, -1),       /* [4] */
7300             BTF_DECL_TAG_ENC(NAME_NTH(5), 2, -1),       /* [5] */
7301             /* tag -> t/m2: tag1, tag2 */
7302             BTF_DECL_TAG_ENC(NAME_NTH(4), 2, 1),        /* [6] */
7303             BTF_DECL_TAG_ENC(NAME_NTH(5), 2, 1),        /* [7] */
7304             /* tag -> t: tag1, tag3 */
7305             BTF_DECL_TAG_ENC(NAME_NTH(4), 3, -1),       /* [8] */
7306             BTF_DECL_TAG_ENC(NAME_NTH(6), 3, -1),       /* [9] */
7307             /* tag -> t/m2: tag1, tag3 */
7308             BTF_DECL_TAG_ENC(NAME_NTH(4), 3, 1),        /* [10] */
7309             BTF_DECL_TAG_ENC(NAME_NTH(6), 3, 1),        /* [11] */
7310             BTF_END_RAW,
7311         },
7312         BTF_STR_SEC("\0t\0m1\0m2\0tag1\0tag2\0tag3"),
7313     },
7314     .expect = {
7315         .raw_types = {
7316             BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),  /* [1] */
7317             BTF_STRUCT_ENC(NAME_NTH(1), 2, 8),      /* [2] */
7318                 BTF_MEMBER_ENC(NAME_NTH(2), 1, 0),
7319                 BTF_MEMBER_ENC(NAME_NTH(3), 1, 32),
7320             BTF_DECL_TAG_ENC(NAME_NTH(4), 2, -1),       /* [3] */
7321             BTF_DECL_TAG_ENC(NAME_NTH(5), 2, -1),       /* [4] */
7322             BTF_DECL_TAG_ENC(NAME_NTH(6), 2, -1),       /* [5] */
7323             BTF_DECL_TAG_ENC(NAME_NTH(4), 2, 1),        /* [6] */
7324             BTF_DECL_TAG_ENC(NAME_NTH(5), 2, 1),        /* [7] */
7325             BTF_DECL_TAG_ENC(NAME_NTH(6), 2, 1),        /* [8] */
7326             BTF_END_RAW,
7327         },
7328         BTF_STR_SEC("\0t\0m1\0m2\0tag1\0tag2\0tag3"),
7329     },
7330 },
7331 {
7332     .descr = "dedup: typedef tags",
7333     .input = {
7334         .raw_types = {
7335             /* int */
7336             BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),  /* [1] */
7337             BTF_TYPEDEF_ENC(NAME_NTH(1), 1),        /* [2] */
7338             BTF_TYPEDEF_ENC(NAME_NTH(1), 1),        /* [3] */
7339             /* tag -> t: tag1, tag2 */
7340             BTF_DECL_TAG_ENC(NAME_NTH(2), 2, -1),       /* [4] */
7341             BTF_DECL_TAG_ENC(NAME_NTH(3), 2, -1),       /* [5] */
7342             /* tag -> t: tag1, tag3 */
7343             BTF_DECL_TAG_ENC(NAME_NTH(2), 3, -1),       /* [6] */
7344             BTF_DECL_TAG_ENC(NAME_NTH(4), 3, -1),       /* [7] */
7345             BTF_END_RAW,
7346         },
7347         BTF_STR_SEC("\0t\0tag1\0tag2\0tag3"),
7348     },
7349     .expect = {
7350         .raw_types = {
7351             BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),  /* [1] */
7352             BTF_TYPEDEF_ENC(NAME_NTH(1), 1),        /* [2] */
7353             BTF_DECL_TAG_ENC(NAME_NTH(2), 2, -1),       /* [3] */
7354             BTF_DECL_TAG_ENC(NAME_NTH(3), 2, -1),       /* [4] */
7355             BTF_DECL_TAG_ENC(NAME_NTH(4), 2, -1),       /* [5] */
7356             BTF_END_RAW,
7357         },
7358         BTF_STR_SEC("\0t\0tag1\0tag2\0tag3"),
7359     },
7360 },
7361 {
7362     .descr = "dedup: btf_type_tag #1",
7363     .input = {
7364         .raw_types = {
7365             /* ptr -> tag2 -> tag1 -> int */
7366             BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),  /* [1] */
7367             BTF_TYPE_TAG_ENC(NAME_NTH(1), 1),       /* [2] */
7368             BTF_TYPE_TAG_ENC(NAME_NTH(2), 2),       /* [3] */
7369             BTF_PTR_ENC(3),                 /* [4] */
7370             /* ptr -> tag2 -> tag1 -> int */
7371             BTF_TYPE_TAG_ENC(NAME_NTH(1), 1),       /* [5] */
7372             BTF_TYPE_TAG_ENC(NAME_NTH(2), 5),       /* [6] */
7373             BTF_PTR_ENC(6),                 /* [7] */
7374             /* ptr -> tag1 -> int */
7375             BTF_TYPE_TAG_ENC(NAME_NTH(1), 1),       /* [8] */
7376             BTF_PTR_ENC(8),                 /* [9] */
7377             BTF_END_RAW,
7378         },
7379         BTF_STR_SEC("\0tag1\0tag2"),
7380     },
7381     .expect = {
7382         .raw_types = {
7383             /* ptr -> tag2 -> tag1 -> int */
7384             BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),  /* [1] */
7385             BTF_TYPE_TAG_ENC(NAME_NTH(1), 1),       /* [2] */
7386             BTF_TYPE_TAG_ENC(NAME_NTH(2), 2),       /* [3] */
7387             BTF_PTR_ENC(3),                 /* [4] */
7388             /* ptr -> tag1 -> int */
7389             BTF_PTR_ENC(2),                 /* [5] */
7390             BTF_END_RAW,
7391         },
7392         BTF_STR_SEC("\0tag1\0tag2"),
7393     },
7394 },
7395 {
7396     .descr = "dedup: btf_type_tag #2",
7397     .input = {
7398         .raw_types = {
7399             /* ptr -> tag2 -> tag1 -> int */
7400             BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),  /* [1] */
7401             BTF_TYPE_TAG_ENC(NAME_NTH(1), 1),       /* [2] */
7402             BTF_TYPE_TAG_ENC(NAME_NTH(2), 2),       /* [3] */
7403             BTF_PTR_ENC(3),                 /* [4] */
7404             /* ptr -> tag2 -> int */
7405             BTF_TYPE_TAG_ENC(NAME_NTH(2), 1),       /* [5] */
7406             BTF_PTR_ENC(5),                 /* [6] */
7407             BTF_END_RAW,
7408         },
7409         BTF_STR_SEC("\0tag1\0tag2"),
7410     },
7411     .expect = {
7412         .raw_types = {
7413             /* ptr -> tag2 -> tag1 -> int */
7414             BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),  /* [1] */
7415             BTF_TYPE_TAG_ENC(NAME_NTH(1), 1),       /* [2] */
7416             BTF_TYPE_TAG_ENC(NAME_NTH(2), 2),       /* [3] */
7417             BTF_PTR_ENC(3),                 /* [4] */
7418             /* ptr -> tag2 -> int */
7419             BTF_TYPE_TAG_ENC(NAME_NTH(2), 1),       /* [5] */
7420             BTF_PTR_ENC(5),                 /* [6] */
7421             BTF_END_RAW,
7422         },
7423         BTF_STR_SEC("\0tag1\0tag2"),
7424     },
7425 },
7426 {
7427     .descr = "dedup: btf_type_tag #3",
7428     .input = {
7429         .raw_types = {
7430             /* ptr -> tag2 -> tag1 -> int */
7431             BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),  /* [1] */
7432             BTF_TYPE_TAG_ENC(NAME_NTH(1), 1),       /* [2] */
7433             BTF_TYPE_TAG_ENC(NAME_NTH(2), 2),       /* [3] */
7434             BTF_PTR_ENC(3),                 /* [4] */
7435             /* ptr -> tag1 -> tag2 -> int */
7436             BTF_TYPE_TAG_ENC(NAME_NTH(2), 1),       /* [5] */
7437             BTF_TYPE_TAG_ENC(NAME_NTH(1), 5),       /* [6] */
7438             BTF_PTR_ENC(6),                 /* [7] */
7439             BTF_END_RAW,
7440         },
7441         BTF_STR_SEC("\0tag1\0tag2"),
7442     },
7443     .expect = {
7444         .raw_types = {
7445             /* ptr -> tag2 -> tag1 -> int */
7446             BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),  /* [1] */
7447             BTF_TYPE_TAG_ENC(NAME_NTH(1), 1),       /* [2] */
7448             BTF_TYPE_TAG_ENC(NAME_NTH(2), 2),       /* [3] */
7449             BTF_PTR_ENC(3),                 /* [4] */
7450             /* ptr -> tag1 -> tag2 -> int */
7451             BTF_TYPE_TAG_ENC(NAME_NTH(2), 1),       /* [5] */
7452             BTF_TYPE_TAG_ENC(NAME_NTH(1), 5),       /* [6] */
7453             BTF_PTR_ENC(6),                 /* [7] */
7454             BTF_END_RAW,
7455         },
7456         BTF_STR_SEC("\0tag1\0tag2"),
7457     },
7458 },
7459 {
7460     .descr = "dedup: btf_type_tag #4",
7461     .input = {
7462         .raw_types = {
7463             /* ptr -> tag1 -> int */
7464             BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),  /* [1] */
7465             BTF_TYPE_TAG_ENC(NAME_NTH(1), 1),       /* [2] */
7466             BTF_PTR_ENC(2),                 /* [3] */
7467             /* ptr -> tag1 -> long */
7468             BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 64, 8),  /* [4] */
7469             BTF_TYPE_TAG_ENC(NAME_NTH(1), 4),       /* [5] */
7470             BTF_PTR_ENC(5),                 /* [6] */
7471             BTF_END_RAW,
7472         },
7473         BTF_STR_SEC("\0tag1"),
7474     },
7475     .expect = {
7476         .raw_types = {
7477             /* ptr -> tag1 -> int */
7478             BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),  /* [1] */
7479             BTF_TYPE_TAG_ENC(NAME_NTH(1), 1),       /* [2] */
7480             BTF_PTR_ENC(2),                 /* [3] */
7481             /* ptr -> tag1 -> long */
7482             BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 64, 8),  /* [4] */
7483             BTF_TYPE_TAG_ENC(NAME_NTH(1), 4),       /* [5] */
7484             BTF_PTR_ENC(5),                 /* [6] */
7485             BTF_END_RAW,
7486         },
7487         BTF_STR_SEC("\0tag1"),
7488     },
7489 },
7490 {
7491     .descr = "dedup: btf_type_tag #5, struct",
7492     .input = {
7493         .raw_types = {
7494             BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),              /* [1] */
7495             BTF_TYPE_TAG_ENC(NAME_NTH(1), 1),                   /* [2] */
7496             BTF_TYPE_ENC(NAME_NTH(2), BTF_INFO_ENC(BTF_KIND_STRUCT, 1, 1), 4),  /* [3] */
7497             BTF_MEMBER_ENC(NAME_NTH(3), 2, BTF_MEMBER_OFFSET(0, 0)),
7498             BTF_TYPE_TAG_ENC(NAME_NTH(1), 1),                   /* [4] */
7499             BTF_TYPE_ENC(NAME_NTH(2), BTF_INFO_ENC(BTF_KIND_STRUCT, 1, 1), 4),  /* [5] */
7500             BTF_MEMBER_ENC(NAME_NTH(3), 4, BTF_MEMBER_OFFSET(0, 0)),
7501             BTF_END_RAW,
7502         },
7503         BTF_STR_SEC("\0tag1\0t\0m"),
7504     },
7505     .expect = {
7506         .raw_types = {
7507             BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),              /* [1] */
7508             BTF_TYPE_TAG_ENC(NAME_NTH(1), 1),                   /* [2] */
7509             BTF_TYPE_ENC(NAME_NTH(2), BTF_INFO_ENC(BTF_KIND_STRUCT, 1, 1), 4),  /* [3] */
7510             BTF_MEMBER_ENC(NAME_NTH(3), 2, BTF_MEMBER_OFFSET(0, 0)),
7511             BTF_END_RAW,
7512         },
7513         BTF_STR_SEC("\0tag1\0t\0m"),
7514     },
7515 },
7516 {
7517     .descr = "dedup: enum64, standalone",
7518     .input = {
7519         .raw_types = {
7520             BTF_TYPE_ENC(NAME_NTH(1), BTF_INFO_ENC(BTF_KIND_ENUM64, 0, 1), 8),
7521                 BTF_ENUM64_ENC(NAME_NTH(2), 1, 123),
7522             BTF_TYPE_ENC(NAME_NTH(1), BTF_INFO_ENC(BTF_KIND_ENUM64, 0, 1), 8),
7523                 BTF_ENUM64_ENC(NAME_NTH(2), 1, 123),
7524             BTF_END_RAW,
7525         },
7526         BTF_STR_SEC("\0e1\0e1_val"),
7527     },
7528     .expect = {
7529         .raw_types = {
7530             BTF_TYPE_ENC(NAME_NTH(1), BTF_INFO_ENC(BTF_KIND_ENUM64, 0, 1), 8),
7531                 BTF_ENUM64_ENC(NAME_NTH(2), 1, 123),
7532             BTF_END_RAW,
7533         },
7534         BTF_STR_SEC("\0e1\0e1_val"),
7535     },
7536 },
7537 {
7538     .descr = "dedup: enum64, fwd resolution",
7539     .input = {
7540         .raw_types = {
7541             /* [1] fwd enum64 'e1' before full enum */
7542             BTF_TYPE_ENC(NAME_NTH(1), BTF_INFO_ENC(BTF_KIND_ENUM64, 0, 0), 8),
7543             /* [2] full enum64 'e1' after fwd */
7544             BTF_TYPE_ENC(NAME_NTH(1), BTF_INFO_ENC(BTF_KIND_ENUM64, 0, 1), 8),
7545                 BTF_ENUM64_ENC(NAME_NTH(2), 1, 123),
7546             /* [3] full enum64 'e2' before fwd */
7547             BTF_TYPE_ENC(NAME_NTH(3), BTF_INFO_ENC(BTF_KIND_ENUM64, 0, 1), 8),
7548                 BTF_ENUM64_ENC(NAME_NTH(4), 0, 456),
7549             /* [4] fwd enum64 'e2' after full enum */
7550             BTF_TYPE_ENC(NAME_NTH(3), BTF_INFO_ENC(BTF_KIND_ENUM64, 0, 0), 8),
7551             /* [5] incompatible full enum64 with different value */
7552             BTF_TYPE_ENC(NAME_NTH(1), BTF_INFO_ENC(BTF_KIND_ENUM64, 0, 1), 8),
7553                 BTF_ENUM64_ENC(NAME_NTH(2), 0, 321),
7554             BTF_END_RAW,
7555         },
7556         BTF_STR_SEC("\0e1\0e1_val\0e2\0e2_val"),
7557     },
7558     .expect = {
7559         .raw_types = {
7560             /* [1] full enum64 'e1' */
7561             BTF_TYPE_ENC(NAME_NTH(1), BTF_INFO_ENC(BTF_KIND_ENUM64, 0, 1), 8),
7562                 BTF_ENUM64_ENC(NAME_NTH(2), 1, 123),
7563             /* [2] full enum64 'e2' */
7564             BTF_TYPE_ENC(NAME_NTH(3), BTF_INFO_ENC(BTF_KIND_ENUM64, 0, 1), 8),
7565                 BTF_ENUM64_ENC(NAME_NTH(4), 0, 456),
7566             /* [3] incompatible full enum64 with different value */
7567             BTF_TYPE_ENC(NAME_NTH(1), BTF_INFO_ENC(BTF_KIND_ENUM64, 0, 1), 8),
7568                 BTF_ENUM64_ENC(NAME_NTH(2), 0, 321),
7569             BTF_END_RAW,
7570         },
7571         BTF_STR_SEC("\0e1\0e1_val\0e2\0e2_val"),
7572     },
7573 },
7574 {
7575     .descr = "dedup: enum and enum64, no dedup",
7576     .input = {
7577         .raw_types = {
7578             /* [1] enum 'e1' */
7579             BTF_TYPE_ENC(NAME_NTH(1), BTF_INFO_ENC(BTF_KIND_ENUM, 0, 1), 4),
7580                 BTF_ENUM_ENC(NAME_NTH(2), 1),
7581             /* [2] enum64 'e1' */
7582             BTF_TYPE_ENC(NAME_NTH(1), BTF_INFO_ENC(BTF_KIND_ENUM64, 0, 1), 4),
7583                 BTF_ENUM64_ENC(NAME_NTH(2), 1, 0),
7584             BTF_END_RAW,
7585         },
7586         BTF_STR_SEC("\0e1\0e1_val"),
7587     },
7588     .expect = {
7589         .raw_types = {
7590             /* [1] enum 'e1' */
7591             BTF_TYPE_ENC(NAME_NTH(1), BTF_INFO_ENC(BTF_KIND_ENUM, 0, 1), 4),
7592                 BTF_ENUM_ENC(NAME_NTH(2), 1),
7593             /* [2] enum64 'e1' */
7594             BTF_TYPE_ENC(NAME_NTH(1), BTF_INFO_ENC(BTF_KIND_ENUM64, 0, 1), 4),
7595                 BTF_ENUM64_ENC(NAME_NTH(2), 1, 0),
7596             BTF_END_RAW,
7597         },
7598         BTF_STR_SEC("\0e1\0e1_val"),
7599     },
7600 },
7601 
7602 };
7603 
7604 static int btf_type_size(const struct btf_type *t)
7605 {
7606     int base_size = sizeof(struct btf_type);
7607     __u16 vlen = BTF_INFO_VLEN(t->info);
7608     __u16 kind = BTF_INFO_KIND(t->info);
7609 
7610     switch (kind) {
7611     case BTF_KIND_FWD:
7612     case BTF_KIND_CONST:
7613     case BTF_KIND_VOLATILE:
7614     case BTF_KIND_RESTRICT:
7615     case BTF_KIND_PTR:
7616     case BTF_KIND_TYPEDEF:
7617     case BTF_KIND_FUNC:
7618     case BTF_KIND_FLOAT:
7619     case BTF_KIND_TYPE_TAG:
7620         return base_size;
7621     case BTF_KIND_INT:
7622         return base_size + sizeof(__u32);
7623     case BTF_KIND_ENUM:
7624         return base_size + vlen * sizeof(struct btf_enum);
7625     case BTF_KIND_ENUM64:
7626         return base_size + vlen * sizeof(struct btf_enum64);
7627     case BTF_KIND_ARRAY:
7628         return base_size + sizeof(struct btf_array);
7629     case BTF_KIND_STRUCT:
7630     case BTF_KIND_UNION:
7631         return base_size + vlen * sizeof(struct btf_member);
7632     case BTF_KIND_FUNC_PROTO:
7633         return base_size + vlen * sizeof(struct btf_param);
7634     case BTF_KIND_VAR:
7635         return base_size + sizeof(struct btf_var);
7636     case BTF_KIND_DATASEC:
7637         return base_size + vlen * sizeof(struct btf_var_secinfo);
7638     case BTF_KIND_DECL_TAG:
7639         return base_size + sizeof(struct btf_decl_tag);
7640     default:
7641         fprintf(stderr, "Unsupported BTF_KIND:%u\n", kind);
7642         return -EINVAL;
7643     }
7644 }
7645 
7646 static void dump_btf_strings(const char *strs, __u32 len)
7647 {
7648     const char *cur = strs;
7649     int i = 0;
7650 
7651     while (cur < strs + len) {
7652         fprintf(stderr, "string #%d: '%s'\n", i, cur);
7653         cur += strlen(cur) + 1;
7654         i++;
7655     }
7656 }
7657 
7658 static void do_test_dedup(unsigned int test_num)
7659 {
7660     struct btf_dedup_test *test = &dedup_tests[test_num - 1];
7661     __u32 test_nr_types, expect_nr_types, test_btf_size, expect_btf_size;
7662     const struct btf_header *test_hdr, *expect_hdr;
7663     struct btf *test_btf = NULL, *expect_btf = NULL;
7664     const void *test_btf_data, *expect_btf_data;
7665     const char *ret_test_next_str, *ret_expect_next_str;
7666     const char *test_strs, *expect_strs;
7667     const char *test_str_cur;
7668     const char *expect_str_cur, *expect_str_end;
7669     unsigned int raw_btf_size;
7670     void *raw_btf;
7671     int err = 0, i;
7672 
7673     if (!test__start_subtest(test->descr))
7674         return;
7675 
7676     raw_btf = btf_raw_create(&hdr_tmpl, test->input.raw_types,
7677                  test->input.str_sec, test->input.str_sec_size,
7678                  &raw_btf_size, &ret_test_next_str);
7679     if (!raw_btf)
7680         return;
7681 
7682     test_btf = btf__new((__u8 *)raw_btf, raw_btf_size);
7683     err = libbpf_get_error(test_btf);
7684     free(raw_btf);
7685     if (CHECK(err, "invalid test_btf errno:%d", err)) {
7686         err = -1;
7687         goto done;
7688     }
7689 
7690     raw_btf = btf_raw_create(&hdr_tmpl, test->expect.raw_types,
7691                  test->expect.str_sec,
7692                  test->expect.str_sec_size,
7693                  &raw_btf_size, &ret_expect_next_str);
7694     if (!raw_btf)
7695         return;
7696     expect_btf = btf__new((__u8 *)raw_btf, raw_btf_size);
7697     err = libbpf_get_error(expect_btf);
7698     free(raw_btf);
7699     if (CHECK(err, "invalid expect_btf errno:%d", err)) {
7700         err = -1;
7701         goto done;
7702     }
7703 
7704     test->opts.sz = sizeof(test->opts);
7705     err = btf__dedup(test_btf, &test->opts);
7706     if (CHECK(err, "btf_dedup failed errno:%d", err)) {
7707         err = -1;
7708         goto done;
7709     }
7710 
7711     test_btf_data = btf__raw_data(test_btf, &test_btf_size);
7712     expect_btf_data = btf__raw_data(expect_btf, &expect_btf_size);
7713     if (CHECK(test_btf_size != expect_btf_size,
7714           "test_btf_size:%u != expect_btf_size:%u",
7715           test_btf_size, expect_btf_size)) {
7716         err = -1;
7717         goto done;
7718     }
7719 
7720     test_hdr = test_btf_data;
7721     test_strs = test_btf_data + sizeof(*test_hdr) + test_hdr->str_off;
7722     expect_hdr = expect_btf_data;
7723     expect_strs = expect_btf_data + sizeof(*test_hdr) + expect_hdr->str_off;
7724     if (CHECK(test_hdr->str_len != expect_hdr->str_len,
7725           "test_hdr->str_len:%u != expect_hdr->str_len:%u",
7726           test_hdr->str_len, expect_hdr->str_len)) {
7727         fprintf(stderr, "\ntest strings:\n");
7728         dump_btf_strings(test_strs, test_hdr->str_len);
7729         fprintf(stderr, "\nexpected strings:\n");
7730         dump_btf_strings(expect_strs, expect_hdr->str_len);
7731         err = -1;
7732         goto done;
7733     }
7734 
7735     expect_str_cur = expect_strs;
7736     expect_str_end = expect_strs + expect_hdr->str_len;
7737     while (expect_str_cur < expect_str_end) {
7738         size_t test_len, expect_len;
7739         int off;
7740 
7741         off = btf__find_str(test_btf, expect_str_cur);
7742         if (CHECK(off < 0, "exp str '%s' not found: %d\n", expect_str_cur, off)) {
7743             err = -1;
7744             goto done;
7745         }
7746         test_str_cur = btf__str_by_offset(test_btf, off);
7747 
7748         test_len = strlen(test_str_cur);
7749         expect_len = strlen(expect_str_cur);
7750         if (CHECK(test_len != expect_len,
7751               "test_len:%zu != expect_len:%zu "
7752               "(test_str:%s, expect_str:%s)",
7753               test_len, expect_len, test_str_cur, expect_str_cur)) {
7754             err = -1;
7755             goto done;
7756         }
7757         if (CHECK(strcmp(test_str_cur, expect_str_cur),
7758               "test_str:%s != expect_str:%s",
7759               test_str_cur, expect_str_cur)) {
7760             err = -1;
7761             goto done;
7762         }
7763         expect_str_cur += expect_len + 1;
7764     }
7765 
7766     test_nr_types = btf__type_cnt(test_btf);
7767     expect_nr_types = btf__type_cnt(expect_btf);
7768     if (CHECK(test_nr_types != expect_nr_types,
7769           "test_nr_types:%u != expect_nr_types:%u",
7770           test_nr_types, expect_nr_types)) {
7771         err = -1;
7772         goto done;
7773     }
7774 
7775     for (i = 1; i < test_nr_types; i++) {
7776         const struct btf_type *test_type, *expect_type;
7777         int test_size, expect_size;
7778 
7779         test_type = btf__type_by_id(test_btf, i);
7780         expect_type = btf__type_by_id(expect_btf, i);
7781         test_size = btf_type_size(test_type);
7782         expect_size = btf_type_size(expect_type);
7783 
7784         if (CHECK(test_size != expect_size,
7785               "type #%d: test_size:%d != expect_size:%u",
7786               i, test_size, expect_size)) {
7787             err = -1;
7788             goto done;
7789         }
7790         if (CHECK(btf_kind(test_type) != btf_kind(expect_type),
7791               "type %d kind: exp %d != got %u\n",
7792               i, btf_kind(expect_type), btf_kind(test_type))) {
7793             err = -1;
7794             goto done;
7795         }
7796         if (CHECK(test_type->info != expect_type->info,
7797               "type %d info: exp %d != got %u\n",
7798               i, expect_type->info, test_type->info)) {
7799             err = -1;
7800             goto done;
7801         }
7802         if (CHECK(test_type->size != expect_type->size,
7803               "type %d size/type: exp %d != got %u\n",
7804               i, expect_type->size, test_type->size)) {
7805             err = -1;
7806             goto done;
7807         }
7808     }
7809 
7810 done:
7811     btf__free(test_btf);
7812     btf__free(expect_btf);
7813 }
7814 
7815 void test_btf(void)
7816 {
7817     int i;
7818 
7819     always_log = env.verbosity > VERBOSE_NONE;
7820 
7821     for (i = 1; i <= ARRAY_SIZE(raw_tests); i++)
7822         do_test_raw(i);
7823     for (i = 1; i <= ARRAY_SIZE(get_info_tests); i++)
7824         do_test_get_info(i);
7825     for (i = 1; i <= ARRAY_SIZE(file_tests); i++)
7826         do_test_file(i);
7827     for (i = 1; i <= ARRAY_SIZE(info_raw_tests); i++)
7828         do_test_info_raw(i);
7829     for (i = 1; i <= ARRAY_SIZE(dedup_tests); i++)
7830         do_test_dedup(i);
7831     test_pprint();
7832 }