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