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