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