Linux Audio

Check our new training course

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