Linux Audio

Check our new training course

Yocto / OpenEmbedded training

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