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