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