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