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, 0x10000000, 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}; /* struct btf_raw_test raw_tests[] */
3535
3536static const char *get_next_str(const char *start, const char *end)
3537{
3538        return start < end - 1 ? start + 1 : NULL;
3539}
3540
3541static int get_raw_sec_size(const __u32 *raw_types)
3542{
3543        int i;
3544
3545        for (i = MAX_NR_RAW_U32 - 1;
3546             i >= 0 && raw_types[i] != BTF_END_RAW;
3547             i--)
3548                ;
3549
3550        return i < 0 ? i : i * sizeof(raw_types[0]);
3551}
3552
3553static void *btf_raw_create(const struct btf_header *hdr,
3554                            const __u32 *raw_types,
3555                            const char *str,
3556                            unsigned int str_sec_size,
3557                            unsigned int *btf_size,
3558                            const char **ret_next_str)
3559{
3560        const char *next_str = str, *end_str = str + str_sec_size;
3561        const char **strs_idx = NULL, **tmp_strs_idx;
3562        int strs_cap = 0, strs_cnt = 0, next_str_idx = 0;
3563        unsigned int size_needed, offset;
3564        struct btf_header *ret_hdr;
3565        int i, type_sec_size, err = 0;
3566        uint32_t *ret_types;
3567        void *raw_btf = NULL;
3568
3569        type_sec_size = get_raw_sec_size(raw_types);
3570        if (CHECK(type_sec_size < 0, "Cannot get nr_raw_types"))
3571                return NULL;
3572
3573        size_needed = sizeof(*hdr) + type_sec_size + str_sec_size;
3574        raw_btf = malloc(size_needed);
3575        if (CHECK(!raw_btf, "Cannot allocate memory for raw_btf"))
3576                return NULL;
3577
3578        /* Copy header */
3579        memcpy(raw_btf, hdr, sizeof(*hdr));
3580        offset = sizeof(*hdr);
3581
3582        /* Index strings */
3583        while ((next_str = get_next_str(next_str, end_str))) {
3584                if (strs_cnt == strs_cap) {
3585                        strs_cap += max(16, strs_cap / 2);
3586                        tmp_strs_idx = realloc(strs_idx,
3587                                               sizeof(*strs_idx) * strs_cap);
3588                        if (CHECK(!tmp_strs_idx,
3589                                  "Cannot allocate memory for strs_idx")) {
3590                                err = -1;
3591                                goto done;
3592                        }
3593                        strs_idx = tmp_strs_idx;
3594                }
3595                strs_idx[strs_cnt++] = next_str;
3596                next_str += strlen(next_str);
3597        }
3598
3599        /* Copy type section */
3600        ret_types = raw_btf + offset;
3601        for (i = 0; i < type_sec_size / sizeof(raw_types[0]); i++) {
3602                if (raw_types[i] == NAME_TBD) {
3603                        if (CHECK(next_str_idx == strs_cnt,
3604                                  "Error in getting next_str #%d",
3605                                  next_str_idx)) {
3606                                err = -1;
3607                                goto done;
3608                        }
3609                        ret_types[i] = strs_idx[next_str_idx++] - str;
3610                } else if (IS_NAME_NTH(raw_types[i])) {
3611                        int idx = GET_NAME_NTH_IDX(raw_types[i]);
3612
3613                        if (CHECK(idx <= 0 || idx > strs_cnt,
3614                                  "Error getting string #%d, strs_cnt:%d",
3615                                  idx, strs_cnt)) {
3616                                err = -1;
3617                                goto done;
3618                        }
3619                        ret_types[i] = strs_idx[idx-1] - str;
3620                } else {
3621                        ret_types[i] = raw_types[i];
3622                }
3623        }
3624        offset += type_sec_size;
3625
3626        /* Copy string section */
3627        memcpy(raw_btf + offset, str, str_sec_size);
3628
3629        ret_hdr = (struct btf_header *)raw_btf;
3630        ret_hdr->type_len = type_sec_size;
3631        ret_hdr->str_off = type_sec_size;
3632        ret_hdr->str_len = str_sec_size;
3633
3634        *btf_size = size_needed;
3635        if (ret_next_str)
3636                *ret_next_str =
3637                        next_str_idx < strs_cnt ? strs_idx[next_str_idx] : NULL;
3638
3639done:
3640        if (err) {
3641                if (raw_btf)
3642                        free(raw_btf);
3643                if (strs_idx)
3644                        free(strs_idx);
3645                return NULL;
3646        }
3647        return raw_btf;
3648}
3649
3650static void do_test_raw(unsigned int test_num)
3651{
3652        struct btf_raw_test *test = &raw_tests[test_num - 1];
3653        struct bpf_create_map_attr create_attr = {};
3654        int map_fd = -1, btf_fd = -1;
3655        unsigned int raw_btf_size;
3656        struct btf_header *hdr;
3657        void *raw_btf;
3658        int err;
3659
3660        if (!test__start_subtest(test->descr))
3661                return;
3662
3663        raw_btf = btf_raw_create(&hdr_tmpl,
3664                                 test->raw_types,
3665                                 test->str_sec,
3666                                 test->str_sec_size,
3667                                 &raw_btf_size, NULL);
3668        if (!raw_btf)
3669                return;
3670
3671        hdr = raw_btf;
3672
3673        hdr->hdr_len = (int)hdr->hdr_len + test->hdr_len_delta;
3674        hdr->type_off = (int)hdr->type_off + test->type_off_delta;
3675        hdr->str_off = (int)hdr->str_off + test->str_off_delta;
3676        hdr->str_len = (int)hdr->str_len + test->str_len_delta;
3677
3678        *btf_log_buf = '\0';
3679        btf_fd = bpf_load_btf(raw_btf, raw_btf_size,
3680                              btf_log_buf, BTF_LOG_BUF_SIZE,
3681                              always_log);
3682        free(raw_btf);
3683
3684        err = ((btf_fd == -1) != test->btf_load_err);
3685        if (CHECK(err, "btf_fd:%d test->btf_load_err:%u",
3686                  btf_fd, test->btf_load_err) ||
3687            CHECK(test->err_str && !strstr(btf_log_buf, test->err_str),
3688                  "expected err_str:%s", test->err_str)) {
3689                err = -1;
3690                goto done;
3691        }
3692
3693        if (err || btf_fd == -1)
3694                goto done;
3695
3696        create_attr.name = test->map_name;
3697        create_attr.map_type = test->map_type;
3698        create_attr.key_size = test->key_size;
3699        create_attr.value_size = test->value_size;
3700        create_attr.max_entries = test->max_entries;
3701        create_attr.btf_fd = btf_fd;
3702        create_attr.btf_key_type_id = test->key_type_id;
3703        create_attr.btf_value_type_id = test->value_type_id;
3704
3705        map_fd = bpf_create_map_xattr(&create_attr);
3706
3707        err = ((map_fd == -1) != test->map_create_err);
3708        CHECK(err, "map_fd:%d test->map_create_err:%u",
3709              map_fd, test->map_create_err);
3710
3711done:
3712        if (*btf_log_buf && (err || always_log))
3713                fprintf(stderr, "\n%s", btf_log_buf);
3714        if (btf_fd != -1)
3715                close(btf_fd);
3716        if (map_fd != -1)
3717                close(map_fd);
3718}
3719
3720struct btf_get_info_test {
3721        const char *descr;
3722        const char *str_sec;
3723        __u32 raw_types[MAX_NR_RAW_U32];
3724        __u32 str_sec_size;
3725        int btf_size_delta;
3726        int (*special_test)(unsigned int test_num);
3727};
3728
3729static int test_big_btf_info(unsigned int test_num);
3730static int test_btf_id(unsigned int test_num);
3731
3732const struct btf_get_info_test get_info_tests[] = {
3733{
3734        .descr = "== raw_btf_size+1",
3735        .raw_types = {
3736                /* int */                               /* [1] */
3737                BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
3738                BTF_END_RAW,
3739        },
3740        .str_sec = "",
3741        .str_sec_size = sizeof(""),
3742        .btf_size_delta = 1,
3743},
3744{
3745        .descr = "== raw_btf_size-3",
3746        .raw_types = {
3747                /* int */                               /* [1] */
3748                BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
3749                BTF_END_RAW,
3750        },
3751        .str_sec = "",
3752        .str_sec_size = sizeof(""),
3753        .btf_size_delta = -3,
3754},
3755{
3756        .descr = "Large bpf_btf_info",
3757        .raw_types = {
3758                /* int */                               /* [1] */
3759                BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
3760                BTF_END_RAW,
3761        },
3762        .str_sec = "",
3763        .str_sec_size = sizeof(""),
3764        .special_test = test_big_btf_info,
3765},
3766{
3767        .descr = "BTF ID",
3768        .raw_types = {
3769                /* int */                               /* [1] */
3770                BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
3771                /* unsigned int */                      /* [2] */
3772                BTF_TYPE_INT_ENC(0, 0, 0, 32, 4),
3773                BTF_END_RAW,
3774        },
3775        .str_sec = "",
3776        .str_sec_size = sizeof(""),
3777        .special_test = test_btf_id,
3778},
3779};
3780
3781static int test_big_btf_info(unsigned int test_num)
3782{
3783        const struct btf_get_info_test *test = &get_info_tests[test_num - 1];
3784        uint8_t *raw_btf = NULL, *user_btf = NULL;
3785        unsigned int raw_btf_size;
3786        struct {
3787                struct bpf_btf_info info;
3788                uint64_t garbage;
3789        } info_garbage;
3790        struct bpf_btf_info *info;
3791        int btf_fd = -1, err;
3792        uint32_t info_len;
3793
3794        raw_btf = btf_raw_create(&hdr_tmpl,
3795                                 test->raw_types,
3796                                 test->str_sec,
3797                                 test->str_sec_size,
3798                                 &raw_btf_size, NULL);
3799
3800        if (!raw_btf)
3801                return -1;
3802
3803        *btf_log_buf = '\0';
3804
3805        user_btf = malloc(raw_btf_size);
3806        if (CHECK(!user_btf, "!user_btf")) {
3807                err = -1;
3808                goto done;
3809        }
3810
3811        btf_fd = bpf_load_btf(raw_btf, raw_btf_size,
3812                              btf_log_buf, BTF_LOG_BUF_SIZE,
3813                              always_log);
3814        if (CHECK(btf_fd == -1, "errno:%d", errno)) {
3815                err = -1;
3816                goto done;
3817        }
3818
3819        /*
3820         * GET_INFO should error out if the userspace info
3821         * has non zero tailing bytes.
3822         */
3823        info = &info_garbage.info;
3824        memset(info, 0, sizeof(*info));
3825        info_garbage.garbage = 0xdeadbeef;
3826        info_len = sizeof(info_garbage);
3827        info->btf = ptr_to_u64(user_btf);
3828        info->btf_size = raw_btf_size;
3829
3830        err = bpf_obj_get_info_by_fd(btf_fd, info, &info_len);
3831        if (CHECK(!err, "!err")) {
3832                err = -1;
3833                goto done;
3834        }
3835
3836        /*
3837         * GET_INFO should succeed even info_len is larger than
3838         * the kernel supported as long as tailing bytes are zero.
3839         * The kernel supported info len should also be returned
3840         * to userspace.
3841         */
3842        info_garbage.garbage = 0;
3843        err = bpf_obj_get_info_by_fd(btf_fd, info, &info_len);
3844        if (CHECK(err || info_len != sizeof(*info),
3845                  "err:%d errno:%d info_len:%u sizeof(*info):%zu",
3846                  err, errno, info_len, sizeof(*info))) {
3847                err = -1;
3848                goto done;
3849        }
3850
3851        fprintf(stderr, "OK");
3852
3853done:
3854        if (*btf_log_buf && (err || always_log))
3855                fprintf(stderr, "\n%s", btf_log_buf);
3856
3857        free(raw_btf);
3858        free(user_btf);
3859
3860        if (btf_fd != -1)
3861                close(btf_fd);
3862
3863        return err;
3864}
3865
3866static int test_btf_id(unsigned int test_num)
3867{
3868        const struct btf_get_info_test *test = &get_info_tests[test_num - 1];
3869        struct bpf_create_map_attr create_attr = {};
3870        uint8_t *raw_btf = NULL, *user_btf[2] = {};
3871        int btf_fd[2] = {-1, -1}, map_fd = -1;
3872        struct bpf_map_info map_info = {};
3873        struct bpf_btf_info info[2] = {};
3874        unsigned int raw_btf_size;
3875        uint32_t info_len;
3876        int err, i, ret;
3877
3878        raw_btf = btf_raw_create(&hdr_tmpl,
3879                                 test->raw_types,
3880                                 test->str_sec,
3881                                 test->str_sec_size,
3882                                 &raw_btf_size, NULL);
3883
3884        if (!raw_btf)
3885                return -1;
3886
3887        *btf_log_buf = '\0';
3888
3889        for (i = 0; i < 2; i++) {
3890                user_btf[i] = malloc(raw_btf_size);
3891                if (CHECK(!user_btf[i], "!user_btf[%d]", i)) {
3892                        err = -1;
3893                        goto done;
3894                }
3895                info[i].btf = ptr_to_u64(user_btf[i]);
3896                info[i].btf_size = raw_btf_size;
3897        }
3898
3899        btf_fd[0] = bpf_load_btf(raw_btf, raw_btf_size,
3900                                 btf_log_buf, BTF_LOG_BUF_SIZE,
3901                                 always_log);
3902        if (CHECK(btf_fd[0] == -1, "errno:%d", errno)) {
3903                err = -1;
3904                goto done;
3905        }
3906
3907        /* Test BPF_OBJ_GET_INFO_BY_ID on btf_id */
3908        info_len = sizeof(info[0]);
3909        err = bpf_obj_get_info_by_fd(btf_fd[0], &info[0], &info_len);
3910        if (CHECK(err, "errno:%d", errno)) {
3911                err = -1;
3912                goto done;
3913        }
3914
3915        btf_fd[1] = bpf_btf_get_fd_by_id(info[0].id);
3916        if (CHECK(btf_fd[1] == -1, "errno:%d", errno)) {
3917                err = -1;
3918                goto done;
3919        }
3920
3921        ret = 0;
3922        err = bpf_obj_get_info_by_fd(btf_fd[1], &info[1], &info_len);
3923        if (CHECK(err || info[0].id != info[1].id ||
3924                  info[0].btf_size != info[1].btf_size ||
3925                  (ret = memcmp(user_btf[0], user_btf[1], info[0].btf_size)),
3926                  "err:%d errno:%d id0:%u id1:%u btf_size0:%u btf_size1:%u memcmp:%d",
3927                  err, errno, info[0].id, info[1].id,
3928                  info[0].btf_size, info[1].btf_size, ret)) {
3929                err = -1;
3930                goto done;
3931        }
3932
3933        /* Test btf members in struct bpf_map_info */
3934        create_attr.name = "test_btf_id";
3935        create_attr.map_type = BPF_MAP_TYPE_ARRAY;
3936        create_attr.key_size = sizeof(int);
3937        create_attr.value_size = sizeof(unsigned int);
3938        create_attr.max_entries = 4;
3939        create_attr.btf_fd = btf_fd[0];
3940        create_attr.btf_key_type_id = 1;
3941        create_attr.btf_value_type_id = 2;
3942
3943        map_fd = bpf_create_map_xattr(&create_attr);
3944        if (CHECK(map_fd == -1, "errno:%d", errno)) {
3945                err = -1;
3946                goto done;
3947        }
3948
3949        info_len = sizeof(map_info);
3950        err = bpf_obj_get_info_by_fd(map_fd, &map_info, &info_len);
3951        if (CHECK(err || map_info.btf_id != info[0].id ||
3952                  map_info.btf_key_type_id != 1 || map_info.btf_value_type_id != 2,
3953                  "err:%d errno:%d info.id:%u btf_id:%u btf_key_type_id:%u btf_value_type_id:%u",
3954                  err, errno, info[0].id, map_info.btf_id, map_info.btf_key_type_id,
3955                  map_info.btf_value_type_id)) {
3956                err = -1;
3957                goto done;
3958        }
3959
3960        for (i = 0; i < 2; i++) {
3961                close(btf_fd[i]);
3962                btf_fd[i] = -1;
3963        }
3964
3965        /* Test BTF ID is removed from the kernel */
3966        btf_fd[0] = bpf_btf_get_fd_by_id(map_info.btf_id);
3967        if (CHECK(btf_fd[0] == -1, "errno:%d", errno)) {
3968                err = -1;
3969                goto done;
3970        }
3971        close(btf_fd[0]);
3972        btf_fd[0] = -1;
3973
3974        /* The map holds the last ref to BTF and its btf_id */
3975        close(map_fd);
3976        map_fd = -1;
3977        btf_fd[0] = bpf_btf_get_fd_by_id(map_info.btf_id);
3978        if (CHECK(btf_fd[0] != -1, "BTF lingers")) {
3979                err = -1;
3980                goto done;
3981        }
3982
3983        fprintf(stderr, "OK");
3984
3985done:
3986        if (*btf_log_buf && (err || always_log))
3987                fprintf(stderr, "\n%s", btf_log_buf);
3988
3989        free(raw_btf);
3990        if (map_fd != -1)
3991                close(map_fd);
3992        for (i = 0; i < 2; i++) {
3993                free(user_btf[i]);
3994                if (btf_fd[i] != -1)
3995                        close(btf_fd[i]);
3996        }
3997
3998        return err;
3999}
4000
4001static void do_test_get_info(unsigned int test_num)
4002{
4003        const struct btf_get_info_test *test = &get_info_tests[test_num - 1];
4004        unsigned int raw_btf_size, user_btf_size, expected_nbytes;
4005        uint8_t *raw_btf = NULL, *user_btf = NULL;
4006        struct bpf_btf_info info = {};
4007        int btf_fd = -1, err, ret;
4008        uint32_t info_len;
4009
4010        if (!test__start_subtest(test->descr))
4011                return;
4012
4013        if (test->special_test) {
4014                err = test->special_test(test_num);
4015                if (CHECK(err, "failed: %d\n", err))
4016                        return;
4017        }
4018
4019        raw_btf = btf_raw_create(&hdr_tmpl,
4020                                 test->raw_types,
4021                                 test->str_sec,
4022                                 test->str_sec_size,
4023                                 &raw_btf_size, NULL);
4024
4025        if (!raw_btf)
4026                return;
4027
4028        *btf_log_buf = '\0';
4029
4030        user_btf = malloc(raw_btf_size);
4031        if (CHECK(!user_btf, "!user_btf")) {
4032                err = -1;
4033                goto done;
4034        }
4035
4036        btf_fd = bpf_load_btf(raw_btf, raw_btf_size,
4037                              btf_log_buf, BTF_LOG_BUF_SIZE,
4038                              always_log);
4039        if (CHECK(btf_fd == -1, "errno:%d", errno)) {
4040                err = -1;
4041                goto done;
4042        }
4043
4044        user_btf_size = (int)raw_btf_size + test->btf_size_delta;
4045        expected_nbytes = min(raw_btf_size, user_btf_size);
4046        if (raw_btf_size > expected_nbytes)
4047                memset(user_btf + expected_nbytes, 0xff,
4048                       raw_btf_size - expected_nbytes);
4049
4050        info_len = sizeof(info);
4051        info.btf = ptr_to_u64(user_btf);
4052        info.btf_size = user_btf_size;
4053
4054        ret = 0;
4055        err = bpf_obj_get_info_by_fd(btf_fd, &info, &info_len);
4056        if (CHECK(err || !info.id || info_len != sizeof(info) ||
4057                  info.btf_size != raw_btf_size ||
4058                  (ret = memcmp(raw_btf, user_btf, expected_nbytes)),
4059                  "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",
4060                  err, errno, info.id, info_len, sizeof(info),
4061                  raw_btf_size, info.btf_size, expected_nbytes, ret)) {
4062                err = -1;
4063                goto done;
4064        }
4065
4066        while (expected_nbytes < raw_btf_size) {
4067                fprintf(stderr, "%u...", expected_nbytes);
4068                if (CHECK(user_btf[expected_nbytes++] != 0xff,
4069                          "user_btf[%u]:%x != 0xff", expected_nbytes - 1,
4070                          user_btf[expected_nbytes - 1])) {
4071                        err = -1;
4072                        goto done;
4073                }
4074        }
4075
4076        fprintf(stderr, "OK");
4077
4078done:
4079        if (*btf_log_buf && (err || always_log))
4080                fprintf(stderr, "\n%s", btf_log_buf);
4081
4082        free(raw_btf);
4083        free(user_btf);
4084
4085        if (btf_fd != -1)
4086                close(btf_fd);
4087}
4088
4089struct btf_file_test {
4090        const char *file;
4091        bool btf_kv_notfound;
4092};
4093
4094static struct btf_file_test file_tests[] = {
4095        { .file = "test_btf_haskv.o", },
4096        { .file = "test_btf_newkv.o", },
4097        { .file = "test_btf_nokv.o", .btf_kv_notfound = true, },
4098};
4099
4100static void do_test_file(unsigned int test_num)
4101{
4102        const struct btf_file_test *test = &file_tests[test_num - 1];
4103        const char *expected_fnames[] = {"_dummy_tracepoint",
4104                                         "test_long_fname_1",
4105                                         "test_long_fname_2"};
4106        struct btf_ext *btf_ext = NULL;
4107        struct bpf_prog_info info = {};
4108        struct bpf_object *obj = NULL;
4109        struct bpf_func_info *finfo;
4110        struct bpf_program *prog;
4111        __u32 info_len, rec_size;
4112        bool has_btf_ext = false;
4113        struct btf *btf = NULL;
4114        void *func_info = NULL;
4115        struct bpf_map *map;
4116        int i, err, prog_fd;
4117
4118        if (!test__start_subtest(test->file))
4119                return;
4120
4121        btf = btf__parse_elf(test->file, &btf_ext);
4122        if (IS_ERR(btf)) {
4123                if (PTR_ERR(btf) == -ENOENT) {
4124                        printf("%s:SKIP: No ELF %s found", __func__, BTF_ELF_SEC);
4125                        test__skip();
4126                        return;
4127                }
4128                return;
4129        }
4130        btf__free(btf);
4131
4132        has_btf_ext = btf_ext != NULL;
4133        btf_ext__free(btf_ext);
4134
4135        obj = bpf_object__open(test->file);
4136        if (CHECK(IS_ERR(obj), "obj: %ld", PTR_ERR(obj)))
4137                return;
4138
4139        prog = bpf_program__next(NULL, obj);
4140        if (CHECK(!prog, "Cannot find bpf_prog")) {
4141                err = -1;
4142                goto done;
4143        }
4144
4145        bpf_program__set_type(prog, BPF_PROG_TYPE_TRACEPOINT);
4146        err = bpf_object__load(obj);
4147        if (CHECK(err < 0, "bpf_object__load: %d", err))
4148                goto done;
4149        prog_fd = bpf_program__fd(prog);
4150
4151        map = bpf_object__find_map_by_name(obj, "btf_map");
4152        if (CHECK(!map, "btf_map not found")) {
4153                err = -1;
4154                goto done;
4155        }
4156
4157        err = (bpf_map__btf_key_type_id(map) == 0 || bpf_map__btf_value_type_id(map) == 0)
4158                != test->btf_kv_notfound;
4159        if (CHECK(err, "btf_key_type_id:%u btf_value_type_id:%u test->btf_kv_notfound:%u",
4160                  bpf_map__btf_key_type_id(map), bpf_map__btf_value_type_id(map),
4161                  test->btf_kv_notfound))
4162                goto done;
4163
4164        if (!has_btf_ext)
4165                goto skip;
4166
4167        /* get necessary program info */
4168        info_len = sizeof(struct bpf_prog_info);
4169        err = bpf_obj_get_info_by_fd(prog_fd, &info, &info_len);
4170
4171        if (CHECK(err == -1, "invalid get info (1st) errno:%d", errno)) {
4172                fprintf(stderr, "%s\n", btf_log_buf);
4173                err = -1;
4174                goto done;
4175        }
4176        if (CHECK(info.nr_func_info != 3,
4177                  "incorrect info.nr_func_info (1st) %d",
4178                  info.nr_func_info)) {
4179                err = -1;
4180                goto done;
4181        }
4182        rec_size = info.func_info_rec_size;
4183        if (CHECK(rec_size != sizeof(struct bpf_func_info),
4184                  "incorrect info.func_info_rec_size (1st) %d\n", rec_size)) {
4185                err = -1;
4186                goto done;
4187        }
4188
4189        func_info = malloc(info.nr_func_info * rec_size);
4190        if (CHECK(!func_info, "out of memory")) {
4191                err = -1;
4192                goto done;
4193        }
4194
4195        /* reset info to only retrieve func_info related data */
4196        memset(&info, 0, sizeof(info));
4197        info.nr_func_info = 3;
4198        info.func_info_rec_size = rec_size;
4199        info.func_info = ptr_to_u64(func_info);
4200
4201        err = bpf_obj_get_info_by_fd(prog_fd, &info, &info_len);
4202
4203        if (CHECK(err == -1, "invalid get info (2nd) errno:%d", errno)) {
4204                fprintf(stderr, "%s\n", btf_log_buf);
4205                err = -1;
4206                goto done;
4207        }
4208        if (CHECK(info.nr_func_info != 3,
4209                  "incorrect info.nr_func_info (2nd) %d",
4210                  info.nr_func_info)) {
4211                err = -1;
4212                goto done;
4213        }
4214        if (CHECK(info.func_info_rec_size != rec_size,
4215                  "incorrect info.func_info_rec_size (2nd) %d",
4216                  info.func_info_rec_size)) {
4217                err = -1;
4218                goto done;
4219        }
4220
4221        err = btf__get_from_id(info.btf_id, &btf);
4222        if (CHECK(err, "cannot get btf from kernel, err: %d", err))
4223                goto done;
4224
4225        /* check three functions */
4226        finfo = func_info;
4227        for (i = 0; i < 3; i++) {
4228                const struct btf_type *t;
4229                const char *fname;
4230
4231                t = btf__type_by_id(btf, finfo->type_id);
4232                if (CHECK(!t, "btf__type_by_id failure: id %u",
4233                          finfo->type_id)) {
4234                        err = -1;
4235                        goto done;
4236                }
4237
4238                fname = btf__name_by_offset(btf, t->name_off);
4239                err = strcmp(fname, expected_fnames[i]);
4240                /* for the second and third functions in .text section,
4241                 * the compiler may order them either way.
4242                 */
4243                if (i && err)
4244                        err = strcmp(fname, expected_fnames[3 - i]);
4245                if (CHECK(err, "incorrect fname %s", fname ? : "")) {
4246                        err = -1;
4247                        goto done;
4248                }
4249
4250                finfo = (void *)finfo + rec_size;
4251        }
4252
4253skip:
4254        fprintf(stderr, "OK");
4255
4256done:
4257        free(func_info);
4258        bpf_object__close(obj);
4259}
4260
4261const char *pprint_enum_str[] = {
4262        "ENUM_ZERO",
4263        "ENUM_ONE",
4264        "ENUM_TWO",
4265        "ENUM_THREE",
4266};
4267
4268struct pprint_mapv {
4269        uint32_t ui32;
4270        uint16_t ui16;
4271        /* 2 bytes hole */
4272        int32_t si32;
4273        uint32_t unused_bits2a:2,
4274                bits28:28,
4275                unused_bits2b:2;
4276        union {
4277                uint64_t ui64;
4278                uint8_t ui8a[8];
4279        };
4280        enum {
4281                ENUM_ZERO,
4282                ENUM_ONE,
4283                ENUM_TWO,
4284                ENUM_THREE,
4285        } aenum;
4286        uint32_t ui32b;
4287        uint32_t bits2c:2;
4288        uint8_t si8_4[2][2];
4289};
4290
4291#ifdef __SIZEOF_INT128__
4292struct pprint_mapv_int128 {
4293        __int128 si128a;
4294        __int128 si128b;
4295        unsigned __int128 bits3:3;
4296        unsigned __int128 bits80:80;
4297        unsigned __int128 ui128;
4298};
4299#endif
4300
4301static struct btf_raw_test pprint_test_template[] = {
4302{
4303        .raw_types = {
4304                /* unsighed char */                     /* [1] */
4305                BTF_TYPE_INT_ENC(NAME_TBD, 0, 0, 8, 1),
4306                /* unsigned short */                    /* [2] */
4307                BTF_TYPE_INT_ENC(NAME_TBD, 0, 0, 16, 2),
4308                /* unsigned int */                      /* [3] */
4309                BTF_TYPE_INT_ENC(NAME_TBD, 0, 0, 32, 4),
4310                /* int */                               /* [4] */
4311                BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),
4312                /* unsigned long long */                /* [5] */
4313                BTF_TYPE_INT_ENC(NAME_TBD, 0, 0, 64, 8),
4314                /* 2 bits */                            /* [6] */
4315                BTF_TYPE_INT_ENC(0, 0, 0, 2, 2),
4316                /* 28 bits */                           /* [7] */
4317                BTF_TYPE_INT_ENC(0, 0, 0, 28, 4),
4318                /* uint8_t[8] */                        /* [8] */
4319                BTF_TYPE_ARRAY_ENC(9, 1, 8),
4320                /* typedef unsigned char uint8_t */     /* [9] */
4321                BTF_TYPEDEF_ENC(NAME_TBD, 1),
4322                /* typedef unsigned short uint16_t */   /* [10] */
4323                BTF_TYPEDEF_ENC(NAME_TBD, 2),
4324                /* typedef unsigned int uint32_t */     /* [11] */
4325                BTF_TYPEDEF_ENC(NAME_TBD, 3),
4326                /* typedef int int32_t */               /* [12] */
4327                BTF_TYPEDEF_ENC(NAME_TBD, 4),
4328                /* typedef unsigned long long uint64_t *//* [13] */
4329                BTF_TYPEDEF_ENC(NAME_TBD, 5),
4330                /* union (anon) */                      /* [14] */
4331                BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_UNION, 0, 2), 8),
4332                BTF_MEMBER_ENC(NAME_TBD, 13, 0),/* uint64_t ui64; */
4333                BTF_MEMBER_ENC(NAME_TBD, 8, 0), /* uint8_t ui8a[8]; */
4334                /* enum (anon) */                       /* [15] */
4335                BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_ENUM, 0, 4), 4),
4336                BTF_ENUM_ENC(NAME_TBD, 0),
4337                BTF_ENUM_ENC(NAME_TBD, 1),
4338                BTF_ENUM_ENC(NAME_TBD, 2),
4339                BTF_ENUM_ENC(NAME_TBD, 3),
4340                /* struct pprint_mapv */                /* [16] */
4341                BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 11), 40),
4342                BTF_MEMBER_ENC(NAME_TBD, 11, 0),        /* uint32_t ui32 */
4343                BTF_MEMBER_ENC(NAME_TBD, 10, 32),       /* uint16_t ui16 */
4344                BTF_MEMBER_ENC(NAME_TBD, 12, 64),       /* int32_t si32 */
4345                BTF_MEMBER_ENC(NAME_TBD, 6, 96),        /* unused_bits2a */
4346                BTF_MEMBER_ENC(NAME_TBD, 7, 98),        /* bits28 */
4347                BTF_MEMBER_ENC(NAME_TBD, 6, 126),       /* unused_bits2b */
4348                BTF_MEMBER_ENC(0, 14, 128),             /* union (anon) */
4349                BTF_MEMBER_ENC(NAME_TBD, 15, 192),      /* aenum */
4350                BTF_MEMBER_ENC(NAME_TBD, 11, 224),      /* uint32_t ui32b */
4351                BTF_MEMBER_ENC(NAME_TBD, 6, 256),       /* bits2c */
4352                BTF_MEMBER_ENC(NAME_TBD, 17, 264),      /* si8_4 */
4353                BTF_TYPE_ARRAY_ENC(18, 1, 2),           /* [17] */
4354                BTF_TYPE_ARRAY_ENC(1, 1, 2),            /* [18] */
4355                BTF_END_RAW,
4356        },
4357        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"),
4358        .key_size = sizeof(unsigned int),
4359        .value_size = sizeof(struct pprint_mapv),
4360        .key_type_id = 3,       /* unsigned int */
4361        .value_type_id = 16,    /* struct pprint_mapv */
4362        .max_entries = 128,
4363},
4364
4365{
4366        /* this type will have the same type as the
4367         * first .raw_types definition, but struct type will
4368         * be encoded with kind_flag set.
4369         */
4370        .raw_types = {
4371                /* unsighed char */                     /* [1] */
4372                BTF_TYPE_INT_ENC(NAME_TBD, 0, 0, 8, 1),
4373                /* unsigned short */                    /* [2] */
4374                BTF_TYPE_INT_ENC(NAME_TBD, 0, 0, 16, 2),
4375                /* unsigned int */                      /* [3] */
4376                BTF_TYPE_INT_ENC(NAME_TBD, 0, 0, 32, 4),
4377                /* int */                               /* [4] */
4378                BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),
4379                /* unsigned long long */                /* [5] */
4380                BTF_TYPE_INT_ENC(NAME_TBD, 0, 0, 64, 8),
4381                BTF_TYPE_INT_ENC(0, 0, 0, 32, 4),       /* [6] */
4382                BTF_TYPE_INT_ENC(0, 0, 0, 32, 4),       /* [7] */
4383                /* uint8_t[8] */                        /* [8] */
4384                BTF_TYPE_ARRAY_ENC(9, 1, 8),
4385                /* typedef unsigned char uint8_t */     /* [9] */
4386                BTF_TYPEDEF_ENC(NAME_TBD, 1),
4387                /* typedef unsigned short uint16_t */   /* [10] */
4388                BTF_TYPEDEF_ENC(NAME_TBD, 2),
4389                /* typedef unsigned int uint32_t */     /* [11] */
4390                BTF_TYPEDEF_ENC(NAME_TBD, 3),
4391                /* typedef int int32_t */               /* [12] */
4392                BTF_TYPEDEF_ENC(NAME_TBD, 4),
4393                /* typedef unsigned long long uint64_t *//* [13] */
4394                BTF_TYPEDEF_ENC(NAME_TBD, 5),
4395                /* union (anon) */                      /* [14] */
4396                BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_UNION, 0, 2), 8),
4397                BTF_MEMBER_ENC(NAME_TBD, 13, 0),/* uint64_t ui64; */
4398                BTF_MEMBER_ENC(NAME_TBD, 8, 0), /* uint8_t ui8a[8]; */
4399                /* enum (anon) */                       /* [15] */
4400                BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_ENUM, 0, 4), 4),
4401                BTF_ENUM_ENC(NAME_TBD, 0),
4402                BTF_ENUM_ENC(NAME_TBD, 1),
4403                BTF_ENUM_ENC(NAME_TBD, 2),
4404                BTF_ENUM_ENC(NAME_TBD, 3),
4405                /* struct pprint_mapv */                /* [16] */
4406                BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 1, 11), 40),
4407                BTF_MEMBER_ENC(NAME_TBD, 11, BTF_MEMBER_OFFSET(0, 0)),  /* uint32_t ui32 */
4408                BTF_MEMBER_ENC(NAME_TBD, 10, BTF_MEMBER_OFFSET(0, 32)), /* uint16_t ui16 */
4409                BTF_MEMBER_ENC(NAME_TBD, 12, BTF_MEMBER_OFFSET(0, 64)), /* int32_t si32 */
4410                BTF_MEMBER_ENC(NAME_TBD, 6, BTF_MEMBER_OFFSET(2, 96)),  /* unused_bits2a */
4411                BTF_MEMBER_ENC(NAME_TBD, 7, BTF_MEMBER_OFFSET(28, 98)), /* bits28 */
4412                BTF_MEMBER_ENC(NAME_TBD, 6, BTF_MEMBER_OFFSET(2, 126)), /* unused_bits2b */
4413                BTF_MEMBER_ENC(0, 14, BTF_MEMBER_OFFSET(0, 128)),       /* union (anon) */
4414                BTF_MEMBER_ENC(NAME_TBD, 15, BTF_MEMBER_OFFSET(0, 192)),        /* aenum */
4415                BTF_MEMBER_ENC(NAME_TBD, 11, BTF_MEMBER_OFFSET(0, 224)),        /* uint32_t ui32b */
4416                BTF_MEMBER_ENC(NAME_TBD, 6, BTF_MEMBER_OFFSET(2, 256)), /* bits2c */
4417                BTF_MEMBER_ENC(NAME_TBD, 17, 264),      /* si8_4 */
4418                BTF_TYPE_ARRAY_ENC(18, 1, 2),           /* [17] */
4419                BTF_TYPE_ARRAY_ENC(1, 1, 2),            /* [18] */
4420                BTF_END_RAW,
4421        },
4422        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"),
4423        .key_size = sizeof(unsigned int),
4424        .value_size = sizeof(struct pprint_mapv),
4425        .key_type_id = 3,       /* unsigned int */
4426        .value_type_id = 16,    /* struct pprint_mapv */
4427        .max_entries = 128,
4428},
4429
4430{
4431        /* this type will have the same layout as the
4432         * first .raw_types definition. The struct type will
4433         * be encoded with kind_flag set, bitfield members
4434         * are added typedef/const/volatile, and bitfield members
4435         * will have both int and enum types.
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                BTF_TYPE_INT_ENC(0, 0, 0, 32, 4),       /* [6] */
4449                BTF_TYPE_INT_ENC(0, 0, 0, 32, 4),       /* [7] */
4450                /* uint8_t[8] */                        /* [8] */
4451                BTF_TYPE_ARRAY_ENC(9, 1, 8),
4452                /* typedef unsigned char uint8_t */     /* [9] */
4453                BTF_TYPEDEF_ENC(NAME_TBD, 1),
4454                /* typedef unsigned short uint16_t */   /* [10] */
4455                BTF_TYPEDEF_ENC(NAME_TBD, 2),
4456                /* typedef unsigned int uint32_t */     /* [11] */
4457                BTF_TYPEDEF_ENC(NAME_TBD, 3),
4458                /* typedef int int32_t */               /* [12] */
4459                BTF_TYPEDEF_ENC(NAME_TBD, 4),
4460                /* typedef unsigned long long uint64_t *//* [13] */
4461                BTF_TYPEDEF_ENC(NAME_TBD, 5),
4462                /* union (anon) */                      /* [14] */
4463                BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_UNION, 0, 2), 8),
4464                BTF_MEMBER_ENC(NAME_TBD, 13, 0),/* uint64_t ui64; */
4465                BTF_MEMBER_ENC(NAME_TBD, 8, 0), /* uint8_t ui8a[8]; */
4466                /* enum (anon) */                       /* [15] */
4467                BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_ENUM, 0, 4), 4),
4468                BTF_ENUM_ENC(NAME_TBD, 0),
4469                BTF_ENUM_ENC(NAME_TBD, 1),
4470                BTF_ENUM_ENC(NAME_TBD, 2),
4471                BTF_ENUM_ENC(NAME_TBD, 3),
4472                /* struct pprint_mapv */                /* [16] */
4473                BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 1, 11), 40),
4474                BTF_MEMBER_ENC(NAME_TBD, 11, BTF_MEMBER_OFFSET(0, 0)),  /* uint32_t ui32 */
4475                BTF_MEMBER_ENC(NAME_TBD, 10, BTF_MEMBER_OFFSET(0, 32)), /* uint16_t ui16 */
4476                BTF_MEMBER_ENC(NAME_TBD, 12, BTF_MEMBER_OFFSET(0, 64)), /* int32_t si32 */
4477                BTF_MEMBER_ENC(NAME_TBD, 17, BTF_MEMBER_OFFSET(2, 96)), /* unused_bits2a */
4478                BTF_MEMBER_ENC(NAME_TBD, 7, BTF_MEMBER_OFFSET(28, 98)), /* bits28 */
4479                BTF_MEMBER_ENC(NAME_TBD, 19, BTF_MEMBER_OFFSET(2, 126)),/* unused_bits2b */
4480                BTF_MEMBER_ENC(0, 14, BTF_MEMBER_OFFSET(0, 128)),       /* union (anon) */
4481                BTF_MEMBER_ENC(NAME_TBD, 15, BTF_MEMBER_OFFSET(0, 192)),        /* aenum */
4482                BTF_MEMBER_ENC(NAME_TBD, 11, BTF_MEMBER_OFFSET(0, 224)),        /* uint32_t ui32b */
4483                BTF_MEMBER_ENC(NAME_TBD, 17, BTF_MEMBER_OFFSET(2, 256)),        /* bits2c */
4484                BTF_MEMBER_ENC(NAME_TBD, 20, BTF_MEMBER_OFFSET(0, 264)),        /* si8_4 */
4485                /* typedef unsigned int ___int */       /* [17] */
4486                BTF_TYPEDEF_ENC(NAME_TBD, 18),
4487                BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_VOLATILE, 0, 0), 6),      /* [18] */
4488                BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_CONST, 0, 0), 15),        /* [19] */
4489                BTF_TYPE_ARRAY_ENC(21, 1, 2),                                   /* [20] */
4490                BTF_TYPE_ARRAY_ENC(1, 1, 2),                                    /* [21] */
4491                BTF_END_RAW,
4492        },
4493        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"),
4494        .key_size = sizeof(unsigned int),
4495        .value_size = sizeof(struct pprint_mapv),
4496        .key_type_id = 3,       /* unsigned int */
4497        .value_type_id = 16,    /* struct pprint_mapv */
4498        .max_entries = 128,
4499},
4500
4501#ifdef __SIZEOF_INT128__
4502{
4503        /* test int128 */
4504        .raw_types = {
4505                /* unsigned int */                              /* [1] */
4506                BTF_TYPE_INT_ENC(NAME_TBD, 0, 0, 32, 4),
4507                /* __int128 */                                  /* [2] */
4508                BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 128, 16),
4509                /* unsigned __int128 */                         /* [3] */
4510                BTF_TYPE_INT_ENC(NAME_TBD, 0, 0, 128, 16),
4511                /* struct pprint_mapv_int128 */                 /* [4] */
4512                BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 1, 5), 64),
4513                BTF_MEMBER_ENC(NAME_TBD, 2, BTF_MEMBER_OFFSET(0, 0)),           /* si128a */
4514                BTF_MEMBER_ENC(NAME_TBD, 2, BTF_MEMBER_OFFSET(0, 128)),         /* si128b */
4515                BTF_MEMBER_ENC(NAME_TBD, 3, BTF_MEMBER_OFFSET(3, 256)),         /* bits3 */
4516                BTF_MEMBER_ENC(NAME_TBD, 3, BTF_MEMBER_OFFSET(80, 259)),        /* bits80 */
4517                BTF_MEMBER_ENC(NAME_TBD, 3, BTF_MEMBER_OFFSET(0, 384)),         /* ui128 */
4518                BTF_END_RAW,
4519        },
4520        BTF_STR_SEC("\0unsigned int\0__int128\0unsigned __int128\0pprint_mapv_int128\0si128a\0si128b\0bits3\0bits80\0ui128"),
4521        .key_size = sizeof(unsigned int),
4522        .value_size = sizeof(struct pprint_mapv_int128),
4523        .key_type_id = 1,
4524        .value_type_id = 4,
4525        .max_entries = 128,
4526        .mapv_kind = PPRINT_MAPV_KIND_INT128,
4527},
4528#endif
4529
4530};
4531
4532static struct btf_pprint_test_meta {
4533        const char *descr;
4534        enum bpf_map_type map_type;
4535        const char *map_name;
4536        bool ordered_map;
4537        bool lossless_map;
4538        bool percpu_map;
4539} pprint_tests_meta[] = {
4540{
4541        .descr = "BTF pretty print array",
4542        .map_type = BPF_MAP_TYPE_ARRAY,
4543        .map_name = "pprint_test_array",
4544        .ordered_map = true,
4545        .lossless_map = true,
4546        .percpu_map = false,
4547},
4548
4549{
4550        .descr = "BTF pretty print hash",
4551        .map_type = BPF_MAP_TYPE_HASH,
4552        .map_name = "pprint_test_hash",
4553        .ordered_map = false,
4554        .lossless_map = true,
4555        .percpu_map = false,
4556},
4557
4558{
4559        .descr = "BTF pretty print lru hash",
4560        .map_type = BPF_MAP_TYPE_LRU_HASH,
4561        .map_name = "pprint_test_lru_hash",
4562        .ordered_map = false,
4563        .lossless_map = false,
4564        .percpu_map = false,
4565},
4566
4567{
4568        .descr = "BTF pretty print percpu array",
4569        .map_type = BPF_MAP_TYPE_PERCPU_ARRAY,
4570        .map_name = "pprint_test_percpu_array",
4571        .ordered_map = true,
4572        .lossless_map = true,
4573        .percpu_map = true,
4574},
4575
4576{
4577        .descr = "BTF pretty print percpu hash",
4578        .map_type = BPF_MAP_TYPE_PERCPU_HASH,
4579        .map_name = "pprint_test_percpu_hash",
4580        .ordered_map = false,
4581        .lossless_map = true,
4582        .percpu_map = true,
4583},
4584
4585{
4586        .descr = "BTF pretty print lru percpu hash",
4587        .map_type = BPF_MAP_TYPE_LRU_PERCPU_HASH,
4588        .map_name = "pprint_test_lru_percpu_hash",
4589        .ordered_map = false,
4590        .lossless_map = false,
4591        .percpu_map = true,
4592},
4593
4594};
4595
4596static size_t get_pprint_mapv_size(enum pprint_mapv_kind_t mapv_kind)
4597{
4598        if (mapv_kind == PPRINT_MAPV_KIND_BASIC)
4599                return sizeof(struct pprint_mapv);
4600
4601#ifdef __SIZEOF_INT128__
4602        if (mapv_kind == PPRINT_MAPV_KIND_INT128)
4603                return sizeof(struct pprint_mapv_int128);
4604#endif
4605
4606        assert(0);
4607}
4608
4609static void set_pprint_mapv(enum pprint_mapv_kind_t mapv_kind,
4610                            void *mapv, uint32_t i,
4611                            int num_cpus, int rounded_value_size)
4612{
4613        int cpu;
4614
4615        if (mapv_kind == PPRINT_MAPV_KIND_BASIC) {
4616                struct pprint_mapv *v = mapv;
4617
4618                for (cpu = 0; cpu < num_cpus; cpu++) {
4619                        v->ui32 = i + cpu;
4620                        v->si32 = -i;
4621                        v->unused_bits2a = 3;
4622                        v->bits28 = i;
4623                        v->unused_bits2b = 3;
4624                        v->ui64 = i;
4625                        v->aenum = i & 0x03;
4626                        v->ui32b = 4;
4627                        v->bits2c = 1;
4628                        v->si8_4[0][0] = (cpu + i) & 0xff;
4629                        v->si8_4[0][1] = (cpu + i + 1) & 0xff;
4630                        v->si8_4[1][0] = (cpu + i + 2) & 0xff;
4631                        v->si8_4[1][1] = (cpu + i + 3) & 0xff;
4632                        v = (void *)v + rounded_value_size;
4633                }
4634        }
4635
4636#ifdef __SIZEOF_INT128__
4637        if (mapv_kind == PPRINT_MAPV_KIND_INT128) {
4638                struct pprint_mapv_int128 *v = mapv;
4639
4640                for (cpu = 0; cpu < num_cpus; cpu++) {
4641                        v->si128a = i;
4642                        v->si128b = -i;
4643                        v->bits3 = i & 0x07;
4644                        v->bits80 = (((unsigned __int128)1) << 64) + i;
4645                        v->ui128 = (((unsigned __int128)2) << 64) + i;
4646                        v = (void *)v + rounded_value_size;
4647                }
4648        }
4649#endif
4650}
4651
4652ssize_t get_pprint_expected_line(enum pprint_mapv_kind_t mapv_kind,
4653                                 char *expected_line, ssize_t line_size,
4654                                 bool percpu_map, unsigned int next_key,
4655                                 int cpu, void *mapv)
4656{
4657        ssize_t nexpected_line = -1;
4658
4659        if (mapv_kind == PPRINT_MAPV_KIND_BASIC) {
4660                struct pprint_mapv *v = mapv;
4661
4662                nexpected_line = snprintf(expected_line, line_size,
4663                                          "%s%u: {%u,0,%d,0x%x,0x%x,0x%x,"
4664                                          "{%llu|[%u,%u,%u,%u,%u,%u,%u,%u]},%s,"
4665                                          "%u,0x%x,[[%d,%d],[%d,%d]]}\n",
4666                                          percpu_map ? "\tcpu" : "",
4667                                          percpu_map ? cpu : next_key,
4668                                          v->ui32, v->si32,
4669                                          v->unused_bits2a,
4670                                          v->bits28,
4671                                          v->unused_bits2b,
4672                                          (__u64)v->ui64,
4673                                          v->ui8a[0], v->ui8a[1],
4674                                          v->ui8a[2], v->ui8a[3],
4675                                          v->ui8a[4], v->ui8a[5],
4676                                          v->ui8a[6], v->ui8a[7],
4677                                          pprint_enum_str[v->aenum],
4678                                          v->ui32b,
4679                                          v->bits2c,
4680                                          v->si8_4[0][0], v->si8_4[0][1],
4681                                          v->si8_4[1][0], v->si8_4[1][1]);
4682        }
4683
4684#ifdef __SIZEOF_INT128__
4685        if (mapv_kind == PPRINT_MAPV_KIND_INT128) {
4686                struct pprint_mapv_int128 *v = mapv;
4687
4688                nexpected_line = snprintf(expected_line, line_size,
4689                                          "%s%u: {0x%lx,0x%lx,0x%lx,"
4690                                          "0x%lx%016lx,0x%lx%016lx}\n",
4691                                          percpu_map ? "\tcpu" : "",
4692                                          percpu_map ? cpu : next_key,
4693                                          (uint64_t)v->si128a,
4694                                          (uint64_t)v->si128b,
4695                                          (uint64_t)v->bits3,
4696                                          (uint64_t)(v->bits80 >> 64),
4697                                          (uint64_t)v->bits80,
4698                                          (uint64_t)(v->ui128 >> 64),
4699                                          (uint64_t)v->ui128);
4700        }
4701#endif
4702
4703        return nexpected_line;
4704}
4705
4706static int check_line(const char *expected_line, int nexpected_line,
4707                      int expected_line_len, const char *line)
4708{
4709        if (CHECK(nexpected_line == expected_line_len,
4710                  "expected_line is too long"))
4711                return -1;
4712
4713        if (strcmp(expected_line, line)) {
4714                fprintf(stderr, "unexpected pprint output\n");
4715                fprintf(stderr, "expected: %s", expected_line);
4716                fprintf(stderr, "    read: %s", line);
4717                return -1;
4718        }
4719
4720        return 0;
4721}
4722
4723
4724static void do_test_pprint(int test_num)
4725{
4726        const struct btf_raw_test *test = &pprint_test_template[test_num];
4727        enum pprint_mapv_kind_t mapv_kind = test->mapv_kind;
4728        struct bpf_create_map_attr create_attr = {};
4729        bool ordered_map, lossless_map, percpu_map;
4730        int err, ret, num_cpus, rounded_value_size;
4731        unsigned int key, nr_read_elems;
4732        int map_fd = -1, btf_fd = -1;
4733        unsigned int raw_btf_size;
4734        char expected_line[255];
4735        FILE *pin_file = NULL;
4736        char pin_path[255];
4737        size_t line_len = 0;
4738        char *line = NULL;
4739        void *mapv = NULL;
4740        uint8_t *raw_btf;
4741        ssize_t nread;
4742
4743        if (!test__start_subtest(test->descr))
4744                return;
4745
4746        raw_btf = btf_raw_create(&hdr_tmpl, test->raw_types,
4747                                 test->str_sec, test->str_sec_size,
4748                                 &raw_btf_size, NULL);
4749
4750        if (!raw_btf)
4751                return;
4752
4753        *btf_log_buf = '\0';
4754        btf_fd = bpf_load_btf(raw_btf, raw_btf_size,
4755                              btf_log_buf, BTF_LOG_BUF_SIZE,
4756                              always_log);
4757        free(raw_btf);
4758
4759        if (CHECK(btf_fd == -1, "errno:%d", errno)) {
4760                err = -1;
4761                goto done;
4762        }
4763
4764        create_attr.name = test->map_name;
4765        create_attr.map_type = test->map_type;
4766        create_attr.key_size = test->key_size;
4767        create_attr.value_size = test->value_size;
4768        create_attr.max_entries = test->max_entries;
4769        create_attr.btf_fd = btf_fd;
4770        create_attr.btf_key_type_id = test->key_type_id;
4771        create_attr.btf_value_type_id = test->value_type_id;
4772
4773        map_fd = bpf_create_map_xattr(&create_attr);
4774        if (CHECK(map_fd == -1, "errno:%d", errno)) {
4775                err = -1;
4776                goto done;
4777        }
4778
4779        ret = snprintf(pin_path, sizeof(pin_path), "%s/%s",
4780                       "/sys/fs/bpf", test->map_name);
4781
4782        if (CHECK(ret == sizeof(pin_path), "pin_path %s/%s is too long",
4783                  "/sys/fs/bpf", test->map_name)) {
4784                err = -1;
4785                goto done;
4786        }
4787
4788        err = bpf_obj_pin(map_fd, pin_path);
4789        if (CHECK(err, "bpf_obj_pin(%s): errno:%d.", pin_path, errno))
4790                goto done;
4791
4792        percpu_map = test->percpu_map;
4793        num_cpus = percpu_map ? bpf_num_possible_cpus() : 1;
4794        rounded_value_size = round_up(get_pprint_mapv_size(mapv_kind), 8);
4795        mapv = calloc(num_cpus, rounded_value_size);
4796        if (CHECK(!mapv, "mapv allocation failure")) {
4797                err = -1;
4798                goto done;
4799        }
4800
4801        for (key = 0; key < test->max_entries; key++) {
4802                set_pprint_mapv(mapv_kind, mapv, key, num_cpus, rounded_value_size);
4803                bpf_map_update_elem(map_fd, &key, mapv, 0);
4804        }
4805
4806        pin_file = fopen(pin_path, "r");
4807        if (CHECK(!pin_file, "fopen(%s): errno:%d", pin_path, errno)) {
4808                err = -1;
4809                goto done;
4810        }
4811
4812        /* Skip lines start with '#' */
4813        while ((nread = getline(&line, &line_len, pin_file)) > 0 &&
4814               *line == '#')
4815                ;
4816
4817        if (CHECK(nread <= 0, "Unexpected EOF")) {
4818                err = -1;
4819                goto done;
4820        }
4821
4822        nr_read_elems = 0;
4823        ordered_map = test->ordered_map;
4824        lossless_map = test->lossless_map;
4825        do {
4826                ssize_t nexpected_line;
4827                unsigned int next_key;
4828                void *cmapv;
4829                int cpu;
4830
4831                next_key = ordered_map ? nr_read_elems : atoi(line);
4832                set_pprint_mapv(mapv_kind, mapv, next_key, num_cpus, rounded_value_size);
4833                cmapv = mapv;
4834
4835                for (cpu = 0; cpu < num_cpus; cpu++) {
4836                        if (percpu_map) {
4837                                /* for percpu map, the format looks like:
4838                                 * <key>: {
4839                                 *      cpu0: <value_on_cpu0>
4840                                 *      cpu1: <value_on_cpu1>
4841                                 *      ...
4842                                 *      cpun: <value_on_cpun>
4843                                 * }
4844                                 *
4845                                 * let us verify the line containing the key here.
4846                                 */
4847                                if (cpu == 0) {
4848                                        nexpected_line = snprintf(expected_line,
4849                                                                  sizeof(expected_line),
4850                                                                  "%u: {\n",
4851                                                                  next_key);
4852
4853                                        err = check_line(expected_line, nexpected_line,
4854                                                         sizeof(expected_line), line);
4855                                        if (err == -1)
4856                                                goto done;
4857                                }
4858
4859                                /* read value@cpu */
4860                                nread = getline(&line, &line_len, pin_file);
4861                                if (nread < 0)
4862                                        break;
4863                        }
4864
4865                        nexpected_line = get_pprint_expected_line(mapv_kind, expected_line,
4866                                                                  sizeof(expected_line),
4867                                                                  percpu_map, next_key,
4868                                                                  cpu, cmapv);
4869                        err = check_line(expected_line, nexpected_line,
4870                                         sizeof(expected_line), line);
4871                        if (err == -1)
4872                                goto done;
4873
4874                        cmapv = cmapv + rounded_value_size;
4875                }
4876
4877                if (percpu_map) {
4878                        /* skip the last bracket for the percpu map */
4879                        nread = getline(&line, &line_len, pin_file);
4880                        if (nread < 0)
4881                                break;
4882                }
4883
4884                nread = getline(&line, &line_len, pin_file);
4885        } while (++nr_read_elems < test->max_entries && nread > 0);
4886
4887        if (lossless_map &&
4888            CHECK(nr_read_elems < test->max_entries,
4889                  "Unexpected EOF. nr_read_elems:%u test->max_entries:%u",
4890                  nr_read_elems, test->max_entries)) {
4891                err = -1;
4892                goto done;
4893        }
4894
4895        if (CHECK(nread > 0, "Unexpected extra pprint output: %s", line)) {
4896                err = -1;
4897                goto done;
4898        }
4899
4900        err = 0;
4901
4902done:
4903        if (mapv)
4904                free(mapv);
4905        if (!err)
4906                fprintf(stderr, "OK");
4907        if (*btf_log_buf && (err || always_log))
4908                fprintf(stderr, "\n%s", btf_log_buf);
4909        if (btf_fd != -1)
4910                close(btf_fd);
4911        if (map_fd != -1)
4912                close(map_fd);
4913        if (pin_file)
4914                fclose(pin_file);
4915        unlink(pin_path);
4916        free(line);
4917}
4918
4919static void test_pprint(void)
4920{
4921        unsigned int i;
4922
4923        /* test various maps with the first test template */
4924        for (i = 0; i < ARRAY_SIZE(pprint_tests_meta); i++) {
4925                pprint_test_template[0].descr = pprint_tests_meta[i].descr;
4926                pprint_test_template[0].map_type = pprint_tests_meta[i].map_type;
4927                pprint_test_template[0].map_name = pprint_tests_meta[i].map_name;
4928                pprint_test_template[0].ordered_map = pprint_tests_meta[i].ordered_map;
4929                pprint_test_template[0].lossless_map = pprint_tests_meta[i].lossless_map;
4930                pprint_test_template[0].percpu_map = pprint_tests_meta[i].percpu_map;
4931
4932                do_test_pprint(0);
4933        }
4934
4935        /* test rest test templates with the first map */
4936        for (i = 1; i < ARRAY_SIZE(pprint_test_template); i++) {
4937                pprint_test_template[i].descr = pprint_tests_meta[0].descr;
4938                pprint_test_template[i].map_type = pprint_tests_meta[0].map_type;
4939                pprint_test_template[i].map_name = pprint_tests_meta[0].map_name;
4940                pprint_test_template[i].ordered_map = pprint_tests_meta[0].ordered_map;
4941                pprint_test_template[i].lossless_map = pprint_tests_meta[0].lossless_map;
4942                pprint_test_template[i].percpu_map = pprint_tests_meta[0].percpu_map;
4943                do_test_pprint(i);
4944        }
4945}
4946
4947#define BPF_LINE_INFO_ENC(insn_off, file_off, line_off, line_num, line_col) \
4948        (insn_off), (file_off), (line_off), ((line_num) << 10 | ((line_col) & 0x3ff))
4949
4950static struct prog_info_raw_test {
4951        const char *descr;
4952        const char *str_sec;
4953        const char *err_str;
4954        __u32 raw_types[MAX_NR_RAW_U32];
4955        __u32 str_sec_size;
4956        struct bpf_insn insns[MAX_INSNS];
4957        __u32 prog_type;
4958        __u32 func_info[MAX_SUBPROGS][2];
4959        __u32 func_info_rec_size;
4960        __u32 func_info_cnt;
4961        __u32 line_info[MAX_NR_RAW_U32];
4962        __u32 line_info_rec_size;
4963        __u32 nr_jited_ksyms;
4964        bool expected_prog_load_failure;
4965        __u32 dead_code_cnt;
4966        __u32 dead_code_mask;
4967        __u32 dead_func_cnt;
4968        __u32 dead_func_mask;
4969} info_raw_tests[] = {
4970{
4971        .descr = "func_type (main func + one sub)",
4972        .raw_types = {
4973                BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),   /* [1] */
4974                BTF_TYPE_INT_ENC(NAME_TBD, 0, 0, 32, 4),        /* [2] */
4975                BTF_FUNC_PROTO_ENC(1, 2),                       /* [3] */
4976                        BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
4977                        BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 2),
4978                BTF_FUNC_PROTO_ENC(1, 2),                       /* [4] */
4979                        BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 2),
4980                        BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
4981                BTF_FUNC_ENC(NAME_TBD, 3),                      /* [5] */
4982                BTF_FUNC_ENC(NAME_TBD, 4),                      /* [6] */
4983                BTF_END_RAW,
4984        },
4985        .str_sec = "\0int\0unsigned int\0a\0b\0c\0d\0funcA\0funcB",
4986        .str_sec_size = sizeof("\0int\0unsigned int\0a\0b\0c\0d\0funcA\0funcB"),
4987        .insns = {
4988                BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2),
4989                BPF_MOV64_IMM(BPF_REG_0, 1),
4990                BPF_EXIT_INSN(),
4991                BPF_MOV64_IMM(BPF_REG_0, 2),
4992                BPF_EXIT_INSN(),
4993        },
4994        .prog_type = BPF_PROG_TYPE_TRACEPOINT,
4995        .func_info = { {0, 5}, {3, 6} },
4996        .func_info_rec_size = 8,
4997        .func_info_cnt = 2,
4998        .line_info = { BTF_END_RAW },
4999},
5000
5001{
5002        .descr = "func_type (Incorrect func_info_rec_size)",
5003        .raw_types = {
5004                BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),   /* [1] */
5005                BTF_TYPE_INT_ENC(NAME_TBD, 0, 0, 32, 4),        /* [2] */
5006                BTF_FUNC_PROTO_ENC(1, 2),                       /* [3] */
5007                        BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
5008                        BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 2),
5009                BTF_FUNC_PROTO_ENC(1, 2),                       /* [4] */
5010                        BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 2),
5011                        BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
5012                BTF_FUNC_ENC(NAME_TBD, 3),                      /* [5] */
5013                BTF_FUNC_ENC(NAME_TBD, 4),                      /* [6] */
5014                BTF_END_RAW,
5015        },
5016        .str_sec = "\0int\0unsigned int\0a\0b\0c\0d\0funcA\0funcB",
5017        .str_sec_size = sizeof("\0int\0unsigned int\0a\0b\0c\0d\0funcA\0funcB"),
5018        .insns = {
5019                BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2),
5020                BPF_MOV64_IMM(BPF_REG_0, 1),
5021                BPF_EXIT_INSN(),
5022                BPF_MOV64_IMM(BPF_REG_0, 2),
5023                BPF_EXIT_INSN(),
5024        },
5025        .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5026        .func_info = { {0, 5}, {3, 6} },
5027        .func_info_rec_size = 4,
5028        .func_info_cnt = 2,
5029        .line_info = { BTF_END_RAW },
5030        .expected_prog_load_failure = true,
5031},
5032
5033{
5034        .descr = "func_type (Incorrect func_info_cnt)",
5035        .raw_types = {
5036                BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),   /* [1] */
5037                BTF_TYPE_INT_ENC(NAME_TBD, 0, 0, 32, 4),        /* [2] */
5038                BTF_FUNC_PROTO_ENC(1, 2),                       /* [3] */
5039                        BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
5040                        BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 2),
5041                BTF_FUNC_PROTO_ENC(1, 2),                       /* [4] */
5042                        BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 2),
5043                        BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
5044                BTF_FUNC_ENC(NAME_TBD, 3),                      /* [5] */
5045                BTF_FUNC_ENC(NAME_TBD, 4),                      /* [6] */
5046                BTF_END_RAW,
5047        },
5048        .str_sec = "\0int\0unsigned int\0a\0b\0c\0d\0funcA\0funcB",
5049        .str_sec_size = sizeof("\0int\0unsigned int\0a\0b\0c\0d\0funcA\0funcB"),
5050        .insns = {
5051                BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2),
5052                BPF_MOV64_IMM(BPF_REG_0, 1),
5053                BPF_EXIT_INSN(),
5054                BPF_MOV64_IMM(BPF_REG_0, 2),
5055                BPF_EXIT_INSN(),
5056        },
5057        .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5058        .func_info = { {0, 5}, {3, 6} },
5059        .func_info_rec_size = 8,
5060        .func_info_cnt = 1,
5061        .line_info = { BTF_END_RAW },
5062        .expected_prog_load_failure = true,
5063},
5064
5065{
5066        .descr = "func_type (Incorrect bpf_func_info.insn_off)",
5067        .raw_types = {
5068                BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),   /* [1] */
5069                BTF_TYPE_INT_ENC(NAME_TBD, 0, 0, 32, 4),        /* [2] */
5070                BTF_FUNC_PROTO_ENC(1, 2),                       /* [3] */
5071                        BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
5072                        BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 2),
5073                BTF_FUNC_PROTO_ENC(1, 2),                       /* [4] */
5074                        BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 2),
5075                        BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
5076                BTF_FUNC_ENC(NAME_TBD, 3),                      /* [5] */
5077                BTF_FUNC_ENC(NAME_TBD, 4),                      /* [6] */
5078                BTF_END_RAW,
5079        },
5080        .str_sec = "\0int\0unsigned int\0a\0b\0c\0d\0funcA\0funcB",
5081        .str_sec_size = sizeof("\0int\0unsigned int\0a\0b\0c\0d\0funcA\0funcB"),
5082        .insns = {
5083                BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2),
5084                BPF_MOV64_IMM(BPF_REG_0, 1),
5085                BPF_EXIT_INSN(),
5086                BPF_MOV64_IMM(BPF_REG_0, 2),
5087                BPF_EXIT_INSN(),
5088        },
5089        .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5090        .func_info = { {0, 5}, {2, 6} },
5091        .func_info_rec_size = 8,
5092        .func_info_cnt = 2,
5093        .line_info = { BTF_END_RAW },
5094        .expected_prog_load_failure = true,
5095},
5096
5097{
5098        .descr = "line_info (No subprog)",
5099        .raw_types = {
5100                BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),   /* [1] */
5101                BTF_END_RAW,
5102        },
5103        BTF_STR_SEC("\0int\0int a=1;\0int b=2;\0return a + b;\0return a + b;"),
5104        .insns = {
5105                BPF_MOV64_IMM(BPF_REG_0, 1),
5106                BPF_MOV64_IMM(BPF_REG_1, 2),
5107                BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
5108                BPF_EXIT_INSN(),
5109        },
5110        .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5111        .func_info_cnt = 0,
5112        .line_info = {
5113                BPF_LINE_INFO_ENC(0, 0, NAME_TBD, 1, 10),
5114                BPF_LINE_INFO_ENC(1, 0, NAME_TBD, 2, 9),
5115                BPF_LINE_INFO_ENC(2, 0, NAME_TBD, 3, 8),
5116                BPF_LINE_INFO_ENC(3, 0, NAME_TBD, 4, 7),
5117                BTF_END_RAW,
5118        },
5119        .line_info_rec_size = sizeof(struct bpf_line_info),
5120        .nr_jited_ksyms = 1,
5121},
5122
5123{
5124        .descr = "line_info (No subprog. insn_off >= prog->len)",
5125        .raw_types = {
5126                BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),   /* [1] */
5127                BTF_END_RAW,
5128        },
5129        BTF_STR_SEC("\0int\0int a=1;\0int b=2;\0return a + b;\0return a + b;"),
5130        .insns = {
5131                BPF_MOV64_IMM(BPF_REG_0, 1),
5132                BPF_MOV64_IMM(BPF_REG_1, 2),
5133                BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
5134                BPF_EXIT_INSN(),
5135        },
5136        .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5137        .func_info_cnt = 0,
5138        .line_info = {
5139                BPF_LINE_INFO_ENC(0, 0, NAME_TBD, 1, 10),
5140                BPF_LINE_INFO_ENC(1, 0, NAME_TBD, 2, 9),
5141                BPF_LINE_INFO_ENC(2, 0, NAME_TBD, 3, 8),
5142                BPF_LINE_INFO_ENC(3, 0, NAME_TBD, 4, 7),
5143                BPF_LINE_INFO_ENC(4, 0, 0, 5, 6),
5144                BTF_END_RAW,
5145        },
5146        .line_info_rec_size = sizeof(struct bpf_line_info),
5147        .nr_jited_ksyms = 1,
5148        .err_str = "line_info[4].insn_off",
5149        .expected_prog_load_failure = true,
5150},
5151
5152{
5153        .descr = "line_info (Zero bpf insn code)",
5154        .raw_types = {
5155                BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),   /* [1] */
5156                BTF_TYPE_INT_ENC(NAME_TBD, 0, 0, 64, 8),        /* [2] */
5157                BTF_TYPEDEF_ENC(NAME_TBD, 2),                   /* [3] */
5158                BTF_END_RAW,
5159        },
5160        BTF_STR_SEC("\0int\0unsigned long\0u64\0u64 a=1;\0return a;"),
5161        .insns = {
5162                BPF_LD_IMM64(BPF_REG_0, 1),
5163                BPF_EXIT_INSN(),
5164        },
5165        .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5166        .func_info_cnt = 0,
5167        .line_info = {
5168                BPF_LINE_INFO_ENC(0, 0, NAME_TBD, 1, 10),
5169                BPF_LINE_INFO_ENC(1, 0, 0, 2, 9),
5170                BPF_LINE_INFO_ENC(2, 0, NAME_TBD, 3, 8),
5171                BTF_END_RAW,
5172        },
5173        .line_info_rec_size = sizeof(struct bpf_line_info),
5174        .nr_jited_ksyms = 1,
5175        .err_str = "Invalid insn code at line_info[1]",
5176        .expected_prog_load_failure = true,
5177},
5178
5179{
5180        .descr = "line_info (No subprog. zero tailing line_info",
5181        .raw_types = {
5182                BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),   /* [1] */
5183                BTF_END_RAW,
5184        },
5185        BTF_STR_SEC("\0int\0int a=1;\0int b=2;\0return a + b;\0return a + b;"),
5186        .insns = {
5187                BPF_MOV64_IMM(BPF_REG_0, 1),
5188                BPF_MOV64_IMM(BPF_REG_1, 2),
5189                BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
5190                BPF_EXIT_INSN(),
5191        },
5192        .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5193        .func_info_cnt = 0,
5194        .line_info = {
5195                BPF_LINE_INFO_ENC(0, 0, NAME_TBD, 1, 10), 0,
5196                BPF_LINE_INFO_ENC(1, 0, NAME_TBD, 2, 9), 0,
5197                BPF_LINE_INFO_ENC(2, 0, NAME_TBD, 3, 8), 0,
5198                BPF_LINE_INFO_ENC(3, 0, NAME_TBD, 4, 7), 0,
5199                BTF_END_RAW,
5200        },
5201        .line_info_rec_size = sizeof(struct bpf_line_info) + sizeof(__u32),
5202        .nr_jited_ksyms = 1,
5203},
5204
5205{
5206        .descr = "line_info (No subprog. nonzero tailing line_info)",
5207        .raw_types = {
5208                BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),   /* [1] */
5209                BTF_END_RAW,
5210        },
5211        BTF_STR_SEC("\0int\0int a=1;\0int b=2;\0return a + b;\0return a + b;"),
5212        .insns = {
5213                BPF_MOV64_IMM(BPF_REG_0, 1),
5214                BPF_MOV64_IMM(BPF_REG_1, 2),
5215                BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
5216                BPF_EXIT_INSN(),
5217        },
5218        .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5219        .func_info_cnt = 0,
5220        .line_info = {
5221                BPF_LINE_INFO_ENC(0, 0, NAME_TBD, 1, 10), 0,
5222                BPF_LINE_INFO_ENC(1, 0, NAME_TBD, 2, 9), 0,
5223                BPF_LINE_INFO_ENC(2, 0, NAME_TBD, 3, 8), 0,
5224                BPF_LINE_INFO_ENC(3, 0, NAME_TBD, 4, 7), 1,
5225                BTF_END_RAW,
5226        },
5227        .line_info_rec_size = sizeof(struct bpf_line_info) + sizeof(__u32),
5228        .nr_jited_ksyms = 1,
5229        .err_str = "nonzero tailing record in line_info",
5230        .expected_prog_load_failure = true,
5231},
5232
5233{
5234        .descr = "line_info (subprog)",
5235        .raw_types = {
5236                BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),   /* [1] */
5237                BTF_END_RAW,
5238        },
5239        BTF_STR_SEC("\0int\0int a=1+1;\0return func(a);\0b+=1;\0return b;"),
5240        .insns = {
5241                BPF_MOV64_IMM(BPF_REG_2, 1),
5242                BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, 1),
5243                BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
5244                BPF_CALL_REL(1),
5245                BPF_EXIT_INSN(),
5246                BPF_MOV64_REG(BPF_REG_0, BPF_REG_1),
5247                BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 1),
5248                BPF_EXIT_INSN(),
5249        },
5250        .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5251        .func_info_cnt = 0,
5252        .line_info = {
5253                BPF_LINE_INFO_ENC(0, 0, NAME_TBD, 1, 10),
5254                BPF_LINE_INFO_ENC(2, 0, NAME_TBD, 2, 9),
5255                BPF_LINE_INFO_ENC(5, 0, NAME_TBD, 3, 8),
5256                BPF_LINE_INFO_ENC(7, 0, NAME_TBD, 4, 7),
5257                BTF_END_RAW,
5258        },
5259        .line_info_rec_size = sizeof(struct bpf_line_info),
5260        .nr_jited_ksyms = 2,
5261},
5262
5263{
5264        .descr = "line_info (subprog + func_info)",
5265        .raw_types = {
5266                BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),   /* [1] */
5267                BTF_FUNC_PROTO_ENC(1, 1),                       /* [2] */
5268                        BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
5269                BTF_FUNC_ENC(NAME_TBD, 2),                      /* [3] */
5270                BTF_FUNC_ENC(NAME_TBD, 2),                      /* [4] */
5271                BTF_END_RAW,
5272        },
5273        BTF_STR_SEC("\0int\0x\0sub\0main\0int a=1+1;\0return func(a);\0b+=1;\0return b;"),
5274        .insns = {
5275                BPF_MOV64_IMM(BPF_REG_2, 1),
5276                BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, 1),
5277                BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
5278                BPF_CALL_REL(1),
5279                BPF_EXIT_INSN(),
5280                BPF_MOV64_REG(BPF_REG_0, BPF_REG_1),
5281                BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 1),
5282                BPF_EXIT_INSN(),
5283        },
5284        .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5285        .func_info_cnt = 2,
5286        .func_info_rec_size = 8,
5287        .func_info = { {0, 4}, {5, 3} },
5288        .line_info = {
5289                BPF_LINE_INFO_ENC(0, 0, NAME_TBD, 1, 10),
5290                BPF_LINE_INFO_ENC(2, 0, NAME_TBD, 2, 9),
5291                BPF_LINE_INFO_ENC(5, 0, NAME_TBD, 3, 8),
5292                BPF_LINE_INFO_ENC(7, 0, NAME_TBD, 4, 7),
5293                BTF_END_RAW,
5294        },
5295        .line_info_rec_size = sizeof(struct bpf_line_info),
5296        .nr_jited_ksyms = 2,
5297},
5298
5299{
5300        .descr = "line_info (subprog. missing 1st func line info)",
5301        .raw_types = {
5302                BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),   /* [1] */
5303                BTF_END_RAW,
5304        },
5305        BTF_STR_SEC("\0int\0int a=1+1;\0return func(a);\0b+=1;\0return b;"),
5306        .insns = {
5307                BPF_MOV64_IMM(BPF_REG_2, 1),
5308                BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, 1),
5309                BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
5310                BPF_CALL_REL(1),
5311                BPF_EXIT_INSN(),
5312                BPF_MOV64_REG(BPF_REG_0, BPF_REG_1),
5313                BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 1),
5314                BPF_EXIT_INSN(),
5315        },
5316        .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5317        .func_info_cnt = 0,
5318        .line_info = {
5319                BPF_LINE_INFO_ENC(1, 0, NAME_TBD, 1, 10),
5320                BPF_LINE_INFO_ENC(2, 0, NAME_TBD, 2, 9),
5321                BPF_LINE_INFO_ENC(5, 0, NAME_TBD, 3, 8),
5322                BPF_LINE_INFO_ENC(7, 0, NAME_TBD, 4, 7),
5323                BTF_END_RAW,
5324        },
5325        .line_info_rec_size = sizeof(struct bpf_line_info),
5326        .nr_jited_ksyms = 2,
5327        .err_str = "missing bpf_line_info for func#0",
5328        .expected_prog_load_failure = true,
5329},
5330
5331{
5332        .descr = "line_info (subprog. missing 2nd func line info)",
5333        .raw_types = {
5334                BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),   /* [1] */
5335                BTF_END_RAW,
5336        },
5337        BTF_STR_SEC("\0int\0int a=1+1;\0return func(a);\0b+=1;\0return b;"),
5338        .insns = {
5339                BPF_MOV64_IMM(BPF_REG_2, 1),
5340                BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, 1),
5341                BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
5342                BPF_CALL_REL(1),
5343                BPF_EXIT_INSN(),
5344                BPF_MOV64_REG(BPF_REG_0, BPF_REG_1),
5345                BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 1),
5346                BPF_EXIT_INSN(),
5347        },
5348        .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5349        .func_info_cnt = 0,
5350        .line_info = {
5351                BPF_LINE_INFO_ENC(0, 0, NAME_TBD, 1, 10),
5352                BPF_LINE_INFO_ENC(2, 0, NAME_TBD, 2, 9),
5353                BPF_LINE_INFO_ENC(6, 0, NAME_TBD, 3, 8),
5354                BPF_LINE_INFO_ENC(7, 0, NAME_TBD, 4, 7),
5355                BTF_END_RAW,
5356        },
5357        .line_info_rec_size = sizeof(struct bpf_line_info),
5358        .nr_jited_ksyms = 2,
5359        .err_str = "missing bpf_line_info for func#1",
5360        .expected_prog_load_failure = true,
5361},
5362
5363{
5364        .descr = "line_info (subprog. unordered insn offset)",
5365        .raw_types = {
5366                BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),   /* [1] */
5367                BTF_END_RAW,
5368        },
5369        BTF_STR_SEC("\0int\0int a=1+1;\0return func(a);\0b+=1;\0return b;"),
5370        .insns = {
5371                BPF_MOV64_IMM(BPF_REG_2, 1),
5372                BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, 1),
5373                BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
5374                BPF_CALL_REL(1),
5375                BPF_EXIT_INSN(),
5376                BPF_MOV64_REG(BPF_REG_0, BPF_REG_1),
5377                BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 1),
5378                BPF_EXIT_INSN(),
5379        },
5380        .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5381        .func_info_cnt = 0,
5382        .line_info = {
5383                BPF_LINE_INFO_ENC(0, 0, NAME_TBD, 1, 10),
5384                BPF_LINE_INFO_ENC(5, 0, NAME_TBD, 2, 9),
5385                BPF_LINE_INFO_ENC(2, 0, NAME_TBD, 3, 8),
5386                BPF_LINE_INFO_ENC(7, 0, NAME_TBD, 4, 7),
5387                BTF_END_RAW,
5388        },
5389        .line_info_rec_size = sizeof(struct bpf_line_info),
5390        .nr_jited_ksyms = 2,
5391        .err_str = "Invalid line_info[2].insn_off",
5392        .expected_prog_load_failure = true,
5393},
5394
5395{
5396        .descr = "line_info (dead start)",
5397        .raw_types = {
5398                BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),   /* [1] */
5399                BTF_END_RAW,
5400        },
5401        BTF_STR_SEC("\0int\0/* dead jmp */\0int a=1;\0int b=2;\0return a + b;\0return a + b;"),
5402        .insns = {
5403                BPF_JMP_IMM(BPF_JA, 0, 0, 0),
5404                BPF_MOV64_IMM(BPF_REG_0, 1),
5405                BPF_MOV64_IMM(BPF_REG_1, 2),
5406                BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
5407                BPF_EXIT_INSN(),
5408        },
5409        .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5410        .func_info_cnt = 0,
5411        .line_info = {
5412                BPF_LINE_INFO_ENC(0, 0, NAME_TBD, 1, 10),
5413                BPF_LINE_INFO_ENC(1, 0, NAME_TBD, 2, 9),
5414                BPF_LINE_INFO_ENC(2, 0, NAME_TBD, 3, 8),
5415                BPF_LINE_INFO_ENC(3, 0, NAME_TBD, 4, 7),
5416                BPF_LINE_INFO_ENC(4, 0, NAME_TBD, 5, 6),
5417                BTF_END_RAW,
5418        },
5419        .line_info_rec_size = sizeof(struct bpf_line_info),
5420        .nr_jited_ksyms = 1,
5421        .dead_code_cnt = 1,
5422        .dead_code_mask = 0x01,
5423},
5424
5425{
5426        .descr = "line_info (dead end)",
5427        .raw_types = {
5428                BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),   /* [1] */
5429                BTF_END_RAW,
5430        },
5431        BTF_STR_SEC("\0int\0int a=1;\0int b=2;\0return a + b;\0/* dead jmp */\0return a + b;\0/* dead exit */"),
5432        .insns = {
5433                BPF_MOV64_IMM(BPF_REG_0, 1),
5434                BPF_MOV64_IMM(BPF_REG_1, 2),
5435                BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
5436                BPF_JMP_IMM(BPF_JGE, BPF_REG_0, 10, 1),
5437                BPF_EXIT_INSN(),
5438                BPF_EXIT_INSN(),
5439        },
5440        .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5441        .func_info_cnt = 0,
5442        .line_info = {
5443                BPF_LINE_INFO_ENC(0, 0, NAME_TBD, 1, 12),
5444                BPF_LINE_INFO_ENC(1, 0, NAME_TBD, 2, 11),
5445                BPF_LINE_INFO_ENC(2, 0, NAME_TBD, 3, 10),
5446                BPF_LINE_INFO_ENC(3, 0, NAME_TBD, 4, 9),
5447                BPF_LINE_INFO_ENC(4, 0, NAME_TBD, 5, 8),
5448                BPF_LINE_INFO_ENC(5, 0, NAME_TBD, 6, 7),
5449                BTF_END_RAW,
5450        },
5451        .line_info_rec_size = sizeof(struct bpf_line_info),
5452        .nr_jited_ksyms = 1,
5453        .dead_code_cnt = 2,
5454        .dead_code_mask = 0x28,
5455},
5456
5457{
5458        .descr = "line_info (dead code + subprog + func_info)",
5459        .raw_types = {
5460                BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),   /* [1] */
5461                BTF_FUNC_PROTO_ENC(1, 1),                       /* [2] */
5462                        BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
5463                BTF_FUNC_ENC(NAME_TBD, 2),                      /* [3] */
5464                BTF_FUNC_ENC(NAME_TBD, 2),                      /* [4] */
5465                BTF_END_RAW,
5466        },
5467        BTF_STR_SEC("\0int\0x\0sub\0main\0int a=1+1;\0/* dead jmp */"
5468                    "\0/* dead */\0/* dead */\0/* dead */\0/* dead */"
5469                    "\0/* dead */\0/* dead */\0/* dead */\0/* dead */"
5470                    "\0return func(a);\0b+=1;\0return b;"),
5471        .insns = {
5472                BPF_MOV64_IMM(BPF_REG_2, 1),
5473                BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, 1),
5474                BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
5475                BPF_JMP_IMM(BPF_JGE, BPF_REG_2, 0, 8),
5476                BPF_MOV64_IMM(BPF_REG_2, 1),
5477                BPF_MOV64_IMM(BPF_REG_2, 1),
5478                BPF_MOV64_IMM(BPF_REG_2, 1),
5479                BPF_MOV64_IMM(BPF_REG_2, 1),
5480                BPF_MOV64_IMM(BPF_REG_2, 1),
5481                BPF_MOV64_IMM(BPF_REG_2, 1),
5482                BPF_MOV64_IMM(BPF_REG_2, 1),
5483                BPF_MOV64_IMM(BPF_REG_2, 1),
5484                BPF_CALL_REL(1),
5485                BPF_EXIT_INSN(),
5486                BPF_MOV64_REG(BPF_REG_0, BPF_REG_1),
5487                BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 1),
5488                BPF_EXIT_INSN(),
5489        },
5490        .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5491        .func_info_cnt = 2,
5492        .func_info_rec_size = 8,
5493        .func_info = { {0, 4}, {14, 3} },
5494        .line_info = {
5495                BPF_LINE_INFO_ENC(0, 0, NAME_TBD, 1, 10),
5496                BPF_LINE_INFO_ENC(3, 0, NAME_TBD, 1, 10),
5497                BPF_LINE_INFO_ENC(4, 0, NAME_TBD, 1, 10),
5498                BPF_LINE_INFO_ENC(5, 0, NAME_TBD, 1, 10),
5499                BPF_LINE_INFO_ENC(6, 0, NAME_TBD, 1, 10),
5500                BPF_LINE_INFO_ENC(7, 0, NAME_TBD, 1, 10),
5501                BPF_LINE_INFO_ENC(8, 0, NAME_TBD, 1, 10),
5502                BPF_LINE_INFO_ENC(9, 0, NAME_TBD, 1, 10),
5503                BPF_LINE_INFO_ENC(10, 0, NAME_TBD, 1, 10),
5504                BPF_LINE_INFO_ENC(11, 0, NAME_TBD, 2, 9),
5505                BPF_LINE_INFO_ENC(12, 0, NAME_TBD, 2, 9),
5506                BPF_LINE_INFO_ENC(14, 0, NAME_TBD, 3, 8),
5507                BPF_LINE_INFO_ENC(16, 0, NAME_TBD, 4, 7),
5508                BTF_END_RAW,
5509        },
5510        .line_info_rec_size = sizeof(struct bpf_line_info),
5511        .nr_jited_ksyms = 2,
5512        .dead_code_cnt = 9,
5513        .dead_code_mask = 0x3fe,
5514},
5515
5516{
5517        .descr = "line_info (dead subprog)",
5518        .raw_types = {
5519                BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),   /* [1] */
5520                BTF_FUNC_PROTO_ENC(1, 1),                       /* [2] */
5521                        BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
5522                BTF_FUNC_ENC(NAME_TBD, 2),                      /* [3] */
5523                BTF_FUNC_ENC(NAME_TBD, 2),                      /* [4] */
5524                BTF_FUNC_ENC(NAME_TBD, 2),                      /* [5] */
5525                BTF_END_RAW,
5526        },
5527        BTF_STR_SEC("\0int\0x\0dead\0main\0func\0int a=1+1;\0/* live call */"
5528                    "\0return 0;\0return 0;\0/* dead */\0/* dead */"
5529                    "\0/* dead */\0return bla + 1;\0return bla + 1;"
5530                    "\0return bla + 1;\0return func(a);\0b+=1;\0return b;"),
5531        .insns = {
5532                BPF_MOV64_IMM(BPF_REG_2, 1),
5533                BPF_JMP_IMM(BPF_JGE, BPF_REG_2, 0, 1),
5534                BPF_CALL_REL(3),
5535                BPF_CALL_REL(5),
5536                BPF_MOV64_IMM(BPF_REG_0, 0),
5537                BPF_EXIT_INSN(),
5538                BPF_MOV64_IMM(BPF_REG_0, 0),
5539                BPF_CALL_REL(1),
5540                BPF_EXIT_INSN(),
5541                BPF_MOV64_REG(BPF_REG_0, 2),
5542                BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 1),
5543                BPF_EXIT_INSN(),
5544        },
5545        .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5546        .func_info_cnt = 3,
5547        .func_info_rec_size = 8,
5548                .func_info = { {0, 4}, {6, 3}, {9, 5} },
5549        .line_info = {
5550                BPF_LINE_INFO_ENC(0, 0, NAME_TBD, 1, 10),
5551                BPF_LINE_INFO_ENC(3, 0, NAME_TBD, 1, 10),
5552                BPF_LINE_INFO_ENC(4, 0, NAME_TBD, 1, 10),
5553                BPF_LINE_INFO_ENC(5, 0, NAME_TBD, 1, 10),
5554                BPF_LINE_INFO_ENC(6, 0, NAME_TBD, 1, 10),
5555                BPF_LINE_INFO_ENC(7, 0, NAME_TBD, 1, 10),
5556                BPF_LINE_INFO_ENC(8, 0, NAME_TBD, 1, 10),
5557                BPF_LINE_INFO_ENC(9, 0, NAME_TBD, 1, 10),
5558                BPF_LINE_INFO_ENC(10, 0, NAME_TBD, 1, 10),
5559                BPF_LINE_INFO_ENC(11, 0, NAME_TBD, 2, 9),
5560                BTF_END_RAW,
5561        },
5562        .line_info_rec_size = sizeof(struct bpf_line_info),
5563        .nr_jited_ksyms = 2,
5564        .dead_code_cnt = 3,
5565        .dead_code_mask = 0x70,
5566        .dead_func_cnt = 1,
5567        .dead_func_mask = 0x2,
5568},
5569
5570{
5571        .descr = "line_info (dead last subprog)",
5572        .raw_types = {
5573                BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),   /* [1] */
5574                BTF_FUNC_PROTO_ENC(1, 1),                       /* [2] */
5575                        BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
5576                BTF_FUNC_ENC(NAME_TBD, 2),                      /* [3] */
5577                BTF_FUNC_ENC(NAME_TBD, 2),                      /* [5] */
5578                BTF_END_RAW,
5579        },
5580        BTF_STR_SEC("\0int\0x\0dead\0main\0int a=1+1;\0/* live call */"
5581                    "\0return 0;\0/* dead */\0/* dead */"),
5582        .insns = {
5583                BPF_MOV64_IMM(BPF_REG_2, 1),
5584                BPF_JMP_IMM(BPF_JGE, BPF_REG_2, 0, 1),
5585                BPF_CALL_REL(2),
5586                BPF_MOV64_IMM(BPF_REG_0, 0),
5587                BPF_EXIT_INSN(),
5588                BPF_MOV64_IMM(BPF_REG_0, 0),
5589                BPF_EXIT_INSN(),
5590        },
5591        .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5592        .func_info_cnt = 2,
5593        .func_info_rec_size = 8,
5594                .func_info = { {0, 4}, {5, 3} },
5595        .line_info = {
5596                BPF_LINE_INFO_ENC(0, 0, NAME_TBD, 1, 10),
5597                BPF_LINE_INFO_ENC(3, 0, NAME_TBD, 1, 10),
5598                BPF_LINE_INFO_ENC(4, 0, NAME_TBD, 1, 10),
5599                BPF_LINE_INFO_ENC(5, 0, NAME_TBD, 1, 10),
5600                BPF_LINE_INFO_ENC(6, 0, NAME_TBD, 1, 10),
5601                BTF_END_RAW,
5602        },
5603        .line_info_rec_size = sizeof(struct bpf_line_info),
5604        .nr_jited_ksyms = 1,
5605        .dead_code_cnt = 2,
5606        .dead_code_mask = 0x18,
5607        .dead_func_cnt = 1,
5608        .dead_func_mask = 0x2,
5609},
5610
5611{
5612        .descr = "line_info (dead subprog + dead start)",
5613        .raw_types = {
5614                BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),   /* [1] */
5615                BTF_FUNC_PROTO_ENC(1, 1),                       /* [2] */
5616                        BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
5617                BTF_FUNC_ENC(NAME_TBD, 2),                      /* [3] */
5618                BTF_FUNC_ENC(NAME_TBD, 2),                      /* [4] */
5619                BTF_FUNC_ENC(NAME_TBD, 2),                      /* [5] */
5620                BTF_END_RAW,
5621        },
5622        BTF_STR_SEC("\0int\0x\0dead\0main\0func\0int a=1+1;\0/* dead */"
5623                    "\0return 0;\0return 0;\0return 0;"
5624                    "\0/* dead */\0/* dead */\0/* dead */\0/* dead */"
5625                    "\0return b + 1;\0return b + 1;\0return b + 1;"),
5626        .insns = {
5627                BPF_JMP_IMM(BPF_JA, 0, 0, 0),
5628                BPF_MOV64_IMM(BPF_REG_2, 1),
5629                BPF_JMP_IMM(BPF_JGE, BPF_REG_2, 0, 1),
5630                BPF_CALL_REL(3),
5631                BPF_CALL_REL(5),
5632                BPF_MOV64_IMM(BPF_REG_0, 0),
5633                BPF_EXIT_INSN(),
5634                BPF_MOV64_IMM(BPF_REG_0, 0),
5635                BPF_CALL_REL(1),
5636                BPF_EXIT_INSN(),
5637                BPF_JMP_IMM(BPF_JA, 0, 0, 0),
5638                BPF_MOV64_REG(BPF_REG_0, 2),
5639                BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 1),
5640                BPF_EXIT_INSN(),
5641        },
5642        .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5643        .func_info_cnt = 3,
5644        .func_info_rec_size = 8,
5645                .func_info = { {0, 4}, {7, 3}, {10, 5} },
5646        .line_info = {
5647                BPF_LINE_INFO_ENC(0, 0, NAME_TBD, 1, 10),
5648                BPF_LINE_INFO_ENC(3, 0, NAME_TBD, 1, 10),
5649                BPF_LINE_INFO_ENC(4, 0, NAME_TBD, 1, 10),
5650                BPF_LINE_INFO_ENC(5, 0, NAME_TBD, 1, 10),
5651                BPF_LINE_INFO_ENC(6, 0, NAME_TBD, 1, 10),
5652                BPF_LINE_INFO_ENC(7, 0, NAME_TBD, 1, 10),
5653                BPF_LINE_INFO_ENC(8, 0, NAME_TBD, 1, 10),
5654                BPF_LINE_INFO_ENC(9, 0, NAME_TBD, 1, 10),
5655                BPF_LINE_INFO_ENC(10, 0, NAME_TBD, 1, 10),
5656                BPF_LINE_INFO_ENC(11, 0, NAME_TBD, 2, 9),
5657                BPF_LINE_INFO_ENC(12, 0, NAME_TBD, 2, 9),
5658                BPF_LINE_INFO_ENC(13, 0, NAME_TBD, 2, 9),
5659                BTF_END_RAW,
5660        },
5661        .line_info_rec_size = sizeof(struct bpf_line_info),
5662        .nr_jited_ksyms = 2,
5663        .dead_code_cnt = 5,
5664        .dead_code_mask = 0x1e2,
5665        .dead_func_cnt = 1,
5666        .dead_func_mask = 0x2,
5667},
5668
5669{
5670        .descr = "line_info (dead subprog + dead start w/ move)",
5671        .raw_types = {
5672                BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),   /* [1] */
5673                BTF_FUNC_PROTO_ENC(1, 1),                       /* [2] */
5674                        BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
5675                BTF_FUNC_ENC(NAME_TBD, 2),                      /* [3] */
5676                BTF_FUNC_ENC(NAME_TBD, 2),                      /* [4] */
5677                BTF_FUNC_ENC(NAME_TBD, 2),                      /* [5] */
5678                BTF_END_RAW,
5679        },
5680        BTF_STR_SEC("\0int\0x\0dead\0main\0func\0int a=1+1;\0/* live call */"
5681                    "\0return 0;\0return 0;\0/* dead */\0/* dead */"
5682                    "\0/* dead */\0return bla + 1;\0return bla + 1;"
5683                    "\0return bla + 1;\0return func(a);\0b+=1;\0return b;"),
5684        .insns = {
5685                BPF_MOV64_IMM(BPF_REG_2, 1),
5686                BPF_JMP_IMM(BPF_JGE, BPF_REG_2, 0, 1),
5687                BPF_CALL_REL(3),
5688                BPF_CALL_REL(5),
5689                BPF_MOV64_IMM(BPF_REG_0, 0),
5690                BPF_EXIT_INSN(),
5691                BPF_MOV64_IMM(BPF_REG_0, 0),
5692                BPF_CALL_REL(1),
5693                BPF_EXIT_INSN(),
5694                BPF_JMP_IMM(BPF_JA, 0, 0, 0),
5695                BPF_MOV64_REG(BPF_REG_0, 2),
5696                BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 1),
5697                BPF_EXIT_INSN(),
5698        },
5699        .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5700        .func_info_cnt = 3,
5701        .func_info_rec_size = 8,
5702                .func_info = { {0, 4}, {6, 3}, {9, 5} },
5703        .line_info = {
5704                BPF_LINE_INFO_ENC(0, 0, NAME_TBD, 1, 10),
5705                BPF_LINE_INFO_ENC(3, 0, NAME_TBD, 1, 10),
5706                BPF_LINE_INFO_ENC(4, 0, NAME_TBD, 1, 10),
5707                BPF_LINE_INFO_ENC(5, 0, NAME_TBD, 1, 10),
5708                BPF_LINE_INFO_ENC(6, 0, NAME_TBD, 1, 10),
5709                BPF_LINE_INFO_ENC(7, 0, NAME_TBD, 1, 10),
5710                BPF_LINE_INFO_ENC(8, 0, NAME_TBD, 1, 10),
5711                BPF_LINE_INFO_ENC(9, 0, NAME_TBD, 1, 10),
5712                BPF_LINE_INFO_ENC(11, 0, NAME_TBD, 1, 10),
5713                BPF_LINE_INFO_ENC(12, 0, NAME_TBD, 2, 9),
5714                BTF_END_RAW,
5715        },
5716        .line_info_rec_size = sizeof(struct bpf_line_info),
5717        .nr_jited_ksyms = 2,
5718        .dead_code_cnt = 3,
5719        .dead_code_mask = 0x70,
5720        .dead_func_cnt = 1,
5721        .dead_func_mask = 0x2,
5722},
5723
5724{
5725        .descr = "line_info (dead end + subprog start w/ no linfo)",
5726        .raw_types = {
5727                BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),   /* [1] */
5728                BTF_FUNC_PROTO_ENC(1, 1),                       /* [2] */
5729                        BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
5730                BTF_FUNC_ENC(NAME_TBD, 2),                      /* [3] */
5731                BTF_FUNC_ENC(NAME_TBD, 2),                      /* [4] */
5732                BTF_END_RAW,
5733        },
5734        BTF_STR_SEC("\0int\0x\0main\0func\0/* main linfo */\0/* func linfo */"),
5735        .insns = {
5736                BPF_MOV64_IMM(BPF_REG_0, 0),
5737                BPF_JMP_IMM(BPF_JGE, BPF_REG_0, 1, 3),
5738                BPF_CALL_REL(3),
5739                BPF_MOV64_IMM(BPF_REG_0, 0),
5740                BPF_EXIT_INSN(),
5741                BPF_EXIT_INSN(),
5742                BPF_JMP_IMM(BPF_JA, 0, 0, 0),
5743                BPF_EXIT_INSN(),
5744        },
5745        .prog_type = BPF_PROG_TYPE_TRACEPOINT,
5746        .func_info_cnt = 2,
5747        .func_info_rec_size = 8,
5748        .func_info = { {0, 3}, {6, 4}, },
5749        .line_info = {
5750                BPF_LINE_INFO_ENC(0, 0, NAME_TBD, 1, 10),
5751                BPF_LINE_INFO_ENC(6, 0, NAME_TBD, 1, 10),
5752                BTF_END_RAW,
5753        },
5754        .line_info_rec_size = sizeof(struct bpf_line_info),
5755        .nr_jited_ksyms = 2,
5756},
5757
5758};
5759
5760static size_t probe_prog_length(const struct bpf_insn *fp)
5761{
5762        size_t len;
5763
5764        for (len = MAX_INSNS - 1; len > 0; --len)
5765                if (fp[len].code != 0 || fp[len].imm != 0)
5766                        break;
5767        return len + 1;
5768}
5769
5770static __u32 *patch_name_tbd(const __u32 *raw_u32,
5771                             const char *str, __u32 str_off,
5772                             unsigned int str_sec_size,
5773                             unsigned int *ret_size)
5774{
5775        int i, raw_u32_size = get_raw_sec_size(raw_u32);
5776        const char *end_str = str + str_sec_size;
5777        const char *next_str = str + str_off;
5778        __u32 *new_u32 = NULL;
5779
5780        if (raw_u32_size == -1)
5781                return ERR_PTR(-EINVAL);
5782
5783        if (!raw_u32_size) {
5784                *ret_size = 0;
5785                return NULL;
5786        }
5787
5788        new_u32 = malloc(raw_u32_size);
5789        if (!new_u32)
5790                return ERR_PTR(-ENOMEM);
5791
5792        for (i = 0; i < raw_u32_size / sizeof(raw_u32[0]); i++) {
5793                if (raw_u32[i] == NAME_TBD) {
5794                        next_str = get_next_str(next_str, end_str);
5795                        if (CHECK(!next_str, "Error in getting next_str\n")) {
5796                                free(new_u32);
5797                                return ERR_PTR(-EINVAL);
5798                        }
5799                        new_u32[i] = next_str - str;
5800                        next_str += strlen(next_str);
5801                } else {
5802                        new_u32[i] = raw_u32[i];
5803                }
5804        }
5805
5806        *ret_size = raw_u32_size;
5807        return new_u32;
5808}
5809
5810static int test_get_finfo(const struct prog_info_raw_test *test,
5811                          int prog_fd)
5812{
5813        struct bpf_prog_info info = {};
5814        struct bpf_func_info *finfo;
5815        __u32 info_len, rec_size, i;
5816        void *func_info = NULL;
5817        __u32 nr_func_info;
5818        int err;
5819
5820        /* get necessary lens */
5821        info_len = sizeof(struct bpf_prog_info);
5822        err = bpf_obj_get_info_by_fd(prog_fd, &info, &info_len);
5823        if (CHECK(err == -1, "invalid get info (1st) errno:%d", errno)) {
5824                fprintf(stderr, "%s\n", btf_log_buf);
5825                return -1;
5826        }
5827        nr_func_info = test->func_info_cnt - test->dead_func_cnt;
5828        if (CHECK(info.nr_func_info != nr_func_info,
5829                  "incorrect info.nr_func_info (1st) %d",
5830                  info.nr_func_info)) {
5831                return -1;
5832        }
5833
5834        rec_size = info.func_info_rec_size;
5835        if (CHECK(rec_size != sizeof(struct bpf_func_info),
5836                  "incorrect info.func_info_rec_size (1st) %d", rec_size)) {
5837                return -1;
5838        }
5839
5840        if (!info.nr_func_info)
5841                return 0;
5842
5843        func_info = malloc(info.nr_func_info * rec_size);
5844        if (CHECK(!func_info, "out of memory"))
5845                return -1;
5846
5847        /* reset info to only retrieve func_info related data */
5848        memset(&info, 0, sizeof(info));
5849        info.nr_func_info = nr_func_info;
5850        info.func_info_rec_size = rec_size;
5851        info.func_info = ptr_to_u64(func_info);
5852        err = bpf_obj_get_info_by_fd(prog_fd, &info, &info_len);
5853        if (CHECK(err == -1, "invalid get info (2nd) errno:%d", errno)) {
5854                fprintf(stderr, "%s\n", btf_log_buf);
5855                err = -1;
5856                goto done;
5857        }
5858        if (CHECK(info.nr_func_info != nr_func_info,
5859                  "incorrect info.nr_func_info (2nd) %d",
5860                  info.nr_func_info)) {
5861                err = -1;
5862                goto done;
5863        }
5864        if (CHECK(info.func_info_rec_size != rec_size,
5865                  "incorrect info.func_info_rec_size (2nd) %d",
5866                  info.func_info_rec_size)) {
5867                err = -1;
5868                goto done;
5869        }
5870
5871        finfo = func_info;
5872        for (i = 0; i < nr_func_info; i++) {
5873                if (test->dead_func_mask & (1 << i))
5874                        continue;
5875                if (CHECK(finfo->type_id != test->func_info[i][1],
5876                          "incorrect func_type %u expected %u",
5877                          finfo->type_id, test->func_info[i][1])) {
5878                        err = -1;
5879                        goto done;
5880                }
5881                finfo = (void *)finfo + rec_size;
5882        }
5883
5884        err = 0;
5885
5886done:
5887        free(func_info);
5888        return err;
5889}
5890
5891static int test_get_linfo(const struct prog_info_raw_test *test,
5892                          const void *patched_linfo,
5893                          __u32 cnt, int prog_fd)
5894{
5895        __u32 i, info_len, nr_jited_ksyms, nr_jited_func_lens;
5896        __u64 *jited_linfo = NULL, *jited_ksyms = NULL;
5897        __u32 rec_size, jited_rec_size, jited_cnt;
5898        struct bpf_line_info *linfo = NULL;
5899        __u32 cur_func_len, ksyms_found;
5900        struct bpf_prog_info info = {};
5901        __u32 *jited_func_lens = NULL;
5902        __u64 cur_func_ksyms;
5903        __u32 dead_insns;
5904        int err;
5905
5906        jited_cnt = cnt;
5907        rec_size = sizeof(*linfo);
5908        jited_rec_size = sizeof(*jited_linfo);
5909        if (test->nr_jited_ksyms)
5910                nr_jited_ksyms = test->nr_jited_ksyms;
5911        else
5912                nr_jited_ksyms = test->func_info_cnt - test->dead_func_cnt;
5913        nr_jited_func_lens = nr_jited_ksyms;
5914
5915        info_len = sizeof(struct bpf_prog_info);
5916        err = bpf_obj_get_info_by_fd(prog_fd, &info, &info_len);
5917        if (CHECK(err == -1, "err:%d errno:%d", err, errno)) {
5918                err = -1;
5919                goto done;
5920        }
5921
5922        if (!info.jited_prog_len) {
5923                /* prog is not jited */
5924                jited_cnt = 0;
5925                nr_jited_ksyms = 1;
5926                nr_jited_func_lens = 1;
5927        }
5928
5929        if (CHECK(info.nr_line_info != cnt ||
5930                  info.nr_jited_line_info != jited_cnt ||
5931                  info.nr_jited_ksyms != nr_jited_ksyms ||
5932                  info.nr_jited_func_lens != nr_jited_func_lens ||
5933                  (!info.nr_line_info && info.nr_jited_line_info),
5934                  "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)",
5935                  info.nr_line_info, cnt,
5936                  info.nr_jited_line_info, jited_cnt,
5937                  info.nr_jited_ksyms, nr_jited_ksyms,
5938                  info.nr_jited_func_lens, nr_jited_func_lens)) {
5939                err = -1;
5940                goto done;
5941        }
5942
5943        if (CHECK(info.line_info_rec_size != sizeof(struct bpf_line_info) ||
5944                  info.jited_line_info_rec_size != sizeof(__u64),
5945                  "info: line_info_rec_size:%u(userspace expected:%u) jited_line_info_rec_size:%u(userspace expected:%u)",
5946                  info.line_info_rec_size, rec_size,
5947                  info.jited_line_info_rec_size, jited_rec_size)) {
5948                err = -1;
5949                goto done;
5950        }
5951
5952        if (!cnt)
5953                return 0;
5954
5955        rec_size = info.line_info_rec_size;
5956        jited_rec_size = info.jited_line_info_rec_size;
5957
5958        memset(&info, 0, sizeof(info));
5959
5960        linfo = calloc(cnt, rec_size);
5961        if (CHECK(!linfo, "!linfo")) {
5962                err = -1;
5963                goto done;
5964        }
5965        info.nr_line_info = cnt;
5966        info.line_info_rec_size = rec_size;
5967        info.line_info = ptr_to_u64(linfo);
5968
5969        if (jited_cnt) {
5970                jited_linfo = calloc(jited_cnt, jited_rec_size);
5971                jited_ksyms = calloc(nr_jited_ksyms, sizeof(*jited_ksyms));
5972                jited_func_lens = calloc(nr_jited_func_lens,
5973                                         sizeof(*jited_func_lens));
5974                if (CHECK(!jited_linfo || !jited_ksyms || !jited_func_lens,
5975                          "jited_linfo:%p jited_ksyms:%p jited_func_lens:%p",
5976                          jited_linfo, jited_ksyms, jited_func_lens)) {
5977                        err = -1;
5978                        goto done;
5979                }
5980
5981                info.nr_jited_line_info = jited_cnt;
5982                info.jited_line_info_rec_size = jited_rec_size;
5983                info.jited_line_info = ptr_to_u64(jited_linfo);
5984                info.nr_jited_ksyms = nr_jited_ksyms;
5985                info.jited_ksyms = ptr_to_u64(jited_ksyms);
5986                info.nr_jited_func_lens = nr_jited_func_lens;
5987                info.jited_func_lens = ptr_to_u64(jited_func_lens);
5988        }
5989
5990        err = bpf_obj_get_info_by_fd(prog_fd, &info, &info_len);
5991
5992        /*
5993         * Only recheck the info.*line_info* fields.
5994         * Other fields are not the concern of this test.
5995         */
5996        if (CHECK(err == -1 ||
5997                  info.nr_line_info != cnt ||
5998                  (jited_cnt && !info.jited_line_info) ||
5999                  info.nr_jited_line_info != jited_cnt ||
6000                  info.line_info_rec_size != rec_size ||
6001                  info.jited_line_info_rec_size != jited_rec_size,
6002                  "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",
6003                  err, errno,
6004                  info.nr_line_info, cnt,
6005                  info.nr_jited_line_info, jited_cnt,
6006                  info.line_info_rec_size, rec_size,
6007                  info.jited_line_info_rec_size, jited_rec_size,
6008                  (void *)(long)info.line_info,
6009                  (void *)(long)info.jited_line_info)) {
6010                err = -1;
6011                goto done;
6012        }
6013
6014        dead_insns = 0;
6015        while (test->dead_code_mask & (1 << dead_insns))
6016                dead_insns++;
6017
6018        CHECK(linfo[0].insn_off, "linfo[0].insn_off:%u",
6019              linfo[0].insn_off);
6020        for (i = 1; i < cnt; i++) {
6021                const struct bpf_line_info *expected_linfo;
6022
6023                while (test->dead_code_mask & (1 << (i + dead_insns)))
6024                        dead_insns++;
6025
6026                expected_linfo = patched_linfo +
6027                        ((i + dead_insns) * test->line_info_rec_size);
6028                if (CHECK(linfo[i].insn_off <= linfo[i - 1].insn_off,
6029                          "linfo[%u].insn_off:%u <= linfo[%u].insn_off:%u",
6030                          i, linfo[i].insn_off,
6031                          i - 1, linfo[i - 1].insn_off)) {
6032                        err = -1;
6033                        goto done;
6034                }
6035                if (CHECK(linfo[i].file_name_off != expected_linfo->file_name_off ||
6036                          linfo[i].line_off != expected_linfo->line_off ||
6037                          linfo[i].line_col != expected_linfo->line_col,
6038                          "linfo[%u] (%u, %u, %u) != (%u, %u, %u)", i,
6039                          linfo[i].file_name_off,
6040                          linfo[i].line_off,
6041                          linfo[i].line_col,
6042                          expected_linfo->file_name_off,
6043                          expected_linfo->line_off,
6044                          expected_linfo->line_col)) {
6045                        err = -1;
6046                        goto done;
6047                }
6048        }
6049
6050        if (!jited_cnt) {
6051                fprintf(stderr, "not jited. skipping jited_line_info check. ");
6052                err = 0;
6053                goto done;
6054        }
6055
6056        if (CHECK(jited_linfo[0] != jited_ksyms[0],
6057                  "jited_linfo[0]:%lx != jited_ksyms[0]:%lx",
6058                  (long)(jited_linfo[0]), (long)(jited_ksyms[0]))) {
6059                err = -1;
6060                goto done;
6061        }
6062
6063        ksyms_found = 1;
6064        cur_func_len = jited_func_lens[0];
6065        cur_func_ksyms = jited_ksyms[0];
6066        for (i = 1; i < jited_cnt; i++) {
6067                if (ksyms_found < nr_jited_ksyms &&
6068                    jited_linfo[i] == jited_ksyms[ksyms_found]) {
6069                        cur_func_ksyms = jited_ksyms[ksyms_found];
6070                        cur_func_len = jited_ksyms[ksyms_found];
6071                        ksyms_found++;
6072                        continue;
6073                }
6074
6075                if (CHECK(jited_linfo[i] <= jited_linfo[i - 1],
6076                          "jited_linfo[%u]:%lx <= jited_linfo[%u]:%lx",
6077                          i, (long)jited_linfo[i],
6078                          i - 1, (long)(jited_linfo[i - 1]))) {
6079                        err = -1;
6080                        goto done;
6081                }
6082
6083                if (CHECK(jited_linfo[i] - cur_func_ksyms > cur_func_len,
6084                          "jited_linfo[%u]:%lx - %lx > %u",
6085                          i, (long)jited_linfo[i], (long)cur_func_ksyms,
6086                          cur_func_len)) {
6087                        err = -1;
6088                        goto done;
6089                }
6090        }
6091
6092        if (CHECK(ksyms_found != nr_jited_ksyms,
6093                  "ksyms_found:%u != nr_jited_ksyms:%u",
6094                  ksyms_found, nr_jited_ksyms)) {
6095                err = -1;
6096                goto done;
6097        }
6098
6099        err = 0;
6100
6101done:
6102        free(linfo);
6103        free(jited_linfo);
6104        free(jited_ksyms);
6105        free(jited_func_lens);
6106        return err;
6107}
6108
6109static void do_test_info_raw(unsigned int test_num)
6110{
6111        const struct prog_info_raw_test *test = &info_raw_tests[test_num - 1];
6112        unsigned int raw_btf_size, linfo_str_off, linfo_size;
6113        int btf_fd = -1, prog_fd = -1, err = 0;
6114        void *raw_btf, *patched_linfo = NULL;
6115        const char *ret_next_str;
6116        union bpf_attr attr = {};
6117
6118        if (!test__start_subtest(test->descr))
6119                return;
6120
6121        raw_btf = btf_raw_create(&hdr_tmpl, test->raw_types,
6122                                 test->str_sec, test->str_sec_size,
6123                                 &raw_btf_size, &ret_next_str);
6124        if (!raw_btf)
6125                return;
6126
6127        *btf_log_buf = '\0';
6128        btf_fd = bpf_load_btf(raw_btf, raw_btf_size,
6129                              btf_log_buf, BTF_LOG_BUF_SIZE,
6130                              always_log);
6131        free(raw_btf);
6132
6133        if (CHECK(btf_fd == -1, "invalid btf_fd errno:%d", errno)) {
6134                err = -1;
6135                goto done;
6136        }
6137
6138        if (*btf_log_buf && always_log)
6139                fprintf(stderr, "\n%s", btf_log_buf);
6140        *btf_log_buf = '\0';
6141
6142        linfo_str_off = ret_next_str - test->str_sec;
6143        patched_linfo = patch_name_tbd(test->line_info,
6144                                       test->str_sec, linfo_str_off,
6145                                       test->str_sec_size, &linfo_size);
6146        if (IS_ERR(patched_linfo)) {
6147                fprintf(stderr, "error in creating raw bpf_line_info");
6148                err = -1;
6149                goto done;
6150        }
6151
6152        attr.prog_type = test->prog_type;
6153        attr.insns = ptr_to_u64(test->insns);
6154        attr.insn_cnt = probe_prog_length(test->insns);
6155        attr.license = ptr_to_u64("GPL");
6156        attr.prog_btf_fd = btf_fd;
6157        attr.func_info_rec_size = test->func_info_rec_size;
6158        attr.func_info_cnt = test->func_info_cnt;
6159        attr.func_info = ptr_to_u64(test->func_info);
6160        attr.log_buf = ptr_to_u64(btf_log_buf);
6161        attr.log_size = BTF_LOG_BUF_SIZE;
6162        attr.log_level = 1;
6163        if (linfo_size) {
6164                attr.line_info_rec_size = test->line_info_rec_size;
6165                attr.line_info = ptr_to_u64(patched_linfo);
6166                attr.line_info_cnt = linfo_size / attr.line_info_rec_size;
6167        }
6168
6169        prog_fd = syscall(__NR_bpf, BPF_PROG_LOAD, &attr, sizeof(attr));
6170        err = ((prog_fd == -1) != test->expected_prog_load_failure);
6171        if (CHECK(err, "prog_fd:%d expected_prog_load_failure:%u errno:%d",
6172                  prog_fd, test->expected_prog_load_failure, errno) ||
6173            CHECK(test->err_str && !strstr(btf_log_buf, test->err_str),
6174                  "expected err_str:%s", test->err_str)) {
6175                err = -1;
6176                goto done;
6177        }
6178
6179        if (prog_fd == -1)
6180                goto done;
6181
6182        err = test_get_finfo(test, prog_fd);
6183        if (err)
6184                goto done;
6185
6186        err = test_get_linfo(test, patched_linfo,
6187                             attr.line_info_cnt - test->dead_code_cnt,
6188                             prog_fd);
6189        if (err)
6190                goto done;
6191
6192done:
6193        if (*btf_log_buf && (err || always_log))
6194                fprintf(stderr, "\n%s", btf_log_buf);
6195
6196        if (btf_fd != -1)
6197                close(btf_fd);
6198        if (prog_fd != -1)
6199                close(prog_fd);
6200
6201        if (!IS_ERR(patched_linfo))
6202                free(patched_linfo);
6203}
6204
6205struct btf_raw_data {
6206        __u32 raw_types[MAX_NR_RAW_U32];
6207        const char *str_sec;
6208        __u32 str_sec_size;
6209};
6210
6211struct btf_dedup_test {
6212        const char *descr;
6213        struct btf_raw_data input;
6214        struct btf_raw_data expect;
6215        struct btf_dedup_opts opts;
6216};
6217
6218const struct btf_dedup_test dedup_tests[] = {
6219
6220{
6221        .descr = "dedup: unused strings filtering",
6222        .input = {
6223                .raw_types = {
6224                        BTF_TYPE_INT_ENC(NAME_NTH(2), BTF_INT_SIGNED, 0, 32, 4),
6225                        BTF_TYPE_INT_ENC(NAME_NTH(5), BTF_INT_SIGNED, 0, 64, 8),
6226                        BTF_END_RAW,
6227                },
6228                BTF_STR_SEC("\0unused\0int\0foo\0bar\0long"),
6229        },
6230        .expect = {
6231                .raw_types = {
6232                        BTF_TYPE_INT_ENC(NAME_NTH(1), BTF_INT_SIGNED, 0, 32, 4),
6233                        BTF_TYPE_INT_ENC(NAME_NTH(2), BTF_INT_SIGNED, 0, 64, 8),
6234                        BTF_END_RAW,
6235                },
6236                BTF_STR_SEC("\0int\0long"),
6237        },
6238        .opts = {
6239                .dont_resolve_fwds = false,
6240        },
6241},
6242{
6243        .descr = "dedup: strings deduplication",
6244        .input = {
6245                .raw_types = {
6246                        BTF_TYPE_INT_ENC(NAME_NTH(1), BTF_INT_SIGNED, 0, 32, 4),
6247                        BTF_TYPE_INT_ENC(NAME_NTH(2), BTF_INT_SIGNED, 0, 64, 8),
6248                        BTF_TYPE_INT_ENC(NAME_NTH(3), BTF_INT_SIGNED, 0, 32, 4),
6249                        BTF_TYPE_INT_ENC(NAME_NTH(4), BTF_INT_SIGNED, 0, 64, 8),
6250                        BTF_TYPE_INT_ENC(NAME_NTH(5), BTF_INT_SIGNED, 0, 32, 4),
6251                        BTF_END_RAW,
6252                },
6253                BTF_STR_SEC("\0int\0long int\0int\0long int\0int"),
6254        },
6255        .expect = {
6256                .raw_types = {
6257                        BTF_TYPE_INT_ENC(NAME_NTH(1), BTF_INT_SIGNED, 0, 32, 4),
6258                        BTF_TYPE_INT_ENC(NAME_NTH(2), BTF_INT_SIGNED, 0, 64, 8),
6259                        BTF_END_RAW,
6260                },
6261                BTF_STR_SEC("\0int\0long int"),
6262        },
6263        .opts = {
6264                .dont_resolve_fwds = false,
6265        },
6266},
6267{
6268        .descr = "dedup: struct example #1",
6269        /*
6270         * struct s {
6271         *      struct s *next;
6272         *      const int *a;
6273         *      int b[16];
6274         *      int c;
6275         * }
6276         */
6277        .input = {
6278                .raw_types = {
6279                        /* int */
6280                        BTF_TYPE_INT_ENC(NAME_NTH(1), BTF_INT_SIGNED, 0, 32, 4),        /* [1] */
6281                        /* int[16] */
6282                        BTF_TYPE_ARRAY_ENC(1, 1, 16),                                   /* [2] */
6283                        /* struct s { */
6284                        BTF_STRUCT_ENC(NAME_NTH(2), 4, 84),                             /* [3] */
6285                                BTF_MEMBER_ENC(NAME_NTH(3), 4, 0),      /* struct s *next;      */
6286                                BTF_MEMBER_ENC(NAME_NTH(4), 5, 64),     /* const int *a;        */
6287                                BTF_MEMBER_ENC(NAME_NTH(5), 2, 128),    /* int b[16];           */
6288                                BTF_MEMBER_ENC(NAME_NTH(6), 1, 640),    /* int c;               */
6289                        /* ptr -> [3] struct s */
6290                        BTF_PTR_ENC(3),                                                 /* [4] */
6291                        /* ptr -> [6] const int */
6292                        BTF_PTR_ENC(6),                                                 /* [5] */
6293                        /* const -> [1] int */
6294                        BTF_CONST_ENC(1),                                               /* [6] */
6295
6296                        /* full copy of the above */
6297                        BTF_TYPE_INT_ENC(NAME_NTH(1), BTF_INT_SIGNED, 0, 32, 4),        /* [7] */
6298                        BTF_TYPE_ARRAY_ENC(7, 7, 16),                                   /* [8] */
6299                        BTF_STRUCT_ENC(NAME_NTH(2), 4, 84),                             /* [9] */
6300                                BTF_MEMBER_ENC(NAME_NTH(3), 10, 0),
6301                                BTF_MEMBER_ENC(NAME_NTH(4), 11, 64),
6302                                BTF_MEMBER_ENC(NAME_NTH(5), 8, 128),
6303                                BTF_MEMBER_ENC(NAME_NTH(6), 7, 640),
6304                        BTF_PTR_ENC(9),                                                 /* [10] */
6305                        BTF_PTR_ENC(12),                                                /* [11] */
6306                        BTF_CONST_ENC(7),                                               /* [12] */
6307                        BTF_END_RAW,
6308                },
6309                BTF_STR_SEC("\0int\0s\0next\0a\0b\0c\0"),
6310        },
6311        .expect = {
6312                .raw_types = {
6313                        /* int */
6314                        BTF_TYPE_INT_ENC(NAME_NTH(4), BTF_INT_SIGNED, 0, 32, 4),        /* [1] */
6315                        /* int[16] */
6316                        BTF_TYPE_ARRAY_ENC(1, 1, 16),                                   /* [2] */
6317                        /* struct s { */
6318                        BTF_STRUCT_ENC(NAME_NTH(6), 4, 84),                             /* [3] */
6319                                BTF_MEMBER_ENC(NAME_NTH(5), 4, 0),      /* struct s *next;      */
6320                                BTF_MEMBER_ENC(NAME_NTH(1), 5, 64),     /* const int *a;        */
6321                                BTF_MEMBER_ENC(NAME_NTH(2), 2, 128),    /* int b[16];           */
6322                                BTF_MEMBER_ENC(NAME_NTH(3), 1, 640),    /* int c;               */
6323                        /* ptr -> [3] struct s */
6324                        BTF_PTR_ENC(3),                                                 /* [4] */
6325                        /* ptr -> [6] const int */
6326                        BTF_PTR_ENC(6),                                                 /* [5] */
6327                        /* const -> [1] int */
6328                        BTF_CONST_ENC(1),                                               /* [6] */
6329                        BTF_END_RAW,
6330                },
6331                BTF_STR_SEC("\0a\0b\0c\0int\0next\0s"),
6332        },
6333        .opts = {
6334                .dont_resolve_fwds = false,
6335        },
6336},
6337{
6338        .descr = "dedup: struct <-> fwd resolution w/ hash collision",
6339        /*
6340         * // CU 1:
6341         * struct x;
6342         * struct s {
6343         *      struct x *x;
6344         * };
6345         * // CU 2:
6346         * struct x {};
6347         * struct s {
6348         *      struct x *x;
6349         * };
6350         */
6351        .input = {
6352                .raw_types = {
6353                        /* CU 1 */
6354                        BTF_FWD_ENC(NAME_TBD, 0 /* struct fwd */),      /* [1] fwd x      */
6355                        BTF_PTR_ENC(1),                                 /* [2] ptr -> [1] */
6356                        BTF_STRUCT_ENC(NAME_TBD, 1, 8),                 /* [3] struct s   */
6357                                BTF_MEMBER_ENC(NAME_TBD, 2, 0),
6358                        /* CU 2 */
6359                        BTF_STRUCT_ENC(NAME_TBD, 0, 0),                 /* [4] struct x   */
6360                        BTF_PTR_ENC(4),                                 /* [5] ptr -> [4] */
6361                        BTF_STRUCT_ENC(NAME_TBD, 1, 8),                 /* [6] struct s   */
6362                                BTF_MEMBER_ENC(NAME_TBD, 5, 0),
6363                        BTF_END_RAW,
6364                },
6365                BTF_STR_SEC("\0x\0s\0x\0x\0s\0x\0"),
6366        },
6367        .expect = {
6368                .raw_types = {
6369                        BTF_PTR_ENC(3),                                 /* [1] ptr -> [3] */
6370                        BTF_STRUCT_ENC(NAME_TBD, 1, 8),                 /* [2] struct s   */
6371                                BTF_MEMBER_ENC(NAME_TBD, 1, 0),
6372                        BTF_STRUCT_ENC(NAME_NTH(2), 0, 0),              /* [3] struct x   */
6373                        BTF_END_RAW,
6374                },
6375                BTF_STR_SEC("\0s\0x"),
6376        },
6377        .opts = {
6378                .dont_resolve_fwds = false,
6379                .dedup_table_size = 1, /* force hash collisions */
6380        },
6381},
6382{
6383        .descr = "dedup: void equiv check",
6384        /*
6385         * // CU 1:
6386         * struct s {
6387         *      struct {} *x;
6388         * };
6389         * // CU 2:
6390         * struct s {
6391         *      int *x;
6392         * };
6393         */
6394        .input = {
6395                .raw_types = {
6396                        /* CU 1 */
6397                        BTF_STRUCT_ENC(0, 0, 1),                                /* [1] struct {}  */
6398                        BTF_PTR_ENC(1),                                         /* [2] ptr -> [1] */
6399                        BTF_STRUCT_ENC(NAME_NTH(1), 1, 8),                      /* [3] struct s   */
6400                                BTF_MEMBER_ENC(NAME_NTH(2), 2, 0),
6401                        /* CU 2 */
6402                        BTF_PTR_ENC(0),                                         /* [4] ptr -> void */
6403                        BTF_STRUCT_ENC(NAME_NTH(1), 1, 8),                      /* [5] struct s   */
6404                                BTF_MEMBER_ENC(NAME_NTH(2), 4, 0),
6405                        BTF_END_RAW,
6406                },
6407                BTF_STR_SEC("\0s\0x"),
6408        },
6409        .expect = {
6410                .raw_types = {
6411                        /* CU 1 */
6412                        BTF_STRUCT_ENC(0, 0, 1),                                /* [1] struct {}  */
6413                        BTF_PTR_ENC(1),                                         /* [2] ptr -> [1] */
6414                        BTF_STRUCT_ENC(NAME_NTH(1), 1, 8),                      /* [3] struct s   */
6415                                BTF_MEMBER_ENC(NAME_NTH(2), 2, 0),
6416                        /* CU 2 */
6417                        BTF_PTR_ENC(0),                                         /* [4] ptr -> void */
6418                        BTF_STRUCT_ENC(NAME_NTH(1), 1, 8),                      /* [5] struct s   */
6419                                BTF_MEMBER_ENC(NAME_NTH(2), 4, 0),
6420                        BTF_END_RAW,
6421                },
6422                BTF_STR_SEC("\0s\0x"),
6423        },
6424        .opts = {
6425                .dont_resolve_fwds = false,
6426                .dedup_table_size = 1, /* force hash collisions */
6427        },
6428},
6429{
6430        .descr = "dedup: all possible kinds (no duplicates)",
6431        .input = {
6432                .raw_types = {
6433                        BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 8),           /* [1] int */
6434                        BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_ENUM, 0, 2), 4),   /* [2] enum */
6435                                BTF_ENUM_ENC(NAME_TBD, 0),
6436                                BTF_ENUM_ENC(NAME_TBD, 1),
6437                        BTF_FWD_ENC(NAME_TBD, 1 /* union kind_flag */),                 /* [3] fwd */
6438                        BTF_TYPE_ARRAY_ENC(2, 1, 7),                                    /* [4] array */
6439                        BTF_STRUCT_ENC(NAME_TBD, 1, 4),                                 /* [5] struct */
6440                                BTF_MEMBER_ENC(NAME_TBD, 1, 0),
6441                        BTF_UNION_ENC(NAME_TBD, 1, 4),                                  /* [6] union */
6442                                BTF_MEMBER_ENC(NAME_TBD, 1, 0),
6443                        BTF_TYPEDEF_ENC(NAME_TBD, 1),                                   /* [7] typedef */
6444                        BTF_PTR_ENC(0),                                                 /* [8] ptr */
6445                        BTF_CONST_ENC(8),                                               /* [9] const */
6446                        BTF_VOLATILE_ENC(8),                                            /* [10] volatile */
6447                        BTF_RESTRICT_ENC(8),                                            /* [11] restrict */
6448                        BTF_FUNC_PROTO_ENC(1, 2),                                       /* [12] func_proto */
6449                                BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
6450                                BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 8),
6451                        BTF_FUNC_ENC(NAME_TBD, 12),                                     /* [13] func */
6452                        BTF_END_RAW,
6453                },
6454                BTF_STR_SEC("\0A\0B\0C\0D\0E\0F\0G\0H\0I\0J\0K\0L\0M"),
6455        },
6456        .expect = {
6457                .raw_types = {
6458                        BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 8),           /* [1] int */
6459                        BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_ENUM, 0, 2), 4),   /* [2] enum */
6460                                BTF_ENUM_ENC(NAME_TBD, 0),
6461                                BTF_ENUM_ENC(NAME_TBD, 1),
6462                        BTF_FWD_ENC(NAME_TBD, 1 /* union kind_flag */),                 /* [3] fwd */
6463                        BTF_TYPE_ARRAY_ENC(2, 1, 7),                                    /* [4] array */
6464                        BTF_STRUCT_ENC(NAME_TBD, 1, 4),                                 /* [5] struct */
6465                                BTF_MEMBER_ENC(NAME_TBD, 1, 0),
6466                        BTF_UNION_ENC(NAME_TBD, 1, 4),                                  /* [6] union */
6467                                BTF_MEMBER_ENC(NAME_TBD, 1, 0),
6468                        BTF_TYPEDEF_ENC(NAME_TBD, 1),                                   /* [7] typedef */
6469                        BTF_PTR_ENC(0),                                                 /* [8] ptr */
6470                        BTF_CONST_ENC(8),                                               /* [9] const */
6471                        BTF_VOLATILE_ENC(8),                                            /* [10] volatile */
6472                        BTF_RESTRICT_ENC(8),                                            /* [11] restrict */
6473                        BTF_FUNC_PROTO_ENC(1, 2),                                       /* [12] func_proto */
6474                                BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
6475                                BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 8),
6476                        BTF_FUNC_ENC(NAME_TBD, 12),                                     /* [13] func */
6477                        BTF_END_RAW,
6478                },
6479                BTF_STR_SEC("\0A\0B\0C\0D\0E\0F\0G\0H\0I\0J\0K\0L\0M"),
6480        },
6481        .opts = {
6482                .dont_resolve_fwds = false,
6483        },
6484},
6485{
6486        .descr = "dedup: no int duplicates",
6487        .input = {
6488                .raw_types = {
6489                        BTF_TYPE_INT_ENC(NAME_NTH(1), BTF_INT_SIGNED, 0, 32, 8),
6490                        /* different name */
6491                        BTF_TYPE_INT_ENC(NAME_NTH(2), BTF_INT_SIGNED, 0, 32, 8),
6492                        /* different encoding */
6493                        BTF_TYPE_INT_ENC(NAME_NTH(1), BTF_INT_CHAR, 0, 32, 8),
6494                        BTF_TYPE_INT_ENC(NAME_NTH(1), BTF_INT_BOOL, 0, 32, 8),
6495                        /* different bit offset */
6496                        BTF_TYPE_INT_ENC(NAME_NTH(1), BTF_INT_SIGNED, 8, 32, 8),
6497                        /* different bit size */
6498                        BTF_TYPE_INT_ENC(NAME_NTH(1), BTF_INT_SIGNED, 0, 27, 8),
6499                        /* different byte size */
6500                        BTF_TYPE_INT_ENC(NAME_NTH(1), BTF_INT_SIGNED, 0, 32, 4),
6501                        BTF_END_RAW,
6502                },
6503                BTF_STR_SEC("\0int\0some other int"),
6504        },
6505        .expect = {
6506                .raw_types = {
6507                        BTF_TYPE_INT_ENC(NAME_NTH(1), BTF_INT_SIGNED, 0, 32, 8),
6508                        /* different name */
6509                        BTF_TYPE_INT_ENC(NAME_NTH(2), BTF_INT_SIGNED, 0, 32, 8),
6510                        /* different encoding */
6511                        BTF_TYPE_INT_ENC(NAME_NTH(1), BTF_INT_CHAR, 0, 32, 8),
6512                        BTF_TYPE_INT_ENC(NAME_NTH(1), BTF_INT_BOOL, 0, 32, 8),
6513                        /* different bit offset */
6514                        BTF_TYPE_INT_ENC(NAME_NTH(1), BTF_INT_SIGNED, 8, 32, 8),
6515                        /* different bit size */
6516                        BTF_TYPE_INT_ENC(NAME_NTH(1), BTF_INT_SIGNED, 0, 27, 8),
6517                        /* different byte size */
6518                        BTF_TYPE_INT_ENC(NAME_NTH(1), BTF_INT_SIGNED, 0, 32, 4),
6519                        BTF_END_RAW,
6520                },
6521                BTF_STR_SEC("\0int\0some other int"),
6522        },
6523        .opts = {
6524                .dont_resolve_fwds = false,
6525        },
6526},
6527{
6528        .descr = "dedup: enum fwd resolution",
6529        .input = {
6530                .raw_types = {
6531                        /* [1] fwd enum 'e1' before full enum */
6532                        BTF_TYPE_ENC(NAME_NTH(1), BTF_INFO_ENC(BTF_KIND_ENUM, 0, 0), 4),
6533                        /* [2] full enum 'e1' after fwd */
6534                        BTF_TYPE_ENC(NAME_NTH(1), BTF_INFO_ENC(BTF_KIND_ENUM, 0, 1), 4),
6535                                BTF_ENUM_ENC(NAME_NTH(2), 123),
6536                        /* [3] full enum 'e2' before fwd */
6537                        BTF_TYPE_ENC(NAME_NTH(3), BTF_INFO_ENC(BTF_KIND_ENUM, 0, 1), 4),
6538                                BTF_ENUM_ENC(NAME_NTH(4), 456),
6539                        /* [4] fwd enum 'e2' after full enum */
6540                        BTF_TYPE_ENC(NAME_NTH(3), BTF_INFO_ENC(BTF_KIND_ENUM, 0, 0), 4),
6541                        /* [5] incompatible fwd enum with different size */
6542                        BTF_TYPE_ENC(NAME_NTH(1), BTF_INFO_ENC(BTF_KIND_ENUM, 0, 0), 1),
6543                        /* [6] incompatible full enum with different value */
6544                        BTF_TYPE_ENC(NAME_NTH(1), BTF_INFO_ENC(BTF_KIND_ENUM, 0, 1), 4),
6545                                BTF_ENUM_ENC(NAME_NTH(2), 321),
6546                        BTF_END_RAW,
6547                },
6548                BTF_STR_SEC("\0e1\0e1_val\0e2\0e2_val"),
6549        },
6550        .expect = {
6551                .raw_types = {
6552                        /* [1] full enum 'e1' */
6553                        BTF_TYPE_ENC(NAME_NTH(1), BTF_INFO_ENC(BTF_KIND_ENUM, 0, 1), 4),
6554                                BTF_ENUM_ENC(NAME_NTH(2), 123),
6555                        /* [2] full enum 'e2' */
6556                        BTF_TYPE_ENC(NAME_NTH(3), BTF_INFO_ENC(BTF_KIND_ENUM, 0, 1), 4),
6557                                BTF_ENUM_ENC(NAME_NTH(4), 456),
6558                        /* [3] incompatible fwd enum with different size */
6559                        BTF_TYPE_ENC(NAME_NTH(1), BTF_INFO_ENC(BTF_KIND_ENUM, 0, 0), 1),
6560                        /* [4] incompatible full enum with different value */
6561                        BTF_TYPE_ENC(NAME_NTH(1), BTF_INFO_ENC(BTF_KIND_ENUM, 0, 1), 4),
6562                                BTF_ENUM_ENC(NAME_NTH(2), 321),
6563                        BTF_END_RAW,
6564                },
6565                BTF_STR_SEC("\0e1\0e1_val\0e2\0e2_val"),
6566        },
6567        .opts = {
6568                .dont_resolve_fwds = false,
6569        },
6570},
6571{
6572        .descr = "dedup: datasec and vars pass-through",
6573        .input = {
6574                .raw_types = {
6575                        /* int */
6576                        BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),  /* [1] */
6577                        /* static int t */
6578                        BTF_VAR_ENC(NAME_NTH(2), 1, 0),                 /* [2] */
6579                        /* .bss section */                              /* [3] */
6580                        BTF_TYPE_ENC(NAME_NTH(1), BTF_INFO_ENC(BTF_KIND_DATASEC, 0, 1), 4),
6581                        BTF_VAR_SECINFO_ENC(2, 0, 4),
6582                        /* int, referenced from [5] */
6583                        BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),  /* [4] */
6584                        /* another static int t */
6585                        BTF_VAR_ENC(NAME_NTH(2), 4, 0),                 /* [5] */
6586                        /* another .bss section */                      /* [6] */
6587                        BTF_TYPE_ENC(NAME_NTH(1), BTF_INFO_ENC(BTF_KIND_DATASEC, 0, 1), 4),
6588                        BTF_VAR_SECINFO_ENC(5, 0, 4),
6589                        BTF_END_RAW,
6590                },
6591                BTF_STR_SEC("\0.bss\0t"),
6592        },
6593        .expect = {
6594                .raw_types = {
6595                        /* int */
6596                        BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),  /* [1] */
6597                        /* static int t */
6598                        BTF_VAR_ENC(NAME_NTH(2), 1, 0),                 /* [2] */
6599                        /* .bss section */                              /* [3] */
6600                        BTF_TYPE_ENC(NAME_NTH(1), BTF_INFO_ENC(BTF_KIND_DATASEC, 0, 1), 4),
6601                        BTF_VAR_SECINFO_ENC(2, 0, 4),
6602                        /* another static int t */
6603                        BTF_VAR_ENC(NAME_NTH(2), 1, 0),                 /* [4] */
6604                        /* another .bss section */                      /* [5] */
6605                        BTF_TYPE_ENC(NAME_NTH(1), BTF_INFO_ENC(BTF_KIND_DATASEC, 0, 1), 4),
6606                        BTF_VAR_SECINFO_ENC(4, 0, 4),
6607                        BTF_END_RAW,
6608                },
6609                BTF_STR_SEC("\0.bss\0t"),
6610        },
6611        .opts = {
6612                .dont_resolve_fwds = false,
6613                .dedup_table_size = 1
6614        },
6615},
6616
6617};
6618
6619static int btf_type_size(const struct btf_type *t)
6620{
6621        int base_size = sizeof(struct btf_type);
6622        __u16 vlen = BTF_INFO_VLEN(t->info);
6623        __u16 kind = BTF_INFO_KIND(t->info);
6624
6625        switch (kind) {
6626        case BTF_KIND_FWD:
6627        case BTF_KIND_CONST:
6628        case BTF_KIND_VOLATILE:
6629        case BTF_KIND_RESTRICT:
6630        case BTF_KIND_PTR:
6631        case BTF_KIND_TYPEDEF:
6632        case BTF_KIND_FUNC:
6633                return base_size;
6634        case BTF_KIND_INT:
6635                return base_size + sizeof(__u32);
6636        case BTF_KIND_ENUM:
6637                return base_size + vlen * sizeof(struct btf_enum);
6638        case BTF_KIND_ARRAY:
6639                return base_size + sizeof(struct btf_array);
6640        case BTF_KIND_STRUCT:
6641        case BTF_KIND_UNION:
6642                return base_size + vlen * sizeof(struct btf_member);
6643        case BTF_KIND_FUNC_PROTO:
6644                return base_size + vlen * sizeof(struct btf_param);
6645        case BTF_KIND_VAR:
6646                return base_size + sizeof(struct btf_var);
6647        case BTF_KIND_DATASEC:
6648                return base_size + vlen * sizeof(struct btf_var_secinfo);
6649        default:
6650                fprintf(stderr, "Unsupported BTF_KIND:%u\n", kind);
6651                return -EINVAL;
6652        }
6653}
6654
6655static void dump_btf_strings(const char *strs, __u32 len)
6656{
6657        const char *cur = strs;
6658        int i = 0;
6659
6660        while (cur < strs + len) {
6661                fprintf(stderr, "string #%d: '%s'\n", i, cur);
6662                cur += strlen(cur) + 1;
6663                i++;
6664        }
6665}
6666
6667static void do_test_dedup(unsigned int test_num)
6668{
6669        const struct btf_dedup_test *test = &dedup_tests[test_num - 1];
6670        __u32 test_nr_types, expect_nr_types, test_btf_size, expect_btf_size;
6671        const struct btf_header *test_hdr, *expect_hdr;
6672        struct btf *test_btf = NULL, *expect_btf = NULL;
6673        const void *test_btf_data, *expect_btf_data;
6674        const char *ret_test_next_str, *ret_expect_next_str;
6675        const char *test_strs, *expect_strs;
6676        const char *test_str_cur;
6677        const char *expect_str_cur, *expect_str_end;
6678        unsigned int raw_btf_size;
6679        void *raw_btf;
6680        int err = 0, i;
6681
6682        if (!test__start_subtest(test->descr))
6683                return;
6684
6685        raw_btf = btf_raw_create(&hdr_tmpl, test->input.raw_types,
6686                                 test->input.str_sec, test->input.str_sec_size,
6687                                 &raw_btf_size, &ret_test_next_str);
6688        if (!raw_btf)
6689                return;
6690
6691        test_btf = btf__new((__u8 *)raw_btf, raw_btf_size);
6692        free(raw_btf);
6693        if (CHECK(IS_ERR(test_btf), "invalid test_btf errno:%ld",
6694                  PTR_ERR(test_btf))) {
6695                err = -1;
6696                goto done;
6697        }
6698
6699        raw_btf = btf_raw_create(&hdr_tmpl, test->expect.raw_types,
6700                                 test->expect.str_sec,
6701                                 test->expect.str_sec_size,
6702                                 &raw_btf_size, &ret_expect_next_str);
6703        if (!raw_btf)
6704                return;
6705        expect_btf = btf__new((__u8 *)raw_btf, raw_btf_size);
6706        free(raw_btf);
6707        if (CHECK(IS_ERR(expect_btf), "invalid expect_btf errno:%ld",
6708                  PTR_ERR(expect_btf))) {
6709                err = -1;
6710                goto done;
6711        }
6712
6713        err = btf__dedup(test_btf, NULL, &test->opts);
6714        if (CHECK(err, "btf_dedup failed errno:%d", err)) {
6715                err = -1;
6716                goto done;
6717        }
6718
6719        test_btf_data = btf__get_raw_data(test_btf, &test_btf_size);
6720        expect_btf_data = btf__get_raw_data(expect_btf, &expect_btf_size);
6721        if (CHECK(test_btf_size != expect_btf_size,
6722                  "test_btf_size:%u != expect_btf_size:%u",
6723                  test_btf_size, expect_btf_size)) {
6724                err = -1;
6725                goto done;
6726        }
6727
6728        test_hdr = test_btf_data;
6729        test_strs = test_btf_data + sizeof(*test_hdr) + test_hdr->str_off;
6730        expect_hdr = expect_btf_data;
6731        expect_strs = expect_btf_data + sizeof(*test_hdr) + expect_hdr->str_off;
6732        if (CHECK(test_hdr->str_len != expect_hdr->str_len,
6733                  "test_hdr->str_len:%u != expect_hdr->str_len:%u",
6734                  test_hdr->str_len, expect_hdr->str_len)) {
6735                fprintf(stderr, "\ntest strings:\n");
6736                dump_btf_strings(test_strs, test_hdr->str_len);
6737                fprintf(stderr, "\nexpected strings:\n");
6738                dump_btf_strings(expect_strs, expect_hdr->str_len);
6739                err = -1;
6740                goto done;
6741        }
6742
6743        expect_str_cur = expect_strs;
6744        expect_str_end = expect_strs + expect_hdr->str_len;
6745        while (expect_str_cur < expect_str_end) {
6746                size_t test_len, expect_len;
6747                int off;
6748
6749                off = btf__find_str(test_btf, expect_str_cur);
6750                if (CHECK(off < 0, "exp str '%s' not found: %d\n", expect_str_cur, off)) {
6751                        err = -1;
6752                        goto done;
6753                }
6754                test_str_cur = btf__str_by_offset(test_btf, off);
6755
6756                test_len = strlen(test_str_cur);
6757                expect_len = strlen(expect_str_cur);
6758                if (CHECK(test_len != expect_len,
6759                          "test_len:%zu != expect_len:%zu "
6760                          "(test_str:%s, expect_str:%s)",
6761                          test_len, expect_len, test_str_cur, expect_str_cur)) {
6762                        err = -1;
6763                        goto done;
6764                }
6765                if (CHECK(strcmp(test_str_cur, expect_str_cur),
6766                          "test_str:%s != expect_str:%s",
6767                          test_str_cur, expect_str_cur)) {
6768                        err = -1;
6769                        goto done;
6770                }
6771                expect_str_cur += expect_len + 1;
6772        }
6773
6774        test_nr_types = btf__get_nr_types(test_btf);
6775        expect_nr_types = btf__get_nr_types(expect_btf);
6776        if (CHECK(test_nr_types != expect_nr_types,
6777                  "test_nr_types:%u != expect_nr_types:%u",
6778                  test_nr_types, expect_nr_types)) {
6779                err = -1;
6780                goto done;
6781        }
6782
6783        for (i = 1; i <= test_nr_types; i++) {
6784                const struct btf_type *test_type, *expect_type;
6785                int test_size, expect_size;
6786
6787                test_type = btf__type_by_id(test_btf, i);
6788                expect_type = btf__type_by_id(expect_btf, i);
6789                test_size = btf_type_size(test_type);
6790                expect_size = btf_type_size(expect_type);
6791
6792                if (CHECK(test_size != expect_size,
6793                          "type #%d: test_size:%d != expect_size:%u",
6794                          i, test_size, expect_size)) {
6795                        err = -1;
6796                        goto done;
6797                }
6798                if (CHECK(btf_kind(test_type) != btf_kind(expect_type),
6799                          "type %d kind: exp %d != got %u\n",
6800                          i, btf_kind(expect_type), btf_kind(test_type))) {
6801                        err = -1;
6802                        goto done;
6803                }
6804                if (CHECK(test_type->info != expect_type->info,
6805                          "type %d info: exp %d != got %u\n",
6806                          i, expect_type->info, test_type->info)) {
6807                        err = -1;
6808                        goto done;
6809                }
6810                if (CHECK(test_type->size != expect_type->size,
6811                          "type %d size/type: exp %d != got %u\n",
6812                          i, expect_type->size, test_type->size)) {
6813                        err = -1;
6814                        goto done;
6815                }
6816        }
6817
6818done:
6819        if (!IS_ERR(test_btf))
6820                btf__free(test_btf);
6821        if (!IS_ERR(expect_btf))
6822                btf__free(expect_btf);
6823}
6824
6825void test_btf(void)
6826{
6827        int i;
6828
6829        always_log = env.verbosity > VERBOSE_NONE;
6830
6831        for (i = 1; i <= ARRAY_SIZE(raw_tests); i++)
6832                do_test_raw(i);
6833        for (i = 1; i <= ARRAY_SIZE(get_info_tests); i++)
6834                do_test_get_info(i);
6835        for (i = 1; i <= ARRAY_SIZE(file_tests); i++)
6836                do_test_file(i);
6837        for (i = 1; i <= ARRAY_SIZE(info_raw_tests); i++)
6838                do_test_info_raw(i);
6839        for (i = 1; i <= ARRAY_SIZE(dedup_tests); i++)
6840                do_test_dedup(i);
6841        test_pprint();
6842}
6843