xref: /linux/tools/testing/selftests/bpf/prog_tests/btf.c (revision 9094a158e842323b4487e32e88f01bd45a16af66)
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 <libelf.h>
12 #include <gelf.h>
13 #include <string.h>
14 #include <stdlib.h>
15 #include <stdio.h>
16 #include <stdarg.h>
17 #include <unistd.h>
18 #include <fcntl.h>
19 #include <errno.h>
20 #include <assert.h>
21 #include <bpf/libbpf.h>
22 #include <bpf/btf.h>
23 
24 #include "bpf_util.h"
25 #include "../test_btf.h"
26 #include "test_progs.h"
27 
28 #define MAX_INSNS	512
29 #define MAX_SUBPROGS	16
30 
31 static int duration = 0;
32 static bool always_log;
33 
34 #undef CHECK
35 #define CHECK(condition, format...) _CHECK(condition, "check", duration, format)
36 
37 #define NAME_TBD 0xdeadb33f
38 
39 #define NAME_NTH(N) (0xfffe0000 | N)
40 #define IS_NAME_NTH(X) ((X & 0xffff0000) == 0xfffe0000)
41 #define GET_NAME_NTH_IDX(X) (X & 0x0000ffff)
42 
43 #define MAX_NR_RAW_U32 1024
44 #define BTF_LOG_BUF_SIZE 65535
45 
46 static char btf_log_buf[BTF_LOG_BUF_SIZE];
47 
48 static struct btf_header hdr_tmpl = {
49 	.magic = BTF_MAGIC,
50 	.version = BTF_VERSION,
51 	.hdr_len = sizeof(struct btf_header),
52 };
53 
54 /* several different mapv kinds(types) supported by pprint */
55 enum pprint_mapv_kind_t {
56 	PPRINT_MAPV_KIND_BASIC = 0,
57 	PPRINT_MAPV_KIND_INT128,
58 };
59 
60 struct btf_raw_test {
61 	const char *descr;
62 	const char *str_sec;
63 	const char *map_name;
64 	const char *err_str;
65 	__u32 raw_types[MAX_NR_RAW_U32];
66 	__u32 str_sec_size;
67 	enum bpf_map_type map_type;
68 	__u32 key_size;
69 	__u32 value_size;
70 	__u32 key_type_id;
71 	__u32 value_type_id;
72 	__u32 max_entries;
73 	bool btf_load_err;
74 	bool map_create_err;
75 	bool ordered_map;
76 	bool lossless_map;
77 	bool percpu_map;
78 	int hdr_len_delta;
79 	int type_off_delta;
80 	int str_off_delta;
81 	int str_len_delta;
82 	enum pprint_mapv_kind_t mapv_kind;
83 };
84 
85 #define BTF_STR_SEC(str) \
86 	.str_sec = str, .str_sec_size = sizeof(str)
87 
88 static struct btf_raw_test raw_tests[] = {
89 /* enum E {
90  *     E0,
91  *     E1,
92  * };
93  *
94  * struct A {
95  *	unsigned long long m;
96  *	int n;
97  *	char o;
98  *	[3 bytes hole]
99  *	int p[8];
100  *	int q[4][8];
101  *	enum E r;
102  * };
103  */
104 {
105 	.descr = "struct test #1",
106 	.raw_types = {
107 		/* int */
108 		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),	/* [1] */
109 		/* unsigned long long */
110 		BTF_TYPE_INT_ENC(0, 0, 0, 64, 8),		/* [2] */
111 		/* char */
112 		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 8, 1),	/* [3] */
113 		/* int[8] */
114 		BTF_TYPE_ARRAY_ENC(1, 1, 8),			/* [4] */
115 		/* struct A { */				/* [5] */
116 		BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 6), 180),
117 		BTF_MEMBER_ENC(NAME_TBD, 2, 0),	/* unsigned long long m;*/
118 		BTF_MEMBER_ENC(NAME_TBD, 1, 64),/* int n;		*/
119 		BTF_MEMBER_ENC(NAME_TBD, 3, 96),/* char o;		*/
120 		BTF_MEMBER_ENC(NAME_TBD, 4, 128),/* int p[8]		*/
121 		BTF_MEMBER_ENC(NAME_TBD, 6, 384),/* int q[4][8]		*/
122 		BTF_MEMBER_ENC(NAME_TBD, 7, 1408), /* enum E r		*/
123 		/* } */
124 		/* int[4][8] */
125 		BTF_TYPE_ARRAY_ENC(4, 1, 4),			/* [6] */
126 		/* enum E */					/* [7] */
127 		BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_ENUM, 0, 2), sizeof(int)),
128 		BTF_ENUM_ENC(NAME_TBD, 0),
129 		BTF_ENUM_ENC(NAME_TBD, 1),
130 		BTF_END_RAW,
131 	},
132 	.str_sec = "\0A\0m\0n\0o\0p\0q\0r\0E\0E0\0E1",
133 	.str_sec_size = sizeof("\0A\0m\0n\0o\0p\0q\0r\0E\0E0\0E1"),
134 	.map_type = BPF_MAP_TYPE_ARRAY,
135 	.map_name = "struct_test1_map",
136 	.key_size = sizeof(int),
137 	.value_size = 180,
138 	.key_type_id = 1,
139 	.value_type_id = 5,
140 	.max_entries = 4,
141 },
142 
143 /* typedef struct b Struct_B;
144  *
145  * struct A {
146  *     int m;
147  *     struct b n[4];
148  *     const Struct_B o[4];
149  * };
150  *
151  * struct B {
152  *     int m;
153  *     int n;
154  * };
155  */
156 {
157 	.descr = "struct test #2",
158 	.raw_types = {
159 		/* int */					/* [1] */
160 		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
161 		/* struct b [4] */				/* [2] */
162 		BTF_TYPE_ARRAY_ENC(4, 1, 4),
163 
164 		/* struct A { */				/* [3] */
165 		BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 3), 68),
166 		BTF_MEMBER_ENC(NAME_TBD, 1, 0),	/* int m;		*/
167 		BTF_MEMBER_ENC(NAME_TBD, 2, 32),/* struct B n[4]	*/
168 		BTF_MEMBER_ENC(NAME_TBD, 8, 288),/* const Struct_B o[4];*/
169 		/* } */
170 
171 		/* struct B { */				/* [4] */
172 		BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 2), 8),
173 		BTF_MEMBER_ENC(NAME_TBD, 1, 0),	/* int m; */
174 		BTF_MEMBER_ENC(NAME_TBD, 1, 32),/* int n; */
175 		/* } */
176 
177 		/* const int */					/* [5] */
178 		BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_CONST, 0, 0), 1),
179 		/* typedef struct b Struct_B */	/* [6] */
180 		BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_TYPEDEF, 0, 0), 4),
181 		/* const Struct_B */				/* [7] */
182 		BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_CONST, 0, 0), 6),
183 		/* const Struct_B [4] */			/* [8] */
184 		BTF_TYPE_ARRAY_ENC(7, 1, 4),
185 		BTF_END_RAW,
186 	},
187 	.str_sec = "\0A\0m\0n\0o\0B\0m\0n\0Struct_B",
188 	.str_sec_size = sizeof("\0A\0m\0n\0o\0B\0m\0n\0Struct_B"),
189 	.map_type = BPF_MAP_TYPE_ARRAY,
190 	.map_name = "struct_test2_map",
191 	.key_size = sizeof(int),
192 	.value_size = 68,
193 	.key_type_id = 1,
194 	.value_type_id = 3,
195 	.max_entries = 4,
196 },
197 {
198 	.descr = "struct test #3 Invalid member offset",
199 	.raw_types = {
200 		/* int */					/* [1] */
201 		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
202 		/* int64 */					/* [2] */
203 		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 64, 8),
204 
205 		/* struct A { */				/* [3] */
206 		BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 2), 16),
207 		BTF_MEMBER_ENC(NAME_TBD, 1, 64),	/* int m;		*/
208 		BTF_MEMBER_ENC(NAME_TBD, 2, 0),		/* int64 n; */
209 		/* } */
210 		BTF_END_RAW,
211 	},
212 	.str_sec = "\0A\0m\0n\0",
213 	.str_sec_size = sizeof("\0A\0m\0n\0"),
214 	.map_type = BPF_MAP_TYPE_ARRAY,
215 	.map_name = "struct_test3_map",
216 	.key_size = sizeof(int),
217 	.value_size = 16,
218 	.key_type_id = 1,
219 	.value_type_id = 3,
220 	.max_entries = 4,
221 	.btf_load_err = true,
222 	.err_str = "Invalid member bits_offset",
223 },
224 /*
225  * struct A {
226  *	unsigned long long m;
227  *	int n;
228  *	char o;
229  *	[3 bytes hole]
230  *	int p[8];
231  * };
232  */
233 {
234 	.descr = "global data test #1",
235 	.raw_types = {
236 		/* int */
237 		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),	/* [1] */
238 		/* unsigned long long */
239 		BTF_TYPE_INT_ENC(0, 0, 0, 64, 8),		/* [2] */
240 		/* char */
241 		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 8, 1),	/* [3] */
242 		/* int[8] */
243 		BTF_TYPE_ARRAY_ENC(1, 1, 8),			/* [4] */
244 		/* struct A { */				/* [5] */
245 		BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 4), 48),
246 		BTF_MEMBER_ENC(NAME_TBD, 2, 0),	/* unsigned long long m;*/
247 		BTF_MEMBER_ENC(NAME_TBD, 1, 64),/* int n;		*/
248 		BTF_MEMBER_ENC(NAME_TBD, 3, 96),/* char o;		*/
249 		BTF_MEMBER_ENC(NAME_TBD, 4, 128),/* int p[8]		*/
250 		/* } */
251 		BTF_END_RAW,
252 	},
253 	.str_sec = "\0A\0m\0n\0o\0p",
254 	.str_sec_size = sizeof("\0A\0m\0n\0o\0p"),
255 	.map_type = BPF_MAP_TYPE_ARRAY,
256 	.map_name = "struct_test1_map",
257 	.key_size = sizeof(int),
258 	.value_size = 48,
259 	.key_type_id = 1,
260 	.value_type_id = 5,
261 	.max_entries = 4,
262 },
263 /*
264  * struct A {
265  *	unsigned long long m;
266  *	int n;
267  *	char o;
268  *	[3 bytes hole]
269  *	int p[8];
270  * };
271  * static struct A t; <- in .bss
272  */
273 {
274 	.descr = "global data test #2",
275 	.raw_types = {
276 		/* int */
277 		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),	/* [1] */
278 		/* unsigned long long */
279 		BTF_TYPE_INT_ENC(0, 0, 0, 64, 8),		/* [2] */
280 		/* char */
281 		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 8, 1),	/* [3] */
282 		/* int[8] */
283 		BTF_TYPE_ARRAY_ENC(1, 1, 8),			/* [4] */
284 		/* struct A { */				/* [5] */
285 		BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 4), 48),
286 		BTF_MEMBER_ENC(NAME_TBD, 2, 0),	/* unsigned long long m;*/
287 		BTF_MEMBER_ENC(NAME_TBD, 1, 64),/* int n;		*/
288 		BTF_MEMBER_ENC(NAME_TBD, 3, 96),/* char o;		*/
289 		BTF_MEMBER_ENC(NAME_TBD, 4, 128),/* int p[8]		*/
290 		/* } */
291 		/* static struct A t */
292 		BTF_VAR_ENC(NAME_TBD, 5, 0),			/* [6] */
293 		/* .bss section */				/* [7] */
294 		BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_DATASEC, 0, 1), 48),
295 		BTF_VAR_SECINFO_ENC(6, 0, 48),
296 		BTF_END_RAW,
297 	},
298 	.str_sec = "\0A\0m\0n\0o\0p\0t\0.bss",
299 	.str_sec_size = sizeof("\0A\0m\0n\0o\0p\0t\0.bss"),
300 	.map_type = BPF_MAP_TYPE_ARRAY,
301 	.map_name = ".bss",
302 	.key_size = sizeof(int),
303 	.value_size = 48,
304 	.key_type_id = 0,
305 	.value_type_id = 7,
306 	.max_entries = 1,
307 },
308 {
309 	.descr = "global data test #3",
310 	.raw_types = {
311 		/* int */
312 		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),	/* [1] */
313 		/* static int t */
314 		BTF_VAR_ENC(NAME_TBD, 1, 0),			/* [2] */
315 		/* .bss section */				/* [3] */
316 		BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_DATASEC, 0, 1), 4),
317 		BTF_VAR_SECINFO_ENC(2, 0, 4),
318 		BTF_END_RAW,
319 	},
320 	.str_sec = "\0t\0.bss",
321 	.str_sec_size = sizeof("\0t\0.bss"),
322 	.map_type = BPF_MAP_TYPE_ARRAY,
323 	.map_name = ".bss",
324 	.key_size = sizeof(int),
325 	.value_size = 4,
326 	.key_type_id = 0,
327 	.value_type_id = 3,
328 	.max_entries = 1,
329 },
330 {
331 	.descr = "global data test #4, unsupported linkage",
332 	.raw_types = {
333 		/* int */
334 		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),	/* [1] */
335 		/* static int t */
336 		BTF_VAR_ENC(NAME_TBD, 1, 2),			/* [2] */
337 		/* .bss section */				/* [3] */
338 		BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_DATASEC, 0, 1), 4),
339 		BTF_VAR_SECINFO_ENC(2, 0, 4),
340 		BTF_END_RAW,
341 	},
342 	.str_sec = "\0t\0.bss",
343 	.str_sec_size = sizeof("\0t\0.bss"),
344 	.map_type = BPF_MAP_TYPE_ARRAY,
345 	.map_name = ".bss",
346 	.key_size = sizeof(int),
347 	.value_size = 4,
348 	.key_type_id = 0,
349 	.value_type_id = 3,
350 	.max_entries = 1,
351 	.btf_load_err = true,
352 	.err_str = "Linkage not supported",
353 },
354 {
355 	.descr = "global data test #5, invalid var type",
356 	.raw_types = {
357 		/* static void t */
358 		BTF_VAR_ENC(NAME_TBD, 0, 0),			/* [1] */
359 		/* .bss section */				/* [2] */
360 		BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_DATASEC, 0, 1), 4),
361 		BTF_VAR_SECINFO_ENC(1, 0, 4),
362 		BTF_END_RAW,
363 	},
364 	.str_sec = "\0t\0.bss",
365 	.str_sec_size = sizeof("\0t\0.bss"),
366 	.map_type = BPF_MAP_TYPE_ARRAY,
367 	.map_name = ".bss",
368 	.key_size = sizeof(int),
369 	.value_size = 4,
370 	.key_type_id = 0,
371 	.value_type_id = 2,
372 	.max_entries = 1,
373 	.btf_load_err = true,
374 	.err_str = "Invalid type_id",
375 },
376 {
377 	.descr = "global data test #6, invalid var type (fwd type)",
378 	.raw_types = {
379 		/* union A */
380 		BTF_TYPE_ENC(NAME_TBD,
381 			     BTF_INFO_ENC(BTF_KIND_FWD, 1, 0), 0), /* [1] */
382 		/* static union A t */
383 		BTF_VAR_ENC(NAME_TBD, 1, 0),			/* [2] */
384 		/* .bss section */				/* [3] */
385 		BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_DATASEC, 0, 1), 4),
386 		BTF_VAR_SECINFO_ENC(2, 0, 4),
387 		BTF_END_RAW,
388 	},
389 	.str_sec = "\0A\0t\0.bss",
390 	.str_sec_size = sizeof("\0A\0t\0.bss"),
391 	.map_type = BPF_MAP_TYPE_ARRAY,
392 	.map_name = ".bss",
393 	.key_size = sizeof(int),
394 	.value_size = 4,
395 	.key_type_id = 0,
396 	.value_type_id = 2,
397 	.max_entries = 1,
398 	.btf_load_err = true,
399 	.err_str = "Invalid type",
400 },
401 {
402 	.descr = "global data test #7, invalid var type (fwd type)",
403 	.raw_types = {
404 		/* union A */
405 		BTF_TYPE_ENC(NAME_TBD,
406 			     BTF_INFO_ENC(BTF_KIND_FWD, 1, 0), 0), /* [1] */
407 		/* static union A t */
408 		BTF_VAR_ENC(NAME_TBD, 1, 0),			/* [2] */
409 		/* .bss section */				/* [3] */
410 		BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_DATASEC, 0, 1), 4),
411 		BTF_VAR_SECINFO_ENC(1, 0, 4),
412 		BTF_END_RAW,
413 	},
414 	.str_sec = "\0A\0t\0.bss",
415 	.str_sec_size = sizeof("\0A\0t\0.bss"),
416 	.map_type = BPF_MAP_TYPE_ARRAY,
417 	.map_name = ".bss",
418 	.key_size = sizeof(int),
419 	.value_size = 4,
420 	.key_type_id = 0,
421 	.value_type_id = 2,
422 	.max_entries = 1,
423 	.btf_load_err = true,
424 	.err_str = "Invalid type",
425 },
426 {
427 	.descr = "global data test #8, var is smaller than its type",
428 	.raw_types = {
429 		/* int */
430 		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),	/* [1] */
431 		/* unsigned long long */
432 		BTF_TYPE_INT_ENC(0, 0, 0, 64, 8),		/* [2] */
433 		/* char */
434 		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 8, 1),	/* [3] */
435 		/* int[8] */
436 		BTF_TYPE_ARRAY_ENC(1, 1, 8),			/* [4] */
437 		/* struct A { */				/* [5] */
438 		BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 4), 48),
439 		BTF_MEMBER_ENC(NAME_TBD, 2, 0),	/* unsigned long long m;*/
440 		BTF_MEMBER_ENC(NAME_TBD, 1, 64),/* int n;		*/
441 		BTF_MEMBER_ENC(NAME_TBD, 3, 96),/* char o;		*/
442 		BTF_MEMBER_ENC(NAME_TBD, 4, 128),/* int p[8]		*/
443 		/* } */
444 		/* static struct A t */
445 		BTF_VAR_ENC(NAME_TBD, 5, 0),			/* [6] */
446 		/* .bss section */				/* [7] */
447 		BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_DATASEC, 0, 1), 48),
448 		BTF_VAR_SECINFO_ENC(6, 0, 47),
449 		BTF_END_RAW,
450 	},
451 	.str_sec = "\0A\0m\0n\0o\0p\0t\0.bss",
452 	.str_sec_size = sizeof("\0A\0m\0n\0o\0p\0t\0.bss"),
453 	.map_type = BPF_MAP_TYPE_ARRAY,
454 	.map_name = ".bss",
455 	.key_size = sizeof(int),
456 	.value_size = 48,
457 	.key_type_id = 0,
458 	.value_type_id = 7,
459 	.max_entries = 1,
460 },
461 {
462 	.descr = "global data test #9, invalid var size",
463 	.raw_types = {
464 		/* int */
465 		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),	/* [1] */
466 		/* unsigned long long */
467 		BTF_TYPE_INT_ENC(0, 0, 0, 64, 8),		/* [2] */
468 		/* char */
469 		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 8, 1),	/* [3] */
470 		/* int[8] */
471 		BTF_TYPE_ARRAY_ENC(1, 1, 8),			/* [4] */
472 		/* struct A { */				/* [5] */
473 		BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 4), 48),
474 		BTF_MEMBER_ENC(NAME_TBD, 2, 0),	/* unsigned long long m;*/
475 		BTF_MEMBER_ENC(NAME_TBD, 1, 64),/* int n;		*/
476 		BTF_MEMBER_ENC(NAME_TBD, 3, 96),/* char o;		*/
477 		BTF_MEMBER_ENC(NAME_TBD, 4, 128),/* int p[8]		*/
478 		/* } */
479 		/* static struct A t */
480 		BTF_VAR_ENC(NAME_TBD, 5, 0),			/* [6] */
481 		/* .bss section */				/* [7] */
482 		BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_DATASEC, 0, 1), 46),
483 		BTF_VAR_SECINFO_ENC(6, 0, 48),
484 		BTF_END_RAW,
485 	},
486 	.str_sec = "\0A\0m\0n\0o\0p\0t\0.bss",
487 	.str_sec_size = sizeof("\0A\0m\0n\0o\0p\0t\0.bss"),
488 	.map_type = BPF_MAP_TYPE_ARRAY,
489 	.map_name = ".bss",
490 	.key_size = sizeof(int),
491 	.value_size = 48,
492 	.key_type_id = 0,
493 	.value_type_id = 7,
494 	.max_entries = 1,
495 	.btf_load_err = true,
496 	.err_str = "Invalid size",
497 },
498 {
499 	.descr = "global data test #10, section is smaller than map value",
500 	.raw_types = {
501 		/* int */
502 		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),	/* [1] */
503 		/* unsigned long long */
504 		BTF_TYPE_INT_ENC(0, 0, 0, 64, 8),		/* [2] */
505 		/* char */
506 		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 8, 1),	/* [3] */
507 		/* int[8] */
508 		BTF_TYPE_ARRAY_ENC(1, 1, 8),			/* [4] */
509 		/* struct A { */				/* [5] */
510 		BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 4), 48),
511 		BTF_MEMBER_ENC(NAME_TBD, 2, 0),	/* unsigned long long m;*/
512 		BTF_MEMBER_ENC(NAME_TBD, 1, 64),/* int n;		*/
513 		BTF_MEMBER_ENC(NAME_TBD, 3, 96),/* char o;		*/
514 		BTF_MEMBER_ENC(NAME_TBD, 4, 128),/* int p[8]		*/
515 		/* } */
516 		/* static struct A t */
517 		BTF_VAR_ENC(NAME_TBD, 5, 0),			/* [6] */
518 		/* .bss section */				/* [7] */
519 		BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_DATASEC, 0, 1), 46),
520 		BTF_VAR_SECINFO_ENC(6, 0, 46),
521 		BTF_END_RAW,
522 	},
523 	.str_sec = "\0A\0m\0n\0o\0p\0t\0.bss",
524 	.str_sec_size = sizeof("\0A\0m\0n\0o\0p\0t\0.bss"),
525 	.map_type = BPF_MAP_TYPE_ARRAY,
526 	.map_name = ".bss",
527 	.key_size = sizeof(int),
528 	.value_size = 48,
529 	.key_type_id = 0,
530 	.value_type_id = 7,
531 	.max_entries = 1,
532 	.map_create_err = true,
533 },
534 {
535 	.descr = "global data test #11, multiple section members",
536 	.raw_types = {
537 		/* int */
538 		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),	/* [1] */
539 		/* unsigned long long */
540 		BTF_TYPE_INT_ENC(0, 0, 0, 64, 8),		/* [2] */
541 		/* char */
542 		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 8, 1),	/* [3] */
543 		/* int[8] */
544 		BTF_TYPE_ARRAY_ENC(1, 1, 8),			/* [4] */
545 		/* struct A { */				/* [5] */
546 		BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 4), 48),
547 		BTF_MEMBER_ENC(NAME_TBD, 2, 0),	/* unsigned long long m;*/
548 		BTF_MEMBER_ENC(NAME_TBD, 1, 64),/* int n;		*/
549 		BTF_MEMBER_ENC(NAME_TBD, 3, 96),/* char o;		*/
550 		BTF_MEMBER_ENC(NAME_TBD, 4, 128),/* int p[8]		*/
551 		/* } */
552 		/* static struct A t */
553 		BTF_VAR_ENC(NAME_TBD, 5, 0),			/* [6] */
554 		/* static int u */
555 		BTF_VAR_ENC(NAME_TBD, 1, 0),			/* [7] */
556 		/* .bss section */				/* [8] */
557 		BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_DATASEC, 0, 2), 62),
558 		BTF_VAR_SECINFO_ENC(6, 10, 48),
559 		BTF_VAR_SECINFO_ENC(7, 58, 4),
560 		BTF_END_RAW,
561 	},
562 	.str_sec = "\0A\0m\0n\0o\0p\0t\0u\0.bss",
563 	.str_sec_size = sizeof("\0A\0m\0n\0o\0p\0t\0u\0.bss"),
564 	.map_type = BPF_MAP_TYPE_ARRAY,
565 	.map_name = ".bss",
566 	.key_size = sizeof(int),
567 	.value_size = 62,
568 	.key_type_id = 0,
569 	.value_type_id = 8,
570 	.max_entries = 1,
571 },
572 {
573 	.descr = "global data test #12, invalid offset",
574 	.raw_types = {
575 		/* int */
576 		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),	/* [1] */
577 		/* unsigned long long */
578 		BTF_TYPE_INT_ENC(0, 0, 0, 64, 8),		/* [2] */
579 		/* char */
580 		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 8, 1),	/* [3] */
581 		/* int[8] */
582 		BTF_TYPE_ARRAY_ENC(1, 1, 8),			/* [4] */
583 		/* struct A { */				/* [5] */
584 		BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 4), 48),
585 		BTF_MEMBER_ENC(NAME_TBD, 2, 0),	/* unsigned long long m;*/
586 		BTF_MEMBER_ENC(NAME_TBD, 1, 64),/* int n;		*/
587 		BTF_MEMBER_ENC(NAME_TBD, 3, 96),/* char o;		*/
588 		BTF_MEMBER_ENC(NAME_TBD, 4, 128),/* int p[8]		*/
589 		/* } */
590 		/* static struct A t */
591 		BTF_VAR_ENC(NAME_TBD, 5, 0),			/* [6] */
592 		/* static int u */
593 		BTF_VAR_ENC(NAME_TBD, 1, 0),			/* [7] */
594 		/* .bss section */				/* [8] */
595 		BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_DATASEC, 0, 2), 62),
596 		BTF_VAR_SECINFO_ENC(6, 10, 48),
597 		BTF_VAR_SECINFO_ENC(7, 60, 4),
598 		BTF_END_RAW,
599 	},
600 	.str_sec = "\0A\0m\0n\0o\0p\0t\0u\0.bss",
601 	.str_sec_size = sizeof("\0A\0m\0n\0o\0p\0t\0u\0.bss"),
602 	.map_type = BPF_MAP_TYPE_ARRAY,
603 	.map_name = ".bss",
604 	.key_size = sizeof(int),
605 	.value_size = 62,
606 	.key_type_id = 0,
607 	.value_type_id = 8,
608 	.max_entries = 1,
609 	.btf_load_err = true,
610 	.err_str = "Invalid offset+size",
611 },
612 {
613 	.descr = "global data test #13, invalid offset",
614 	.raw_types = {
615 		/* int */
616 		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),	/* [1] */
617 		/* unsigned long long */
618 		BTF_TYPE_INT_ENC(0, 0, 0, 64, 8),		/* [2] */
619 		/* char */
620 		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 8, 1),	/* [3] */
621 		/* int[8] */
622 		BTF_TYPE_ARRAY_ENC(1, 1, 8),			/* [4] */
623 		/* struct A { */				/* [5] */
624 		BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 4), 48),
625 		BTF_MEMBER_ENC(NAME_TBD, 2, 0),	/* unsigned long long m;*/
626 		BTF_MEMBER_ENC(NAME_TBD, 1, 64),/* int n;		*/
627 		BTF_MEMBER_ENC(NAME_TBD, 3, 96),/* char o;		*/
628 		BTF_MEMBER_ENC(NAME_TBD, 4, 128),/* int p[8]		*/
629 		/* } */
630 		/* static struct A t */
631 		BTF_VAR_ENC(NAME_TBD, 5, 0),			/* [6] */
632 		/* static int u */
633 		BTF_VAR_ENC(NAME_TBD, 1, 0),			/* [7] */
634 		/* .bss section */				/* [8] */
635 		BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_DATASEC, 0, 2), 62),
636 		BTF_VAR_SECINFO_ENC(6, 10, 48),
637 		BTF_VAR_SECINFO_ENC(7, 12, 4),
638 		BTF_END_RAW,
639 	},
640 	.str_sec = "\0A\0m\0n\0o\0p\0t\0u\0.bss",
641 	.str_sec_size = sizeof("\0A\0m\0n\0o\0p\0t\0u\0.bss"),
642 	.map_type = BPF_MAP_TYPE_ARRAY,
643 	.map_name = ".bss",
644 	.key_size = sizeof(int),
645 	.value_size = 62,
646 	.key_type_id = 0,
647 	.value_type_id = 8,
648 	.max_entries = 1,
649 	.btf_load_err = true,
650 	.err_str = "Invalid offset",
651 },
652 {
653 	.descr = "global data test #14, invalid offset",
654 	.raw_types = {
655 		/* int */
656 		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),	/* [1] */
657 		/* unsigned long long */
658 		BTF_TYPE_INT_ENC(0, 0, 0, 64, 8),		/* [2] */
659 		/* char */
660 		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 8, 1),	/* [3] */
661 		/* int[8] */
662 		BTF_TYPE_ARRAY_ENC(1, 1, 8),			/* [4] */
663 		/* struct A { */				/* [5] */
664 		BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 4), 48),
665 		BTF_MEMBER_ENC(NAME_TBD, 2, 0),	/* unsigned long long m;*/
666 		BTF_MEMBER_ENC(NAME_TBD, 1, 64),/* int n;		*/
667 		BTF_MEMBER_ENC(NAME_TBD, 3, 96),/* char o;		*/
668 		BTF_MEMBER_ENC(NAME_TBD, 4, 128),/* int p[8]		*/
669 		/* } */
670 		/* static struct A t */
671 		BTF_VAR_ENC(NAME_TBD, 5, 0),			/* [6] */
672 		/* static int u */
673 		BTF_VAR_ENC(NAME_TBD, 1, 0),			/* [7] */
674 		/* .bss section */				/* [8] */
675 		BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_DATASEC, 0, 2), 62),
676 		BTF_VAR_SECINFO_ENC(7, 58, 4),
677 		BTF_VAR_SECINFO_ENC(6, 10, 48),
678 		BTF_END_RAW,
679 	},
680 	.str_sec = "\0A\0m\0n\0o\0p\0t\0u\0.bss",
681 	.str_sec_size = sizeof("\0A\0m\0n\0o\0p\0t\0u\0.bss"),
682 	.map_type = BPF_MAP_TYPE_ARRAY,
683 	.map_name = ".bss",
684 	.key_size = sizeof(int),
685 	.value_size = 62,
686 	.key_type_id = 0,
687 	.value_type_id = 8,
688 	.max_entries = 1,
689 	.btf_load_err = true,
690 	.err_str = "Invalid offset",
691 },
692 {
693 	.descr = "global data test #15, not var kind",
694 	.raw_types = {
695 		/* int */
696 		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),	/* [1] */
697 		BTF_VAR_ENC(NAME_TBD, 1, 0),			/* [2] */
698 		/* .bss section */				/* [3] */
699 		BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_DATASEC, 0, 1), 4),
700 		BTF_VAR_SECINFO_ENC(1, 0, 4),
701 		BTF_END_RAW,
702 	},
703 	.str_sec = "\0A\0t\0.bss",
704 	.str_sec_size = sizeof("\0A\0t\0.bss"),
705 	.map_type = BPF_MAP_TYPE_ARRAY,
706 	.map_name = ".bss",
707 	.key_size = sizeof(int),
708 	.value_size = 4,
709 	.key_type_id = 0,
710 	.value_type_id = 3,
711 	.max_entries = 1,
712 	.btf_load_err = true,
713 	.err_str = "Not a VAR kind member",
714 },
715 {
716 	.descr = "global data test #16, invalid var referencing sec",
717 	.raw_types = {
718 		/* int */
719 		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),	/* [1] */
720 		BTF_VAR_ENC(NAME_TBD, 5, 0),			/* [2] */
721 		BTF_VAR_ENC(NAME_TBD, 2, 0),			/* [3] */
722 		/* a section */					/* [4] */
723 		BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_DATASEC, 0, 1), 4),
724 		BTF_VAR_SECINFO_ENC(3, 0, 4),
725 		/* a section */					/* [5] */
726 		BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_DATASEC, 0, 1), 4),
727 		BTF_VAR_SECINFO_ENC(6, 0, 4),
728 		BTF_VAR_ENC(NAME_TBD, 1, 0),			/* [6] */
729 		BTF_END_RAW,
730 	},
731 	.str_sec = "\0A\0t\0s\0a\0a",
732 	.str_sec_size = sizeof("\0A\0t\0s\0a\0a"),
733 	.map_type = BPF_MAP_TYPE_ARRAY,
734 	.map_name = ".bss",
735 	.key_size = sizeof(int),
736 	.value_size = 4,
737 	.key_type_id = 0,
738 	.value_type_id = 4,
739 	.max_entries = 1,
740 	.btf_load_err = true,
741 	.err_str = "Invalid type_id",
742 },
743 {
744 	.descr = "global data test #17, invalid var referencing var",
745 	.raw_types = {
746 		/* int */
747 		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),	/* [1] */
748 		BTF_VAR_ENC(NAME_TBD, 1, 0),			/* [2] */
749 		BTF_VAR_ENC(NAME_TBD, 2, 0),			/* [3] */
750 		/* a section */					/* [4] */
751 		BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_DATASEC, 0, 1), 4),
752 		BTF_VAR_SECINFO_ENC(3, 0, 4),
753 		BTF_END_RAW,
754 	},
755 	.str_sec = "\0A\0t\0s\0a\0a",
756 	.str_sec_size = sizeof("\0A\0t\0s\0a\0a"),
757 	.map_type = BPF_MAP_TYPE_ARRAY,
758 	.map_name = ".bss",
759 	.key_size = sizeof(int),
760 	.value_size = 4,
761 	.key_type_id = 0,
762 	.value_type_id = 4,
763 	.max_entries = 1,
764 	.btf_load_err = true,
765 	.err_str = "Invalid type_id",
766 },
767 {
768 	.descr = "global data test #18, invalid var loop",
769 	.raw_types = {
770 		/* int */
771 		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),	/* [1] */
772 		BTF_VAR_ENC(NAME_TBD, 2, 0),			/* [2] */
773 		/* .bss section */				/* [3] */
774 		BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_DATASEC, 0, 1), 4),
775 		BTF_VAR_SECINFO_ENC(2, 0, 4),
776 		BTF_END_RAW,
777 	},
778 	.str_sec = "\0A\0t\0aaa",
779 	.str_sec_size = sizeof("\0A\0t\0aaa"),
780 	.map_type = BPF_MAP_TYPE_ARRAY,
781 	.map_name = ".bss",
782 	.key_size = sizeof(int),
783 	.value_size = 4,
784 	.key_type_id = 0,
785 	.value_type_id = 4,
786 	.max_entries = 1,
787 	.btf_load_err = true,
788 	.err_str = "Invalid type_id",
789 },
790 {
791 	.descr = "global data test #19, invalid var referencing var",
792 	.raw_types = {
793 		/* int */
794 		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),	/* [1] */
795 		BTF_VAR_ENC(NAME_TBD, 3, 0),			/* [2] */
796 		BTF_VAR_ENC(NAME_TBD, 1, 0),			/* [3] */
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 #20, invalid ptr referencing var",
813 	.raw_types = {
814 		/* int */
815 		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),	/* [1] */
816 		/* PTR type_id=3	*/			/* [2] */
817 		BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_PTR, 0, 0), 3),
818 		BTF_VAR_ENC(NAME_TBD, 1, 0),			/* [3] */
819 		BTF_END_RAW,
820 	},
821 	.str_sec = "\0A\0t\0s\0a\0a",
822 	.str_sec_size = sizeof("\0A\0t\0s\0a\0a"),
823 	.map_type = BPF_MAP_TYPE_ARRAY,
824 	.map_name = ".bss",
825 	.key_size = sizeof(int),
826 	.value_size = 4,
827 	.key_type_id = 0,
828 	.value_type_id = 4,
829 	.max_entries = 1,
830 	.btf_load_err = true,
831 	.err_str = "Invalid type_id",
832 },
833 {
834 	.descr = "global data test #21, var included in struct",
835 	.raw_types = {
836 		/* int */
837 		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),	/* [1] */
838 		/* struct A { */				/* [2] */
839 		BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 2), sizeof(int) * 2),
840 		BTF_MEMBER_ENC(NAME_TBD, 1, 0),	/* int m; */
841 		BTF_MEMBER_ENC(NAME_TBD, 3, 32),/* VAR type_id=3; */
842 		/* } */
843 		BTF_VAR_ENC(NAME_TBD, 1, 0),			/* [3] */
844 		BTF_END_RAW,
845 	},
846 	.str_sec = "\0A\0t\0s\0a\0a",
847 	.str_sec_size = sizeof("\0A\0t\0s\0a\0a"),
848 	.map_type = BPF_MAP_TYPE_ARRAY,
849 	.map_name = ".bss",
850 	.key_size = sizeof(int),
851 	.value_size = 4,
852 	.key_type_id = 0,
853 	.value_type_id = 4,
854 	.max_entries = 1,
855 	.btf_load_err = true,
856 	.err_str = "Invalid member",
857 },
858 {
859 	.descr = "global data test #22, array of var",
860 	.raw_types = {
861 		/* int */
862 		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),	/* [1] */
863 		BTF_TYPE_ARRAY_ENC(3, 1, 4),			/* [2] */
864 		BTF_VAR_ENC(NAME_TBD, 1, 0),			/* [3] */
865 		BTF_END_RAW,
866 	},
867 	.str_sec = "\0A\0t\0s\0a\0a",
868 	.str_sec_size = sizeof("\0A\0t\0s\0a\0a"),
869 	.map_type = BPF_MAP_TYPE_ARRAY,
870 	.map_name = ".bss",
871 	.key_size = sizeof(int),
872 	.value_size = 4,
873 	.key_type_id = 0,
874 	.value_type_id = 4,
875 	.max_entries = 1,
876 	.btf_load_err = true,
877 	.err_str = "Invalid elem",
878 },
879 {
880 	.descr = "var after datasec, ptr followed by modifier",
881 	.raw_types = {
882 		/* .bss section */				/* [1] */
883 		BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_DATASEC, 0, 2),
884 			sizeof(void*)+4),
885 		BTF_VAR_SECINFO_ENC(4, 0, sizeof(void*)),
886 		BTF_VAR_SECINFO_ENC(6, sizeof(void*), 4),
887 		/* int */					/* [2] */
888 		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
889 		/* int* */					/* [3] */
890 		BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_PTR, 0, 0), 2),
891 		BTF_VAR_ENC(NAME_TBD, 3, 0),			/* [4] */
892 		/* const int */					/* [5] */
893 		BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_CONST, 0, 0), 2),
894 		BTF_VAR_ENC(NAME_TBD, 5, 0),			/* [6] */
895 		BTF_END_RAW,
896 	},
897 	.str_sec = "\0a\0b\0c\0",
898 	.str_sec_size = sizeof("\0a\0b\0c\0"),
899 	.map_type = BPF_MAP_TYPE_ARRAY,
900 	.map_name = ".bss",
901 	.key_size = sizeof(int),
902 	.value_size = sizeof(void*)+4,
903 	.key_type_id = 0,
904 	.value_type_id = 1,
905 	.max_entries = 1,
906 },
907 /* Test member exceeds the size of struct.
908  *
909  * struct A {
910  *     int m;
911  *     int n;
912  * };
913  */
914 {
915 	.descr = "size check test #1",
916 	.raw_types = {
917 		/* int */					/* [1] */
918 		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
919 		/* struct A { */				/* [2] */
920 		BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 2), sizeof(int) * 2 -  1),
921 		BTF_MEMBER_ENC(NAME_TBD, 1, 0),	/* int m; */
922 		BTF_MEMBER_ENC(NAME_TBD, 1, 32),/* int n; */
923 		/* } */
924 		BTF_END_RAW,
925 	},
926 	.str_sec = "\0A\0m\0n",
927 	.str_sec_size = sizeof("\0A\0m\0n"),
928 	.map_type = BPF_MAP_TYPE_ARRAY,
929 	.map_name = "size_check1_map",
930 	.key_size = sizeof(int),
931 	.value_size = 1,
932 	.key_type_id = 1,
933 	.value_type_id = 2,
934 	.max_entries = 4,
935 	.btf_load_err = true,
936 	.err_str = "Member exceeds struct_size",
937 },
938 
939 /* Test member exceeds the size of struct
940  *
941  * struct A {
942  *     int m;
943  *     int n[2];
944  * };
945  */
946 {
947 	.descr = "size check test #2",
948 	.raw_types = {
949 		/* int */					/* [1] */
950 		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, sizeof(int)),
951 		/* int[2] */					/* [2] */
952 		BTF_TYPE_ARRAY_ENC(1, 1, 2),
953 		/* struct A { */				/* [3] */
954 		BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 2), sizeof(int) * 3 - 1),
955 		BTF_MEMBER_ENC(NAME_TBD, 1, 0),	/* int m; */
956 		BTF_MEMBER_ENC(NAME_TBD, 2, 32),/* int n[2]; */
957 		/* } */
958 		BTF_END_RAW,
959 	},
960 	.str_sec = "\0A\0m\0n",
961 	.str_sec_size = sizeof("\0A\0m\0n"),
962 	.map_type = BPF_MAP_TYPE_ARRAY,
963 	.map_name = "size_check2_map",
964 	.key_size = sizeof(int),
965 	.value_size = 1,
966 	.key_type_id = 1,
967 	.value_type_id = 3,
968 	.max_entries = 4,
969 	.btf_load_err = true,
970 	.err_str = "Member exceeds struct_size",
971 },
972 
973 /* Test member exceeds the size of struct
974  *
975  * struct A {
976  *     int m;
977  *     void *n;
978  * };
979  */
980 {
981 	.descr = "size check test #3",
982 	.raw_types = {
983 		/* int */					/* [1] */
984 		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, sizeof(int)),
985 		/* void* */					/* [2] */
986 		BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_PTR, 0, 0), 0),
987 		/* struct A { */				/* [3] */
988 		BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 2), sizeof(int) + sizeof(void *) - 1),
989 		BTF_MEMBER_ENC(NAME_TBD, 1, 0),	/* int m; */
990 		BTF_MEMBER_ENC(NAME_TBD, 2, 32),/* void *n; */
991 		/* } */
992 		BTF_END_RAW,
993 	},
994 	.str_sec = "\0A\0m\0n",
995 	.str_sec_size = sizeof("\0A\0m\0n"),
996 	.map_type = BPF_MAP_TYPE_ARRAY,
997 	.map_name = "size_check3_map",
998 	.key_size = sizeof(int),
999 	.value_size = 1,
1000 	.key_type_id = 1,
1001 	.value_type_id = 3,
1002 	.max_entries = 4,
1003 	.btf_load_err = true,
1004 	.err_str = "Member exceeds struct_size",
1005 },
1006 
1007 /* Test member exceeds the size of struct
1008  *
1009  * enum E {
1010  *     E0,
1011  *     E1,
1012  * };
1013  *
1014  * struct A {
1015  *     int m;
1016  *     enum E n;
1017  * };
1018  */
1019 {
1020 	.descr = "size check test #4",
1021 	.raw_types = {
1022 		/* int */			/* [1] */
1023 		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, sizeof(int)),
1024 		/* enum E { */			/* [2] */
1025 		BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_ENUM, 0, 2), sizeof(int)),
1026 		BTF_ENUM_ENC(NAME_TBD, 0),
1027 		BTF_ENUM_ENC(NAME_TBD, 1),
1028 		/* } */
1029 		/* struct A { */		/* [3] */
1030 		BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 2), sizeof(int) * 2 - 1),
1031 		BTF_MEMBER_ENC(NAME_TBD, 1, 0),	/* int m; */
1032 		BTF_MEMBER_ENC(NAME_TBD, 2, 32),/* enum E n; */
1033 		/* } */
1034 		BTF_END_RAW,
1035 	},
1036 	.str_sec = "\0E\0E0\0E1\0A\0m\0n",
1037 	.str_sec_size = sizeof("\0E\0E0\0E1\0A\0m\0n"),
1038 	.map_type = BPF_MAP_TYPE_ARRAY,
1039 	.map_name = "size_check4_map",
1040 	.key_size = sizeof(int),
1041 	.value_size = 1,
1042 	.key_type_id = 1,
1043 	.value_type_id = 3,
1044 	.max_entries = 4,
1045 	.btf_load_err = true,
1046 	.err_str = "Member exceeds struct_size",
1047 },
1048 
1049 /* Test member unexceeds the size of struct
1050  *
1051  * enum E {
1052  *     E0,
1053  *     E1,
1054  * };
1055  *
1056  * struct A {
1057  *     char m;
1058  *     enum E __attribute__((packed)) n;
1059  * };
1060  */
1061 {
1062 	.descr = "size check test #5",
1063 	.raw_types = {
1064 		/* int */			/* [1] */
1065 		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, sizeof(int)),
1066 		/* char */			/* [2] */
1067 		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 8, 1),
1068 		/* enum E { */			/* [3] */
1069 		BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_ENUM, 0, 2), 1),
1070 		BTF_ENUM_ENC(NAME_TBD, 0),
1071 		BTF_ENUM_ENC(NAME_TBD, 1),
1072 		/* } */
1073 		/* struct A { */		/* [4] */
1074 		BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 2), 2),
1075 		BTF_MEMBER_ENC(NAME_TBD, 2, 0),	/* char m; */
1076 		BTF_MEMBER_ENC(NAME_TBD, 3, 8),/* enum E __attribute__((packed)) n; */
1077 		/* } */
1078 		BTF_END_RAW,
1079 	},
1080 	.str_sec = "\0E\0E0\0E1\0A\0m\0n",
1081 	.str_sec_size = sizeof("\0E\0E0\0E1\0A\0m\0n"),
1082 	.map_type = BPF_MAP_TYPE_ARRAY,
1083 	.map_name = "size_check5_map",
1084 	.key_size = sizeof(int),
1085 	.value_size = 2,
1086 	.key_type_id = 1,
1087 	.value_type_id = 4,
1088 	.max_entries = 4,
1089 },
1090 
1091 /* typedef const void * const_void_ptr;
1092  * struct A {
1093  *	const_void_ptr m;
1094  * };
1095  */
1096 {
1097 	.descr = "void test #1",
1098 	.raw_types = {
1099 		/* int */		/* [1] */
1100 		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
1101 		/* const void */	/* [2] */
1102 		BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_CONST, 0, 0), 0),
1103 		/* const void* */	/* [3] */
1104 		BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_PTR, 0, 0), 2),
1105 		/* typedef const void * const_void_ptr */
1106 		BTF_TYPEDEF_ENC(NAME_TBD, 3),	/* [4] */
1107 		/* struct A { */	/* [5] */
1108 		BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 1), sizeof(void *)),
1109 		/* const_void_ptr m; */
1110 		BTF_MEMBER_ENC(NAME_TBD, 4, 0),
1111 		/* } */
1112 		BTF_END_RAW,
1113 	},
1114 	.str_sec = "\0const_void_ptr\0A\0m",
1115 	.str_sec_size = sizeof("\0const_void_ptr\0A\0m"),
1116 	.map_type = BPF_MAP_TYPE_ARRAY,
1117 	.map_name = "void_test1_map",
1118 	.key_size = sizeof(int),
1119 	.value_size = sizeof(void *),
1120 	.key_type_id = 1,
1121 	.value_type_id = 4,
1122 	.max_entries = 4,
1123 },
1124 
1125 /* struct A {
1126  *     const void m;
1127  * };
1128  */
1129 {
1130 	.descr = "void test #2",
1131 	.raw_types = {
1132 		/* int */		/* [1] */
1133 		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
1134 		/* const void */	/* [2] */
1135 		BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_CONST, 0, 0), 0),
1136 		/* struct A { */	/* [3] */
1137 		BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 1), 8),
1138 		/* const void m; */
1139 		BTF_MEMBER_ENC(NAME_TBD, 2, 0),
1140 		/* } */
1141 		BTF_END_RAW,
1142 	},
1143 	.str_sec = "\0A\0m",
1144 	.str_sec_size = sizeof("\0A\0m"),
1145 	.map_type = BPF_MAP_TYPE_ARRAY,
1146 	.map_name = "void_test2_map",
1147 	.key_size = sizeof(int),
1148 	.value_size = sizeof(void *),
1149 	.key_type_id = 1,
1150 	.value_type_id = 3,
1151 	.max_entries = 4,
1152 	.btf_load_err = true,
1153 	.err_str = "Invalid member",
1154 },
1155 
1156 /* typedef const void * const_void_ptr;
1157  * const_void_ptr[4]
1158  */
1159 {
1160 	.descr = "void test #3",
1161 	.raw_types = {
1162 		/* int */		/* [1] */
1163 		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
1164 		/* const void */	/* [2] */
1165 		BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_CONST, 0, 0), 0),
1166 		/* const void* */	/* [3] */
1167 		BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_PTR, 0, 0), 2),
1168 		/* typedef const void * const_void_ptr */
1169 		BTF_TYPEDEF_ENC(NAME_TBD, 3),	/* [4] */
1170 		/* const_void_ptr[4] */
1171 		BTF_TYPE_ARRAY_ENC(4, 1, 4),	/* [5] */
1172 		BTF_END_RAW,
1173 	},
1174 	.str_sec = "\0const_void_ptr",
1175 	.str_sec_size = sizeof("\0const_void_ptr"),
1176 	.map_type = BPF_MAP_TYPE_ARRAY,
1177 	.map_name = "void_test3_map",
1178 	.key_size = sizeof(int),
1179 	.value_size = sizeof(void *) * 4,
1180 	.key_type_id = 1,
1181 	.value_type_id = 5,
1182 	.max_entries = 4,
1183 },
1184 
1185 /* const void[4]  */
1186 {
1187 	.descr = "void test #4",
1188 	.raw_types = {
1189 		/* int */		/* [1] */
1190 		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
1191 		/* const void */	/* [2] */
1192 		BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_CONST, 0, 0), 0),
1193 		/* const void[4] */	/* [3] */
1194 		BTF_TYPE_ARRAY_ENC(2, 1, 4),
1195 		BTF_END_RAW,
1196 	},
1197 	.str_sec = "\0A\0m",
1198 	.str_sec_size = sizeof("\0A\0m"),
1199 	.map_type = BPF_MAP_TYPE_ARRAY,
1200 	.map_name = "void_test4_map",
1201 	.key_size = sizeof(int),
1202 	.value_size = sizeof(void *) * 4,
1203 	.key_type_id = 1,
1204 	.value_type_id = 3,
1205 	.max_entries = 4,
1206 	.btf_load_err = true,
1207 	.err_str = "Invalid elem",
1208 },
1209 
1210 /* Array_A  <------------------+
1211  *     elem_type == Array_B    |
1212  *                    |        |
1213  *                    |        |
1214  * Array_B  <-------- +        |
1215  *      elem_type == Array A --+
1216  */
1217 {
1218 	.descr = "loop test #1",
1219 	.raw_types = {
1220 		/* int */			/* [1] */
1221 		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
1222 		/* Array_A */			/* [2] */
1223 		BTF_TYPE_ARRAY_ENC(3, 1, 8),
1224 		/* Array_B */			/* [3] */
1225 		BTF_TYPE_ARRAY_ENC(2, 1, 8),
1226 		BTF_END_RAW,
1227 	},
1228 	.str_sec = "",
1229 	.str_sec_size = sizeof(""),
1230 	.map_type = BPF_MAP_TYPE_ARRAY,
1231 	.map_name = "loop_test1_map",
1232 	.key_size = sizeof(int),
1233 	.value_size = sizeof(sizeof(int) * 8),
1234 	.key_type_id = 1,
1235 	.value_type_id = 2,
1236 	.max_entries = 4,
1237 	.btf_load_err = true,
1238 	.err_str = "Loop detected",
1239 },
1240 
1241 /* typedef is _before_ the BTF type of Array_A and Array_B
1242  *
1243  * typedef Array_B int_array;
1244  *
1245  * Array_A  <------------------+
1246  *     elem_type == int_array  |
1247  *                    |        |
1248  *                    |        |
1249  * Array_B  <-------- +        |
1250  *      elem_type == Array_A --+
1251  */
1252 {
1253 	.descr = "loop test #2",
1254 	.raw_types = {
1255 		/* int */
1256 		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),	/* [1] */
1257 		/* typedef Array_B int_array */
1258 		BTF_TYPEDEF_ENC(1, 4),				/* [2] */
1259 		/* Array_A */
1260 		BTF_TYPE_ARRAY_ENC(2, 1, 8),			/* [3] */
1261 		/* Array_B */
1262 		BTF_TYPE_ARRAY_ENC(3, 1, 8),			/* [4] */
1263 		BTF_END_RAW,
1264 	},
1265 	.str_sec = "\0int_array\0",
1266 	.str_sec_size = sizeof("\0int_array"),
1267 	.map_type = BPF_MAP_TYPE_ARRAY,
1268 	.map_name = "loop_test2_map",
1269 	.key_size = sizeof(int),
1270 	.value_size = sizeof(sizeof(int) * 8),
1271 	.key_type_id = 1,
1272 	.value_type_id = 2,
1273 	.max_entries = 4,
1274 	.btf_load_err = true,
1275 	.err_str = "Loop detected",
1276 },
1277 
1278 /* Array_A  <------------------+
1279  *     elem_type == Array_B    |
1280  *                    |        |
1281  *                    |        |
1282  * Array_B  <-------- +        |
1283  *      elem_type == Array_A --+
1284  */
1285 {
1286 	.descr = "loop test #3",
1287 	.raw_types = {
1288 		/* int */				/* [1] */
1289 		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
1290 		/* Array_A */				/* [2] */
1291 		BTF_TYPE_ARRAY_ENC(3, 1, 8),
1292 		/* Array_B */				/* [3] */
1293 		BTF_TYPE_ARRAY_ENC(2, 1, 8),
1294 		BTF_END_RAW,
1295 	},
1296 	.str_sec = "",
1297 	.str_sec_size = sizeof(""),
1298 	.map_type = BPF_MAP_TYPE_ARRAY,
1299 	.map_name = "loop_test3_map",
1300 	.key_size = sizeof(int),
1301 	.value_size = sizeof(sizeof(int) * 8),
1302 	.key_type_id = 1,
1303 	.value_type_id = 2,
1304 	.max_entries = 4,
1305 	.btf_load_err = true,
1306 	.err_str = "Loop detected",
1307 },
1308 
1309 /* typedef is _between_ the BTF type of Array_A and Array_B
1310  *
1311  * typedef Array_B int_array;
1312  *
1313  * Array_A  <------------------+
1314  *     elem_type == int_array  |
1315  *                    |        |
1316  *                    |        |
1317  * Array_B  <-------- +        |
1318  *      elem_type == Array_A --+
1319  */
1320 {
1321 	.descr = "loop test #4",
1322 	.raw_types = {
1323 		/* int */				/* [1] */
1324 		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
1325 		/* Array_A */				/* [2] */
1326 		BTF_TYPE_ARRAY_ENC(3, 1, 8),
1327 		/* typedef Array_B int_array */		/* [3] */
1328 		BTF_TYPEDEF_ENC(NAME_TBD, 4),
1329 		/* Array_B */				/* [4] */
1330 		BTF_TYPE_ARRAY_ENC(2, 1, 8),
1331 		BTF_END_RAW,
1332 	},
1333 	.str_sec = "\0int_array\0",
1334 	.str_sec_size = sizeof("\0int_array"),
1335 	.map_type = BPF_MAP_TYPE_ARRAY,
1336 	.map_name = "loop_test4_map",
1337 	.key_size = sizeof(int),
1338 	.value_size = sizeof(sizeof(int) * 8),
1339 	.key_type_id = 1,
1340 	.value_type_id = 2,
1341 	.max_entries = 4,
1342 	.btf_load_err = true,
1343 	.err_str = "Loop detected",
1344 },
1345 
1346 /* typedef struct B Struct_B
1347  *
1348  * struct A {
1349  *     int x;
1350  *     Struct_B y;
1351  * };
1352  *
1353  * struct B {
1354  *     int x;
1355  *     struct A y;
1356  * };
1357  */
1358 {
1359 	.descr = "loop test #5",
1360 	.raw_types = {
1361 		/* int */
1362 		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),	/* [1] */
1363 		/* struct A */					/* [2] */
1364 		BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 2), 8),
1365 		BTF_MEMBER_ENC(NAME_TBD, 1, 0),	/* int x;	*/
1366 		BTF_MEMBER_ENC(NAME_TBD, 3, 32),/* Struct_B y;	*/
1367 		/* typedef struct B Struct_B */
1368 		BTF_TYPEDEF_ENC(NAME_TBD, 4),			/* [3] */
1369 		/* struct B */					/* [4] */
1370 		BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 2), 8),
1371 		BTF_MEMBER_ENC(NAME_TBD, 1, 0),	/* int x;	*/
1372 		BTF_MEMBER_ENC(NAME_TBD, 2, 32),/* struct A y;	*/
1373 		BTF_END_RAW,
1374 	},
1375 	.str_sec = "\0A\0x\0y\0Struct_B\0B\0x\0y",
1376 	.str_sec_size = sizeof("\0A\0x\0y\0Struct_B\0B\0x\0y"),
1377 	.map_type = BPF_MAP_TYPE_ARRAY,
1378 	.map_name = "loop_test5_map",
1379 	.key_size = sizeof(int),
1380 	.value_size = 8,
1381 	.key_type_id = 1,
1382 	.value_type_id = 2,
1383 	.max_entries = 4,
1384 	.btf_load_err = true,
1385 	.err_str = "Loop detected",
1386 },
1387 
1388 /* struct A {
1389  *     int x;
1390  *     struct A array_a[4];
1391  * };
1392  */
1393 {
1394 	.descr = "loop test #6",
1395 	.raw_types = {
1396 		/* int */
1397 		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),	/* [1] */
1398 		BTF_TYPE_ARRAY_ENC(3, 1, 4),			/* [2] */
1399 		/* struct A */					/* [3] */
1400 		BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 2), 8),
1401 		BTF_MEMBER_ENC(NAME_TBD, 1, 0),	/* int x;		*/
1402 		BTF_MEMBER_ENC(NAME_TBD, 2, 32),/* struct A array_a[4];	*/
1403 		BTF_END_RAW,
1404 	},
1405 	.str_sec = "\0A\0x\0y",
1406 	.str_sec_size = sizeof("\0A\0x\0y"),
1407 	.map_type = BPF_MAP_TYPE_ARRAY,
1408 	.map_name = "loop_test6_map",
1409 	.key_size = sizeof(int),
1410 	.value_size = 8,
1411 	.key_type_id = 1,
1412 	.value_type_id = 2,
1413 	.max_entries = 4,
1414 	.btf_load_err = true,
1415 	.err_str = "Loop detected",
1416 },
1417 
1418 {
1419 	.descr = "loop test #7",
1420 	.raw_types = {
1421 		/* int */				/* [1] */
1422 		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
1423 		/* struct A { */			/* [2] */
1424 		BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 1), sizeof(void *)),
1425 		/*     const void *m;	*/
1426 		BTF_MEMBER_ENC(NAME_TBD, 3, 0),
1427 		/* CONST type_id=3	*/		/* [3] */
1428 		BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_CONST, 0, 0), 4),
1429 		/* PTR type_id=2	*/		/* [4] */
1430 		BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_PTR, 0, 0), 3),
1431 		BTF_END_RAW,
1432 	},
1433 	.str_sec = "\0A\0m",
1434 	.str_sec_size = sizeof("\0A\0m"),
1435 	.map_type = BPF_MAP_TYPE_ARRAY,
1436 	.map_name = "loop_test7_map",
1437 	.key_size = sizeof(int),
1438 	.value_size = sizeof(void *),
1439 	.key_type_id = 1,
1440 	.value_type_id = 2,
1441 	.max_entries = 4,
1442 	.btf_load_err = true,
1443 	.err_str = "Loop detected",
1444 },
1445 
1446 {
1447 	.descr = "loop test #8",
1448 	.raw_types = {
1449 		/* int */				/* [1] */
1450 		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
1451 		/* struct A { */			/* [2] */
1452 		BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 1), sizeof(void *)),
1453 		/*     const void *m;	*/
1454 		BTF_MEMBER_ENC(NAME_TBD, 4, 0),
1455 		/* struct B { */			/* [3] */
1456 		BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 1), sizeof(void *)),
1457 		/*     const void *n;	*/
1458 		BTF_MEMBER_ENC(NAME_TBD, 6, 0),
1459 		/* CONST type_id=5	*/		/* [4] */
1460 		BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_CONST, 0, 0), 5),
1461 		/* PTR type_id=6	*/		/* [5] */
1462 		BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_PTR, 0, 0), 6),
1463 		/* CONST type_id=7	*/		/* [6] */
1464 		BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_CONST, 0, 0), 7),
1465 		/* PTR type_id=4	*/		/* [7] */
1466 		BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_PTR, 0, 0), 4),
1467 		BTF_END_RAW,
1468 	},
1469 	.str_sec = "\0A\0m\0B\0n",
1470 	.str_sec_size = sizeof("\0A\0m\0B\0n"),
1471 	.map_type = BPF_MAP_TYPE_ARRAY,
1472 	.map_name = "loop_test8_map",
1473 	.key_size = sizeof(int),
1474 	.value_size = sizeof(void *),
1475 	.key_type_id = 1,
1476 	.value_type_id = 2,
1477 	.max_entries = 4,
1478 	.btf_load_err = true,
1479 	.err_str = "Loop detected",
1480 },
1481 
1482 {
1483 	.descr = "string section does not end with null",
1484 	.raw_types = {
1485 		/* int */				/* [1] */
1486 		BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),
1487 		BTF_END_RAW,
1488 	},
1489 	.str_sec = "\0int",
1490 	.str_sec_size = sizeof("\0int") - 1,
1491 	.map_type = BPF_MAP_TYPE_ARRAY,
1492 	.map_name = "hdr_test_map",
1493 	.key_size = sizeof(int),
1494 	.value_size = sizeof(int),
1495 	.key_type_id = 1,
1496 	.value_type_id = 1,
1497 	.max_entries = 4,
1498 	.btf_load_err = true,
1499 	.err_str = "Invalid string section",
1500 },
1501 
1502 {
1503 	.descr = "empty string section",
1504 	.raw_types = {
1505 		/* int */				/* [1] */
1506 		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
1507 		BTF_END_RAW,
1508 	},
1509 	.str_sec = "",
1510 	.str_sec_size = 0,
1511 	.map_type = BPF_MAP_TYPE_ARRAY,
1512 	.map_name = "hdr_test_map",
1513 	.key_size = sizeof(int),
1514 	.value_size = sizeof(int),
1515 	.key_type_id = 1,
1516 	.value_type_id = 1,
1517 	.max_entries = 4,
1518 	.btf_load_err = true,
1519 	.err_str = "Invalid string section",
1520 },
1521 
1522 {
1523 	.descr = "empty type section",
1524 	.raw_types = {
1525 		BTF_END_RAW,
1526 	},
1527 	.str_sec = "\0int",
1528 	.str_sec_size = sizeof("\0int"),
1529 	.map_type = BPF_MAP_TYPE_ARRAY,
1530 	.map_name = "hdr_test_map",
1531 	.key_size = sizeof(int),
1532 	.value_size = sizeof(int),
1533 	.key_type_id = 1,
1534 	.value_type_id = 1,
1535 	.max_entries = 4,
1536 	.btf_load_err = true,
1537 	.err_str = "No type found",
1538 },
1539 
1540 {
1541 	.descr = "btf_header test. Longer hdr_len",
1542 	.raw_types = {
1543 		/* int */				/* [1] */
1544 		BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),
1545 		BTF_END_RAW,
1546 	},
1547 	.str_sec = "\0int",
1548 	.str_sec_size = sizeof("\0int"),
1549 	.map_type = BPF_MAP_TYPE_ARRAY,
1550 	.map_name = "hdr_test_map",
1551 	.key_size = sizeof(int),
1552 	.value_size = sizeof(int),
1553 	.key_type_id = 1,
1554 	.value_type_id = 1,
1555 	.max_entries = 4,
1556 	.btf_load_err = true,
1557 	.hdr_len_delta = 4,
1558 	.err_str = "Unsupported btf_header",
1559 },
1560 
1561 {
1562 	.descr = "btf_header test. Gap between hdr and type",
1563 	.raw_types = {
1564 		/* int */				/* [1] */
1565 		BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),
1566 		BTF_END_RAW,
1567 	},
1568 	.str_sec = "\0int",
1569 	.str_sec_size = sizeof("\0int"),
1570 	.map_type = BPF_MAP_TYPE_ARRAY,
1571 	.map_name = "hdr_test_map",
1572 	.key_size = sizeof(int),
1573 	.value_size = sizeof(int),
1574 	.key_type_id = 1,
1575 	.value_type_id = 1,
1576 	.max_entries = 4,
1577 	.btf_load_err = true,
1578 	.type_off_delta = 4,
1579 	.err_str = "Unsupported section found",
1580 },
1581 
1582 {
1583 	.descr = "btf_header test. Gap between type and str",
1584 	.raw_types = {
1585 		/* int */				/* [1] */
1586 		BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),
1587 		BTF_END_RAW,
1588 	},
1589 	.str_sec = "\0int",
1590 	.str_sec_size = sizeof("\0int"),
1591 	.map_type = BPF_MAP_TYPE_ARRAY,
1592 	.map_name = "hdr_test_map",
1593 	.key_size = sizeof(int),
1594 	.value_size = sizeof(int),
1595 	.key_type_id = 1,
1596 	.value_type_id = 1,
1597 	.max_entries = 4,
1598 	.btf_load_err = true,
1599 	.str_off_delta = 4,
1600 	.err_str = "Unsupported section found",
1601 },
1602 
1603 {
1604 	.descr = "btf_header test. Overlap between type and str",
1605 	.raw_types = {
1606 		/* int */				/* [1] */
1607 		BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),
1608 		BTF_END_RAW,
1609 	},
1610 	.str_sec = "\0int",
1611 	.str_sec_size = sizeof("\0int"),
1612 	.map_type = BPF_MAP_TYPE_ARRAY,
1613 	.map_name = "hdr_test_map",
1614 	.key_size = sizeof(int),
1615 	.value_size = sizeof(int),
1616 	.key_type_id = 1,
1617 	.value_type_id = 1,
1618 	.max_entries = 4,
1619 	.btf_load_err = true,
1620 	.str_off_delta = -4,
1621 	.err_str = "Section overlap found",
1622 },
1623 
1624 {
1625 	.descr = "btf_header test. Larger BTF size",
1626 	.raw_types = {
1627 		/* int */				/* [1] */
1628 		BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),
1629 		BTF_END_RAW,
1630 	},
1631 	.str_sec = "\0int",
1632 	.str_sec_size = sizeof("\0int"),
1633 	.map_type = BPF_MAP_TYPE_ARRAY,
1634 	.map_name = "hdr_test_map",
1635 	.key_size = sizeof(int),
1636 	.value_size = sizeof(int),
1637 	.key_type_id = 1,
1638 	.value_type_id = 1,
1639 	.max_entries = 4,
1640 	.btf_load_err = true,
1641 	.str_len_delta = -4,
1642 	.err_str = "Unsupported section found",
1643 },
1644 
1645 {
1646 	.descr = "btf_header test. Smaller BTF size",
1647 	.raw_types = {
1648 		/* int */				/* [1] */
1649 		BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),
1650 		BTF_END_RAW,
1651 	},
1652 	.str_sec = "\0int",
1653 	.str_sec_size = sizeof("\0int"),
1654 	.map_type = BPF_MAP_TYPE_ARRAY,
1655 	.map_name = "hdr_test_map",
1656 	.key_size = sizeof(int),
1657 	.value_size = sizeof(int),
1658 	.key_type_id = 1,
1659 	.value_type_id = 1,
1660 	.max_entries = 4,
1661 	.btf_load_err = true,
1662 	.str_len_delta = 4,
1663 	.err_str = "Total section length too long",
1664 },
1665 
1666 {
1667 	.descr = "array test. index_type/elem_type \"int\"",
1668 	.raw_types = {
1669 		/* int */				/* [1] */
1670 		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
1671 		/* int[16] */				/* [2] */
1672 		BTF_TYPE_ARRAY_ENC(1, 1, 16),
1673 		BTF_END_RAW,
1674 	},
1675 	.str_sec = "",
1676 	.str_sec_size = sizeof(""),
1677 	.map_type = BPF_MAP_TYPE_ARRAY,
1678 	.map_name = "array_test_map",
1679 	.key_size = sizeof(int),
1680 	.value_size = sizeof(int),
1681 	.key_type_id = 1,
1682 	.value_type_id = 1,
1683 	.max_entries = 4,
1684 },
1685 
1686 {
1687 	.descr = "array test. index_type/elem_type \"const int\"",
1688 	.raw_types = {
1689 		/* int */				/* [1] */
1690 		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
1691 		/* int[16] */				/* [2] */
1692 		BTF_TYPE_ARRAY_ENC(3, 3, 16),
1693 		/* CONST type_id=1 */			/* [3] */
1694 		BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_CONST, 0, 0), 1),
1695 		BTF_END_RAW,
1696 	},
1697 	.str_sec = "",
1698 	.str_sec_size = sizeof(""),
1699 	.map_type = BPF_MAP_TYPE_ARRAY,
1700 	.map_name = "array_test_map",
1701 	.key_size = sizeof(int),
1702 	.value_size = sizeof(int),
1703 	.key_type_id = 1,
1704 	.value_type_id = 1,
1705 	.max_entries = 4,
1706 },
1707 
1708 {
1709 	.descr = "array test. index_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(1, 4, 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 index",
1732 },
1733 
1734 {
1735 	.descr = "array test. elem_type \"const int:31\"",
1736 	.raw_types = {
1737 		/* int */				/* [1] */
1738 		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
1739 		/* int:31 */				/* [2] */
1740 		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 31, 4),
1741 		/* int[16] */				/* [3] */
1742 		BTF_TYPE_ARRAY_ENC(4, 1, 16),
1743 		/* CONST type_id=2 */			/* [4] */
1744 		BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_CONST, 0, 0), 2),
1745 		BTF_END_RAW,
1746 	},
1747 	.str_sec = "",
1748 	.str_sec_size = sizeof(""),
1749 	.map_type = BPF_MAP_TYPE_ARRAY,
1750 	.map_name = "array_test_map",
1751 	.key_size = sizeof(int),
1752 	.value_size = sizeof(int),
1753 	.key_type_id = 1,
1754 	.value_type_id = 1,
1755 	.max_entries = 4,
1756 	.btf_load_err = true,
1757 	.err_str = "Invalid array of int",
1758 },
1759 
1760 {
1761 	.descr = "array test. index_type \"void\"",
1762 	.raw_types = {
1763 		/* int */				/* [1] */
1764 		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
1765 		/* int[16] */				/* [2] */
1766 		BTF_TYPE_ARRAY_ENC(1, 0, 16),
1767 		BTF_END_RAW,
1768 	},
1769 	.str_sec = "",
1770 	.str_sec_size = sizeof(""),
1771 	.map_type = BPF_MAP_TYPE_ARRAY,
1772 	.map_name = "array_test_map",
1773 	.key_size = sizeof(int),
1774 	.value_size = sizeof(int),
1775 	.key_type_id = 1,
1776 	.value_type_id = 1,
1777 	.max_entries = 4,
1778 	.btf_load_err = true,
1779 	.err_str = "Invalid index",
1780 },
1781 
1782 {
1783 	.descr = "array test. index_type \"const void\"",
1784 	.raw_types = {
1785 		/* int */				/* [1] */
1786 		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
1787 		/* int[16] */				/* [2] */
1788 		BTF_TYPE_ARRAY_ENC(1, 3, 16),
1789 		/* CONST type_id=0 (void) */		/* [3] */
1790 		BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_CONST, 0, 0), 0),
1791 		BTF_END_RAW,
1792 	},
1793 	.str_sec = "",
1794 	.str_sec_size = sizeof(""),
1795 	.map_type = BPF_MAP_TYPE_ARRAY,
1796 	.map_name = "array_test_map",
1797 	.key_size = sizeof(int),
1798 	.value_size = sizeof(int),
1799 	.key_type_id = 1,
1800 	.value_type_id = 1,
1801 	.max_entries = 4,
1802 	.btf_load_err = true,
1803 	.err_str = "Invalid index",
1804 },
1805 
1806 {
1807 	.descr = "array test. elem_type \"const void\"",
1808 	.raw_types = {
1809 		/* int */				/* [1] */
1810 		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
1811 		/* int[16] */				/* [2] */
1812 		BTF_TYPE_ARRAY_ENC(3, 1, 16),
1813 		/* CONST type_id=0 (void) */		/* [3] */
1814 		BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_CONST, 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 	.btf_load_err = true,
1827 	.err_str = "Invalid elem",
1828 },
1829 
1830 {
1831 	.descr = "array test. elem_type \"const void *\"",
1832 	.raw_types = {
1833 		/* int */				/* [1] */
1834 		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
1835 		/* const void *[16] */			/* [2] */
1836 		BTF_TYPE_ARRAY_ENC(3, 1, 16),
1837 		/* CONST type_id=4 */			/* [3] */
1838 		BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_CONST, 0, 0), 4),
1839 		/* void* */				/* [4] */
1840 		BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_PTR, 0, 0), 0),
1841 		BTF_END_RAW,
1842 	},
1843 	.str_sec = "",
1844 	.str_sec_size = sizeof(""),
1845 	.map_type = BPF_MAP_TYPE_ARRAY,
1846 	.map_name = "array_test_map",
1847 	.key_size = sizeof(int),
1848 	.value_size = sizeof(int),
1849 	.key_type_id = 1,
1850 	.value_type_id = 1,
1851 	.max_entries = 4,
1852 },
1853 
1854 {
1855 	.descr = "array test. index_type \"const void *\"",
1856 	.raw_types = {
1857 		/* int */				/* [1] */
1858 		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
1859 		/* const void *[16] */			/* [2] */
1860 		BTF_TYPE_ARRAY_ENC(3, 3, 16),
1861 		/* CONST type_id=4 */			/* [3] */
1862 		BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_CONST, 0, 0), 4),
1863 		/* void* */				/* [4] */
1864 		BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_PTR, 0, 0), 0),
1865 		BTF_END_RAW,
1866 	},
1867 	.str_sec = "",
1868 	.str_sec_size = sizeof(""),
1869 	.map_type = BPF_MAP_TYPE_ARRAY,
1870 	.map_name = "array_test_map",
1871 	.key_size = sizeof(int),
1872 	.value_size = sizeof(int),
1873 	.key_type_id = 1,
1874 	.value_type_id = 1,
1875 	.max_entries = 4,
1876 	.btf_load_err = true,
1877 	.err_str = "Invalid index",
1878 },
1879 
1880 {
1881 	.descr = "array test. t->size != 0\"",
1882 	.raw_types = {
1883 		/* int */				/* [1] */
1884 		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
1885 		/* int[16] */				/* [2] */
1886 		BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_ARRAY, 0, 0), 1),
1887 		BTF_ARRAY_ENC(1, 1, 16),
1888 		BTF_END_RAW,
1889 	},
1890 	.str_sec = "",
1891 	.str_sec_size = sizeof(""),
1892 	.map_type = BPF_MAP_TYPE_ARRAY,
1893 	.map_name = "array_test_map",
1894 	.key_size = sizeof(int),
1895 	.value_size = sizeof(int),
1896 	.key_type_id = 1,
1897 	.value_type_id = 1,
1898 	.max_entries = 4,
1899 	.btf_load_err = true,
1900 	.err_str = "size != 0",
1901 },
1902 
1903 {
1904 	.descr = "int test. invalid int_data",
1905 	.raw_types = {
1906 		BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_INT, 0, 0), 4),
1907 		0x10000000,
1908 		BTF_END_RAW,
1909 	},
1910 	.str_sec = "",
1911 	.str_sec_size = sizeof(""),
1912 	.map_type = BPF_MAP_TYPE_ARRAY,
1913 	.map_name = "array_test_map",
1914 	.key_size = sizeof(int),
1915 	.value_size = sizeof(int),
1916 	.key_type_id = 1,
1917 	.value_type_id = 1,
1918 	.max_entries = 4,
1919 	.btf_load_err = true,
1920 	.err_str = "Invalid int_data",
1921 },
1922 
1923 {
1924 	.descr = "invalid BTF kind",
1925 	.raw_types = {
1926 		/* int */				/* [1] */
1927 		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
1928 		BTF_TYPE_ENC(0, 0x7f000000, 4),
1929 		BTF_END_RAW,
1930 	},
1931 	.str_sec = "",
1932 	.str_sec_size = sizeof(""),
1933 	.map_type = BPF_MAP_TYPE_ARRAY,
1934 	.map_name = "array_test_map",
1935 	.key_size = sizeof(int),
1936 	.value_size = sizeof(int),
1937 	.key_type_id = 1,
1938 	.value_type_id = 1,
1939 	.max_entries = 4,
1940 	.btf_load_err = true,
1941 	.err_str = "Invalid kind",
1942 },
1943 
1944 {
1945 	.descr = "fwd test. t->type != 0\"",
1946 	.raw_types = {
1947 		/* int */				/* [1] */
1948 		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
1949 		/* fwd type */				/* [2] */
1950 		BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_FWD, 0, 0), 1),
1951 		BTF_END_RAW,
1952 	},
1953 	.str_sec = "",
1954 	.str_sec_size = sizeof(""),
1955 	.map_type = BPF_MAP_TYPE_ARRAY,
1956 	.map_name = "fwd_test_map",
1957 	.key_size = sizeof(int),
1958 	.value_size = sizeof(int),
1959 	.key_type_id = 1,
1960 	.value_type_id = 1,
1961 	.max_entries = 4,
1962 	.btf_load_err = true,
1963 	.err_str = "type != 0",
1964 },
1965 
1966 {
1967 	.descr = "typedef (invalid name, name_off = 0)",
1968 	.raw_types = {
1969 		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),	/* [1] */
1970 		BTF_TYPEDEF_ENC(0, 1),				/* [2] */
1971 		BTF_END_RAW,
1972 	},
1973 	.str_sec = "\0__int",
1974 	.str_sec_size = sizeof("\0__int"),
1975 	.map_type = BPF_MAP_TYPE_ARRAY,
1976 	.map_name = "typedef_check_btf",
1977 	.key_size = sizeof(int),
1978 	.value_size = sizeof(int),
1979 	.key_type_id = 1,
1980 	.value_type_id = 1,
1981 	.max_entries = 4,
1982 	.btf_load_err = true,
1983 	.err_str = "Invalid name",
1984 },
1985 
1986 {
1987 	.descr = "typedef (invalid name, not printable)",
1988 	.raw_types = {
1989 		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),	/* [1] */
1990 		BTF_TYPEDEF_ENC(NAME_TBD, 1),			/* [2] */
1991 		BTF_END_RAW,
1992 	},
1993 	.str_sec = "\0__\7int",
1994 	.str_sec_size = sizeof("\0__\7int"),
1995 	.map_type = BPF_MAP_TYPE_ARRAY,
1996 	.map_name = "typedef_check_btf",
1997 	.key_size = sizeof(int),
1998 	.value_size = sizeof(int),
1999 	.key_type_id = 1,
2000 	.value_type_id = 1,
2001 	.max_entries = 4,
2002 	.btf_load_err = true,
2003 	.err_str = "Invalid name",
2004 },
2005 
2006 {
2007 	.descr = "ptr type (invalid name, name_off <> 0)",
2008 	.raw_types = {
2009 		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),		/* [1] */
2010 		BTF_TYPE_ENC(NAME_TBD,
2011 			     BTF_INFO_ENC(BTF_KIND_PTR, 0, 0), 1),	/* [2] */
2012 		BTF_END_RAW,
2013 	},
2014 	.str_sec = "\0__int",
2015 	.str_sec_size = sizeof("\0__int"),
2016 	.map_type = BPF_MAP_TYPE_ARRAY,
2017 	.map_name = "ptr_type_check_btf",
2018 	.key_size = sizeof(int),
2019 	.value_size = sizeof(int),
2020 	.key_type_id = 1,
2021 	.value_type_id = 1,
2022 	.max_entries = 4,
2023 	.btf_load_err = true,
2024 	.err_str = "Invalid name",
2025 },
2026 
2027 {
2028 	.descr = "volatile type (invalid name, name_off <> 0)",
2029 	.raw_types = {
2030 		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),		/* [1] */
2031 		BTF_TYPE_ENC(NAME_TBD,
2032 			     BTF_INFO_ENC(BTF_KIND_VOLATILE, 0, 0), 1),	/* [2] */
2033 		BTF_END_RAW,
2034 	},
2035 	.str_sec = "\0__int",
2036 	.str_sec_size = sizeof("\0__int"),
2037 	.map_type = BPF_MAP_TYPE_ARRAY,
2038 	.map_name = "volatile_type_check_btf",
2039 	.key_size = sizeof(int),
2040 	.value_size = sizeof(int),
2041 	.key_type_id = 1,
2042 	.value_type_id = 1,
2043 	.max_entries = 4,
2044 	.btf_load_err = true,
2045 	.err_str = "Invalid name",
2046 },
2047 
2048 {
2049 	.descr = "const type (invalid name, name_off <> 0)",
2050 	.raw_types = {
2051 		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),		/* [1] */
2052 		BTF_TYPE_ENC(NAME_TBD,
2053 			     BTF_INFO_ENC(BTF_KIND_CONST, 0, 0), 1),	/* [2] */
2054 		BTF_END_RAW,
2055 	},
2056 	.str_sec = "\0__int",
2057 	.str_sec_size = sizeof("\0__int"),
2058 	.map_type = BPF_MAP_TYPE_ARRAY,
2059 	.map_name = "const_type_check_btf",
2060 	.key_size = sizeof(int),
2061 	.value_size = sizeof(int),
2062 	.key_type_id = 1,
2063 	.value_type_id = 1,
2064 	.max_entries = 4,
2065 	.btf_load_err = true,
2066 	.err_str = "Invalid name",
2067 },
2068 
2069 {
2070 	.descr = "restrict type (invalid name, name_off <> 0)",
2071 	.raw_types = {
2072 		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),		/* [1] */
2073 		BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_PTR, 0, 0), 1),	/* [2] */
2074 		BTF_TYPE_ENC(NAME_TBD,
2075 			     BTF_INFO_ENC(BTF_KIND_RESTRICT, 0, 0), 2),	/* [3] */
2076 		BTF_END_RAW,
2077 	},
2078 	.str_sec = "\0__int",
2079 	.str_sec_size = sizeof("\0__int"),
2080 	.map_type = BPF_MAP_TYPE_ARRAY,
2081 	.map_name = "restrict_type_check_btf",
2082 	.key_size = sizeof(int),
2083 	.value_size = sizeof(int),
2084 	.key_type_id = 1,
2085 	.value_type_id = 1,
2086 	.max_entries = 4,
2087 	.btf_load_err = true,
2088 	.err_str = "Invalid name",
2089 },
2090 
2091 {
2092 	.descr = "fwd type (invalid name, name_off = 0)",
2093 	.raw_types = {
2094 		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),		/* [1] */
2095 		BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_FWD, 0, 0), 0),	/* [2] */
2096 		BTF_END_RAW,
2097 	},
2098 	.str_sec = "\0__skb",
2099 	.str_sec_size = sizeof("\0__skb"),
2100 	.map_type = BPF_MAP_TYPE_ARRAY,
2101 	.map_name = "fwd_type_check_btf",
2102 	.key_size = sizeof(int),
2103 	.value_size = sizeof(int),
2104 	.key_type_id = 1,
2105 	.value_type_id = 1,
2106 	.max_entries = 4,
2107 	.btf_load_err = true,
2108 	.err_str = "Invalid name",
2109 },
2110 
2111 {
2112 	.descr = "fwd type (invalid name, not printable)",
2113 	.raw_types = {
2114 		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),		/* [1] */
2115 		BTF_TYPE_ENC(NAME_TBD,
2116 			     BTF_INFO_ENC(BTF_KIND_FWD, 0, 0), 0),	/* [2] */
2117 		BTF_END_RAW,
2118 	},
2119 	.str_sec = "\0__\7skb",
2120 	.str_sec_size = sizeof("\0__\7skb"),
2121 	.map_type = BPF_MAP_TYPE_ARRAY,
2122 	.map_name = "fwd_type_check_btf",
2123 	.key_size = sizeof(int),
2124 	.value_size = sizeof(int),
2125 	.key_type_id = 1,
2126 	.value_type_id = 1,
2127 	.max_entries = 4,
2128 	.btf_load_err = true,
2129 	.err_str = "Invalid name",
2130 },
2131 
2132 {
2133 	.descr = "array type (invalid name, name_off <> 0)",
2134 	.raw_types = {
2135 		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),		/* [1] */
2136 		BTF_TYPE_ENC(NAME_TBD,
2137 			     BTF_INFO_ENC(BTF_KIND_ARRAY, 0, 0), 0),	/* [2] */
2138 		BTF_ARRAY_ENC(1, 1, 4),
2139 		BTF_END_RAW,
2140 	},
2141 	.str_sec = "\0__skb",
2142 	.str_sec_size = sizeof("\0__skb"),
2143 	.map_type = BPF_MAP_TYPE_ARRAY,
2144 	.map_name = "array_type_check_btf",
2145 	.key_size = sizeof(int),
2146 	.value_size = sizeof(int),
2147 	.key_type_id = 1,
2148 	.value_type_id = 1,
2149 	.max_entries = 4,
2150 	.btf_load_err = true,
2151 	.err_str = "Invalid name",
2152 },
2153 
2154 {
2155 	.descr = "struct type (name_off = 0)",
2156 	.raw_types = {
2157 		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),		/* [1] */
2158 		BTF_TYPE_ENC(0,
2159 			     BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 1), 4),	/* [2] */
2160 		BTF_MEMBER_ENC(NAME_TBD, 1, 0),
2161 		BTF_END_RAW,
2162 	},
2163 	.str_sec = "\0A",
2164 	.str_sec_size = sizeof("\0A"),
2165 	.map_type = BPF_MAP_TYPE_ARRAY,
2166 	.map_name = "struct_type_check_btf",
2167 	.key_size = sizeof(int),
2168 	.value_size = sizeof(int),
2169 	.key_type_id = 1,
2170 	.value_type_id = 1,
2171 	.max_entries = 4,
2172 },
2173 
2174 {
2175 	.descr = "struct type (invalid name, not printable)",
2176 	.raw_types = {
2177 		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),		/* [1] */
2178 		BTF_TYPE_ENC(NAME_TBD,
2179 			     BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 1), 4),	/* [2] */
2180 		BTF_MEMBER_ENC(NAME_TBD, 1, 0),
2181 		BTF_END_RAW,
2182 	},
2183 	.str_sec = "\0A\7\0B",
2184 	.str_sec_size = sizeof("\0A\7\0B"),
2185 	.map_type = BPF_MAP_TYPE_ARRAY,
2186 	.map_name = "struct_type_check_btf",
2187 	.key_size = sizeof(int),
2188 	.value_size = sizeof(int),
2189 	.key_type_id = 1,
2190 	.value_type_id = 1,
2191 	.max_entries = 4,
2192 	.btf_load_err = true,
2193 	.err_str = "Invalid name",
2194 },
2195 
2196 {
2197 	.descr = "struct member (name_off = 0)",
2198 	.raw_types = {
2199 		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),		/* [1] */
2200 		BTF_TYPE_ENC(0,
2201 			     BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 1), 4),	/* [2] */
2202 		BTF_MEMBER_ENC(NAME_TBD, 1, 0),
2203 		BTF_END_RAW,
2204 	},
2205 	.str_sec = "\0A",
2206 	.str_sec_size = sizeof("\0A"),
2207 	.map_type = BPF_MAP_TYPE_ARRAY,
2208 	.map_name = "struct_type_check_btf",
2209 	.key_size = sizeof(int),
2210 	.value_size = sizeof(int),
2211 	.key_type_id = 1,
2212 	.value_type_id = 1,
2213 	.max_entries = 4,
2214 },
2215 
2216 {
2217 	.descr = "struct member (invalid name, not printable)",
2218 	.raw_types = {
2219 		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),		/* [1] */
2220 		BTF_TYPE_ENC(NAME_TBD,
2221 			     BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 1), 4),	/* [2] */
2222 		BTF_MEMBER_ENC(NAME_TBD, 1, 0),
2223 		BTF_END_RAW,
2224 	},
2225 	.str_sec = "\0A\0B\7",
2226 	.str_sec_size = sizeof("\0A\0B\7"),
2227 	.map_type = BPF_MAP_TYPE_ARRAY,
2228 	.map_name = "struct_type_check_btf",
2229 	.key_size = sizeof(int),
2230 	.value_size = sizeof(int),
2231 	.key_type_id = 1,
2232 	.value_type_id = 1,
2233 	.max_entries = 4,
2234 	.btf_load_err = true,
2235 	.err_str = "Invalid name",
2236 },
2237 
2238 {
2239 	.descr = "enum type (name_off = 0)",
2240 	.raw_types = {
2241 		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),		/* [1] */
2242 		BTF_TYPE_ENC(0,
2243 			     BTF_INFO_ENC(BTF_KIND_ENUM, 0, 1),
2244 			     sizeof(int)),				/* [2] */
2245 		BTF_ENUM_ENC(NAME_TBD, 0),
2246 		BTF_END_RAW,
2247 	},
2248 	.str_sec = "\0A\0B",
2249 	.str_sec_size = sizeof("\0A\0B"),
2250 	.map_type = BPF_MAP_TYPE_ARRAY,
2251 	.map_name = "enum_type_check_btf",
2252 	.key_size = sizeof(int),
2253 	.value_size = sizeof(int),
2254 	.key_type_id = 1,
2255 	.value_type_id = 1,
2256 	.max_entries = 4,
2257 },
2258 
2259 {
2260 	.descr = "enum type (invalid name, not printable)",
2261 	.raw_types = {
2262 		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),		/* [1] */
2263 		BTF_TYPE_ENC(NAME_TBD,
2264 			     BTF_INFO_ENC(BTF_KIND_ENUM, 0, 1),
2265 			     sizeof(int)),				/* [2] */
2266 		BTF_ENUM_ENC(NAME_TBD, 0),
2267 		BTF_END_RAW,
2268 	},
2269 	.str_sec = "\0A\7\0B",
2270 	.str_sec_size = sizeof("\0A\7\0B"),
2271 	.map_type = BPF_MAP_TYPE_ARRAY,
2272 	.map_name = "enum_type_check_btf",
2273 	.key_size = sizeof(int),
2274 	.value_size = sizeof(int),
2275 	.key_type_id = 1,
2276 	.value_type_id = 1,
2277 	.max_entries = 4,
2278 	.btf_load_err = true,
2279 	.err_str = "Invalid name",
2280 },
2281 
2282 {
2283 	.descr = "enum member (invalid name, name_off = 0)",
2284 	.raw_types = {
2285 		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),		/* [1] */
2286 		BTF_TYPE_ENC(0,
2287 			     BTF_INFO_ENC(BTF_KIND_ENUM, 0, 1),
2288 			     sizeof(int)),				/* [2] */
2289 		BTF_ENUM_ENC(0, 0),
2290 		BTF_END_RAW,
2291 	},
2292 	.str_sec = "",
2293 	.str_sec_size = sizeof(""),
2294 	.map_type = BPF_MAP_TYPE_ARRAY,
2295 	.map_name = "enum_type_check_btf",
2296 	.key_size = sizeof(int),
2297 	.value_size = sizeof(int),
2298 	.key_type_id = 1,
2299 	.value_type_id = 1,
2300 	.max_entries = 4,
2301 	.btf_load_err = true,
2302 	.err_str = "Invalid name",
2303 },
2304 
2305 {
2306 	.descr = "enum member (invalid name, not printable)",
2307 	.raw_types = {
2308 		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),		/* [1] */
2309 		BTF_TYPE_ENC(0,
2310 			     BTF_INFO_ENC(BTF_KIND_ENUM, 0, 1),
2311 			     sizeof(int)),				/* [2] */
2312 		BTF_ENUM_ENC(NAME_TBD, 0),
2313 		BTF_END_RAW,
2314 	},
2315 	.str_sec = "\0A\7",
2316 	.str_sec_size = sizeof("\0A\7"),
2317 	.map_type = BPF_MAP_TYPE_ARRAY,
2318 	.map_name = "enum_type_check_btf",
2319 	.key_size = sizeof(int),
2320 	.value_size = sizeof(int),
2321 	.key_type_id = 1,
2322 	.value_type_id = 1,
2323 	.max_entries = 4,
2324 	.btf_load_err = true,
2325 	.err_str = "Invalid name",
2326 },
2327 {
2328 	.descr = "arraymap invalid btf key (a bit field)",
2329 	.raw_types = {
2330 		/* int */				/* [1] */
2331 		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
2332 		/* 32 bit int with 32 bit offset */	/* [2] */
2333 		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 32, 32, 8),
2334 		BTF_END_RAW,
2335 	},
2336 	.str_sec = "",
2337 	.str_sec_size = sizeof(""),
2338 	.map_type = BPF_MAP_TYPE_ARRAY,
2339 	.map_name = "array_map_check_btf",
2340 	.key_size = sizeof(int),
2341 	.value_size = sizeof(int),
2342 	.key_type_id = 2,
2343 	.value_type_id = 1,
2344 	.max_entries = 4,
2345 	.map_create_err = true,
2346 },
2347 
2348 {
2349 	.descr = "arraymap invalid btf key (!= 32 bits)",
2350 	.raw_types = {
2351 		/* int */				/* [1] */
2352 		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
2353 		/* 16 bit int with 0 bit offset */	/* [2] */
2354 		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 16, 2),
2355 		BTF_END_RAW,
2356 	},
2357 	.str_sec = "",
2358 	.str_sec_size = sizeof(""),
2359 	.map_type = BPF_MAP_TYPE_ARRAY,
2360 	.map_name = "array_map_check_btf",
2361 	.key_size = sizeof(int),
2362 	.value_size = sizeof(int),
2363 	.key_type_id = 2,
2364 	.value_type_id = 1,
2365 	.max_entries = 4,
2366 	.map_create_err = true,
2367 },
2368 
2369 {
2370 	.descr = "arraymap invalid btf value (too small)",
2371 	.raw_types = {
2372 		/* int */				/* [1] */
2373 		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
2374 		BTF_END_RAW,
2375 	},
2376 	.str_sec = "",
2377 	.str_sec_size = sizeof(""),
2378 	.map_type = BPF_MAP_TYPE_ARRAY,
2379 	.map_name = "array_map_check_btf",
2380 	.key_size = sizeof(int),
2381 	/* btf_value_size < map->value_size */
2382 	.value_size = sizeof(__u64),
2383 	.key_type_id = 1,
2384 	.value_type_id = 1,
2385 	.max_entries = 4,
2386 	.map_create_err = true,
2387 },
2388 
2389 {
2390 	.descr = "arraymap invalid btf value (too big)",
2391 	.raw_types = {
2392 		/* int */				/* [1] */
2393 		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
2394 		BTF_END_RAW,
2395 	},
2396 	.str_sec = "",
2397 	.str_sec_size = sizeof(""),
2398 	.map_type = BPF_MAP_TYPE_ARRAY,
2399 	.map_name = "array_map_check_btf",
2400 	.key_size = sizeof(int),
2401 	/* btf_value_size > map->value_size */
2402 	.value_size = sizeof(__u16),
2403 	.key_type_id = 1,
2404 	.value_type_id = 1,
2405 	.max_entries = 4,
2406 	.map_create_err = true,
2407 },
2408 
2409 {
2410 	.descr = "func proto (int (*)(int, unsigned int))",
2411 	.raw_types = {
2412 		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
2413 		BTF_TYPE_INT_ENC(0, 0, 0, 32, 4),		/* [2] */
2414 		/* int (*)(int, unsigned int) */
2415 		BTF_FUNC_PROTO_ENC(1, 2),			/* [3] */
2416 			BTF_FUNC_PROTO_ARG_ENC(0, 1),
2417 			BTF_FUNC_PROTO_ARG_ENC(0, 2),
2418 		BTF_END_RAW,
2419 	},
2420 	.str_sec = "",
2421 	.str_sec_size = sizeof(""),
2422 	.map_type = BPF_MAP_TYPE_ARRAY,
2423 	.map_name = "func_proto_type_check_btf",
2424 	.key_size = sizeof(int),
2425 	.value_size = sizeof(int),
2426 	.key_type_id = 1,
2427 	.value_type_id = 1,
2428 	.max_entries = 4,
2429 },
2430 
2431 {
2432 	.descr = "func proto (vararg)",
2433 	.raw_types = {
2434 		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),	/* [1] */
2435 		BTF_TYPE_INT_ENC(0, 0, 0, 32, 4),		/* [2] */
2436 		/* void (*)(int, unsigned int, ...) */
2437 		BTF_FUNC_PROTO_ENC(0, 3),			/* [3] */
2438 			BTF_FUNC_PROTO_ARG_ENC(0, 1),
2439 			BTF_FUNC_PROTO_ARG_ENC(0, 2),
2440 			BTF_FUNC_PROTO_ARG_ENC(0, 0),
2441 		BTF_END_RAW,
2442 	},
2443 	.str_sec = "",
2444 	.str_sec_size = sizeof(""),
2445 	.map_type = BPF_MAP_TYPE_ARRAY,
2446 	.map_name = "func_proto_type_check_btf",
2447 	.key_size = sizeof(int),
2448 	.value_size = sizeof(int),
2449 	.key_type_id = 1,
2450 	.value_type_id = 1,
2451 	.max_entries = 4,
2452 },
2453 
2454 {
2455 	.descr = "func proto (vararg with name)",
2456 	.raw_types = {
2457 		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),	/* [1] */
2458 		BTF_TYPE_INT_ENC(0, 0, 0, 32, 4),		/* [2] */
2459 		/* void (*)(int a, unsigned int b, ... c) */
2460 		BTF_FUNC_PROTO_ENC(0, 3),			/* [3] */
2461 			BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
2462 			BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 2),
2463 			BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 0),
2464 		BTF_END_RAW,
2465 	},
2466 	.str_sec = "\0a\0b\0c",
2467 	.str_sec_size = sizeof("\0a\0b\0c"),
2468 	.map_type = BPF_MAP_TYPE_ARRAY,
2469 	.map_name = "func_proto_type_check_btf",
2470 	.key_size = sizeof(int),
2471 	.value_size = sizeof(int),
2472 	.key_type_id = 1,
2473 	.value_type_id = 1,
2474 	.max_entries = 4,
2475 	.btf_load_err = true,
2476 	.err_str = "Invalid arg#3",
2477 },
2478 
2479 {
2480 	.descr = "func proto (arg after vararg)",
2481 	.raw_types = {
2482 		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),	/* [1] */
2483 		BTF_TYPE_INT_ENC(0, 0, 0, 32, 4),		/* [2] */
2484 		/* void (*)(int a, ..., unsigned int b) */
2485 		BTF_FUNC_PROTO_ENC(0, 3),			/* [3] */
2486 			BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
2487 			BTF_FUNC_PROTO_ARG_ENC(0, 0),
2488 			BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 2),
2489 		BTF_END_RAW,
2490 	},
2491 	.str_sec = "\0a\0b",
2492 	.str_sec_size = sizeof("\0a\0b"),
2493 	.map_type = BPF_MAP_TYPE_ARRAY,
2494 	.map_name = "func_proto_type_check_btf",
2495 	.key_size = sizeof(int),
2496 	.value_size = sizeof(int),
2497 	.key_type_id = 1,
2498 	.value_type_id = 1,
2499 	.max_entries = 4,
2500 	.btf_load_err = true,
2501 	.err_str = "Invalid arg#2",
2502 },
2503 
2504 {
2505 	.descr = "func proto (CONST=>TYPEDEF=>PTR=>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 		/* typedef void (*func_ptr)(int, unsigned int) */
2510 		BTF_TYPEDEF_ENC(NAME_TBD, 5),			/* [3] */
2511 		/* const func_ptr */
2512 		BTF_CONST_ENC(3),				/* [4] */
2513 		BTF_PTR_ENC(6),					/* [5] */
2514 		BTF_FUNC_PROTO_ENC(0, 2),			/* [6] */
2515 			BTF_FUNC_PROTO_ARG_ENC(0, 1),
2516 			BTF_FUNC_PROTO_ARG_ENC(0, 2),
2517 		BTF_END_RAW,
2518 	},
2519 	.str_sec = "\0func_ptr",
2520 	.str_sec_size = sizeof("\0func_ptr"),
2521 	.map_type = BPF_MAP_TYPE_ARRAY,
2522 	.map_name = "func_proto_type_check_btf",
2523 	.key_size = sizeof(int),
2524 	.value_size = sizeof(int),
2525 	.key_type_id = 1,
2526 	.value_type_id = 1,
2527 	.max_entries = 4,
2528 },
2529 
2530 {
2531 	.descr = "func proto (TYPEDEF=>FUNC_PROTO)",
2532 	.raw_types = {
2533 		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),	/* [1] */
2534 		BTF_TYPE_INT_ENC(0, 0, 0, 32, 4),		/* [2] */
2535 		BTF_TYPEDEF_ENC(NAME_TBD, 4),			/* [3] */
2536 		BTF_FUNC_PROTO_ENC(0, 2),			/* [4] */
2537 			BTF_FUNC_PROTO_ARG_ENC(0, 1),
2538 			BTF_FUNC_PROTO_ARG_ENC(0, 2),
2539 		BTF_END_RAW,
2540 	},
2541 	.str_sec = "\0func_typedef",
2542 	.str_sec_size = sizeof("\0func_typedef"),
2543 	.map_type = BPF_MAP_TYPE_ARRAY,
2544 	.map_name = "func_proto_type_check_btf",
2545 	.key_size = sizeof(int),
2546 	.value_size = sizeof(int),
2547 	.key_type_id = 1,
2548 	.value_type_id = 1,
2549 	.max_entries = 4,
2550 },
2551 
2552 {
2553 	.descr = "func proto (btf_resolve(arg))",
2554 	.raw_types = {
2555 		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),	/* [1] */
2556 		/* void (*)(const void *) */
2557 		BTF_FUNC_PROTO_ENC(0, 1),			/* [2] */
2558 			BTF_FUNC_PROTO_ARG_ENC(0, 3),
2559 		BTF_CONST_ENC(4),				/* [3] */
2560 		BTF_PTR_ENC(0),					/* [4] */
2561 		BTF_END_RAW,
2562 	},
2563 	.str_sec = "",
2564 	.str_sec_size = sizeof(""),
2565 	.map_type = BPF_MAP_TYPE_ARRAY,
2566 	.map_name = "func_proto_type_check_btf",
2567 	.key_size = sizeof(int),
2568 	.value_size = sizeof(int),
2569 	.key_type_id = 1,
2570 	.value_type_id = 1,
2571 	.max_entries = 4,
2572 },
2573 
2574 {
2575 	.descr = "func proto (Not all arg has name)",
2576 	.raw_types = {
2577 		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),	/* [1] */
2578 		BTF_TYPE_INT_ENC(0, 0, 0, 32, 4),		/* [2] */
2579 		/* void (*)(int, unsigned int b) */
2580 		BTF_FUNC_PROTO_ENC(0, 2),			/* [3] */
2581 			BTF_FUNC_PROTO_ARG_ENC(0, 1),
2582 			BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 2),
2583 		BTF_END_RAW,
2584 	},
2585 	.str_sec = "\0b",
2586 	.str_sec_size = sizeof("\0b"),
2587 	.map_type = BPF_MAP_TYPE_ARRAY,
2588 	.map_name = "func_proto_type_check_btf",
2589 	.key_size = sizeof(int),
2590 	.value_size = sizeof(int),
2591 	.key_type_id = 1,
2592 	.value_type_id = 1,
2593 	.max_entries = 4,
2594 },
2595 
2596 {
2597 	.descr = "func proto (Bad arg name_off)",
2598 	.raw_types = {
2599 		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),	/* [1] */
2600 		BTF_TYPE_INT_ENC(0, 0, 0, 32, 4),		/* [2] */
2601 		/* void (*)(int a, unsigned int <bad_name_off>) */
2602 		BTF_FUNC_PROTO_ENC(0, 2),			/* [3] */
2603 			BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
2604 			BTF_FUNC_PROTO_ARG_ENC(0x0fffffff, 2),
2605 		BTF_END_RAW,
2606 	},
2607 	.str_sec = "\0a",
2608 	.str_sec_size = sizeof("\0a"),
2609 	.map_type = BPF_MAP_TYPE_ARRAY,
2610 	.map_name = "func_proto_type_check_btf",
2611 	.key_size = sizeof(int),
2612 	.value_size = sizeof(int),
2613 	.key_type_id = 1,
2614 	.value_type_id = 1,
2615 	.max_entries = 4,
2616 	.btf_load_err = true,
2617 	.err_str = "Invalid arg#2",
2618 },
2619 
2620 {
2621 	.descr = "func proto (Bad arg name)",
2622 	.raw_types = {
2623 		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),	/* [1] */
2624 		BTF_TYPE_INT_ENC(0, 0, 0, 32, 4),		/* [2] */
2625 		/* void (*)(int a, unsigned int \7) */
2626 		BTF_FUNC_PROTO_ENC(0, 2),			/* [3] */
2627 			BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
2628 			BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 2),
2629 		BTF_END_RAW,
2630 	},
2631 	.str_sec = "\0a\0\7",
2632 	.str_sec_size = sizeof("\0a\0\7"),
2633 	.map_type = BPF_MAP_TYPE_ARRAY,
2634 	.map_name = "func_proto_type_check_btf",
2635 	.key_size = sizeof(int),
2636 	.value_size = sizeof(int),
2637 	.key_type_id = 1,
2638 	.value_type_id = 1,
2639 	.max_entries = 4,
2640 	.btf_load_err = true,
2641 	.err_str = "Invalid arg#2",
2642 },
2643 
2644 {
2645 	.descr = "func proto (Invalid return type)",
2646 	.raw_types = {
2647 		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),	/* [1] */
2648 		BTF_TYPE_INT_ENC(0, 0, 0, 32, 4),		/* [2] */
2649 		/* <bad_ret_type> (*)(int, unsigned int) */
2650 		BTF_FUNC_PROTO_ENC(100, 2),			/* [3] */
2651 			BTF_FUNC_PROTO_ARG_ENC(0, 1),
2652 			BTF_FUNC_PROTO_ARG_ENC(0, 2),
2653 		BTF_END_RAW,
2654 	},
2655 	.str_sec = "",
2656 	.str_sec_size = sizeof(""),
2657 	.map_type = BPF_MAP_TYPE_ARRAY,
2658 	.map_name = "func_proto_type_check_btf",
2659 	.key_size = sizeof(int),
2660 	.value_size = sizeof(int),
2661 	.key_type_id = 1,
2662 	.value_type_id = 1,
2663 	.max_entries = 4,
2664 	.btf_load_err = true,
2665 	.err_str = "Invalid return type",
2666 },
2667 
2668 {
2669 	.descr = "func proto (with func name)",
2670 	.raw_types = {
2671 		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),	/* [1] */
2672 		BTF_TYPE_INT_ENC(0, 0, 0, 32, 4),		/* [2] */
2673 		/* void func_proto(int, unsigned int) */
2674 		BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_FUNC_PROTO, 0, 2), 0),	/* [3] */
2675 			BTF_FUNC_PROTO_ARG_ENC(0, 1),
2676 			BTF_FUNC_PROTO_ARG_ENC(0, 2),
2677 		BTF_END_RAW,
2678 	},
2679 	.str_sec = "\0func_proto",
2680 	.str_sec_size = sizeof("\0func_proto"),
2681 	.map_type = BPF_MAP_TYPE_ARRAY,
2682 	.map_name = "func_proto_type_check_btf",
2683 	.key_size = sizeof(int),
2684 	.value_size = sizeof(int),
2685 	.key_type_id = 1,
2686 	.value_type_id = 1,
2687 	.max_entries = 4,
2688 	.btf_load_err = true,
2689 	.err_str = "Invalid name",
2690 },
2691 
2692 {
2693 	.descr = "func proto (const void arg)",
2694 	.raw_types = {
2695 		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),	/* [1] */
2696 		BTF_TYPE_INT_ENC(0, 0, 0, 32, 4),		/* [2] */
2697 		/* void (*)(const void) */
2698 		BTF_FUNC_PROTO_ENC(0, 1),			/* [3] */
2699 			BTF_FUNC_PROTO_ARG_ENC(0, 4),
2700 		BTF_CONST_ENC(0),				/* [4] */
2701 		BTF_END_RAW,
2702 	},
2703 	.str_sec = "",
2704 	.str_sec_size = sizeof(""),
2705 	.map_type = BPF_MAP_TYPE_ARRAY,
2706 	.map_name = "func_proto_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 	.btf_load_err = true,
2713 	.err_str = "Invalid arg#1",
2714 },
2715 
2716 {
2717 	.descr = "func (void func(int a, unsigned int b))",
2718 	.raw_types = {
2719 		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),	/* [1] */
2720 		BTF_TYPE_INT_ENC(0, 0, 0, 32, 4),		/* [2] */
2721 		/* void (*)(int a, unsigned int b) */
2722 		BTF_FUNC_PROTO_ENC(0, 2),			/* [3] */
2723 			BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
2724 			BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 2),
2725 		/* void func(int a, unsigned int b) */
2726 		BTF_FUNC_ENC(NAME_TBD, 3),			/* [4] */
2727 		BTF_END_RAW,
2728 	},
2729 	.str_sec = "\0a\0b\0func",
2730 	.str_sec_size = sizeof("\0a\0b\0func"),
2731 	.map_type = BPF_MAP_TYPE_ARRAY,
2732 	.map_name = "func_type_check_btf",
2733 	.key_size = sizeof(int),
2734 	.value_size = sizeof(int),
2735 	.key_type_id = 1,
2736 	.value_type_id = 1,
2737 	.max_entries = 4,
2738 },
2739 
2740 {
2741 	.descr = "func (No 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 <no_name>(int a, unsigned int b) */
2750 		BTF_FUNC_ENC(0, 3),				/* [4] */
2751 		BTF_END_RAW,
2752 	},
2753 	.str_sec = "\0a\0b",
2754 	.str_sec_size = sizeof("\0a\0b"),
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 (Invalid func 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 b) */
2772 		BTF_FUNC_PROTO_ENC(0, 2),			/* [3] */
2773 			BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
2774 			BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 2),
2775 		/* void \7(int a, unsigned int b) */
2776 		BTF_FUNC_ENC(NAME_TBD, 3),			/* [4] */
2777 		BTF_END_RAW,
2778 	},
2779 	.str_sec = "\0a\0b\0\7",
2780 	.str_sec_size = sizeof("\0a\0b\0\7"),
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 name",
2790 },
2791 
2792 {
2793 	.descr = "func (Some arg of global func has no name)",
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) */
2798 		BTF_FUNC_PROTO_ENC(0, 2),			/* [3] */
2799 			BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
2800 			BTF_FUNC_PROTO_ARG_ENC(0, 2),
2801 		/* void func(int a, unsigned int) */
2802 		BTF_TYPE_ENC(NAME_TBD,				/* [4] */
2803 			     BTF_INFO_ENC(BTF_KIND_FUNC, 0, BTF_FUNC_GLOBAL), 3),
2804 		BTF_END_RAW,
2805 	},
2806 	.str_sec = "\0a\0func",
2807 	.str_sec_size = sizeof("\0a\0func"),
2808 	.map_type = BPF_MAP_TYPE_ARRAY,
2809 	.map_name = "func_type_check_btf",
2810 	.key_size = sizeof(int),
2811 	.value_size = sizeof(int),
2812 	.key_type_id = 1,
2813 	.value_type_id = 1,
2814 	.max_entries = 4,
2815 	.btf_load_err = true,
2816 	.err_str = "Invalid arg#2",
2817 },
2818 
2819 {
2820 	.descr = "func (Some arg of static func has no name)",
2821 	.raw_types = {
2822 		/* int */
2823 		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),	/* [1] */
2824 		/* unsigned int */
2825 		BTF_TYPE_INT_ENC(0, 0, 0, 32, 4),		/* [2] */
2826 		/* void (*)(int a, unsigned int) */
2827 		BTF_FUNC_PROTO_ENC(0, 2),			/* [3] */
2828 			BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
2829 			BTF_FUNC_PROTO_ARG_ENC(0, 2),
2830 		/* static void func(int a, unsigned int) */
2831 		BTF_FUNC_ENC(NAME_TBD, 3),			/* [4] */
2832 		BTF_END_RAW,
2833 	},
2834 	.str_sec = "\0a\0func",
2835 	.str_sec_size = sizeof("\0a\0func"),
2836 	.map_type = BPF_MAP_TYPE_ARRAY,
2837 	.map_name = "func_type_check_btf",
2838 	.key_size = sizeof(int),
2839 	.value_size = sizeof(int),
2840 	.key_type_id = 1,
2841 	.value_type_id = 1,
2842 	.max_entries = 4,
2843 },
2844 
2845 {
2846 	.descr = "func (vararg of global func has no name)",
2847 	.raw_types = {
2848 		/* int */
2849 		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),	/* [1] */
2850 		/* void (*)(int a, ...) */
2851 		BTF_FUNC_PROTO_ENC(0, 2),			/* [2] */
2852 			BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
2853 			BTF_FUNC_PROTO_ARG_ENC(0, 0),
2854 		/* void func(int a, ...) */
2855 		BTF_TYPE_ENC(NAME_TBD,				/* [3] */
2856 			     BTF_INFO_ENC(BTF_KIND_FUNC, 0, BTF_FUNC_GLOBAL), 2),
2857 		BTF_END_RAW,
2858 	},
2859 	.str_sec = "\0a\0func",
2860 	.str_sec_size = sizeof("\0a\0func"),
2861 	.map_type = BPF_MAP_TYPE_ARRAY,
2862 	.map_name = "func_type_check_btf",
2863 	.key_size = sizeof(int),
2864 	.value_size = sizeof(int),
2865 	.key_type_id = 1,
2866 	.value_type_id = 1,
2867 	.max_entries = 4,
2868 },
2869 
2870 {
2871 	.descr = "func (Non zero vlen)",
2872 	.raw_types = {
2873 		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),	/* [1] */
2874 		BTF_TYPE_INT_ENC(0, 0, 0, 32, 4),		/* [2] */
2875 		/* void (*)(int a, unsigned int b) */
2876 		BTF_FUNC_PROTO_ENC(0, 2),			/* [3] */
2877 			BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
2878 			BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 2),
2879 		/* void func(int a, unsigned int b) */
2880 		BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_FUNC, 0, 2), 3), 	/* [4] */
2881 		BTF_END_RAW,
2882 	},
2883 	.str_sec = "\0a\0b\0func",
2884 	.str_sec_size = sizeof("\0a\0b\0func"),
2885 	.map_type = BPF_MAP_TYPE_ARRAY,
2886 	.map_name = "func_type_check_btf",
2887 	.key_size = sizeof(int),
2888 	.value_size = sizeof(int),
2889 	.key_type_id = 1,
2890 	.value_type_id = 1,
2891 	.max_entries = 4,
2892 	.btf_load_err = true,
2893 	.err_str = "Invalid func linkage",
2894 },
2895 
2896 {
2897 	.descr = "func (Not referring to FUNC_PROTO)",
2898 	.raw_types = {
2899 		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),	/* [1] */
2900 		BTF_FUNC_ENC(NAME_TBD, 1),			/* [2] */
2901 		BTF_END_RAW,
2902 	},
2903 	.str_sec = "\0func",
2904 	.str_sec_size = sizeof("\0func"),
2905 	.map_type = BPF_MAP_TYPE_ARRAY,
2906 	.map_name = "func_type_check_btf",
2907 	.key_size = sizeof(int),
2908 	.value_size = sizeof(int),
2909 	.key_type_id = 1,
2910 	.value_type_id = 1,
2911 	.max_entries = 4,
2912 	.btf_load_err = true,
2913 	.err_str = "Invalid type_id",
2914 },
2915 
2916 {
2917 	.descr = "invalid int kind_flag",
2918 	.raw_types = {
2919 		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),		/* [1] */
2920 		BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_INT, 1, 0), 4),	/* [2] */
2921 		BTF_INT_ENC(0, 0, 32),
2922 		BTF_END_RAW,
2923 	},
2924 	BTF_STR_SEC(""),
2925 	.map_type = BPF_MAP_TYPE_ARRAY,
2926 	.map_name = "int_type_check_btf",
2927 	.key_size = sizeof(int),
2928 	.value_size = sizeof(int),
2929 	.key_type_id = 1,
2930 	.value_type_id = 1,
2931 	.max_entries = 4,
2932 	.btf_load_err = true,
2933 	.err_str = "Invalid btf_info kind_flag",
2934 },
2935 
2936 {
2937 	.descr = "invalid ptr kind_flag",
2938 	.raw_types = {
2939 		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),		/* [1] */
2940 		BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_PTR, 1, 0), 1),	/* [2] */
2941 		BTF_END_RAW,
2942 	},
2943 	BTF_STR_SEC(""),
2944 	.map_type = BPF_MAP_TYPE_ARRAY,
2945 	.map_name = "ptr_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 array 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_ARRAY, 1, 0), 0),	/* [2] */
2960 		BTF_ARRAY_ENC(1, 1, 1),
2961 		BTF_END_RAW,
2962 	},
2963 	BTF_STR_SEC(""),
2964 	.map_type = BPF_MAP_TYPE_ARRAY,
2965 	.map_name = "array_type_check_btf",
2966 	.key_size = sizeof(int),
2967 	.value_size = sizeof(int),
2968 	.key_type_id = 1,
2969 	.value_type_id = 1,
2970 	.max_entries = 4,
2971 	.btf_load_err = true,
2972 	.err_str = "Invalid btf_info kind_flag",
2973 },
2974 
2975 {
2976 	.descr = "valid fwd kind_flag",
2977 	.raw_types = {
2978 		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),		/* [1] */
2979 		BTF_TYPE_ENC(NAME_TBD,
2980 			     BTF_INFO_ENC(BTF_KIND_FWD, 1, 0), 0),	/* [2] */
2981 		BTF_END_RAW,
2982 	},
2983 	BTF_STR_SEC("\0A"),
2984 	.map_type = BPF_MAP_TYPE_ARRAY,
2985 	.map_name = "fwd_type_check_btf",
2986 	.key_size = sizeof(int),
2987 	.value_size = sizeof(int),
2988 	.key_type_id = 1,
2989 	.value_type_id = 1,
2990 	.max_entries = 4,
2991 },
2992 
2993 {
2994 	.descr = "invalid typedef kind_flag",
2995 	.raw_types = {
2996 		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),		/* [1] */
2997 		BTF_TYPE_ENC(NAME_TBD,
2998 			     BTF_INFO_ENC(BTF_KIND_TYPEDEF, 1, 0), 1),	/* [2] */
2999 		BTF_END_RAW,
3000 	},
3001 	BTF_STR_SEC("\0A"),
3002 	.map_type = BPF_MAP_TYPE_ARRAY,
3003 	.map_name = "typedef_type_check_btf",
3004 	.key_size = sizeof(int),
3005 	.value_size = sizeof(int),
3006 	.key_type_id = 1,
3007 	.value_type_id = 1,
3008 	.max_entries = 4,
3009 	.btf_load_err = true,
3010 	.err_str = "Invalid btf_info kind_flag",
3011 },
3012 
3013 {
3014 	.descr = "invalid volatile kind_flag",
3015 	.raw_types = {
3016 		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),			/* [1] */
3017 		BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_VOLATILE, 1, 0), 1),	/* [2] */
3018 		BTF_END_RAW,
3019 	},
3020 	BTF_STR_SEC(""),
3021 	.map_type = BPF_MAP_TYPE_ARRAY,
3022 	.map_name = "volatile_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 const 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_CONST, 1, 0), 1),	/* [2] */
3037 		BTF_END_RAW,
3038 	},
3039 	BTF_STR_SEC(""),
3040 	.map_type = BPF_MAP_TYPE_ARRAY,
3041 	.map_name = "const_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 = "invalid restrict kind_flag",
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_RESTRICT, 1, 0), 1),	/* [2] */
3056 		BTF_END_RAW,
3057 	},
3058 	BTF_STR_SEC(""),
3059 	.map_type = BPF_MAP_TYPE_ARRAY,
3060 	.map_name = "restrict_type_check_btf",
3061 	.key_size = sizeof(int),
3062 	.value_size = sizeof(int),
3063 	.key_type_id = 1,
3064 	.value_type_id = 1,
3065 	.max_entries = 4,
3066 	.btf_load_err = true,
3067 	.err_str = "Invalid btf_info kind_flag",
3068 },
3069 
3070 {
3071 	.descr = "invalid func kind_flag",
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_FUNC_PROTO, 0, 0), 0),	/* [2] */
3075 		BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_FUNC, 1, 0), 2),	/* [3] */
3076 		BTF_END_RAW,
3077 	},
3078 	BTF_STR_SEC("\0A"),
3079 	.map_type = BPF_MAP_TYPE_ARRAY,
3080 	.map_name = "func_type_check_btf",
3081 	.key_size = sizeof(int),
3082 	.value_size = sizeof(int),
3083 	.key_type_id = 1,
3084 	.value_type_id = 1,
3085 	.max_entries = 4,
3086 	.btf_load_err = true,
3087 	.err_str = "Invalid btf_info kind_flag",
3088 },
3089 
3090 {
3091 	.descr = "invalid func_proto kind_flag",
3092 	.raw_types = {
3093 		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),			/* [1] */
3094 		BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_FUNC_PROTO, 1, 0), 0),	/* [2] */
3095 		BTF_END_RAW,
3096 	},
3097 	BTF_STR_SEC(""),
3098 	.map_type = BPF_MAP_TYPE_ARRAY,
3099 	.map_name = "func_proto_type_check_btf",
3100 	.key_size = sizeof(int),
3101 	.value_size = sizeof(int),
3102 	.key_type_id = 1,
3103 	.value_type_id = 1,
3104 	.max_entries = 4,
3105 	.btf_load_err = true,
3106 	.err_str = "Invalid btf_info kind_flag",
3107 },
3108 
3109 {
3110 	.descr = "valid struct, kind_flag, bitfield_size = 0",
3111 	.raw_types = {
3112 		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),			/* [1] */
3113 		BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_STRUCT, 1, 2), 8),	/* [2] */
3114 		BTF_MEMBER_ENC(NAME_TBD, 1, BTF_MEMBER_OFFSET(0, 0)),
3115 		BTF_MEMBER_ENC(NAME_TBD, 1, BTF_MEMBER_OFFSET(0, 32)),
3116 		BTF_END_RAW,
3117 	},
3118 	BTF_STR_SEC("\0A\0B"),
3119 	.map_type = BPF_MAP_TYPE_ARRAY,
3120 	.map_name = "struct_type_check_btf",
3121 	.key_size = sizeof(int),
3122 	.value_size = sizeof(int),
3123 	.key_type_id = 1,
3124 	.value_type_id = 1,
3125 	.max_entries = 4,
3126 },
3127 
3128 {
3129 	.descr = "valid struct, kind_flag, int member, bitfield_size != 0",
3130 	.raw_types = {
3131 		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),			/* [1] */
3132 		BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_STRUCT, 1, 2), 4),	/* [2] */
3133 		BTF_MEMBER_ENC(NAME_TBD, 1, BTF_MEMBER_OFFSET(4, 0)),
3134 		BTF_MEMBER_ENC(NAME_TBD, 1, BTF_MEMBER_OFFSET(4, 4)),
3135 		BTF_END_RAW,
3136 	},
3137 	BTF_STR_SEC("\0A\0B"),
3138 	.map_type = BPF_MAP_TYPE_ARRAY,
3139 	.map_name = "struct_type_check_btf",
3140 	.key_size = sizeof(int),
3141 	.value_size = sizeof(int),
3142 	.key_type_id = 1,
3143 	.value_type_id = 1,
3144 	.max_entries = 4,
3145 },
3146 
3147 {
3148 	.descr = "valid union, kind_flag, int member, bitfield_size != 0",
3149 	.raw_types = {
3150 		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),		/* [1] */
3151 		BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_UNION, 1, 2), 4),	/* [2] */
3152 		BTF_MEMBER_ENC(NAME_TBD, 1, BTF_MEMBER_OFFSET(4, 0)),
3153 		BTF_MEMBER_ENC(NAME_TBD, 1, BTF_MEMBER_OFFSET(4, 0)),
3154 		BTF_END_RAW,
3155 	},
3156 	BTF_STR_SEC("\0A\0B"),
3157 	.map_type = BPF_MAP_TYPE_ARRAY,
3158 	.map_name = "union_type_check_btf",
3159 	.key_size = sizeof(int),
3160 	.value_size = sizeof(int),
3161 	.key_type_id = 1,
3162 	.value_type_id = 1,
3163 	.max_entries = 4,
3164 },
3165 
3166 {
3167 	.descr = "valid struct, kind_flag, enum member, bitfield_size != 0",
3168 	.raw_types = {
3169 		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),		/* [1] */
3170 		BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_ENUM, 0, 1), 4),	/* [2] */
3171 		BTF_ENUM_ENC(NAME_TBD, 0),
3172 		BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_STRUCT, 1, 2), 4),/* [3] */
3173 		BTF_MEMBER_ENC(NAME_TBD, 2, BTF_MEMBER_OFFSET(4, 0)),
3174 		BTF_MEMBER_ENC(NAME_TBD, 2, BTF_MEMBER_OFFSET(4, 4)),
3175 		BTF_END_RAW,
3176 	},
3177 	BTF_STR_SEC("\0A\0B\0C"),
3178 	.map_type = BPF_MAP_TYPE_ARRAY,
3179 	.map_name = "struct_type_check_btf",
3180 	.key_size = sizeof(int),
3181 	.value_size = sizeof(int),
3182 	.key_type_id = 1,
3183 	.value_type_id = 1,
3184 	.max_entries = 4,
3185 },
3186 
3187 {
3188 	.descr = "valid union, kind_flag, enum member, bitfield_size != 0",
3189 	.raw_types = {
3190 		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),		/* [1] */
3191 		BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_ENUM, 0, 1), 4),	/* [2] */
3192 		BTF_ENUM_ENC(NAME_TBD, 0),
3193 		BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_UNION, 1, 2), 4),	/* [3] */
3194 		BTF_MEMBER_ENC(NAME_TBD, 2, BTF_MEMBER_OFFSET(4, 0)),
3195 		BTF_MEMBER_ENC(NAME_TBD, 2, BTF_MEMBER_OFFSET(4, 0)),
3196 		BTF_END_RAW,
3197 	},
3198 	BTF_STR_SEC("\0A\0B\0C"),
3199 	.map_type = BPF_MAP_TYPE_ARRAY,
3200 	.map_name = "union_type_check_btf",
3201 	.key_size = sizeof(int),
3202 	.value_size = sizeof(int),
3203 	.key_type_id = 1,
3204 	.value_type_id = 1,
3205 	.max_entries = 4,
3206 },
3207 
3208 {
3209 	.descr = "valid struct, kind_flag, typedef member, bitfield_size != 0",
3210 	.raw_types = {
3211 		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),		/* [1] */
3212 		BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_ENUM, 0, 1), 4),	/* [2] */
3213 		BTF_ENUM_ENC(NAME_TBD, 0),
3214 		BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_STRUCT, 1, 2), 4),/* [3] */
3215 		BTF_MEMBER_ENC(NAME_TBD, 4, BTF_MEMBER_OFFSET(4, 0)),
3216 		BTF_MEMBER_ENC(NAME_TBD, 5, BTF_MEMBER_OFFSET(4, 4)),
3217 		BTF_TYPEDEF_ENC(NAME_TBD, 1),				/* [4] */
3218 		BTF_TYPEDEF_ENC(NAME_TBD, 2),				/* [5] */
3219 		BTF_END_RAW,
3220 	},
3221 	BTF_STR_SEC("\0A\0B\0C\0D\0E"),
3222 	.map_type = BPF_MAP_TYPE_ARRAY,
3223 	.map_name = "struct_type_check_btf",
3224 	.key_size = sizeof(int),
3225 	.value_size = sizeof(int),
3226 	.key_type_id = 1,
3227 	.value_type_id = 1,
3228 	.max_entries = 4,
3229 },
3230 
3231 {
3232 	.descr = "valid union, kind_flag, typedef member, bitfield_size != 0",
3233 	.raw_types = {
3234 		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),		/* [1] */
3235 		BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_ENUM, 0, 1), 4),	/* [2] */
3236 		BTF_ENUM_ENC(NAME_TBD, 0),
3237 		BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_UNION, 1, 2), 4),	/* [3] */
3238 		BTF_MEMBER_ENC(NAME_TBD, 4, BTF_MEMBER_OFFSET(4, 0)),
3239 		BTF_MEMBER_ENC(NAME_TBD, 5, BTF_MEMBER_OFFSET(4, 0)),
3240 		BTF_TYPEDEF_ENC(NAME_TBD, 1),				/* [4] */
3241 		BTF_TYPEDEF_ENC(NAME_TBD, 2),				/* [5] */
3242 		BTF_END_RAW,
3243 	},
3244 	BTF_STR_SEC("\0A\0B\0C\0D\0E"),
3245 	.map_type = BPF_MAP_TYPE_ARRAY,
3246 	.map_name = "union_type_check_btf",
3247 	.key_size = sizeof(int),
3248 	.value_size = sizeof(int),
3249 	.key_type_id = 1,
3250 	.value_type_id = 1,
3251 	.max_entries = 4,
3252 },
3253 
3254 {
3255 	.descr = "invalid struct, kind_flag, bitfield_size greater than struct size",
3256 	.raw_types = {
3257 		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),			/* [1] */
3258 		BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_STRUCT, 1, 2), 4),	/* [2] */
3259 		BTF_MEMBER_ENC(NAME_TBD, 1, BTF_MEMBER_OFFSET(20, 0)),
3260 		BTF_MEMBER_ENC(NAME_TBD, 1, BTF_MEMBER_OFFSET(20, 20)),
3261 		BTF_END_RAW,
3262 	},
3263 	BTF_STR_SEC("\0A\0B"),
3264 	.map_type = BPF_MAP_TYPE_ARRAY,
3265 	.map_name = "struct_type_check_btf",
3266 	.key_size = sizeof(int),
3267 	.value_size = sizeof(int),
3268 	.key_type_id = 1,
3269 	.value_type_id = 1,
3270 	.max_entries = 4,
3271 	.btf_load_err = true,
3272 	.err_str = "Member exceeds struct_size",
3273 },
3274 
3275 {
3276 	.descr = "invalid struct, kind_flag, bitfield base_type int not regular",
3277 	.raw_types = {
3278 		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),			/* [1] */
3279 		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 20, 4),			/* [2] */
3280 		BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_STRUCT, 1, 2), 4),	/* [3] */
3281 		BTF_MEMBER_ENC(NAME_TBD, 2, BTF_MEMBER_OFFSET(20, 0)),
3282 		BTF_MEMBER_ENC(NAME_TBD, 2, BTF_MEMBER_OFFSET(20, 20)),
3283 		BTF_END_RAW,
3284 	},
3285 	BTF_STR_SEC("\0A\0B"),
3286 	.map_type = BPF_MAP_TYPE_ARRAY,
3287 	.map_name = "struct_type_check_btf",
3288 	.key_size = sizeof(int),
3289 	.value_size = sizeof(int),
3290 	.key_type_id = 1,
3291 	.value_type_id = 1,
3292 	.max_entries = 4,
3293 	.btf_load_err = true,
3294 	.err_str = "Invalid member base type",
3295 },
3296 
3297 {
3298 	.descr = "invalid struct, kind_flag, base_type int not regular",
3299 	.raw_types = {
3300 		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),			/* [1] */
3301 		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 12, 4),			/* [2] */
3302 		BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_STRUCT, 1, 2), 4),	/* [3] */
3303 		BTF_MEMBER_ENC(NAME_TBD, 2, BTF_MEMBER_OFFSET(8, 0)),
3304 		BTF_MEMBER_ENC(NAME_TBD, 2, BTF_MEMBER_OFFSET(8, 8)),
3305 		BTF_END_RAW,
3306 	},
3307 	BTF_STR_SEC("\0A\0B"),
3308 	.map_type = BPF_MAP_TYPE_ARRAY,
3309 	.map_name = "struct_type_check_btf",
3310 	.key_size = sizeof(int),
3311 	.value_size = sizeof(int),
3312 	.key_type_id = 1,
3313 	.value_type_id = 1,
3314 	.max_entries = 4,
3315 	.btf_load_err = true,
3316 	.err_str = "Invalid member base type",
3317 },
3318 
3319 {
3320 	.descr = "invalid union, kind_flag, bitfield_size greater than struct size",
3321 	.raw_types = {
3322 		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),		/* [1] */
3323 		BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_UNION, 1, 2), 2),	/* [2] */
3324 		BTF_MEMBER_ENC(NAME_TBD, 1, BTF_MEMBER_OFFSET(8, 0)),
3325 		BTF_MEMBER_ENC(NAME_TBD, 1, BTF_MEMBER_OFFSET(20, 0)),
3326 		BTF_END_RAW,
3327 	},
3328 	BTF_STR_SEC("\0A\0B"),
3329 	.map_type = BPF_MAP_TYPE_ARRAY,
3330 	.map_name = "union_type_check_btf",
3331 	.key_size = sizeof(int),
3332 	.value_size = sizeof(int),
3333 	.key_type_id = 1,
3334 	.value_type_id = 1,
3335 	.max_entries = 4,
3336 	.btf_load_err = true,
3337 	.err_str = "Member exceeds struct_size",
3338 },
3339 
3340 {
3341 	.descr = "invalid struct, kind_flag, int member, bitfield_size = 0, wrong byte alignment",
3342 	.raw_types = {
3343 		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),			/* [1] */
3344 		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),			/* [2] */
3345 		BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_STRUCT, 1, 2), 12),	/* [3] */
3346 		BTF_MEMBER_ENC(NAME_TBD, 2, BTF_MEMBER_OFFSET(0, 0)),
3347 		BTF_MEMBER_ENC(NAME_TBD, 2, BTF_MEMBER_OFFSET(0, 36)),
3348 		BTF_END_RAW,
3349 	},
3350 	BTF_STR_SEC("\0A\0B"),
3351 	.map_type = BPF_MAP_TYPE_ARRAY,
3352 	.map_name = "struct_type_check_btf",
3353 	.key_size = sizeof(int),
3354 	.value_size = sizeof(int),
3355 	.key_type_id = 1,
3356 	.value_type_id = 1,
3357 	.max_entries = 4,
3358 	.btf_load_err = true,
3359 	.err_str = "Invalid member offset",
3360 },
3361 
3362 {
3363 	.descr = "invalid struct, kind_flag, enum member, bitfield_size = 0, wrong byte alignment",
3364 	.raw_types = {
3365 		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),			/* [1] */
3366 		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),			/* [2] */
3367 		BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_ENUM, 0, 1), 4),	/* [2] */
3368 		BTF_ENUM_ENC(NAME_TBD, 0),
3369 		BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_STRUCT, 1, 2), 12),	/* [3] */
3370 		BTF_MEMBER_ENC(NAME_TBD, 2, BTF_MEMBER_OFFSET(0, 0)),
3371 		BTF_MEMBER_ENC(NAME_TBD, 2, BTF_MEMBER_OFFSET(0, 36)),
3372 		BTF_END_RAW,
3373 	},
3374 	BTF_STR_SEC("\0A\0B\0C"),
3375 	.map_type = BPF_MAP_TYPE_ARRAY,
3376 	.map_name = "struct_type_check_btf",
3377 	.key_size = sizeof(int),
3378 	.value_size = sizeof(int),
3379 	.key_type_id = 1,
3380 	.value_type_id = 1,
3381 	.max_entries = 4,
3382 	.btf_load_err = true,
3383 	.err_str = "Invalid member offset",
3384 },
3385 
3386 {
3387 	.descr = "128-bit int",
3388 	.raw_types = {
3389 		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),			/* [1] */
3390 		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 128, 16),		/* [2] */
3391 		BTF_END_RAW,
3392 	},
3393 	BTF_STR_SEC("\0A"),
3394 	.map_type = BPF_MAP_TYPE_ARRAY,
3395 	.map_name = "int_type_check_btf",
3396 	.key_size = sizeof(int),
3397 	.value_size = sizeof(int),
3398 	.key_type_id = 1,
3399 	.value_type_id = 1,
3400 	.max_entries = 4,
3401 },
3402 
3403 {
3404 	.descr = "struct, 128-bit int member",
3405 	.raw_types = {
3406 		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),			/* [1] */
3407 		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 128, 16),		/* [2] */
3408 		BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 1), 16),	/* [3] */
3409 		BTF_MEMBER_ENC(NAME_TBD, 2, 0),
3410 		BTF_END_RAW,
3411 	},
3412 	BTF_STR_SEC("\0A"),
3413 	.map_type = BPF_MAP_TYPE_ARRAY,
3414 	.map_name = "struct_type_check_btf",
3415 	.key_size = sizeof(int),
3416 	.value_size = sizeof(int),
3417 	.key_type_id = 1,
3418 	.value_type_id = 1,
3419 	.max_entries = 4,
3420 },
3421 
3422 {
3423 	.descr = "struct, 120-bit int member bitfield",
3424 	.raw_types = {
3425 		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),			/* [1] */
3426 		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 120, 16),		/* [2] */
3427 		BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 1), 16),	/* [3] */
3428 		BTF_MEMBER_ENC(NAME_TBD, 2, 0),
3429 		BTF_END_RAW,
3430 	},
3431 	BTF_STR_SEC("\0A"),
3432 	.map_type = BPF_MAP_TYPE_ARRAY,
3433 	.map_name = "struct_type_check_btf",
3434 	.key_size = sizeof(int),
3435 	.value_size = sizeof(int),
3436 	.key_type_id = 1,
3437 	.value_type_id = 1,
3438 	.max_entries = 4,
3439 },
3440 
3441 {
3442 	.descr = "struct, kind_flag, 128-bit int member",
3443 	.raw_types = {
3444 		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),			/* [1] */
3445 		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 128, 16),		/* [2] */
3446 		BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_STRUCT, 1, 1), 16),	/* [3] */
3447 		BTF_MEMBER_ENC(NAME_TBD, 2, BTF_MEMBER_OFFSET(0, 0)),
3448 		BTF_END_RAW,
3449 	},
3450 	BTF_STR_SEC("\0A"),
3451 	.map_type = BPF_MAP_TYPE_ARRAY,
3452 	.map_name = "struct_type_check_btf",
3453 	.key_size = sizeof(int),
3454 	.value_size = sizeof(int),
3455 	.key_type_id = 1,
3456 	.value_type_id = 1,
3457 	.max_entries = 4,
3458 },
3459 
3460 {
3461 	.descr = "struct, kind_flag, 120-bit int member bitfield",
3462 	.raw_types = {
3463 		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),			/* [1] */
3464 		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 128, 16),		/* [2] */
3465 		BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_STRUCT, 1, 1), 16),	/* [3] */
3466 		BTF_MEMBER_ENC(NAME_TBD, 2, BTF_MEMBER_OFFSET(120, 0)),
3467 		BTF_END_RAW,
3468 	},
3469 	BTF_STR_SEC("\0A"),
3470 	.map_type = BPF_MAP_TYPE_ARRAY,
3471 	.map_name = "struct_type_check_btf",
3472 	.key_size = sizeof(int),
3473 	.value_size = sizeof(int),
3474 	.key_type_id = 1,
3475 	.value_type_id = 1,
3476 	.max_entries = 4,
3477 },
3478 /*
3479  * typedef int arr_t[16];
3480  * struct s {
3481  *	arr_t *a;
3482  * };
3483  */
3484 {
3485 	.descr = "struct->ptr->typedef->array->int size resolution",
3486 	.raw_types = {
3487 		BTF_STRUCT_ENC(NAME_TBD, 1, 8),			/* [1] */
3488 		BTF_MEMBER_ENC(NAME_TBD, 2, 0),
3489 		BTF_PTR_ENC(3),					/* [2] */
3490 		BTF_TYPEDEF_ENC(NAME_TBD, 4),			/* [3] */
3491 		BTF_TYPE_ARRAY_ENC(5, 5, 16),			/* [4] */
3492 		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),	/* [5] */
3493 		BTF_END_RAW,
3494 	},
3495 	BTF_STR_SEC("\0s\0a\0arr_t"),
3496 	.map_type = BPF_MAP_TYPE_ARRAY,
3497 	.map_name = "ptr_mod_chain_size_resolve_map",
3498 	.key_size = sizeof(int),
3499 	.value_size = sizeof(int) * 16,
3500 	.key_type_id = 5 /* int */,
3501 	.value_type_id = 3 /* arr_t */,
3502 	.max_entries = 4,
3503 },
3504 /*
3505  * typedef int arr_t[16][8][4];
3506  * struct s {
3507  *	arr_t *a;
3508  * };
3509  */
3510 {
3511 	.descr = "struct->ptr->typedef->multi-array->int size resolution",
3512 	.raw_types = {
3513 		BTF_STRUCT_ENC(NAME_TBD, 1, 8),			/* [1] */
3514 		BTF_MEMBER_ENC(NAME_TBD, 2, 0),
3515 		BTF_PTR_ENC(3),					/* [2] */
3516 		BTF_TYPEDEF_ENC(NAME_TBD, 4),			/* [3] */
3517 		BTF_TYPE_ARRAY_ENC(5, 7, 16),			/* [4] */
3518 		BTF_TYPE_ARRAY_ENC(6, 7, 8),			/* [5] */
3519 		BTF_TYPE_ARRAY_ENC(7, 7, 4),			/* [6] */
3520 		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),	/* [7] */
3521 		BTF_END_RAW,
3522 	},
3523 	BTF_STR_SEC("\0s\0a\0arr_t"),
3524 	.map_type = BPF_MAP_TYPE_ARRAY,
3525 	.map_name = "multi_arr_size_resolve_map",
3526 	.key_size = sizeof(int),
3527 	.value_size = sizeof(int) * 16 * 8 * 4,
3528 	.key_type_id = 7 /* int */,
3529 	.value_type_id = 3 /* arr_t */,
3530 	.max_entries = 4,
3531 },
3532 /*
3533  * typedef int int_t;
3534  * typedef int_t arr3_t[4];
3535  * typedef arr3_t arr2_t[8];
3536  * typedef arr2_t arr1_t[16];
3537  * struct s {
3538  *	arr1_t *a;
3539  * };
3540  */
3541 {
3542 	.descr = "typedef/multi-arr mix size resolution",
3543 	.raw_types = {
3544 		BTF_STRUCT_ENC(NAME_TBD, 1, 8),			/* [1] */
3545 		BTF_MEMBER_ENC(NAME_TBD, 2, 0),
3546 		BTF_PTR_ENC(3),					/* [2] */
3547 		BTF_TYPEDEF_ENC(NAME_TBD, 4),			/* [3] */
3548 		BTF_TYPE_ARRAY_ENC(5, 10, 16),			/* [4] */
3549 		BTF_TYPEDEF_ENC(NAME_TBD, 6),			/* [5] */
3550 		BTF_TYPE_ARRAY_ENC(7, 10, 8),			/* [6] */
3551 		BTF_TYPEDEF_ENC(NAME_TBD, 8),			/* [7] */
3552 		BTF_TYPE_ARRAY_ENC(9, 10, 4),			/* [8] */
3553 		BTF_TYPEDEF_ENC(NAME_TBD, 10),			/* [9] */
3554 		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),	/* [10] */
3555 		BTF_END_RAW,
3556 	},
3557 	BTF_STR_SEC("\0s\0a\0arr1_t\0arr2_t\0arr3_t\0int_t"),
3558 	.map_type = BPF_MAP_TYPE_ARRAY,
3559 	.map_name = "typedef_arra_mix_size_resolve_map",
3560 	.key_size = sizeof(int),
3561 	.value_size = sizeof(int) * 16 * 8 * 4,
3562 	.key_type_id = 10 /* int */,
3563 	.value_type_id = 3 /* arr_t */,
3564 	.max_entries = 4,
3565 },
3566 /*
3567  * elf .rodata section size 4 and btf .rodata section vlen 0.
3568  */
3569 {
3570 	.descr = "datasec: vlen == 0",
3571 	.raw_types = {
3572 		/* int */
3573 		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),	/* [1] */
3574 		/* .rodata section */
3575 		BTF_TYPE_ENC(NAME_NTH(1), BTF_INFO_ENC(BTF_KIND_DATASEC, 0, 0), 4),
3576 								 /* [2] */
3577 		BTF_END_RAW,
3578 	},
3579 	BTF_STR_SEC("\0.rodata"),
3580 	.map_type = BPF_MAP_TYPE_ARRAY,
3581 	.key_size = sizeof(int),
3582 	.value_size = sizeof(int),
3583 	.key_type_id = 1,
3584 	.value_type_id = 1,
3585 	.max_entries = 1,
3586 },
3587 {
3588 	.descr = "datasec: name '?.foo bar:buz' is ok",
3589 	.raw_types = {
3590 		/* int */
3591 		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),  /* [1] */
3592 		/* VAR x */                                     /* [2] */
3593 		BTF_TYPE_ENC(1, BTF_INFO_ENC(BTF_KIND_VAR, 0, 0), 1),
3594 		BTF_VAR_STATIC,
3595 		/* DATASEC ?.data */                            /* [3] */
3596 		BTF_TYPE_ENC(3, BTF_INFO_ENC(BTF_KIND_DATASEC, 0, 1), 4),
3597 		BTF_VAR_SECINFO_ENC(2, 0, 4),
3598 		BTF_END_RAW,
3599 	},
3600 	BTF_STR_SEC("\0x\0?.foo bar:buz"),
3601 },
3602 {
3603 	.descr = "datasec: name with non-printable first char not is ok",
3604 	.raw_types = {
3605 		/* int */
3606 		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),  /* [1] */
3607 		/* VAR x */                                     /* [2] */
3608 		BTF_TYPE_ENC(1, BTF_INFO_ENC(BTF_KIND_VAR, 0, 0), 1),
3609 		BTF_VAR_STATIC,
3610 		/* DATASEC ?.data */                            /* [3] */
3611 		BTF_TYPE_ENC(3, BTF_INFO_ENC(BTF_KIND_DATASEC, 0, 1), 4),
3612 		BTF_VAR_SECINFO_ENC(2, 0, 4),
3613 		BTF_END_RAW,
3614 	},
3615 	BTF_STR_SEC("\0x\0\7foo"),
3616 	.err_str = "Invalid name",
3617 	.btf_load_err = true,
3618 },
3619 {
3620 	.descr = "datasec: name '\\0' is not ok",
3621 	.raw_types = {
3622 		/* int */
3623 		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),  /* [1] */
3624 		/* VAR x */                                     /* [2] */
3625 		BTF_TYPE_ENC(1, BTF_INFO_ENC(BTF_KIND_VAR, 0, 0), 1),
3626 		BTF_VAR_STATIC,
3627 		/* DATASEC \0 */                                /* [3] */
3628 		BTF_TYPE_ENC(3, BTF_INFO_ENC(BTF_KIND_DATASEC, 0, 1), 4),
3629 		BTF_VAR_SECINFO_ENC(2, 0, 4),
3630 		BTF_END_RAW,
3631 	},
3632 	BTF_STR_SEC("\0x\0"),
3633 	.err_str = "Invalid name",
3634 	.btf_load_err = true,
3635 },
3636 {
3637 	.descr = "type name '?foo' is ok",
3638 	.raw_types = {
3639 		/* union ?foo; */
3640 		BTF_TYPE_ENC(1, BTF_INFO_ENC(BTF_KIND_FWD, 1, 0), 0), /* [1] */
3641 		BTF_END_RAW,
3642 	},
3643 	BTF_STR_SEC("\0?foo"),
3644 },
3645 {
3646 	.descr = "names of Rust types and functions are ok",
3647 	.raw_types = {
3648 		BTF_TYPE_INT_ENC(NAME_NTH(1), 0, 0, 32, 4),	/* [1] */
3649 		BTF_STRUCT_ENC(NAME_NTH(2), 1, 4),		/* [2] */
3650 		BTF_MEMBER_ENC(NAME_NTH(3), 1, 0),
3651 		BTF_FWD_ENC(NAME_NTH(4), 0),			/* [3] */
3652 		BTF_TYPEDEF_ENC(NAME_NTH(5), 2),		/* [4] */
3653 		BTF_FUNC_PROTO_ENC(0, 1),			/* [5] */
3654 			BTF_FUNC_PROTO_ARG_ENC(NAME_NTH(6), 1),
3655 		BTF_FUNC_ENC(NAME_NTH(7), 5),			/* [6] */
3656 		BTF_END_RAW,
3657 	},
3658 	BTF_STR_SEC("\0u32\0Option<&str>\0__0\0*const str\0{impl#9}<[u8; 4]>\0self\0fmt<str>"),
3659 },
3660 
3661 {
3662 	.descr = "float test #1, well-formed",
3663 	.raw_types = {
3664 		BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),
3665 								/* [1] */
3666 		BTF_TYPE_FLOAT_ENC(NAME_TBD, 2),		/* [2] */
3667 		BTF_TYPE_FLOAT_ENC(NAME_TBD, 4),		/* [3] */
3668 		BTF_TYPE_FLOAT_ENC(NAME_TBD, 8),		/* [4] */
3669 		BTF_TYPE_FLOAT_ENC(NAME_TBD, 12),		/* [5] */
3670 		BTF_TYPE_FLOAT_ENC(NAME_TBD, 16),		/* [6] */
3671 		BTF_STRUCT_ENC(NAME_TBD, 5, 48),		/* [7] */
3672 		BTF_MEMBER_ENC(NAME_TBD, 2, 0),
3673 		BTF_MEMBER_ENC(NAME_TBD, 3, 32),
3674 		BTF_MEMBER_ENC(NAME_TBD, 4, 64),
3675 		BTF_MEMBER_ENC(NAME_TBD, 5, 128),
3676 		BTF_MEMBER_ENC(NAME_TBD, 6, 256),
3677 		BTF_END_RAW,
3678 	},
3679 	BTF_STR_SEC("\0int\0_Float16\0float\0double\0_Float80\0long_double"
3680 		    "\0floats\0a\0b\0c\0d\0e"),
3681 	.map_type = BPF_MAP_TYPE_ARRAY,
3682 	.map_name = "float_type_check_btf",
3683 	.key_size = sizeof(int),
3684 	.value_size = 48,
3685 	.key_type_id = 1,
3686 	.value_type_id = 7,
3687 	.max_entries = 1,
3688 },
3689 {
3690 	.descr = "float test #2, invalid vlen",
3691 	.raw_types = {
3692 		BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),
3693 								/* [1] */
3694 		BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_FLOAT, 0, 1), 4),
3695 								/* [2] */
3696 		BTF_END_RAW,
3697 	},
3698 	BTF_STR_SEC("\0int\0float"),
3699 	.map_type = BPF_MAP_TYPE_ARRAY,
3700 	.map_name = "float_type_check_btf",
3701 	.key_size = sizeof(int),
3702 	.value_size = 4,
3703 	.key_type_id = 1,
3704 	.value_type_id = 2,
3705 	.max_entries = 1,
3706 	.btf_load_err = true,
3707 	.err_str = "vlen != 0",
3708 },
3709 {
3710 	.descr = "float test #3, invalid kind_flag",
3711 	.raw_types = {
3712 		BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),
3713 								/* [1] */
3714 		BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_FLOAT, 1, 0), 4),
3715 								/* [2] */
3716 		BTF_END_RAW,
3717 	},
3718 	BTF_STR_SEC("\0int\0float"),
3719 	.map_type = BPF_MAP_TYPE_ARRAY,
3720 	.map_name = "float_type_check_btf",
3721 	.key_size = sizeof(int),
3722 	.value_size = 4,
3723 	.key_type_id = 1,
3724 	.value_type_id = 2,
3725 	.max_entries = 1,
3726 	.btf_load_err = true,
3727 	.err_str = "Invalid btf_info kind_flag",
3728 },
3729 {
3730 	.descr = "float test #4, member does not fit",
3731 	.raw_types = {
3732 		BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),
3733 								/* [1] */
3734 		BTF_TYPE_FLOAT_ENC(NAME_TBD, 4),		/* [2] */
3735 		BTF_STRUCT_ENC(NAME_TBD, 1, 2),			/* [3] */
3736 		BTF_MEMBER_ENC(NAME_TBD, 2, 0),
3737 		BTF_END_RAW,
3738 	},
3739 	BTF_STR_SEC("\0int\0float\0floats\0x"),
3740 	.map_type = BPF_MAP_TYPE_ARRAY,
3741 	.map_name = "float_type_check_btf",
3742 	.key_size = sizeof(int),
3743 	.value_size = 4,
3744 	.key_type_id = 1,
3745 	.value_type_id = 3,
3746 	.max_entries = 1,
3747 	.btf_load_err = true,
3748 	.err_str = "Member exceeds struct_size",
3749 },
3750 {
3751 	.descr = "float test #5, member is not properly aligned",
3752 	.raw_types = {
3753 		BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),
3754 								/* [1] */
3755 		BTF_TYPE_FLOAT_ENC(NAME_TBD, 4),		/* [2] */
3756 		BTF_STRUCT_ENC(NAME_TBD, 1, 8),			/* [3] */
3757 		BTF_MEMBER_ENC(NAME_TBD, 2, 8),
3758 		BTF_END_RAW,
3759 	},
3760 	BTF_STR_SEC("\0int\0float\0floats\0x"),
3761 	.map_type = BPF_MAP_TYPE_ARRAY,
3762 	.map_name = "float_type_check_btf",
3763 	.key_size = sizeof(int),
3764 	.value_size = 4,
3765 	.key_type_id = 1,
3766 	.value_type_id = 3,
3767 	.max_entries = 1,
3768 	.btf_load_err = true,
3769 	.err_str = "Member is not properly aligned",
3770 },
3771 {
3772 	.descr = "float test #6, invalid size",
3773 	.raw_types = {
3774 		BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),
3775 								/* [1] */
3776 		BTF_TYPE_FLOAT_ENC(NAME_TBD, 6),		/* [2] */
3777 		BTF_END_RAW,
3778 	},
3779 	BTF_STR_SEC("\0int\0float"),
3780 	.map_type = BPF_MAP_TYPE_ARRAY,
3781 	.map_name = "float_type_check_btf",
3782 	.key_size = sizeof(int),
3783 	.value_size = 6,
3784 	.key_type_id = 1,
3785 	.value_type_id = 2,
3786 	.max_entries = 1,
3787 	.btf_load_err = true,
3788 	.err_str = "Invalid type_size",
3789 },
3790 
3791 {
3792 	.descr = "decl_tag test #1, struct/member, well-formed",
3793 	.raw_types = {
3794 		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),	/* [1] */
3795 		BTF_STRUCT_ENC(0, 2, 8),			/* [2] */
3796 		BTF_MEMBER_ENC(NAME_TBD, 1, 0),
3797 		BTF_MEMBER_ENC(NAME_TBD, 1, 32),
3798 		BTF_DECL_TAG_ENC(NAME_TBD, 2, -1),
3799 		BTF_DECL_TAG_ENC(NAME_TBD, 2, 0),
3800 		BTF_DECL_TAG_ENC(NAME_TBD, 2, 1),
3801 		BTF_END_RAW,
3802 	},
3803 	BTF_STR_SEC("\0m1\0m2\0tag1\0tag2\0tag3"),
3804 	.map_type = BPF_MAP_TYPE_ARRAY,
3805 	.map_name = "tag_type_check_btf",
3806 	.key_size = sizeof(int),
3807 	.value_size = 8,
3808 	.key_type_id = 1,
3809 	.value_type_id = 2,
3810 	.max_entries = 1,
3811 },
3812 {
3813 	.descr = "decl_tag test #2, union/member, well-formed",
3814 	.raw_types = {
3815 		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),	/* [1] */
3816 		BTF_UNION_ENC(NAME_TBD, 2, 4),			/* [2] */
3817 		BTF_MEMBER_ENC(NAME_TBD, 1, 0),
3818 		BTF_MEMBER_ENC(NAME_TBD, 1, 0),
3819 		BTF_DECL_TAG_ENC(NAME_TBD, 2, -1),
3820 		BTF_DECL_TAG_ENC(NAME_TBD, 2, 0),
3821 		BTF_DECL_TAG_ENC(NAME_TBD, 2, 1),
3822 		BTF_END_RAW,
3823 	},
3824 	BTF_STR_SEC("\0t\0m1\0m2\0tag1\0tag2\0tag3"),
3825 	.map_type = BPF_MAP_TYPE_ARRAY,
3826 	.map_name = "tag_type_check_btf",
3827 	.key_size = sizeof(int),
3828 	.value_size = 4,
3829 	.key_type_id = 1,
3830 	.value_type_id = 2,
3831 	.max_entries = 1,
3832 },
3833 {
3834 	.descr = "decl_tag test #3, variable, well-formed",
3835 	.raw_types = {
3836 		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),	/* [1] */
3837 		BTF_VAR_ENC(NAME_TBD, 1, 0),			/* [2] */
3838 		BTF_VAR_ENC(NAME_TBD, 1, 1),			/* [3] */
3839 		BTF_DECL_TAG_ENC(NAME_TBD, 2, -1),
3840 		BTF_DECL_TAG_ENC(NAME_TBD, 3, -1),
3841 		BTF_END_RAW,
3842 	},
3843 	BTF_STR_SEC("\0local\0global\0tag1\0tag2"),
3844 	.map_type = BPF_MAP_TYPE_ARRAY,
3845 	.map_name = "tag_type_check_btf",
3846 	.key_size = sizeof(int),
3847 	.value_size = 4,
3848 	.key_type_id = 1,
3849 	.value_type_id = 1,
3850 	.max_entries = 1,
3851 },
3852 {
3853 	.descr = "decl_tag test #4, func/parameter, well-formed",
3854 	.raw_types = {
3855 		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),	/* [1] */
3856 		BTF_FUNC_PROTO_ENC(0, 2),			/* [2] */
3857 			BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
3858 			BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
3859 		BTF_FUNC_ENC(NAME_TBD, 2),			/* [3] */
3860 		BTF_DECL_TAG_ENC(NAME_TBD, 3, -1),
3861 		BTF_DECL_TAG_ENC(NAME_TBD, 3, 0),
3862 		BTF_DECL_TAG_ENC(NAME_TBD, 3, 1),
3863 		BTF_END_RAW,
3864 	},
3865 	BTF_STR_SEC("\0arg1\0arg2\0f\0tag1\0tag2\0tag3"),
3866 	.map_type = BPF_MAP_TYPE_ARRAY,
3867 	.map_name = "tag_type_check_btf",
3868 	.key_size = sizeof(int),
3869 	.value_size = 4,
3870 	.key_type_id = 1,
3871 	.value_type_id = 1,
3872 	.max_entries = 1,
3873 },
3874 {
3875 	.descr = "decl_tag test #5, invalid value",
3876 	.raw_types = {
3877 		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),	/* [1] */
3878 		BTF_VAR_ENC(NAME_TBD, 1, 0),			/* [2] */
3879 		BTF_DECL_TAG_ENC(0, 2, -1),
3880 		BTF_END_RAW,
3881 	},
3882 	BTF_STR_SEC("\0local\0tag"),
3883 	.map_type = BPF_MAP_TYPE_ARRAY,
3884 	.map_name = "tag_type_check_btf",
3885 	.key_size = sizeof(int),
3886 	.value_size = 4,
3887 	.key_type_id = 1,
3888 	.value_type_id = 1,
3889 	.max_entries = 1,
3890 	.btf_load_err = true,
3891 	.err_str = "Invalid value",
3892 },
3893 {
3894 	.descr = "decl_tag test #6, invalid target type",
3895 	.raw_types = {
3896 		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),	/* [1] */
3897 		BTF_DECL_TAG_ENC(NAME_TBD, 1, -1),
3898 		BTF_END_RAW,
3899 	},
3900 	BTF_STR_SEC("\0tag1"),
3901 	.map_type = BPF_MAP_TYPE_ARRAY,
3902 	.map_name = "tag_type_check_btf",
3903 	.key_size = sizeof(int),
3904 	.value_size = 4,
3905 	.key_type_id = 1,
3906 	.value_type_id = 1,
3907 	.max_entries = 1,
3908 	.btf_load_err = true,
3909 	.err_str = "Invalid type",
3910 },
3911 {
3912 	.descr = "decl_tag test #7, invalid vlen",
3913 	.raw_types = {
3914 		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),	/* [1] */
3915 		BTF_VAR_ENC(NAME_TBD, 1, 0),			/* [2] */
3916 		BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_DECL_TAG, 0, 1), 2), (0),
3917 		BTF_END_RAW,
3918 	},
3919 	BTF_STR_SEC("\0local\0tag1"),
3920 	.map_type = BPF_MAP_TYPE_ARRAY,
3921 	.map_name = "tag_type_check_btf",
3922 	.key_size = sizeof(int),
3923 	.value_size = 4,
3924 	.key_type_id = 1,
3925 	.value_type_id = 1,
3926 	.max_entries = 1,
3927 	.btf_load_err = true,
3928 	.err_str = "vlen != 0",
3929 },
3930 {
3931 	.descr = "decl_tag test #8, tag with kflag",
3932 	.raw_types = {
3933 		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),	/* [1] */
3934 		BTF_VAR_ENC(NAME_TBD, 1, 0),			/* [2] */
3935 		BTF_DECL_ATTR_ENC(NAME_TBD, 2, -1),
3936 		BTF_END_RAW,
3937 	},
3938 	BTF_STR_SEC("\0local\0tag1"),
3939 	.map_type = BPF_MAP_TYPE_ARRAY,
3940 	.map_name = "tag_type_check_btf",
3941 	.key_size = sizeof(int),
3942 	.value_size = 4,
3943 	.key_type_id = 1,
3944 	.value_type_id = 1,
3945 	.max_entries = 1,
3946 },
3947 {
3948 	.descr = "decl_tag test #9, var, invalid component_idx",
3949 	.raw_types = {
3950 		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),	/* [1] */
3951 		BTF_VAR_ENC(NAME_TBD, 1, 0),			/* [2] */
3952 		BTF_DECL_TAG_ENC(NAME_TBD, 2, 0),
3953 		BTF_END_RAW,
3954 	},
3955 	BTF_STR_SEC("\0local\0tag"),
3956 	.map_type = BPF_MAP_TYPE_ARRAY,
3957 	.map_name = "tag_type_check_btf",
3958 	.key_size = sizeof(int),
3959 	.value_size = 4,
3960 	.key_type_id = 1,
3961 	.value_type_id = 1,
3962 	.max_entries = 1,
3963 	.btf_load_err = true,
3964 	.err_str = "Invalid component_idx",
3965 },
3966 {
3967 	.descr = "decl_tag test #10, struct member, invalid component_idx",
3968 	.raw_types = {
3969 		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),	/* [1] */
3970 		BTF_STRUCT_ENC(0, 2, 8),			/* [2] */
3971 		BTF_MEMBER_ENC(NAME_TBD, 1, 0),
3972 		BTF_MEMBER_ENC(NAME_TBD, 1, 32),
3973 		BTF_DECL_TAG_ENC(NAME_TBD, 2, 2),
3974 		BTF_END_RAW,
3975 	},
3976 	BTF_STR_SEC("\0m1\0m2\0tag"),
3977 	.map_type = BPF_MAP_TYPE_ARRAY,
3978 	.map_name = "tag_type_check_btf",
3979 	.key_size = sizeof(int),
3980 	.value_size = 8,
3981 	.key_type_id = 1,
3982 	.value_type_id = 2,
3983 	.max_entries = 1,
3984 	.btf_load_err = true,
3985 	.err_str = "Invalid component_idx",
3986 },
3987 {
3988 	.descr = "decl_tag test #11, func parameter, invalid component_idx",
3989 	.raw_types = {
3990 		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),	/* [1] */
3991 		BTF_FUNC_PROTO_ENC(0, 2),			/* [2] */
3992 			BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
3993 			BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
3994 		BTF_FUNC_ENC(NAME_TBD, 2),			/* [3] */
3995 		BTF_DECL_TAG_ENC(NAME_TBD, 3, 2),
3996 		BTF_END_RAW,
3997 	},
3998 	BTF_STR_SEC("\0arg1\0arg2\0f\0tag"),
3999 	.map_type = BPF_MAP_TYPE_ARRAY,
4000 	.map_name = "tag_type_check_btf",
4001 	.key_size = sizeof(int),
4002 	.value_size = 4,
4003 	.key_type_id = 1,
4004 	.value_type_id = 1,
4005 	.max_entries = 1,
4006 	.btf_load_err = true,
4007 	.err_str = "Invalid component_idx",
4008 },
4009 {
4010 	.descr = "decl_tag test #12, < -1 component_idx",
4011 	.raw_types = {
4012 		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),	/* [1] */
4013 		BTF_FUNC_PROTO_ENC(0, 2),			/* [2] */
4014 			BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
4015 			BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
4016 		BTF_FUNC_ENC(NAME_TBD, 2),			/* [3] */
4017 		BTF_DECL_TAG_ENC(NAME_TBD, 3, -2),
4018 		BTF_END_RAW,
4019 	},
4020 	BTF_STR_SEC("\0arg1\0arg2\0f\0tag"),
4021 	.map_type = BPF_MAP_TYPE_ARRAY,
4022 	.map_name = "tag_type_check_btf",
4023 	.key_size = sizeof(int),
4024 	.value_size = 4,
4025 	.key_type_id = 1,
4026 	.value_type_id = 1,
4027 	.max_entries = 1,
4028 	.btf_load_err = true,
4029 	.err_str = "Invalid component_idx",
4030 },
4031 {
4032 	.descr = "decl_tag test #13, typedef, well-formed",
4033 	.raw_types = {
4034 		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),	/* [1] */
4035 		BTF_TYPEDEF_ENC(NAME_TBD, 1),			/* [2] */
4036 		BTF_DECL_TAG_ENC(NAME_TBD, 2, -1),
4037 		BTF_END_RAW,
4038 	},
4039 	BTF_STR_SEC("\0t\0tag"),
4040 	.map_type = BPF_MAP_TYPE_ARRAY,
4041 	.map_name = "tag_type_check_btf",
4042 	.key_size = sizeof(int),
4043 	.value_size = 4,
4044 	.key_type_id = 1,
4045 	.value_type_id = 1,
4046 	.max_entries = 1,
4047 },
4048 {
4049 	.descr = "decl_tag test #14, typedef, invalid component_idx",
4050 	.raw_types = {
4051 		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),	/* [1] */
4052 		BTF_TYPEDEF_ENC(NAME_TBD, 1),			/* [2] */
4053 		BTF_DECL_TAG_ENC(NAME_TBD, 2, 0),
4054 		BTF_END_RAW,
4055 	},
4056 	BTF_STR_SEC("\0local\0tag"),
4057 	.map_type = BPF_MAP_TYPE_ARRAY,
4058 	.map_name = "tag_type_check_btf",
4059 	.key_size = sizeof(int),
4060 	.value_size = 4,
4061 	.key_type_id = 1,
4062 	.value_type_id = 1,
4063 	.max_entries = 1,
4064 	.btf_load_err = true,
4065 	.err_str = "Invalid component_idx",
4066 },
4067 {
4068 	.descr = "decl_tag test #15, func, invalid func proto",
4069 	.raw_types = {
4070 		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),	/* [1] */
4071 		BTF_DECL_TAG_ENC(NAME_TBD, 3, 0),		/* [2] */
4072 		BTF_FUNC_ENC(NAME_TBD, 8),			/* [3] */
4073 		BTF_END_RAW,
4074 	},
4075 	BTF_STR_SEC("\0tag\0func"),
4076 	.map_type = BPF_MAP_TYPE_ARRAY,
4077 	.map_name = "tag_type_check_btf",
4078 	.key_size = sizeof(int),
4079 	.value_size = 4,
4080 	.key_type_id = 1,
4081 	.value_type_id = 1,
4082 	.max_entries = 1,
4083 	.btf_load_err = true,
4084 	.err_str = "Invalid type_id",
4085 },
4086 {
4087 	.descr = "decl_tag test #16, func proto, return type",
4088 	.raw_types = {
4089 		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),				/* [1] */
4090 		BTF_VAR_ENC(NAME_TBD, 1, 0),						/* [2] */
4091 		BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_DECL_TAG, 0, 0), 2), (-1),	/* [3] */
4092 		BTF_FUNC_PROTO_ENC(3, 0),						/* [4] */
4093 		BTF_END_RAW,
4094 	},
4095 	BTF_STR_SEC("\0local\0tag1"),
4096 	.btf_load_err = true,
4097 	.err_str = "Invalid return type",
4098 },
4099 {
4100 	.descr = "decl_tag test #17, func proto, argument",
4101 	.raw_types = {
4102 		BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_DECL_TAG, 0, 0), 4), (-1),	/* [1] */
4103 		BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_PTR, 0, 0), 0), /* [2] */
4104 		BTF_FUNC_PROTO_ENC(0, 1),			/* [3] */
4105 			BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
4106 		BTF_VAR_ENC(NAME_TBD, 2, 0),			/* [4] */
4107 		BTF_END_RAW,
4108 	},
4109 	BTF_STR_SEC("\0local\0tag1\0var"),
4110 	.btf_load_err = true,
4111 	.err_str = "Invalid arg#1",
4112 },
4113 {
4114 	.descr = "decl_tag test #18, decl_tag as the map key type",
4115 	.raw_types = {
4116 		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),	/* [1] */
4117 		BTF_STRUCT_ENC(0, 2, 8),			/* [2] */
4118 		BTF_MEMBER_ENC(NAME_TBD, 1, 0),
4119 		BTF_MEMBER_ENC(NAME_TBD, 1, 32),
4120 		BTF_DECL_TAG_ENC(NAME_TBD, 2, -1),		/* [3] */
4121 		BTF_END_RAW,
4122 	},
4123 	BTF_STR_SEC("\0m1\0m2\0tag"),
4124 	.map_type = BPF_MAP_TYPE_HASH,
4125 	.map_name = "tag_type_check_btf",
4126 	.key_size = 8,
4127 	.value_size = 4,
4128 	.key_type_id = 3,
4129 	.value_type_id = 1,
4130 	.max_entries = 1,
4131 	.map_create_err = true,
4132 },
4133 {
4134 	.descr = "decl_tag test #19, decl_tag as the map value type",
4135 	.raw_types = {
4136 		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),	/* [1] */
4137 		BTF_STRUCT_ENC(0, 2, 8),			/* [2] */
4138 		BTF_MEMBER_ENC(NAME_TBD, 1, 0),
4139 		BTF_MEMBER_ENC(NAME_TBD, 1, 32),
4140 		BTF_DECL_TAG_ENC(NAME_TBD, 2, -1),		/* [3] */
4141 		BTF_END_RAW,
4142 	},
4143 	BTF_STR_SEC("\0m1\0m2\0tag"),
4144 	.map_type = BPF_MAP_TYPE_HASH,
4145 	.map_name = "tag_type_check_btf",
4146 	.key_size = 4,
4147 	.value_size = 8,
4148 	.key_type_id = 1,
4149 	.value_type_id = 3,
4150 	.max_entries = 1,
4151 	.map_create_err = true,
4152 },
4153 {
4154 	.descr = "type_tag test #1",
4155 	.raw_types = {
4156 		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),	/* [1] */
4157 		BTF_TYPE_TAG_ENC(NAME_TBD, 1),			/* [2] */
4158 		BTF_PTR_ENC(2),					/* [3] */
4159 		BTF_END_RAW,
4160 	},
4161 	BTF_STR_SEC("\0tag"),
4162 	.map_type = BPF_MAP_TYPE_ARRAY,
4163 	.map_name = "tag_type_check_btf",
4164 	.key_size = sizeof(int),
4165 	.value_size = 4,
4166 	.key_type_id = 1,
4167 	.value_type_id = 1,
4168 	.max_entries = 1,
4169 },
4170 {
4171 	.descr = "type_tag test #2, type tag order",
4172 	.raw_types = {
4173 		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),	/* [1] */
4174 		BTF_CONST_ENC(3),				/* [2] */
4175 		BTF_TYPE_TAG_ENC(NAME_TBD, 1),			/* [3] */
4176 		BTF_END_RAW,
4177 	},
4178 	BTF_STR_SEC("\0tag"),
4179 	.map_type = BPF_MAP_TYPE_ARRAY,
4180 	.map_name = "tag_type_check_btf",
4181 	.key_size = sizeof(int),
4182 	.value_size = 4,
4183 	.key_type_id = 1,
4184 	.value_type_id = 1,
4185 	.max_entries = 1,
4186 },
4187 {
4188 	.descr = "type_tag test #3, type tag order",
4189 	.raw_types = {
4190 		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),	/* [1] */
4191 		BTF_TYPE_TAG_ENC(NAME_TBD, 3),			/* [2] */
4192 		BTF_CONST_ENC(4),				/* [3] */
4193 		BTF_TYPE_TAG_ENC(NAME_TBD, 1),			/* [4] */
4194 		BTF_END_RAW,
4195 	},
4196 	BTF_STR_SEC("\0tag\0tag"),
4197 	.map_type = BPF_MAP_TYPE_ARRAY,
4198 	.map_name = "tag_type_check_btf",
4199 	.key_size = sizeof(int),
4200 	.value_size = 4,
4201 	.key_type_id = 1,
4202 	.value_type_id = 1,
4203 	.max_entries = 1,
4204 },
4205 {
4206 	.descr = "type_tag test #4, type tag order",
4207 	.raw_types = {
4208 		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),	/* [1] */
4209 		BTF_TYPEDEF_ENC(NAME_TBD, 3),			/* [2] */
4210 		BTF_CONST_ENC(4),				/* [3] */
4211 		BTF_TYPE_TAG_ENC(NAME_TBD, 1),			/* [4] */
4212 		BTF_END_RAW,
4213 	},
4214 	BTF_STR_SEC("\0tag\0tag"),
4215 	.map_type = BPF_MAP_TYPE_ARRAY,
4216 	.map_name = "tag_type_check_btf",
4217 	.key_size = sizeof(int),
4218 	.value_size = 4,
4219 	.key_type_id = 1,
4220 	.value_type_id = 1,
4221 	.max_entries = 1,
4222 },
4223 {
4224 	.descr = "type_tag test #5, type tag order",
4225 	.raw_types = {
4226 		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),	/* [1] */
4227 		BTF_TYPE_TAG_ENC(NAME_TBD, 3),			/* [2] */
4228 		BTF_CONST_ENC(1),				/* [3] */
4229 		BTF_TYPE_TAG_ENC(NAME_TBD, 2),			/* [4] */
4230 		BTF_END_RAW,
4231 	},
4232 	BTF_STR_SEC("\0tag\0tag"),
4233 	.map_type = BPF_MAP_TYPE_ARRAY,
4234 	.map_name = "tag_type_check_btf",
4235 	.key_size = sizeof(int),
4236 	.value_size = 4,
4237 	.key_type_id = 1,
4238 	.value_type_id = 1,
4239 	.max_entries = 1,
4240 },
4241 {
4242 	.descr = "type_tag test #6, type tag order",
4243 	.raw_types = {
4244 		BTF_PTR_ENC(2),					/* [1] */
4245 		BTF_TYPE_TAG_ENC(NAME_TBD, 3),			/* [2] */
4246 		BTF_CONST_ENC(4),				/* [3] */
4247 		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),  /* [4] */
4248 		BTF_PTR_ENC(6),					/* [5] */
4249 		BTF_CONST_ENC(2),				/* [6] */
4250 		BTF_END_RAW,
4251 	},
4252 	BTF_STR_SEC("\0tag"),
4253 	.map_type = BPF_MAP_TYPE_ARRAY,
4254 	.map_name = "tag_type_check_btf",
4255 	.key_size = sizeof(int),
4256 	.value_size = 4,
4257 	.key_type_id = 4,
4258 	.value_type_id = 4,
4259 	.max_entries = 1,
4260 },
4261 {
4262 	.descr = "type_tag test #7, tag with kflag",
4263 	.raw_types = {
4264 		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),	/* [1] */
4265 		BTF_TYPE_ATTR_ENC(NAME_TBD, 1),			/* [2] */
4266 		BTF_PTR_ENC(2),					/* [3] */
4267 		BTF_END_RAW,
4268 	},
4269 	BTF_STR_SEC("\0tag"),
4270 	.map_type = BPF_MAP_TYPE_ARRAY,
4271 	.map_name = "tag_type_check_btf",
4272 	.key_size = sizeof(int),
4273 	.value_size = 4,
4274 	.key_type_id = 1,
4275 	.value_type_id = 1,
4276 	.max_entries = 1,
4277 },
4278 {
4279 	.descr = "enum64 test #1, unsigned, size 8",
4280 	.raw_types = {
4281 		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),			/* [1] */
4282 		BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_ENUM64, 0, 2), 8),	/* [2] */
4283 		BTF_ENUM64_ENC(NAME_TBD, 0, 0),
4284 		BTF_ENUM64_ENC(NAME_TBD, 1, 1),
4285 		BTF_END_RAW,
4286 	},
4287 	BTF_STR_SEC("\0a\0b\0c"),
4288 	.map_type = BPF_MAP_TYPE_ARRAY,
4289 	.map_name = "tag_type_check_btf",
4290 	.key_size = sizeof(int),
4291 	.value_size = 8,
4292 	.key_type_id = 1,
4293 	.value_type_id = 2,
4294 	.max_entries = 1,
4295 },
4296 {
4297 	.descr = "enum64 test #2, signed, size 4",
4298 	.raw_types = {
4299 		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),			/* [1] */
4300 		BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_ENUM64, 1, 2), 4),	/* [2] */
4301 		BTF_ENUM64_ENC(NAME_TBD, -1, 0),
4302 		BTF_ENUM64_ENC(NAME_TBD, 1, 0),
4303 		BTF_END_RAW,
4304 	},
4305 	BTF_STR_SEC("\0a\0b\0c"),
4306 	.map_type = BPF_MAP_TYPE_ARRAY,
4307 	.map_name = "tag_type_check_btf",
4308 	.key_size = sizeof(int),
4309 	.value_size = 4,
4310 	.key_type_id = 1,
4311 	.value_type_id = 2,
4312 	.max_entries = 1,
4313 },
4314 
4315 /*
4316  * struct inner {
4317  *     struct bpf_spin_lock lock;
4318  * };
4319  *
4320  * struct value {
4321  *     struct bpf_spin_lock lock;
4322  *     struct inner nested;
4323  * };
4324  */
4325 {
4326 	.descr = "struct test duplicate nested unique fields",
4327 	.raw_types = {
4328 		BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),	/* [1] */
4329 		BTF_STRUCT_ENC(NAME_TBD, 1, 4),				/* [2] */
4330 		BTF_MEMBER_ENC(NAME_TBD, 1, 0),
4331 		BTF_STRUCT_ENC(NAME_TBD, 1, 4),				/* [3] */
4332 		BTF_MEMBER_ENC(NAME_TBD, 2, 0),
4333 		BTF_STRUCT_ENC(NAME_TBD, 2, 8),				/* [4] */
4334 		BTF_MEMBER_ENC(NAME_TBD, 2, 0),
4335 		BTF_MEMBER_ENC(NAME_TBD, 3, 32),
4336 		BTF_END_RAW,
4337 	},
4338 	BTF_STR_SEC("\0int\0bpf_spin_lock\0val\0inner\0lock\0value\0lock\0nested"),
4339 	.btf_load_err = true,
4340 },
4341 
4342 /*
4343  * struct value {
4344  *     struct bpf_refcount a;
4345  *     struct bpf_refcount b;
4346  * };
4347  */
4348 {
4349 	.descr = "struct test duplicate bpf_refcount fields",
4350 	.raw_types = {
4351 		BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),	/* [1] */
4352 		BTF_STRUCT_ENC(NAME_TBD, 1, 4),				/* [2] */
4353 		BTF_MEMBER_ENC(NAME_TBD, 1, 0),
4354 		BTF_STRUCT_ENC(NAME_TBD, 2, 8),				/* [3] */
4355 		BTF_MEMBER_ENC(NAME_TBD, 2, 0),
4356 		BTF_MEMBER_ENC(NAME_TBD, 2, 32),
4357 		BTF_END_RAW,
4358 	},
4359 	BTF_STR_SEC("\0int\0bpf_refcount\0refs\0value\0a\0b"),
4360 	.btf_load_err = true,
4361 },
4362 
4363 {
4364 	.descr = "struct test repeated fields count overflow",
4365 	.raw_types = {
4366 		BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),	/* [1] */
4367 		BTF_STRUCT_ENC(NAME_TBD, 0, 0),				/* [2] */
4368 		BTF_TYPE_TAG_ENC(NAME_TBD, 2),				/* [3] */
4369 		BTF_PTR_ENC(3),						/* [4] */
4370 		BTF_TYPE_ARRAY_ENC(4, 1, 1),				/* [5] */
4371 		BTF_STRUCT_ENC(NAME_TBD, 10, 8),			/* [6] */
4372 		BTF_MEMBER_ENC(NAME_TBD, 5, 0),
4373 		BTF_MEMBER_ENC(NAME_TBD, 5, 0),
4374 		BTF_MEMBER_ENC(NAME_TBD, 5, 0),
4375 		BTF_MEMBER_ENC(NAME_TBD, 5, 0),
4376 		BTF_MEMBER_ENC(NAME_TBD, 5, 0),
4377 		BTF_MEMBER_ENC(NAME_TBD, 5, 0),
4378 		BTF_MEMBER_ENC(NAME_TBD, 5, 0),
4379 		BTF_MEMBER_ENC(NAME_TBD, 5, 0),
4380 		BTF_MEMBER_ENC(NAME_TBD, 5, 0),
4381 		BTF_MEMBER_ENC(NAME_TBD, 5, 0),
4382 		BTF_TYPE_ARRAY_ENC(6, 1, 0x1999999aU),			/* [7] */
4383 		BTF_STRUCT_ENC(NAME_TBD, 2, 8 + 8 * 0x1999999aU),	/* [8] */
4384 		BTF_MEMBER_ENC(NAME_TBD, 4, 0),
4385 		BTF_MEMBER_ENC(NAME_TBD, 7, 64),
4386 		BTF_END_RAW,
4387 	},
4388 	BTF_STR_SEC("\0int\0prog_test_ref_kfunc\0kptr_untrusted\0elem"
4389 		    "\0p0\0p1\0p2\0p3\0p4\0p5\0p6\0p7\0p8\0p9"
4390 		    "\0outer\0trigger\0elems"),
4391 	.map_type = BPF_MAP_TYPE_ARRAY,
4392 	.map_name = "repeat_fields",
4393 	.key_size = sizeof(int),
4394 	.value_size = 8 + 8 * 0x1999999aU,
4395 	.key_type_id = 1,
4396 	.value_type_id = 8,
4397 	.max_entries = 1,
4398 	.btf_load_err = true,
4399 },
4400 }; /* struct btf_raw_test raw_tests[] */
4401 
4402 static const char *get_next_str(const char *start, const char *end)
4403 {
4404 	return start < end - 1 ? start + 1 : NULL;
4405 }
4406 
4407 static int get_raw_sec_size(const __u32 *raw_types)
4408 {
4409 	int i;
4410 
4411 	for (i = MAX_NR_RAW_U32 - 1;
4412 	     i >= 0 && raw_types[i] != BTF_END_RAW;
4413 	     i--)
4414 		;
4415 
4416 	return i < 0 ? i : i * sizeof(raw_types[0]);
4417 }
4418 
4419 static void *btf_raw_create(const struct btf_header *hdr,
4420 			    const __u32 *raw_types,
4421 			    const char *str,
4422 			    unsigned int str_sec_size,
4423 			    unsigned int *btf_size,
4424 			    const char **ret_next_str)
4425 {
4426 	const char *next_str = str, *end_str = str + str_sec_size;
4427 	const char **strs_idx = NULL, **tmp_strs_idx;
4428 	int strs_cap = 0, strs_cnt = 0, next_str_idx = 0;
4429 	unsigned int size_needed, offset;
4430 	struct btf_header *ret_hdr;
4431 	int i, type_sec_size, err = 0;
4432 	uint32_t *ret_types;
4433 	void *raw_btf = NULL;
4434 
4435 	type_sec_size = get_raw_sec_size(raw_types);
4436 	if (CHECK(type_sec_size < 0, "Cannot get nr_raw_types"))
4437 		return NULL;
4438 
4439 	size_needed = sizeof(*hdr) + type_sec_size + str_sec_size;
4440 	raw_btf = malloc(size_needed);
4441 	if (CHECK(!raw_btf, "Cannot allocate memory for raw_btf"))
4442 		return NULL;
4443 
4444 	/* Copy header */
4445 	memcpy(raw_btf, hdr, sizeof(*hdr));
4446 	offset = sizeof(*hdr);
4447 
4448 	/* Index strings */
4449 	while ((next_str = get_next_str(next_str, end_str))) {
4450 		if (strs_cnt == strs_cap) {
4451 			strs_cap += max(16, strs_cap / 2);
4452 			tmp_strs_idx = realloc(strs_idx,
4453 					       sizeof(*strs_idx) * strs_cap);
4454 			if (CHECK(!tmp_strs_idx,
4455 				  "Cannot allocate memory for strs_idx")) {
4456 				err = -1;
4457 				goto done;
4458 			}
4459 			strs_idx = tmp_strs_idx;
4460 		}
4461 		strs_idx[strs_cnt++] = next_str;
4462 		next_str += strlen(next_str);
4463 	}
4464 
4465 	/* Copy type section */
4466 	ret_types = raw_btf + offset;
4467 	for (i = 0; i < type_sec_size / sizeof(raw_types[0]); i++) {
4468 		if (raw_types[i] == NAME_TBD) {
4469 			if (CHECK(next_str_idx == strs_cnt,
4470 				  "Error in getting next_str #%d",
4471 				  next_str_idx)) {
4472 				err = -1;
4473 				goto done;
4474 			}
4475 			ret_types[i] = strs_idx[next_str_idx++] - str;
4476 		} else if (IS_NAME_NTH(raw_types[i])) {
4477 			int idx = GET_NAME_NTH_IDX(raw_types[i]);
4478 
4479 			if (CHECK(idx <= 0 || idx > strs_cnt,
4480 				  "Error getting string #%d, strs_cnt:%d",
4481 				  idx, strs_cnt)) {
4482 				err = -1;
4483 				goto done;
4484 			}
4485 			ret_types[i] = strs_idx[idx-1] - str;
4486 		} else {
4487 			ret_types[i] = raw_types[i];
4488 		}
4489 	}
4490 	offset += type_sec_size;
4491 
4492 	/* Copy string section */
4493 	memcpy(raw_btf + offset, str, str_sec_size);
4494 
4495 	ret_hdr = (struct btf_header *)raw_btf;
4496 	ret_hdr->type_len = type_sec_size;
4497 	ret_hdr->str_off = type_sec_size;
4498 	ret_hdr->str_len = str_sec_size;
4499 
4500 	*btf_size = size_needed;
4501 	if (ret_next_str)
4502 		*ret_next_str =
4503 			next_str_idx < strs_cnt ? strs_idx[next_str_idx] : NULL;
4504 
4505 done:
4506 	free(strs_idx);
4507 	if (err) {
4508 		free(raw_btf);
4509 		return NULL;
4510 	}
4511 	return raw_btf;
4512 }
4513 
4514 static int load_raw_btf(const void *raw_data, size_t raw_size)
4515 {
4516 	LIBBPF_OPTS(bpf_btf_load_opts, opts);
4517 	int btf_fd;
4518 
4519 	if (always_log) {
4520 		opts.log_buf = btf_log_buf,
4521 		opts.log_size = BTF_LOG_BUF_SIZE,
4522 		opts.log_level = 1;
4523 	}
4524 
4525 	btf_fd = bpf_btf_load(raw_data, raw_size, &opts);
4526 	if (btf_fd < 0 && !always_log) {
4527 		opts.log_buf = btf_log_buf,
4528 		opts.log_size = BTF_LOG_BUF_SIZE,
4529 		opts.log_level = 1;
4530 		btf_fd = bpf_btf_load(raw_data, raw_size, &opts);
4531 	}
4532 
4533 	return btf_fd;
4534 }
4535 
4536 static void do_test_raw(unsigned int test_num)
4537 {
4538 	struct btf_raw_test *test = &raw_tests[test_num - 1];
4539 	LIBBPF_OPTS(bpf_map_create_opts, opts);
4540 	int map_fd = -1, btf_fd = -1;
4541 	unsigned int raw_btf_size;
4542 	struct btf_header *hdr;
4543 	void *raw_btf;
4544 	int err;
4545 
4546 	if (!test__start_subtest(test->descr))
4547 		return;
4548 
4549 	raw_btf = btf_raw_create(&hdr_tmpl,
4550 				 test->raw_types,
4551 				 test->str_sec,
4552 				 test->str_sec_size,
4553 				 &raw_btf_size, NULL);
4554 	if (!raw_btf)
4555 		return;
4556 
4557 	hdr = raw_btf;
4558 
4559 	hdr->hdr_len = (int)hdr->hdr_len + test->hdr_len_delta;
4560 	hdr->type_off = (int)hdr->type_off + test->type_off_delta;
4561 	hdr->str_off = (int)hdr->str_off + test->str_off_delta;
4562 	hdr->str_len = (int)hdr->str_len + test->str_len_delta;
4563 
4564 	*btf_log_buf = '\0';
4565 	btf_fd = load_raw_btf(raw_btf, raw_btf_size);
4566 	free(raw_btf);
4567 
4568 	err = ((btf_fd < 0) != test->btf_load_err);
4569 	if (CHECK(err, "btf_fd:%d test->btf_load_err:%u",
4570 		  btf_fd, test->btf_load_err) ||
4571 	    CHECK(test->err_str && !strstr(btf_log_buf, test->err_str),
4572 		  "expected err_str:%s\n", test->err_str)) {
4573 		err = -1;
4574 		goto done;
4575 	}
4576 
4577 	if (err || btf_fd < 0)
4578 		goto done;
4579 
4580 	if (!test->map_type)
4581 		goto done;
4582 
4583 	opts.btf_fd = btf_fd;
4584 	opts.btf_key_type_id = test->key_type_id;
4585 	opts.btf_value_type_id = test->value_type_id;
4586 	map_fd = bpf_map_create(test->map_type, test->map_name,
4587 				test->key_size, test->value_size, test->max_entries, &opts);
4588 
4589 	err = ((map_fd < 0) != test->map_create_err);
4590 	CHECK(err, "map_fd:%d test->map_create_err:%u",
4591 	      map_fd, test->map_create_err);
4592 
4593 done:
4594 	if (*btf_log_buf && (err || always_log))
4595 		fprintf(stderr, "\n%s", btf_log_buf);
4596 	if (btf_fd >= 0)
4597 		close(btf_fd);
4598 	if (map_fd >= 0)
4599 		close(map_fd);
4600 }
4601 
4602 struct btf_get_info_test {
4603 	const char *descr;
4604 	const char *str_sec;
4605 	__u32 raw_types[MAX_NR_RAW_U32];
4606 	__u32 str_sec_size;
4607 	int btf_size_delta;
4608 	int (*special_test)(unsigned int test_num);
4609 };
4610 
4611 static int test_big_btf_info(unsigned int test_num);
4612 static int test_btf_id(unsigned int test_num);
4613 
4614 const struct btf_get_info_test get_info_tests[] = {
4615 {
4616 	.descr = "== raw_btf_size+1",
4617 	.raw_types = {
4618 		/* int */				/* [1] */
4619 		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
4620 		BTF_END_RAW,
4621 	},
4622 	.str_sec = "",
4623 	.str_sec_size = sizeof(""),
4624 	.btf_size_delta = 1,
4625 },
4626 {
4627 	.descr = "== raw_btf_size-3",
4628 	.raw_types = {
4629 		/* int */				/* [1] */
4630 		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
4631 		BTF_END_RAW,
4632 	},
4633 	.str_sec = "",
4634 	.str_sec_size = sizeof(""),
4635 	.btf_size_delta = -3,
4636 },
4637 {
4638 	.descr = "Large bpf_btf_info",
4639 	.raw_types = {
4640 		/* int */				/* [1] */
4641 		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
4642 		BTF_END_RAW,
4643 	},
4644 	.str_sec = "",
4645 	.str_sec_size = sizeof(""),
4646 	.special_test = test_big_btf_info,
4647 },
4648 {
4649 	.descr = "BTF ID",
4650 	.raw_types = {
4651 		/* int */				/* [1] */
4652 		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
4653 		/* unsigned int */			/* [2] */
4654 		BTF_TYPE_INT_ENC(0, 0, 0, 32, 4),
4655 		BTF_END_RAW,
4656 	},
4657 	.str_sec = "",
4658 	.str_sec_size = sizeof(""),
4659 	.special_test = test_btf_id,
4660 },
4661 };
4662 
4663 static int test_big_btf_info(unsigned int test_num)
4664 {
4665 	const struct btf_get_info_test *test = &get_info_tests[test_num - 1];
4666 	uint8_t *raw_btf = NULL, *user_btf = NULL;
4667 	unsigned int raw_btf_size;
4668 	struct {
4669 		struct bpf_btf_info info;
4670 		uint64_t garbage;
4671 	} info_garbage;
4672 	struct bpf_btf_info *info;
4673 	int btf_fd = -1, err;
4674 	uint32_t info_len;
4675 
4676 	raw_btf = btf_raw_create(&hdr_tmpl,
4677 				 test->raw_types,
4678 				 test->str_sec,
4679 				 test->str_sec_size,
4680 				 &raw_btf_size, NULL);
4681 
4682 	if (!raw_btf)
4683 		return -1;
4684 
4685 	*btf_log_buf = '\0';
4686 
4687 	user_btf = malloc(raw_btf_size);
4688 	if (CHECK(!user_btf, "!user_btf")) {
4689 		err = -1;
4690 		goto done;
4691 	}
4692 
4693 	btf_fd = load_raw_btf(raw_btf, raw_btf_size);
4694 	if (CHECK(btf_fd < 0, "errno:%d", errno)) {
4695 		err = -1;
4696 		goto done;
4697 	}
4698 
4699 	/*
4700 	 * GET_INFO should error out if the userspace info
4701 	 * has non zero tailing bytes.
4702 	 */
4703 	info = &info_garbage.info;
4704 	memset(info, 0, sizeof(*info));
4705 	info_garbage.garbage = 0xdeadbeef;
4706 	info_len = sizeof(info_garbage);
4707 	info->btf = ptr_to_u64(user_btf);
4708 	info->btf_size = raw_btf_size;
4709 
4710 	err = bpf_btf_get_info_by_fd(btf_fd, info, &info_len);
4711 	if (CHECK(!err, "!err")) {
4712 		err = -1;
4713 		goto done;
4714 	}
4715 
4716 	/*
4717 	 * GET_INFO should succeed even info_len is larger than
4718 	 * the kernel supported as long as tailing bytes are zero.
4719 	 * The kernel supported info len should also be returned
4720 	 * to userspace.
4721 	 */
4722 	info_garbage.garbage = 0;
4723 	err = bpf_btf_get_info_by_fd(btf_fd, info, &info_len);
4724 	if (CHECK(err || info_len != sizeof(*info),
4725 		  "err:%d errno:%d info_len:%u sizeof(*info):%zu",
4726 		  err, errno, info_len, sizeof(*info))) {
4727 		err = -1;
4728 		goto done;
4729 	}
4730 
4731 	fprintf(stderr, "OK");
4732 
4733 done:
4734 	if (*btf_log_buf && (err || always_log))
4735 		fprintf(stderr, "\n%s", btf_log_buf);
4736 
4737 	free(raw_btf);
4738 	free(user_btf);
4739 
4740 	if (btf_fd >= 0)
4741 		close(btf_fd);
4742 
4743 	return err;
4744 }
4745 
4746 static int test_btf_id(unsigned int test_num)
4747 {
4748 	const struct btf_get_info_test *test = &get_info_tests[test_num - 1];
4749 	LIBBPF_OPTS(bpf_map_create_opts, opts);
4750 	uint8_t *raw_btf = NULL, *user_btf[2] = {};
4751 	int btf_fd[2] = {-1, -1}, map_fd = -1;
4752 	struct bpf_map_info map_info = {};
4753 	struct bpf_btf_info info[2] = {};
4754 	unsigned int raw_btf_size;
4755 	uint32_t info_len;
4756 	int err, i, ret;
4757 
4758 	raw_btf = btf_raw_create(&hdr_tmpl,
4759 				 test->raw_types,
4760 				 test->str_sec,
4761 				 test->str_sec_size,
4762 				 &raw_btf_size, NULL);
4763 
4764 	if (!raw_btf)
4765 		return -1;
4766 
4767 	*btf_log_buf = '\0';
4768 
4769 	for (i = 0; i < 2; i++) {
4770 		user_btf[i] = malloc(raw_btf_size);
4771 		if (CHECK(!user_btf[i], "!user_btf[%d]", i)) {
4772 			err = -1;
4773 			goto done;
4774 		}
4775 		info[i].btf = ptr_to_u64(user_btf[i]);
4776 		info[i].btf_size = raw_btf_size;
4777 	}
4778 
4779 	btf_fd[0] = load_raw_btf(raw_btf, raw_btf_size);
4780 	if (CHECK(btf_fd[0] < 0, "errno:%d", errno)) {
4781 		err = -1;
4782 		goto done;
4783 	}
4784 
4785 	/* Test BPF_OBJ_GET_INFO_BY_ID on btf_id */
4786 	info_len = sizeof(info[0]);
4787 	err = bpf_btf_get_info_by_fd(btf_fd[0], &info[0], &info_len);
4788 	if (CHECK(err, "errno:%d", errno)) {
4789 		err = -1;
4790 		goto done;
4791 	}
4792 
4793 	btf_fd[1] = bpf_btf_get_fd_by_id(info[0].id);
4794 	if (CHECK(btf_fd[1] < 0, "errno:%d", errno)) {
4795 		err = -1;
4796 		goto done;
4797 	}
4798 
4799 	ret = 0;
4800 	err = bpf_btf_get_info_by_fd(btf_fd[1], &info[1], &info_len);
4801 	if (CHECK(err || info[0].id != info[1].id ||
4802 		  info[0].btf_size != info[1].btf_size ||
4803 		  (ret = memcmp(user_btf[0], user_btf[1], info[0].btf_size)),
4804 		  "err:%d errno:%d id0:%u id1:%u btf_size0:%u btf_size1:%u memcmp:%d",
4805 		  err, errno, info[0].id, info[1].id,
4806 		  info[0].btf_size, info[1].btf_size, ret)) {
4807 		err = -1;
4808 		goto done;
4809 	}
4810 
4811 	/* Test btf members in struct bpf_map_info */
4812 	opts.btf_fd = btf_fd[0];
4813 	opts.btf_key_type_id = 1;
4814 	opts.btf_value_type_id = 2;
4815 	map_fd = bpf_map_create(BPF_MAP_TYPE_ARRAY, "test_btf_id",
4816 				sizeof(int), sizeof(int), 4, &opts);
4817 	if (CHECK(map_fd < 0, "errno:%d", errno)) {
4818 		err = -1;
4819 		goto done;
4820 	}
4821 
4822 	info_len = sizeof(map_info);
4823 	err = bpf_map_get_info_by_fd(map_fd, &map_info, &info_len);
4824 	if (CHECK(err || map_info.btf_id != info[0].id ||
4825 		  map_info.btf_key_type_id != 1 || map_info.btf_value_type_id != 2,
4826 		  "err:%d errno:%d info.id:%u btf_id:%u btf_key_type_id:%u btf_value_type_id:%u",
4827 		  err, errno, info[0].id, map_info.btf_id, map_info.btf_key_type_id,
4828 		  map_info.btf_value_type_id)) {
4829 		err = -1;
4830 		goto done;
4831 	}
4832 
4833 	for (i = 0; i < 2; i++) {
4834 		close(btf_fd[i]);
4835 		btf_fd[i] = -1;
4836 	}
4837 
4838 	/* Test BTF ID is removed from the kernel */
4839 	btf_fd[0] = bpf_btf_get_fd_by_id(map_info.btf_id);
4840 	if (CHECK(btf_fd[0] < 0, "errno:%d", errno)) {
4841 		err = -1;
4842 		goto done;
4843 	}
4844 	close(btf_fd[0]);
4845 	btf_fd[0] = -1;
4846 
4847 	/* The map holds the last ref to BTF and its btf_id */
4848 	close(map_fd);
4849 	map_fd = -1;
4850 
4851 	fprintf(stderr, "OK");
4852 
4853 done:
4854 	if (*btf_log_buf && (err || always_log))
4855 		fprintf(stderr, "\n%s", btf_log_buf);
4856 
4857 	free(raw_btf);
4858 	if (map_fd >= 0)
4859 		close(map_fd);
4860 	for (i = 0; i < 2; i++) {
4861 		free(user_btf[i]);
4862 		if (btf_fd[i] >= 0)
4863 			close(btf_fd[i]);
4864 	}
4865 
4866 	return err;
4867 }
4868 
4869 static void do_test_get_info(unsigned int test_num)
4870 {
4871 	const struct btf_get_info_test *test = &get_info_tests[test_num - 1];
4872 	unsigned int raw_btf_size, user_btf_size, expected_nbytes;
4873 	uint8_t *raw_btf = NULL, *user_btf = NULL;
4874 	struct bpf_btf_info info = {};
4875 	int btf_fd = -1, err, ret;
4876 	uint32_t info_len;
4877 
4878 	if (!test__start_subtest(test->descr))
4879 		return;
4880 
4881 	if (test->special_test) {
4882 		err = test->special_test(test_num);
4883 		if (CHECK(err, "failed: %d\n", err))
4884 			return;
4885 	}
4886 
4887 	raw_btf = btf_raw_create(&hdr_tmpl,
4888 				 test->raw_types,
4889 				 test->str_sec,
4890 				 test->str_sec_size,
4891 				 &raw_btf_size, NULL);
4892 
4893 	if (!raw_btf)
4894 		return;
4895 
4896 	*btf_log_buf = '\0';
4897 
4898 	user_btf = malloc(raw_btf_size);
4899 	if (CHECK(!user_btf, "!user_btf")) {
4900 		err = -1;
4901 		goto done;
4902 	}
4903 
4904 	btf_fd = load_raw_btf(raw_btf, raw_btf_size);
4905 	if (CHECK(btf_fd <= 0, "errno:%d", errno)) {
4906 		err = -1;
4907 		goto done;
4908 	}
4909 
4910 	user_btf_size = (int)raw_btf_size + test->btf_size_delta;
4911 	expected_nbytes = min(raw_btf_size, user_btf_size);
4912 	if (raw_btf_size > expected_nbytes)
4913 		memset(user_btf + expected_nbytes, 0xff,
4914 		       raw_btf_size - expected_nbytes);
4915 
4916 	info_len = sizeof(info);
4917 	info.btf = ptr_to_u64(user_btf);
4918 	info.btf_size = user_btf_size;
4919 
4920 	ret = 0;
4921 	err = bpf_btf_get_info_by_fd(btf_fd, &info, &info_len);
4922 	if (CHECK(err || !info.id || info_len != sizeof(info) ||
4923 		  info.btf_size != raw_btf_size ||
4924 		  (ret = memcmp(raw_btf, user_btf, expected_nbytes)),
4925 		  "err:%d errno:%d info.id:%u info_len:%u sizeof(info):%zu raw_btf_size:%u info.btf_size:%u expected_nbytes:%u memcmp:%d",
4926 		  err, errno, info.id, info_len, sizeof(info),
4927 		  raw_btf_size, info.btf_size, expected_nbytes, ret)) {
4928 		err = -1;
4929 		goto done;
4930 	}
4931 
4932 	while (expected_nbytes < raw_btf_size) {
4933 		fprintf(stderr, "%u...", expected_nbytes);
4934 		if (CHECK(user_btf[expected_nbytes++] != 0xff,
4935 			  "user_btf[%u]:%x != 0xff", expected_nbytes - 1,
4936 			  user_btf[expected_nbytes - 1])) {
4937 			err = -1;
4938 			goto done;
4939 		}
4940 	}
4941 
4942 	fprintf(stderr, "OK");
4943 
4944 done:
4945 	if (*btf_log_buf && (err || always_log))
4946 		fprintf(stderr, "\n%s", btf_log_buf);
4947 
4948 	free(raw_btf);
4949 	free(user_btf);
4950 
4951 	if (btf_fd >= 0)
4952 		close(btf_fd);
4953 }
4954 
4955 struct btf_file_test {
4956 	const char *file;
4957 	bool btf_kv_notfound;
4958 };
4959 
4960 static struct btf_file_test file_tests[] = {
4961 	{ .file = "test_btf_newkv.bpf.o", },
4962 	{ .file = "test_btf_nokv.bpf.o", .btf_kv_notfound = true, },
4963 };
4964 
4965 static void do_test_file(unsigned int test_num)
4966 {
4967 	const struct btf_file_test *test = &file_tests[test_num - 1];
4968 	const char *expected_fnames[] = {"_dummy_tracepoint",
4969 					 "test_long_fname_1",
4970 					 "test_long_fname_2"};
4971 	struct btf_ext *btf_ext = NULL;
4972 	struct bpf_prog_info info = {};
4973 	struct bpf_object *obj = NULL;
4974 	struct bpf_func_info *finfo;
4975 	struct bpf_program *prog;
4976 	__u32 info_len, rec_size;
4977 	bool has_btf_ext = false;
4978 	struct btf *btf = NULL;
4979 	void *func_info = NULL;
4980 	struct bpf_map *map;
4981 	int i, err, prog_fd;
4982 
4983 	if (!test__start_subtest(test->file))
4984 		return;
4985 
4986 	btf = btf__parse_elf(test->file, &btf_ext);
4987 	err = libbpf_get_error(btf);
4988 	if (err) {
4989 		if (err == -ENOENT) {
4990 			printf("%s:SKIP: No ELF %s found", __func__, BTF_ELF_SEC);
4991 			test__skip();
4992 			return;
4993 		}
4994 		return;
4995 	}
4996 	btf__free(btf);
4997 
4998 	has_btf_ext = btf_ext != NULL;
4999 	btf_ext__free(btf_ext);
5000 
5001 	/* temporary disable LIBBPF_STRICT_MAP_DEFINITIONS to test legacy maps */
5002 	libbpf_set_strict_mode(LIBBPF_STRICT_ALL & ~LIBBPF_STRICT_MAP_DEFINITIONS);
5003 	obj = bpf_object__open(test->file);
5004 	err = libbpf_get_error(obj);
5005 	if (CHECK(err, "obj: %d", err))
5006 		return;
5007 
5008 	prog = bpf_object__next_program(obj, NULL);
5009 	if (CHECK(!prog, "Cannot find bpf_prog")) {
5010 		err = -1;
5011 		goto done;
5012 	}
5013 
5014 	bpf_program__set_type(prog, BPF_PROG_TYPE_TRACEPOINT);
5015 	err = bpf_object__load(obj);
5016 	if (CHECK(err < 0, "bpf_object__load: %d", err))
5017 		goto done;
5018 	prog_fd = bpf_program__fd(prog);
5019 
5020 	map = bpf_object__find_map_by_name(obj, "btf_map");
5021 	if (CHECK(!map, "btf_map not found")) {
5022 		err = -1;
5023 		goto done;
5024 	}
5025 
5026 	err = (bpf_map__btf_key_type_id(map) == 0 || bpf_map__btf_value_type_id(map) == 0)
5027 		!= test->btf_kv_notfound;
5028 	if (CHECK(err, "btf_key_type_id:%u btf_value_type_id:%u test->btf_kv_notfound:%u",
5029 		  bpf_map__btf_key_type_id(map), bpf_map__btf_value_type_id(map),
5030 		  test->btf_kv_notfound))
5031 		goto done;
5032 
5033 	if (!has_btf_ext)
5034 		goto skip;
5035 
5036 	/* get necessary program info */
5037 	info_len = sizeof(struct bpf_prog_info);
5038 	err = bpf_prog_get_info_by_fd(prog_fd, &info, &info_len);
5039 
5040 	if (CHECK(err < 0, "invalid get info (1st) errno:%d", errno)) {
5041 		fprintf(stderr, "%s\n", btf_log_buf);
5042 		err = -1;
5043 		goto done;
5044 	}
5045 	if (CHECK(info.nr_func_info != 3,
5046 		  "incorrect info.nr_func_info (1st) %d",
5047 		  info.nr_func_info)) {
5048 		err = -1;
5049 		goto done;
5050 	}
5051 	rec_size = info.func_info_rec_size;
5052 	if (CHECK(rec_size != sizeof(struct bpf_func_info),
5053 		  "incorrect info.func_info_rec_size (1st) %d\n", rec_size)) {
5054 		err = -1;
5055 		goto done;
5056 	}
5057 
5058 	func_info = malloc(info.nr_func_info * rec_size);
5059 	if (CHECK(!func_info, "out of memory")) {
5060 		err = -1;
5061 		goto done;
5062 	}
5063 
5064 	/* reset info to only retrieve func_info related data */
5065 	memset(&info, 0, sizeof(info));
5066 	info.nr_func_info = 3;
5067 	info.func_info_rec_size = rec_size;
5068 	info.func_info = ptr_to_u64(func_info);
5069 
5070 	err = bpf_prog_get_info_by_fd(prog_fd, &info, &info_len);
5071 
5072 	if (CHECK(err < 0, "invalid get info (2nd) errno:%d", errno)) {
5073 		fprintf(stderr, "%s\n", btf_log_buf);
5074 		err = -1;
5075 		goto done;
5076 	}
5077 	if (CHECK(info.nr_func_info != 3,
5078 		  "incorrect info.nr_func_info (2nd) %d",
5079 		  info.nr_func_info)) {
5080 		err = -1;
5081 		goto done;
5082 	}
5083 	if (CHECK(info.func_info_rec_size != rec_size,
5084 		  "incorrect info.func_info_rec_size (2nd) %d",
5085 		  info.func_info_rec_size)) {
5086 		err = -1;
5087 		goto done;
5088 	}
5089 
5090 	btf = btf__load_from_kernel_by_id(info.btf_id);
5091 	err = libbpf_get_error(btf);
5092 	if (CHECK(err, "cannot get btf from kernel, err: %d", err))
5093 		goto done;
5094 
5095 	/* check three functions */
5096 	finfo = func_info;
5097 	for (i = 0; i < 3; i++) {
5098 		const struct btf_type *t;
5099 		const char *fname;
5100 
5101 		t = btf__type_by_id(btf, finfo->type_id);
5102 		if (CHECK(!t, "btf__type_by_id failure: id %u",
5103 			  finfo->type_id)) {
5104 			err = -1;
5105 			goto done;
5106 		}
5107 
5108 		fname = btf__name_by_offset(btf, t->name_off);
5109 		err = strcmp(fname, expected_fnames[i]);
5110 		/* for the second and third functions in .text section,
5111 		 * the compiler may order them either way.
5112 		 */
5113 		if (i && err)
5114 			err = strcmp(fname, expected_fnames[3 - i]);
5115 		if (CHECK(err, "incorrect fname %s", fname ? : "")) {
5116 			err = -1;
5117 			goto done;
5118 		}
5119 
5120 		finfo = (void *)finfo + rec_size;
5121 	}
5122 
5123 skip:
5124 	fprintf(stderr, "OK");
5125 
5126 done:
5127 	libbpf_set_strict_mode(LIBBPF_STRICT_ALL);
5128 
5129 	btf__free(btf);
5130 	free(func_info);
5131 	bpf_object__close(obj);
5132 }
5133 
5134 const char *pprint_enum_str[] = {
5135 	"ENUM_ZERO",
5136 	"ENUM_ONE",
5137 	"ENUM_TWO",
5138 	"ENUM_THREE",
5139 };
5140 
5141 struct pprint_mapv {
5142 	uint32_t ui32;
5143 	uint16_t ui16;
5144 	/* 2 bytes hole */
5145 	int32_t si32;
5146 	uint32_t unused_bits2a:2,
5147 		bits28:28,
5148 		unused_bits2b:2;
5149 	union {
5150 		uint64_t ui64;
5151 		uint8_t ui8a[8];
5152 	};
5153 	enum {
5154 		ENUM_ZERO,
5155 		ENUM_ONE,
5156 		ENUM_TWO,
5157 		ENUM_THREE,
5158 	} aenum;
5159 	uint32_t ui32b;
5160 	uint32_t bits2c:2;
5161 	uint8_t si8_4[2][2];
5162 };
5163 
5164 #ifdef __SIZEOF_INT128__
5165 struct pprint_mapv_int128 {
5166 	__int128 si128a;
5167 	__int128 si128b;
5168 	unsigned __int128 bits3:3;
5169 	unsigned __int128 bits80:80;
5170 	unsigned __int128 ui128;
5171 };
5172 #endif
5173 
5174 static struct btf_raw_test pprint_test_template[] = {
5175 {
5176 	.raw_types = {
5177 		/* unsigned char */			/* [1] */
5178 		BTF_TYPE_INT_ENC(NAME_TBD, 0, 0, 8, 1),
5179 		/* unsigned short */			/* [2] */
5180 		BTF_TYPE_INT_ENC(NAME_TBD, 0, 0, 16, 2),
5181 		/* unsigned int */			/* [3] */
5182 		BTF_TYPE_INT_ENC(NAME_TBD, 0, 0, 32, 4),
5183 		/* int */				/* [4] */
5184 		BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),
5185 		/* unsigned long long */		/* [5] */
5186 		BTF_TYPE_INT_ENC(NAME_TBD, 0, 0, 64, 8),
5187 		/* 2 bits */				/* [6] */
5188 		BTF_TYPE_INT_ENC(0, 0, 0, 2, 2),
5189 		/* 28 bits */				/* [7] */
5190 		BTF_TYPE_INT_ENC(0, 0, 0, 28, 4),
5191 		/* uint8_t[8] */			/* [8] */
5192 		BTF_TYPE_ARRAY_ENC(9, 1, 8),
5193 		/* typedef unsigned char uint8_t */	/* [9] */
5194 		BTF_TYPEDEF_ENC(NAME_TBD, 1),
5195 		/* typedef unsigned short uint16_t */	/* [10] */
5196 		BTF_TYPEDEF_ENC(NAME_TBD, 2),
5197 		/* typedef unsigned int uint32_t */	/* [11] */
5198 		BTF_TYPEDEF_ENC(NAME_TBD, 3),
5199 		/* typedef int int32_t */		/* [12] */
5200 		BTF_TYPEDEF_ENC(NAME_TBD, 4),
5201 		/* typedef unsigned long long uint64_t *//* [13] */
5202 		BTF_TYPEDEF_ENC(NAME_TBD, 5),
5203 		/* union (anon) */			/* [14] */
5204 		BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_UNION, 0, 2), 8),
5205 		BTF_MEMBER_ENC(NAME_TBD, 13, 0),/* uint64_t ui64; */
5206 		BTF_MEMBER_ENC(NAME_TBD, 8, 0),	/* uint8_t ui8a[8]; */
5207 		/* enum (anon) */			/* [15] */
5208 		BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_ENUM, 0, 4), 4),
5209 		BTF_ENUM_ENC(NAME_TBD, 0),
5210 		BTF_ENUM_ENC(NAME_TBD, 1),
5211 		BTF_ENUM_ENC(NAME_TBD, 2),
5212 		BTF_ENUM_ENC(NAME_TBD, 3),
5213 		/* struct pprint_mapv */		/* [16] */
5214 		BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 11), 40),
5215 		BTF_MEMBER_ENC(NAME_TBD, 11, 0),	/* uint32_t ui32 */
5216 		BTF_MEMBER_ENC(NAME_TBD, 10, 32),	/* uint16_t ui16 */
5217 		BTF_MEMBER_ENC(NAME_TBD, 12, 64),	/* int32_t si32 */
5218 		BTF_MEMBER_ENC(NAME_TBD, 6, 96),	/* unused_bits2a */
5219 		BTF_MEMBER_ENC(NAME_TBD, 7, 98),	/* bits28 */
5220 		BTF_MEMBER_ENC(NAME_TBD, 6, 126),	/* unused_bits2b */
5221 		BTF_MEMBER_ENC(0, 14, 128),		/* union (anon) */
5222 		BTF_MEMBER_ENC(NAME_TBD, 15, 192),	/* aenum */
5223 		BTF_MEMBER_ENC(NAME_TBD, 11, 224),	/* uint32_t ui32b */
5224 		BTF_MEMBER_ENC(NAME_TBD, 6, 256),	/* bits2c */
5225 		BTF_MEMBER_ENC(NAME_TBD, 17, 264),	/* si8_4 */
5226 		BTF_TYPE_ARRAY_ENC(18, 1, 2),		/* [17] */
5227 		BTF_TYPE_ARRAY_ENC(1, 1, 2),		/* [18] */
5228 		BTF_END_RAW,
5229 	},
5230 	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"),
5231 	.key_size = sizeof(unsigned int),
5232 	.value_size = sizeof(struct pprint_mapv),
5233 	.key_type_id = 3,	/* unsigned int */
5234 	.value_type_id = 16,	/* struct pprint_mapv */
5235 	.max_entries = 128,
5236 },
5237 
5238 {
5239 	/* this type will have the same type as the
5240 	 * first .raw_types definition, but struct type will
5241 	 * be encoded with kind_flag set.
5242 	 */
5243 	.raw_types = {
5244 		/* unsigned char */			/* [1] */
5245 		BTF_TYPE_INT_ENC(NAME_TBD, 0, 0, 8, 1),
5246 		/* unsigned short */			/* [2] */
5247 		BTF_TYPE_INT_ENC(NAME_TBD, 0, 0, 16, 2),
5248 		/* unsigned int */			/* [3] */
5249 		BTF_TYPE_INT_ENC(NAME_TBD, 0, 0, 32, 4),
5250 		/* int */				/* [4] */
5251 		BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),
5252 		/* unsigned long long */		/* [5] */
5253 		BTF_TYPE_INT_ENC(NAME_TBD, 0, 0, 64, 8),
5254 		BTF_TYPE_INT_ENC(0, 0, 0, 32, 4),	/* [6] */
5255 		BTF_TYPE_INT_ENC(0, 0, 0, 32, 4),	/* [7] */
5256 		/* uint8_t[8] */			/* [8] */
5257 		BTF_TYPE_ARRAY_ENC(9, 1, 8),
5258 		/* typedef unsigned char uint8_t */	/* [9] */
5259 		BTF_TYPEDEF_ENC(NAME_TBD, 1),
5260 		/* typedef unsigned short uint16_t */	/* [10] */
5261 		BTF_TYPEDEF_ENC(NAME_TBD, 2),
5262 		/* typedef unsigned int uint32_t */	/* [11] */
5263 		BTF_TYPEDEF_ENC(NAME_TBD, 3),
5264 		/* typedef int int32_t */		/* [12] */
5265 		BTF_TYPEDEF_ENC(NAME_TBD, 4),
5266 		/* typedef unsigned long long uint64_t *//* [13] */
5267 		BTF_TYPEDEF_ENC(NAME_TBD, 5),
5268 		/* union (anon) */			/* [14] */
5269 		BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_UNION, 0, 2), 8),
5270 		BTF_MEMBER_ENC(NAME_TBD, 13, 0),/* uint64_t ui64; */
5271 		BTF_MEMBER_ENC(NAME_TBD, 8, 0),	/* uint8_t ui8a[8]; */
5272 		/* enum (anon) */			/* [15] */
5273 		BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_ENUM, 0, 4), 4),
5274 		BTF_ENUM_ENC(NAME_TBD, 0),
5275 		BTF_ENUM_ENC(NAME_TBD, 1),
5276 		BTF_ENUM_ENC(NAME_TBD, 2),
5277 		BTF_ENUM_ENC(NAME_TBD, 3),
5278 		/* struct pprint_mapv */		/* [16] */
5279 		BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 1, 11), 40),
5280 		BTF_MEMBER_ENC(NAME_TBD, 11, BTF_MEMBER_OFFSET(0, 0)),	/* uint32_t ui32 */
5281 		BTF_MEMBER_ENC(NAME_TBD, 10, BTF_MEMBER_OFFSET(0, 32)),	/* uint16_t ui16 */
5282 		BTF_MEMBER_ENC(NAME_TBD, 12, BTF_MEMBER_OFFSET(0, 64)),	/* int32_t si32 */
5283 		BTF_MEMBER_ENC(NAME_TBD, 6, BTF_MEMBER_OFFSET(2, 96)),	/* unused_bits2a */
5284 		BTF_MEMBER_ENC(NAME_TBD, 7, BTF_MEMBER_OFFSET(28, 98)),	/* bits28 */
5285 		BTF_MEMBER_ENC(NAME_TBD, 6, BTF_MEMBER_OFFSET(2, 126)),	/* unused_bits2b */
5286 		BTF_MEMBER_ENC(0, 14, BTF_MEMBER_OFFSET(0, 128)),	/* union (anon) */
5287 		BTF_MEMBER_ENC(NAME_TBD, 15, BTF_MEMBER_OFFSET(0, 192)),	/* aenum */
5288 		BTF_MEMBER_ENC(NAME_TBD, 11, BTF_MEMBER_OFFSET(0, 224)),	/* uint32_t ui32b */
5289 		BTF_MEMBER_ENC(NAME_TBD, 6, BTF_MEMBER_OFFSET(2, 256)),	/* bits2c */
5290 		BTF_MEMBER_ENC(NAME_TBD, 17, 264),	/* si8_4 */
5291 		BTF_TYPE_ARRAY_ENC(18, 1, 2),		/* [17] */
5292 		BTF_TYPE_ARRAY_ENC(1, 1, 2),		/* [18] */
5293 		BTF_END_RAW,
5294 	},
5295 	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"),
5296 	.key_size = sizeof(unsigned int),
5297 	.value_size = sizeof(struct pprint_mapv),
5298 	.key_type_id = 3,	/* unsigned int */
5299 	.value_type_id = 16,	/* struct pprint_mapv */
5300 	.max_entries = 128,
5301 },
5302 
5303 {
5304 	/* this type will have the same layout as the
5305 	 * first .raw_types definition. The struct type will
5306 	 * be encoded with kind_flag set, bitfield members
5307 	 * are added typedef/const/volatile, and bitfield members
5308 	 * will have both int and enum types.
5309 	 */
5310 	.raw_types = {
5311 		/* unsigned char */			/* [1] */
5312 		BTF_TYPE_INT_ENC(NAME_TBD, 0, 0, 8, 1),
5313 		/* unsigned short */			/* [2] */
5314 		BTF_TYPE_INT_ENC(NAME_TBD, 0, 0, 16, 2),
5315 		/* unsigned int */			/* [3] */
5316 		BTF_TYPE_INT_ENC(NAME_TBD, 0, 0, 32, 4),
5317 		/* int */				/* [4] */
5318 		BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),
5319 		/* unsigned long long */		/* [5] */
5320 		BTF_TYPE_INT_ENC(NAME_TBD, 0, 0, 64, 8),
5321 		BTF_TYPE_INT_ENC(0, 0, 0, 32, 4),	/* [6] */
5322 		BTF_TYPE_INT_ENC(0, 0, 0, 32, 4),	/* [7] */
5323 		/* uint8_t[8] */			/* [8] */
5324 		BTF_TYPE_ARRAY_ENC(9, 1, 8),
5325 		/* typedef unsigned char uint8_t */	/* [9] */
5326 		BTF_TYPEDEF_ENC(NAME_TBD, 1),
5327 		/* typedef unsigned short uint16_t */	/* [10] */
5328 		BTF_TYPEDEF_ENC(NAME_TBD, 2),
5329 		/* typedef unsigned int uint32_t */	/* [11] */
5330 		BTF_TYPEDEF_ENC(NAME_TBD, 3),
5331 		/* typedef int int32_t */		/* [12] */
5332 		BTF_TYPEDEF_ENC(NAME_TBD, 4),
5333 		/* typedef unsigned long long uint64_t *//* [13] */
5334 		BTF_TYPEDEF_ENC(NAME_TBD, 5),
5335 		/* union (anon) */			/* [14] */
5336 		BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_UNION, 0, 2), 8),
5337 		BTF_MEMBER_ENC(NAME_TBD, 13, 0),/* uint64_t ui64; */
5338 		BTF_MEMBER_ENC(NAME_TBD, 8, 0),	/* uint8_t ui8a[8]; */
5339 		/* enum (anon) */			/* [15] */
5340 		BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_ENUM, 0, 4), 4),
5341 		BTF_ENUM_ENC(NAME_TBD, 0),
5342 		BTF_ENUM_ENC(NAME_TBD, 1),
5343 		BTF_ENUM_ENC(NAME_TBD, 2),
5344 		BTF_ENUM_ENC(NAME_TBD, 3),
5345 		/* struct pprint_mapv */		/* [16] */
5346 		BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 1, 11), 40),
5347 		BTF_MEMBER_ENC(NAME_TBD, 11, BTF_MEMBER_OFFSET(0, 0)),	/* uint32_t ui32 */
5348 		BTF_MEMBER_ENC(NAME_TBD, 10, BTF_MEMBER_OFFSET(0, 32)),	/* uint16_t ui16 */
5349 		BTF_MEMBER_ENC(NAME_TBD, 12, BTF_MEMBER_OFFSET(0, 64)),	/* int32_t si32 */
5350 		BTF_MEMBER_ENC(NAME_TBD, 17, BTF_MEMBER_OFFSET(2, 96)),	/* unused_bits2a */
5351 		BTF_MEMBER_ENC(NAME_TBD, 7, BTF_MEMBER_OFFSET(28, 98)),	/* bits28 */
5352 		BTF_MEMBER_ENC(NAME_TBD, 19, BTF_MEMBER_OFFSET(2, 126)),/* unused_bits2b */
5353 		BTF_MEMBER_ENC(0, 14, BTF_MEMBER_OFFSET(0, 128)),	/* union (anon) */
5354 		BTF_MEMBER_ENC(NAME_TBD, 15, BTF_MEMBER_OFFSET(0, 192)),	/* aenum */
5355 		BTF_MEMBER_ENC(NAME_TBD, 11, BTF_MEMBER_OFFSET(0, 224)),	/* uint32_t ui32b */
5356 		BTF_MEMBER_ENC(NAME_TBD, 17, BTF_MEMBER_OFFSET(2, 256)),	/* bits2c */
5357 		BTF_MEMBER_ENC(NAME_TBD, 20, BTF_MEMBER_OFFSET(0, 264)),	/* si8_4 */
5358 		/* typedef unsigned int ___int */	/* [17] */
5359 		BTF_TYPEDEF_ENC(NAME_TBD, 18),
5360 		BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_VOLATILE, 0, 0), 6),	/* [18] */
5361 		BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_CONST, 0, 0), 15),	/* [19] */
5362 		BTF_TYPE_ARRAY_ENC(21, 1, 2),					/* [20] */
5363 		BTF_TYPE_ARRAY_ENC(1, 1, 2),					/* [21] */
5364 		BTF_END_RAW,
5365 	},
5366 	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"),
5367 	.key_size = sizeof(unsigned int),
5368 	.value_size = sizeof(struct pprint_mapv),
5369 	.key_type_id = 3,	/* unsigned int */
5370 	.value_type_id = 16,	/* struct pprint_mapv */
5371 	.max_entries = 128,
5372 },
5373 
5374 #ifdef __SIZEOF_INT128__
5375 {
5376 	/* test int128 */
5377 	.raw_types = {
5378 		/* unsigned int */				/* [1] */
5379 		BTF_TYPE_INT_ENC(NAME_TBD, 0, 0, 32, 4),
5380 		/* __int128 */					/* [2] */
5381 		BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 128, 16),
5382 		/* unsigned __int128 */				/* [3] */
5383 		BTF_TYPE_INT_ENC(NAME_TBD, 0, 0, 128, 16),
5384 		/* struct pprint_mapv_int128 */			/* [4] */
5385 		BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 1, 5), 64),
5386 		BTF_MEMBER_ENC(NAME_TBD, 2, BTF_MEMBER_OFFSET(0, 0)),		/* si128a */
5387 		BTF_MEMBER_ENC(NAME_TBD, 2, BTF_MEMBER_OFFSET(0, 128)),		/* si128b */
5388 		BTF_MEMBER_ENC(NAME_TBD, 3, BTF_MEMBER_OFFSET(3, 256)),		/* bits3 */
5389 		BTF_MEMBER_ENC(NAME_TBD, 3, BTF_MEMBER_OFFSET(80, 259)),	/* bits80 */
5390 		BTF_MEMBER_ENC(NAME_TBD, 3, BTF_MEMBER_OFFSET(0, 384)),		/* ui128 */
5391 		BTF_END_RAW,
5392 	},
5393 	BTF_STR_SEC("\0unsigned int\0__int128\0unsigned __int128\0pprint_mapv_int128\0si128a\0si128b\0bits3\0bits80\0ui128"),
5394 	.key_size = sizeof(unsigned int),
5395 	.value_size = sizeof(struct pprint_mapv_int128),
5396 	.key_type_id = 1,
5397 	.value_type_id = 4,
5398 	.max_entries = 128,
5399 	.mapv_kind = PPRINT_MAPV_KIND_INT128,
5400 },
5401 #endif
5402 
5403 };
5404 
5405 static struct btf_pprint_test_meta {
5406 	const char *descr;
5407 	enum bpf_map_type map_type;
5408 	const char *map_name;
5409 	bool ordered_map;
5410 	bool lossless_map;
5411 	bool percpu_map;
5412 } pprint_tests_meta[] = {
5413 {
5414 	.descr = "BTF pretty print array",
5415 	.map_type = BPF_MAP_TYPE_ARRAY,
5416 	.map_name = "pprint_test_array",
5417 	.ordered_map = true,
5418 	.lossless_map = true,
5419 	.percpu_map = false,
5420 },
5421 
5422 {
5423 	.descr = "BTF pretty print hash",
5424 	.map_type = BPF_MAP_TYPE_HASH,
5425 	.map_name = "pprint_test_hash",
5426 	.ordered_map = false,
5427 	.lossless_map = true,
5428 	.percpu_map = false,
5429 },
5430 
5431 {
5432 	.descr = "BTF pretty print lru hash",
5433 	.map_type = BPF_MAP_TYPE_LRU_HASH,
5434 	.map_name = "pprint_test_lru_hash",
5435 	.ordered_map = false,
5436 	.lossless_map = false,
5437 	.percpu_map = false,
5438 },
5439 
5440 {
5441 	.descr = "BTF pretty print percpu array",
5442 	.map_type = BPF_MAP_TYPE_PERCPU_ARRAY,
5443 	.map_name = "pprint_test_percpu_array",
5444 	.ordered_map = true,
5445 	.lossless_map = true,
5446 	.percpu_map = true,
5447 },
5448 
5449 {
5450 	.descr = "BTF pretty print percpu hash",
5451 	.map_type = BPF_MAP_TYPE_PERCPU_HASH,
5452 	.map_name = "pprint_test_percpu_hash",
5453 	.ordered_map = false,
5454 	.lossless_map = true,
5455 	.percpu_map = true,
5456 },
5457 
5458 {
5459 	.descr = "BTF pretty print lru percpu hash",
5460 	.map_type = BPF_MAP_TYPE_LRU_PERCPU_HASH,
5461 	.map_name = "pprint_test_lru_percpu_hash",
5462 	.ordered_map = false,
5463 	.lossless_map = false,
5464 	.percpu_map = true,
5465 },
5466 
5467 };
5468 
5469 static size_t get_pprint_mapv_size(enum pprint_mapv_kind_t mapv_kind)
5470 {
5471 	if (mapv_kind == PPRINT_MAPV_KIND_BASIC)
5472 		return sizeof(struct pprint_mapv);
5473 
5474 #ifdef __SIZEOF_INT128__
5475 	if (mapv_kind == PPRINT_MAPV_KIND_INT128)
5476 		return sizeof(struct pprint_mapv_int128);
5477 #endif
5478 
5479 	assert(0);
5480 	return 0;
5481 }
5482 
5483 static void set_pprint_mapv(enum pprint_mapv_kind_t mapv_kind,
5484 			    void *mapv, uint32_t i,
5485 			    int num_cpus, int rounded_value_size)
5486 {
5487 	int cpu;
5488 
5489 	if (mapv_kind == PPRINT_MAPV_KIND_BASIC) {
5490 		struct pprint_mapv *v = mapv;
5491 
5492 		for (cpu = 0; cpu < num_cpus; cpu++) {
5493 			v->ui32 = i + cpu;
5494 			v->si32 = -i;
5495 			v->unused_bits2a = 3;
5496 			v->bits28 = i;
5497 			v->unused_bits2b = 3;
5498 			v->ui64 = i;
5499 			v->aenum = i & 0x03;
5500 			v->ui32b = 4;
5501 			v->bits2c = 1;
5502 			v->si8_4[0][0] = (cpu + i) & 0xff;
5503 			v->si8_4[0][1] = (cpu + i + 1) & 0xff;
5504 			v->si8_4[1][0] = (cpu + i + 2) & 0xff;
5505 			v->si8_4[1][1] = (cpu + i + 3) & 0xff;
5506 			v = (void *)v + rounded_value_size;
5507 		}
5508 	}
5509 
5510 #ifdef __SIZEOF_INT128__
5511 	if (mapv_kind == PPRINT_MAPV_KIND_INT128) {
5512 		struct pprint_mapv_int128 *v = mapv;
5513 
5514 		for (cpu = 0; cpu < num_cpus; cpu++) {
5515 			v->si128a = i;
5516 			v->si128b = -i;
5517 			v->bits3 = i & 0x07;
5518 			v->bits80 = (((unsigned __int128)1) << 64) + i;
5519 			v->ui128 = (((unsigned __int128)2) << 64) + i;
5520 			v = (void *)v + rounded_value_size;
5521 		}
5522 	}
5523 #endif
5524 }
5525 
5526 ssize_t get_pprint_expected_line(enum pprint_mapv_kind_t mapv_kind,
5527 				 char *expected_line, ssize_t line_size,
5528 				 bool percpu_map, unsigned int next_key,
5529 				 int cpu, void *mapv)
5530 {
5531 	ssize_t nexpected_line = -1;
5532 
5533 	if (mapv_kind == PPRINT_MAPV_KIND_BASIC) {
5534 		struct pprint_mapv *v = mapv;
5535 
5536 		nexpected_line = snprintf(expected_line, line_size,
5537 					  "%s%u: {%u,0,%d,0x%x,0x%x,0x%x,"
5538 					  "{%llu|[%u,%u,%u,%u,%u,%u,%u,%u]},%s,"
5539 					  "%u,0x%x,[[%d,%d],[%d,%d]]}\n",
5540 					  percpu_map ? "\tcpu" : "",
5541 					  percpu_map ? cpu : next_key,
5542 					  v->ui32, v->si32,
5543 					  v->unused_bits2a,
5544 					  v->bits28,
5545 					  v->unused_bits2b,
5546 					  (__u64)v->ui64,
5547 					  v->ui8a[0], v->ui8a[1],
5548 					  v->ui8a[2], v->ui8a[3],
5549 					  v->ui8a[4], v->ui8a[5],
5550 					  v->ui8a[6], v->ui8a[7],
5551 					  pprint_enum_str[v->aenum],
5552 					  v->ui32b,
5553 					  v->bits2c,
5554 					  v->si8_4[0][0], v->si8_4[0][1],
5555 					  v->si8_4[1][0], v->si8_4[1][1]);
5556 	}
5557 
5558 #ifdef __SIZEOF_INT128__
5559 	if (mapv_kind == PPRINT_MAPV_KIND_INT128) {
5560 		struct pprint_mapv_int128 *v = mapv;
5561 
5562 		nexpected_line = snprintf(expected_line, line_size,
5563 					  "%s%u: {0x%lx,0x%lx,0x%lx,"
5564 					  "0x%lx%016lx,0x%lx%016lx}\n",
5565 					  percpu_map ? "\tcpu" : "",
5566 					  percpu_map ? cpu : next_key,
5567 					  (uint64_t)v->si128a,
5568 					  (uint64_t)v->si128b,
5569 					  (uint64_t)v->bits3,
5570 					  (uint64_t)(v->bits80 >> 64),
5571 					  (uint64_t)v->bits80,
5572 					  (uint64_t)(v->ui128 >> 64),
5573 					  (uint64_t)v->ui128);
5574 	}
5575 #endif
5576 
5577 	return nexpected_line;
5578 }
5579 
5580 static int check_line(const char *expected_line, int nexpected_line,
5581 		      int expected_line_len, const char *line)
5582 {
5583 	if (CHECK(nexpected_line == expected_line_len,
5584 		  "expected_line is too long"))
5585 		return -1;
5586 
5587 	if (strcmp(expected_line, line)) {
5588 		fprintf(stderr, "unexpected pprint output\n");
5589 		fprintf(stderr, "expected: %s", expected_line);
5590 		fprintf(stderr, "    read: %s", line);
5591 		return -1;
5592 	}
5593 
5594 	return 0;
5595 }
5596 
5597 
5598 static void do_test_pprint(int test_num)
5599 {
5600 	const struct btf_raw_test *test = &pprint_test_template[test_num];
5601 	enum pprint_mapv_kind_t mapv_kind = test->mapv_kind;
5602 	LIBBPF_OPTS(bpf_map_create_opts, opts);
5603 	bool ordered_map, lossless_map, percpu_map;
5604 	int err, ret, num_cpus, rounded_value_size;
5605 	unsigned int key, nr_read_elems;
5606 	int map_fd = -1, btf_fd = -1;
5607 	unsigned int raw_btf_size;
5608 	char expected_line[255];
5609 	FILE *pin_file = NULL;
5610 	char pin_path[255];
5611 	size_t line_len = 0;
5612 	char *line = NULL;
5613 	void *mapv = NULL;
5614 	uint8_t *raw_btf;
5615 	ssize_t nread;
5616 
5617 	if (!test__start_subtest(test->descr))
5618 		return;
5619 
5620 	raw_btf = btf_raw_create(&hdr_tmpl, test->raw_types,
5621 				 test->str_sec, test->str_sec_size,
5622 				 &raw_btf_size, NULL);
5623 
5624 	if (!raw_btf)
5625 		return;
5626 
5627 	*btf_log_buf = '\0';
5628 	btf_fd = load_raw_btf(raw_btf, raw_btf_size);
5629 	free(raw_btf);
5630 
5631 	if (CHECK(btf_fd < 0, "errno:%d\n", errno)) {
5632 		err = -1;
5633 		goto done;
5634 	}
5635 
5636 	opts.btf_fd = btf_fd;
5637 	opts.btf_key_type_id = test->key_type_id;
5638 	opts.btf_value_type_id = test->value_type_id;
5639 	map_fd = bpf_map_create(test->map_type, test->map_name,
5640 				test->key_size, test->value_size, test->max_entries, &opts);
5641 	if (CHECK(map_fd < 0, "errno:%d", errno)) {
5642 		err = -1;
5643 		goto done;
5644 	}
5645 
5646 	ret = snprintf(pin_path, sizeof(pin_path), "%s/%s",
5647 		       "/sys/fs/bpf", test->map_name);
5648 
5649 	if (CHECK(ret >= sizeof(pin_path), "pin_path %s/%s is too long",
5650 		  "/sys/fs/bpf", test->map_name)) {
5651 		err = -1;
5652 		goto done;
5653 	}
5654 
5655 	err = bpf_obj_pin(map_fd, pin_path);
5656 	if (CHECK(err, "bpf_obj_pin(%s): errno:%d.", pin_path, errno))
5657 		goto done;
5658 
5659 	percpu_map = test->percpu_map;
5660 	num_cpus = percpu_map ? bpf_num_possible_cpus() : 1;
5661 	rounded_value_size = round_up(get_pprint_mapv_size(mapv_kind), 8);
5662 	mapv = calloc(num_cpus, rounded_value_size);
5663 	if (CHECK(!mapv, "mapv allocation failure")) {
5664 		err = -1;
5665 		goto done;
5666 	}
5667 
5668 	for (key = 0; key < test->max_entries; key++) {
5669 		set_pprint_mapv(mapv_kind, mapv, key, num_cpus, rounded_value_size);
5670 		bpf_map_update_elem(map_fd, &key, mapv, 0);
5671 	}
5672 
5673 	pin_file = fopen(pin_path, "r");
5674 	if (CHECK(!pin_file, "fopen(%s): errno:%d", pin_path, errno)) {
5675 		err = -1;
5676 		goto done;
5677 	}
5678 
5679 	/* Skip lines start with '#' */
5680 	while ((nread = getline(&line, &line_len, pin_file)) > 0 &&
5681 	       *line == '#')
5682 		;
5683 
5684 	if (CHECK(nread <= 0, "Unexpected EOF")) {
5685 		err = -1;
5686 		goto done;
5687 	}
5688 
5689 	nr_read_elems = 0;
5690 	ordered_map = test->ordered_map;
5691 	lossless_map = test->lossless_map;
5692 	do {
5693 		ssize_t nexpected_line;
5694 		unsigned int next_key;
5695 		void *cmapv;
5696 		int cpu;
5697 
5698 		next_key = ordered_map ? nr_read_elems : atoi(line);
5699 		set_pprint_mapv(mapv_kind, mapv, next_key, num_cpus, rounded_value_size);
5700 		cmapv = mapv;
5701 
5702 		for (cpu = 0; cpu < num_cpus; cpu++) {
5703 			if (percpu_map) {
5704 				/* for percpu map, the format looks like:
5705 				 * <key>: {
5706 				 *	cpu0: <value_on_cpu0>
5707 				 *	cpu1: <value_on_cpu1>
5708 				 *	...
5709 				 *	cpun: <value_on_cpun>
5710 				 * }
5711 				 *
5712 				 * let us verify the line containing the key here.
5713 				 */
5714 				if (cpu == 0) {
5715 					nexpected_line = snprintf(expected_line,
5716 								  sizeof(expected_line),
5717 								  "%u: {\n",
5718 								  next_key);
5719 
5720 					err = check_line(expected_line, nexpected_line,
5721 							 sizeof(expected_line), line);
5722 					if (err < 0)
5723 						goto done;
5724 				}
5725 
5726 				/* read value@cpu */
5727 				nread = getline(&line, &line_len, pin_file);
5728 				if (nread < 0)
5729 					break;
5730 			}
5731 
5732 			nexpected_line = get_pprint_expected_line(mapv_kind, expected_line,
5733 								  sizeof(expected_line),
5734 								  percpu_map, next_key,
5735 								  cpu, cmapv);
5736 			err = check_line(expected_line, nexpected_line,
5737 					 sizeof(expected_line), line);
5738 			if (err < 0)
5739 				goto done;
5740 
5741 			cmapv = cmapv + rounded_value_size;
5742 		}
5743 
5744 		if (percpu_map) {
5745 			/* skip the last bracket for the percpu map */
5746 			nread = getline(&line, &line_len, pin_file);
5747 			if (nread < 0)
5748 				break;
5749 		}
5750 
5751 		nread = getline(&line, &line_len, pin_file);
5752 	} while (++nr_read_elems < test->max_entries && nread > 0);
5753 
5754 	if (lossless_map &&
5755 	    CHECK(nr_read_elems < test->max_entries,
5756 		  "Unexpected EOF. nr_read_elems:%u test->max_entries:%u",
5757 		  nr_read_elems, test->max_entries)) {
5758 		err = -1;
5759 		goto done;
5760 	}
5761 
5762 	if (CHECK(nread > 0, "Unexpected extra pprint output: %s", line)) {
5763 		err = -1;
5764 		goto done;
5765 	}
5766 
5767 	err = 0;
5768 
5769 done:
5770 	if (mapv)
5771 		free(mapv);
5772 	if (!err)
5773 		fprintf(stderr, "OK");
5774 	if (*btf_log_buf && (err || always_log))
5775 		fprintf(stderr, "\n%s", btf_log_buf);
5776 	if (btf_fd >= 0)
5777 		close(btf_fd);
5778 	if (map_fd >= 0)
5779 		close(map_fd);
5780 	if (pin_file)
5781 		fclose(pin_file);
5782 	unlink(pin_path);
5783 	free(line);
5784 }
5785 
5786 static void test_pprint(void)
5787 {
5788 	unsigned int i;
5789 
5790 	/* test various maps with the first test template */
5791 	for (i = 0; i < ARRAY_SIZE(pprint_tests_meta); i++) {
5792 		pprint_test_template[0].descr = pprint_tests_meta[i].descr;
5793 		pprint_test_template[0].map_type = pprint_tests_meta[i].map_type;
5794 		pprint_test_template[0].map_name = pprint_tests_meta[i].map_name;
5795 		pprint_test_template[0].ordered_map = pprint_tests_meta[i].ordered_map;
5796 		pprint_test_template[0].lossless_map = pprint_tests_meta[i].lossless_map;
5797 		pprint_test_template[0].percpu_map = pprint_tests_meta[i].percpu_map;
5798 
5799 		do_test_pprint(0);
5800 	}
5801 
5802 	/* test rest test templates with the first map */
5803 	for (i = 1; i < ARRAY_SIZE(pprint_test_template); i++) {
5804 		pprint_test_template[i].descr = pprint_tests_meta[0].descr;
5805 		pprint_test_template[i].map_type = pprint_tests_meta[0].map_type;
5806 		pprint_test_template[i].map_name = pprint_tests_meta[0].map_name;
5807 		pprint_test_template[i].ordered_map = pprint_tests_meta[0].ordered_map;
5808 		pprint_test_template[i].lossless_map = pprint_tests_meta[0].lossless_map;
5809 		pprint_test_template[i].percpu_map = pprint_tests_meta[0].percpu_map;
5810 		do_test_pprint(i);
5811 	}
5812 }
5813 
5814 #define BPF_LINE_INFO_ENC(insn_off, file_off, line_off, line_num, line_col) \
5815 	(insn_off), (file_off), (line_off), ((line_num) << 10 | ((line_col) & 0x3ff))
5816 
5817 static struct prog_info_raw_test {
5818 	const char *descr;
5819 	const char *str_sec;
5820 	const char *err_str;
5821 	__u32 raw_types[MAX_NR_RAW_U32];
5822 	__u32 str_sec_size;
5823 	struct bpf_insn insns[MAX_INSNS];
5824 	__u32 prog_type;
5825 	__u32 func_info[MAX_SUBPROGS][2];
5826 	__u32 func_info_rec_size;
5827 	__u32 func_info_cnt;
5828 	__u32 line_info[MAX_NR_RAW_U32];
5829 	__u32 line_info_rec_size;
5830 	__u32 nr_jited_ksyms;
5831 	bool expected_prog_load_failure;
5832 	__u32 dead_code_cnt;
5833 	__u32 dead_code_mask;
5834 	__u32 dead_func_cnt;
5835 	__u32 dead_func_mask;
5836 } info_raw_tests[] = {
5837 {
5838 	.descr = "func_type (main func + one sub)",
5839 	.raw_types = {
5840 		BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),	/* [1] */
5841 		BTF_TYPE_INT_ENC(NAME_TBD, 0, 0, 32, 4),	/* [2] */
5842 		BTF_FUNC_PROTO_ENC(1, 2),			/* [3] */
5843 			BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
5844 			BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 2),
5845 		BTF_FUNC_PROTO_ENC(1, 2),			/* [4] */
5846 			BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 2),
5847 			BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
5848 		BTF_FUNC_ENC(NAME_TBD, 3),			/* [5] */
5849 		BTF_FUNC_ENC(NAME_TBD, 4),			/* [6] */
5850 		BTF_END_RAW,
5851 	},
5852 	.str_sec = "\0int\0unsigned int\0a\0b\0c\0d\0funcA\0funcB",
5853 	.str_sec_size = sizeof("\0int\0unsigned int\0a\0b\0c\0d\0funcA\0funcB"),
5854 	.insns = {
5855 		BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2),
5856 		BPF_MOV64_IMM(BPF_REG_0, 1),
5857 		BPF_EXIT_INSN(),
5858 		BPF_MOV64_IMM(BPF_REG_0, 2),
5859 		BPF_EXIT_INSN(),
5860 	},
5861 	.prog_type = BPF_PROG_TYPE_TRACEPOINT,
5862 	.func_info = { {0, 5}, {3, 6} },
5863 	.func_info_rec_size = 8,
5864 	.func_info_cnt = 2,
5865 	.line_info = { BTF_END_RAW },
5866 },
5867 
5868 {
5869 	.descr = "func_type (Incorrect func_info_rec_size)",
5870 	.raw_types = {
5871 		BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),	/* [1] */
5872 		BTF_TYPE_INT_ENC(NAME_TBD, 0, 0, 32, 4),	/* [2] */
5873 		BTF_FUNC_PROTO_ENC(1, 2),			/* [3] */
5874 			BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
5875 			BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 2),
5876 		BTF_FUNC_PROTO_ENC(1, 2),			/* [4] */
5877 			BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 2),
5878 			BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
5879 		BTF_FUNC_ENC(NAME_TBD, 3),			/* [5] */
5880 		BTF_FUNC_ENC(NAME_TBD, 4),			/* [6] */
5881 		BTF_END_RAW,
5882 	},
5883 	.str_sec = "\0int\0unsigned int\0a\0b\0c\0d\0funcA\0funcB",
5884 	.str_sec_size = sizeof("\0int\0unsigned int\0a\0b\0c\0d\0funcA\0funcB"),
5885 	.insns = {
5886 		BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2),
5887 		BPF_MOV64_IMM(BPF_REG_0, 1),
5888 		BPF_EXIT_INSN(),
5889 		BPF_MOV64_IMM(BPF_REG_0, 2),
5890 		BPF_EXIT_INSN(),
5891 	},
5892 	.prog_type = BPF_PROG_TYPE_TRACEPOINT,
5893 	.func_info = { {0, 5}, {3, 6} },
5894 	.func_info_rec_size = 4,
5895 	.func_info_cnt = 2,
5896 	.line_info = { BTF_END_RAW },
5897 	.expected_prog_load_failure = true,
5898 },
5899 
5900 {
5901 	.descr = "func_type (Incorrect func_info_cnt)",
5902 	.raw_types = {
5903 		BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),	/* [1] */
5904 		BTF_TYPE_INT_ENC(NAME_TBD, 0, 0, 32, 4),	/* [2] */
5905 		BTF_FUNC_PROTO_ENC(1, 2),			/* [3] */
5906 			BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
5907 			BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 2),
5908 		BTF_FUNC_PROTO_ENC(1, 2),			/* [4] */
5909 			BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 2),
5910 			BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
5911 		BTF_FUNC_ENC(NAME_TBD, 3),			/* [5] */
5912 		BTF_FUNC_ENC(NAME_TBD, 4),			/* [6] */
5913 		BTF_END_RAW,
5914 	},
5915 	.str_sec = "\0int\0unsigned int\0a\0b\0c\0d\0funcA\0funcB",
5916 	.str_sec_size = sizeof("\0int\0unsigned int\0a\0b\0c\0d\0funcA\0funcB"),
5917 	.insns = {
5918 		BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2),
5919 		BPF_MOV64_IMM(BPF_REG_0, 1),
5920 		BPF_EXIT_INSN(),
5921 		BPF_MOV64_IMM(BPF_REG_0, 2),
5922 		BPF_EXIT_INSN(),
5923 	},
5924 	.prog_type = BPF_PROG_TYPE_TRACEPOINT,
5925 	.func_info = { {0, 5}, {3, 6} },
5926 	.func_info_rec_size = 8,
5927 	.func_info_cnt = 1,
5928 	.line_info = { BTF_END_RAW },
5929 	.expected_prog_load_failure = true,
5930 },
5931 
5932 {
5933 	.descr = "func_type (Incorrect bpf_func_info.insn_off)",
5934 	.raw_types = {
5935 		BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),	/* [1] */
5936 		BTF_TYPE_INT_ENC(NAME_TBD, 0, 0, 32, 4),	/* [2] */
5937 		BTF_FUNC_PROTO_ENC(1, 2),			/* [3] */
5938 			BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
5939 			BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 2),
5940 		BTF_FUNC_PROTO_ENC(1, 2),			/* [4] */
5941 			BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 2),
5942 			BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
5943 		BTF_FUNC_ENC(NAME_TBD, 3),			/* [5] */
5944 		BTF_FUNC_ENC(NAME_TBD, 4),			/* [6] */
5945 		BTF_END_RAW,
5946 	},
5947 	.str_sec = "\0int\0unsigned int\0a\0b\0c\0d\0funcA\0funcB",
5948 	.str_sec_size = sizeof("\0int\0unsigned int\0a\0b\0c\0d\0funcA\0funcB"),
5949 	.insns = {
5950 		BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2),
5951 		BPF_MOV64_IMM(BPF_REG_0, 1),
5952 		BPF_EXIT_INSN(),
5953 		BPF_MOV64_IMM(BPF_REG_0, 2),
5954 		BPF_EXIT_INSN(),
5955 	},
5956 	.prog_type = BPF_PROG_TYPE_TRACEPOINT,
5957 	.func_info = { {0, 5}, {2, 6} },
5958 	.func_info_rec_size = 8,
5959 	.func_info_cnt = 2,
5960 	.line_info = { BTF_END_RAW },
5961 	.expected_prog_load_failure = true,
5962 },
5963 
5964 {
5965 	.descr = "line_info (No subprog)",
5966 	.raw_types = {
5967 		BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),	/* [1] */
5968 		BTF_END_RAW,
5969 	},
5970 	BTF_STR_SEC("\0int\0int a=1;\0int b=2;\0return a + b;\0return a + b;"),
5971 	.insns = {
5972 		BPF_MOV64_IMM(BPF_REG_0, 1),
5973 		BPF_MOV64_IMM(BPF_REG_1, 2),
5974 		BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
5975 		BPF_EXIT_INSN(),
5976 	},
5977 	.prog_type = BPF_PROG_TYPE_TRACEPOINT,
5978 	.func_info_cnt = 0,
5979 	.line_info = {
5980 		BPF_LINE_INFO_ENC(0, 0, NAME_TBD, 1, 10),
5981 		BPF_LINE_INFO_ENC(1, 0, NAME_TBD, 2, 9),
5982 		BPF_LINE_INFO_ENC(2, 0, NAME_TBD, 3, 8),
5983 		BPF_LINE_INFO_ENC(3, 0, NAME_TBD, 4, 7),
5984 		BTF_END_RAW,
5985 	},
5986 	.line_info_rec_size = sizeof(struct bpf_line_info),
5987 	.nr_jited_ksyms = 1,
5988 },
5989 
5990 {
5991 	.descr = "line_info (No subprog. insn_off >= prog->len)",
5992 	.raw_types = {
5993 		BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),	/* [1] */
5994 		BTF_END_RAW,
5995 	},
5996 	BTF_STR_SEC("\0int\0int a=1;\0int b=2;\0return a + b;\0return a + b;"),
5997 	.insns = {
5998 		BPF_MOV64_IMM(BPF_REG_0, 1),
5999 		BPF_MOV64_IMM(BPF_REG_1, 2),
6000 		BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
6001 		BPF_EXIT_INSN(),
6002 	},
6003 	.prog_type = BPF_PROG_TYPE_TRACEPOINT,
6004 	.func_info_cnt = 0,
6005 	.line_info = {
6006 		BPF_LINE_INFO_ENC(0, 0, NAME_TBD, 1, 10),
6007 		BPF_LINE_INFO_ENC(1, 0, NAME_TBD, 2, 9),
6008 		BPF_LINE_INFO_ENC(2, 0, NAME_TBD, 3, 8),
6009 		BPF_LINE_INFO_ENC(3, 0, NAME_TBD, 4, 7),
6010 		BPF_LINE_INFO_ENC(4, 0, 0, 5, 6),
6011 		BTF_END_RAW,
6012 	},
6013 	.line_info_rec_size = sizeof(struct bpf_line_info),
6014 	.nr_jited_ksyms = 1,
6015 	.err_str = "line_info[4].insn_off",
6016 	.expected_prog_load_failure = true,
6017 },
6018 
6019 {
6020 	.descr = "line_info (Zero bpf insn code)",
6021 	.raw_types = {
6022 		BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),	/* [1] */
6023 		BTF_TYPE_INT_ENC(NAME_TBD, 0, 0, 64, 8),	/* [2] */
6024 		BTF_TYPEDEF_ENC(NAME_TBD, 2),			/* [3] */
6025 		BTF_END_RAW,
6026 	},
6027 	BTF_STR_SEC("\0int\0unsigned long\0u64\0u64 a=1;\0return a;"),
6028 	.insns = {
6029 		BPF_LD_IMM64(BPF_REG_0, 1),
6030 		BPF_EXIT_INSN(),
6031 	},
6032 	.prog_type = BPF_PROG_TYPE_TRACEPOINT,
6033 	.func_info_cnt = 0,
6034 	.line_info = {
6035 		BPF_LINE_INFO_ENC(0, 0, NAME_TBD, 1, 10),
6036 		BPF_LINE_INFO_ENC(1, 0, 0, 2, 9),
6037 		BPF_LINE_INFO_ENC(2, 0, NAME_TBD, 3, 8),
6038 		BTF_END_RAW,
6039 	},
6040 	.line_info_rec_size = sizeof(struct bpf_line_info),
6041 	.nr_jited_ksyms = 1,
6042 	.err_str = "Invalid insn code at line_info[1]",
6043 	.expected_prog_load_failure = true,
6044 },
6045 
6046 {
6047 	.descr = "line_info (No subprog. zero tailing line_info",
6048 	.raw_types = {
6049 		BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),	/* [1] */
6050 		BTF_END_RAW,
6051 	},
6052 	BTF_STR_SEC("\0int\0int a=1;\0int b=2;\0return a + b;\0return a + b;"),
6053 	.insns = {
6054 		BPF_MOV64_IMM(BPF_REG_0, 1),
6055 		BPF_MOV64_IMM(BPF_REG_1, 2),
6056 		BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
6057 		BPF_EXIT_INSN(),
6058 	},
6059 	.prog_type = BPF_PROG_TYPE_TRACEPOINT,
6060 	.func_info_cnt = 0,
6061 	.line_info = {
6062 		BPF_LINE_INFO_ENC(0, 0, NAME_TBD, 1, 10), 0,
6063 		BPF_LINE_INFO_ENC(1, 0, NAME_TBD, 2, 9), 0,
6064 		BPF_LINE_INFO_ENC(2, 0, NAME_TBD, 3, 8), 0,
6065 		BPF_LINE_INFO_ENC(3, 0, NAME_TBD, 4, 7), 0,
6066 		BTF_END_RAW,
6067 	},
6068 	.line_info_rec_size = sizeof(struct bpf_line_info) + sizeof(__u32),
6069 	.nr_jited_ksyms = 1,
6070 },
6071 
6072 {
6073 	.descr = "line_info (No subprog. nonzero tailing line_info)",
6074 	.raw_types = {
6075 		BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),	/* [1] */
6076 		BTF_END_RAW,
6077 	},
6078 	BTF_STR_SEC("\0int\0int a=1;\0int b=2;\0return a + b;\0return a + b;"),
6079 	.insns = {
6080 		BPF_MOV64_IMM(BPF_REG_0, 1),
6081 		BPF_MOV64_IMM(BPF_REG_1, 2),
6082 		BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
6083 		BPF_EXIT_INSN(),
6084 	},
6085 	.prog_type = BPF_PROG_TYPE_TRACEPOINT,
6086 	.func_info_cnt = 0,
6087 	.line_info = {
6088 		BPF_LINE_INFO_ENC(0, 0, NAME_TBD, 1, 10), 0,
6089 		BPF_LINE_INFO_ENC(1, 0, NAME_TBD, 2, 9), 0,
6090 		BPF_LINE_INFO_ENC(2, 0, NAME_TBD, 3, 8), 0,
6091 		BPF_LINE_INFO_ENC(3, 0, NAME_TBD, 4, 7), 1,
6092 		BTF_END_RAW,
6093 	},
6094 	.line_info_rec_size = sizeof(struct bpf_line_info) + sizeof(__u32),
6095 	.nr_jited_ksyms = 1,
6096 	.err_str = "nonzero tailing record in line_info",
6097 	.expected_prog_load_failure = true,
6098 },
6099 
6100 {
6101 	.descr = "line_info (subprog)",
6102 	.raw_types = {
6103 		BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),	/* [1] */
6104 		BTF_END_RAW,
6105 	},
6106 	BTF_STR_SEC("\0int\0int a=1+1;\0return func(a);\0b+=1;\0return b;"),
6107 	.insns = {
6108 		BPF_MOV64_IMM(BPF_REG_2, 1),
6109 		BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, 1),
6110 		BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
6111 		BPF_CALL_REL(1),
6112 		BPF_EXIT_INSN(),
6113 		BPF_MOV64_REG(BPF_REG_0, BPF_REG_1),
6114 		BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 1),
6115 		BPF_EXIT_INSN(),
6116 	},
6117 	.prog_type = BPF_PROG_TYPE_TRACEPOINT,
6118 	.func_info_cnt = 0,
6119 	.line_info = {
6120 		BPF_LINE_INFO_ENC(0, 0, NAME_TBD, 1, 10),
6121 		BPF_LINE_INFO_ENC(2, 0, NAME_TBD, 2, 9),
6122 		BPF_LINE_INFO_ENC(5, 0, NAME_TBD, 3, 8),
6123 		BPF_LINE_INFO_ENC(7, 0, NAME_TBD, 4, 7),
6124 		BTF_END_RAW,
6125 	},
6126 	.line_info_rec_size = sizeof(struct bpf_line_info),
6127 	.nr_jited_ksyms = 2,
6128 },
6129 
6130 {
6131 	.descr = "line_info (subprog + func_info)",
6132 	.raw_types = {
6133 		BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),	/* [1] */
6134 		BTF_FUNC_PROTO_ENC(1, 1),			/* [2] */
6135 			BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
6136 		BTF_FUNC_ENC(NAME_TBD, 2),			/* [3] */
6137 		BTF_FUNC_ENC(NAME_TBD, 2),			/* [4] */
6138 		BTF_END_RAW,
6139 	},
6140 	BTF_STR_SEC("\0int\0x\0sub\0main\0int a=1+1;\0return func(a);\0b+=1;\0return b;"),
6141 	.insns = {
6142 		BPF_MOV64_IMM(BPF_REG_2, 1),
6143 		BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, 1),
6144 		BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
6145 		BPF_CALL_REL(1),
6146 		BPF_EXIT_INSN(),
6147 		BPF_MOV64_REG(BPF_REG_0, BPF_REG_1),
6148 		BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 1),
6149 		BPF_EXIT_INSN(),
6150 	},
6151 	.prog_type = BPF_PROG_TYPE_TRACEPOINT,
6152 	.func_info_cnt = 2,
6153 	.func_info_rec_size = 8,
6154 	.func_info = { {0, 4}, {5, 3} },
6155 	.line_info = {
6156 		BPF_LINE_INFO_ENC(0, 0, NAME_TBD, 1, 10),
6157 		BPF_LINE_INFO_ENC(2, 0, NAME_TBD, 2, 9),
6158 		BPF_LINE_INFO_ENC(5, 0, NAME_TBD, 3, 8),
6159 		BPF_LINE_INFO_ENC(7, 0, NAME_TBD, 4, 7),
6160 		BTF_END_RAW,
6161 	},
6162 	.line_info_rec_size = sizeof(struct bpf_line_info),
6163 	.nr_jited_ksyms = 2,
6164 },
6165 
6166 {
6167 	.descr = "line_info (subprog. missing 1st func line info)",
6168 	.raw_types = {
6169 		BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),	/* [1] */
6170 		BTF_END_RAW,
6171 	},
6172 	BTF_STR_SEC("\0int\0int a=1+1;\0return func(a);\0b+=1;\0return b;"),
6173 	.insns = {
6174 		BPF_MOV64_IMM(BPF_REG_2, 1),
6175 		BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, 1),
6176 		BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
6177 		BPF_CALL_REL(1),
6178 		BPF_EXIT_INSN(),
6179 		BPF_MOV64_REG(BPF_REG_0, BPF_REG_1),
6180 		BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 1),
6181 		BPF_EXIT_INSN(),
6182 	},
6183 	.prog_type = BPF_PROG_TYPE_TRACEPOINT,
6184 	.func_info_cnt = 0,
6185 	.line_info = {
6186 		BPF_LINE_INFO_ENC(1, 0, NAME_TBD, 1, 10),
6187 		BPF_LINE_INFO_ENC(2, 0, NAME_TBD, 2, 9),
6188 		BPF_LINE_INFO_ENC(5, 0, NAME_TBD, 3, 8),
6189 		BPF_LINE_INFO_ENC(7, 0, NAME_TBD, 4, 7),
6190 		BTF_END_RAW,
6191 	},
6192 	.line_info_rec_size = sizeof(struct bpf_line_info),
6193 	.nr_jited_ksyms = 2,
6194 	.err_str = "missing bpf_line_info for func#0",
6195 	.expected_prog_load_failure = true,
6196 },
6197 
6198 {
6199 	.descr = "line_info (subprog. missing 2nd func line info)",
6200 	.raw_types = {
6201 		BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),	/* [1] */
6202 		BTF_END_RAW,
6203 	},
6204 	BTF_STR_SEC("\0int\0int a=1+1;\0return func(a);\0b+=1;\0return b;"),
6205 	.insns = {
6206 		BPF_MOV64_IMM(BPF_REG_2, 1),
6207 		BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, 1),
6208 		BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
6209 		BPF_CALL_REL(1),
6210 		BPF_EXIT_INSN(),
6211 		BPF_MOV64_REG(BPF_REG_0, BPF_REG_1),
6212 		BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 1),
6213 		BPF_EXIT_INSN(),
6214 	},
6215 	.prog_type = BPF_PROG_TYPE_TRACEPOINT,
6216 	.func_info_cnt = 0,
6217 	.line_info = {
6218 		BPF_LINE_INFO_ENC(0, 0, NAME_TBD, 1, 10),
6219 		BPF_LINE_INFO_ENC(2, 0, NAME_TBD, 2, 9),
6220 		BPF_LINE_INFO_ENC(6, 0, NAME_TBD, 3, 8),
6221 		BPF_LINE_INFO_ENC(7, 0, NAME_TBD, 4, 7),
6222 		BTF_END_RAW,
6223 	},
6224 	.line_info_rec_size = sizeof(struct bpf_line_info),
6225 	.nr_jited_ksyms = 2,
6226 	.err_str = "missing bpf_line_info for func#1",
6227 	.expected_prog_load_failure = true,
6228 },
6229 
6230 {
6231 	.descr = "line_info (subprog. unordered insn offset)",
6232 	.raw_types = {
6233 		BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),	/* [1] */
6234 		BTF_END_RAW,
6235 	},
6236 	BTF_STR_SEC("\0int\0int a=1+1;\0return func(a);\0b+=1;\0return b;"),
6237 	.insns = {
6238 		BPF_MOV64_IMM(BPF_REG_2, 1),
6239 		BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, 1),
6240 		BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
6241 		BPF_CALL_REL(1),
6242 		BPF_EXIT_INSN(),
6243 		BPF_MOV64_REG(BPF_REG_0, BPF_REG_1),
6244 		BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 1),
6245 		BPF_EXIT_INSN(),
6246 	},
6247 	.prog_type = BPF_PROG_TYPE_TRACEPOINT,
6248 	.func_info_cnt = 0,
6249 	.line_info = {
6250 		BPF_LINE_INFO_ENC(0, 0, NAME_TBD, 1, 10),
6251 		BPF_LINE_INFO_ENC(5, 0, NAME_TBD, 2, 9),
6252 		BPF_LINE_INFO_ENC(2, 0, NAME_TBD, 3, 8),
6253 		BPF_LINE_INFO_ENC(7, 0, NAME_TBD, 4, 7),
6254 		BTF_END_RAW,
6255 	},
6256 	.line_info_rec_size = sizeof(struct bpf_line_info),
6257 	.nr_jited_ksyms = 2,
6258 	.err_str = "Invalid line_info[2].insn_off",
6259 	.expected_prog_load_failure = true,
6260 },
6261 
6262 {
6263 	.descr = "line_info (dead start)",
6264 	.raw_types = {
6265 		BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),	/* [1] */
6266 		BTF_END_RAW,
6267 	},
6268 	BTF_STR_SEC("\0int\0/* dead jmp */\0int a=1;\0int b=2;\0return a + b;\0return a + b;"),
6269 	.insns = {
6270 		BPF_JMP_IMM(BPF_JA, 0, 0, 0),
6271 		BPF_MOV64_IMM(BPF_REG_0, 1),
6272 		BPF_MOV64_IMM(BPF_REG_1, 2),
6273 		BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
6274 		BPF_EXIT_INSN(),
6275 	},
6276 	.prog_type = BPF_PROG_TYPE_TRACEPOINT,
6277 	.func_info_cnt = 0,
6278 	.line_info = {
6279 		BPF_LINE_INFO_ENC(0, 0, NAME_TBD, 1, 10),
6280 		BPF_LINE_INFO_ENC(1, 0, NAME_TBD, 2, 9),
6281 		BPF_LINE_INFO_ENC(2, 0, NAME_TBD, 3, 8),
6282 		BPF_LINE_INFO_ENC(3, 0, NAME_TBD, 4, 7),
6283 		BPF_LINE_INFO_ENC(4, 0, NAME_TBD, 5, 6),
6284 		BTF_END_RAW,
6285 	},
6286 	.line_info_rec_size = sizeof(struct bpf_line_info),
6287 	.nr_jited_ksyms = 1,
6288 	.dead_code_cnt = 1,
6289 	.dead_code_mask = 0x01,
6290 },
6291 
6292 {
6293 	.descr = "line_info (dead end)",
6294 	.raw_types = {
6295 		BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),	/* [1] */
6296 		BTF_END_RAW,
6297 	},
6298 	BTF_STR_SEC("\0int\0int a=1;\0int b=2;\0return a + b;\0/* dead jmp */\0return a + b;\0/* dead exit */"),
6299 	.insns = {
6300 		BPF_MOV64_IMM(BPF_REG_0, 1),
6301 		BPF_MOV64_IMM(BPF_REG_1, 2),
6302 		BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
6303 		BPF_JMP_IMM(BPF_JGE, BPF_REG_0, 10, 1),
6304 		BPF_EXIT_INSN(),
6305 		BPF_EXIT_INSN(),
6306 	},
6307 	.prog_type = BPF_PROG_TYPE_TRACEPOINT,
6308 	.func_info_cnt = 0,
6309 	.line_info = {
6310 		BPF_LINE_INFO_ENC(0, 0, NAME_TBD, 1, 12),
6311 		BPF_LINE_INFO_ENC(1, 0, NAME_TBD, 2, 11),
6312 		BPF_LINE_INFO_ENC(2, 0, NAME_TBD, 3, 10),
6313 		BPF_LINE_INFO_ENC(3, 0, NAME_TBD, 4, 9),
6314 		BPF_LINE_INFO_ENC(4, 0, NAME_TBD, 5, 8),
6315 		BPF_LINE_INFO_ENC(5, 0, NAME_TBD, 6, 7),
6316 		BTF_END_RAW,
6317 	},
6318 	.line_info_rec_size = sizeof(struct bpf_line_info),
6319 	.nr_jited_ksyms = 1,
6320 	.dead_code_cnt = 2,
6321 	.dead_code_mask = 0x28,
6322 },
6323 
6324 {
6325 	.descr = "line_info (dead code + subprog + func_info)",
6326 	.raw_types = {
6327 		BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),	/* [1] */
6328 		BTF_FUNC_PROTO_ENC(1, 1),			/* [2] */
6329 			BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
6330 		BTF_FUNC_ENC(NAME_TBD, 2),			/* [3] */
6331 		BTF_FUNC_ENC(NAME_TBD, 2),			/* [4] */
6332 		BTF_END_RAW,
6333 	},
6334 	BTF_STR_SEC("\0int\0x\0sub\0main\0int a=1+1;\0/* dead jmp */"
6335 		    "\0/* dead */\0/* dead */\0/* dead */\0/* dead */"
6336 		    "\0/* dead */\0/* dead */\0/* dead */\0/* dead */"
6337 		    "\0return func(a);\0b+=1;\0return b;"),
6338 	.insns = {
6339 		BPF_MOV64_IMM(BPF_REG_2, 1),
6340 		BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, 1),
6341 		BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
6342 		BPF_JMP_IMM(BPF_JGE, BPF_REG_2, 0, 8),
6343 		BPF_MOV64_IMM(BPF_REG_2, 1),
6344 		BPF_MOV64_IMM(BPF_REG_2, 1),
6345 		BPF_MOV64_IMM(BPF_REG_2, 1),
6346 		BPF_MOV64_IMM(BPF_REG_2, 1),
6347 		BPF_MOV64_IMM(BPF_REG_2, 1),
6348 		BPF_MOV64_IMM(BPF_REG_2, 1),
6349 		BPF_MOV64_IMM(BPF_REG_2, 1),
6350 		BPF_MOV64_IMM(BPF_REG_2, 1),
6351 		BPF_CALL_REL(1),
6352 		BPF_EXIT_INSN(),
6353 		BPF_MOV64_REG(BPF_REG_0, BPF_REG_1),
6354 		BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 1),
6355 		BPF_EXIT_INSN(),
6356 	},
6357 	.prog_type = BPF_PROG_TYPE_TRACEPOINT,
6358 	.func_info_cnt = 2,
6359 	.func_info_rec_size = 8,
6360 	.func_info = { {0, 4}, {14, 3} },
6361 	.line_info = {
6362 		BPF_LINE_INFO_ENC(0, 0, NAME_TBD, 1, 10),
6363 		BPF_LINE_INFO_ENC(3, 0, NAME_TBD, 1, 10),
6364 		BPF_LINE_INFO_ENC(4, 0, NAME_TBD, 1, 10),
6365 		BPF_LINE_INFO_ENC(5, 0, NAME_TBD, 1, 10),
6366 		BPF_LINE_INFO_ENC(6, 0, NAME_TBD, 1, 10),
6367 		BPF_LINE_INFO_ENC(7, 0, NAME_TBD, 1, 10),
6368 		BPF_LINE_INFO_ENC(8, 0, NAME_TBD, 1, 10),
6369 		BPF_LINE_INFO_ENC(9, 0, NAME_TBD, 1, 10),
6370 		BPF_LINE_INFO_ENC(10, 0, NAME_TBD, 1, 10),
6371 		BPF_LINE_INFO_ENC(11, 0, NAME_TBD, 2, 9),
6372 		BPF_LINE_INFO_ENC(12, 0, NAME_TBD, 2, 9),
6373 		BPF_LINE_INFO_ENC(14, 0, NAME_TBD, 3, 8),
6374 		BPF_LINE_INFO_ENC(16, 0, NAME_TBD, 4, 7),
6375 		BTF_END_RAW,
6376 	},
6377 	.line_info_rec_size = sizeof(struct bpf_line_info),
6378 	.nr_jited_ksyms = 2,
6379 	.dead_code_cnt = 9,
6380 	.dead_code_mask = 0x3fe,
6381 },
6382 
6383 {
6384 	.descr = "line_info (dead subprog)",
6385 	.raw_types = {
6386 		BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),	/* [1] */
6387 		BTF_FUNC_PROTO_ENC(1, 1),			/* [2] */
6388 			BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
6389 		BTF_FUNC_ENC(NAME_TBD, 2),			/* [3] */
6390 		BTF_FUNC_ENC(NAME_TBD, 2),			/* [4] */
6391 		BTF_FUNC_ENC(NAME_TBD, 2),			/* [5] */
6392 		BTF_END_RAW,
6393 	},
6394 	BTF_STR_SEC("\0int\0x\0dead\0main\0func\0int a=1+1;\0/* live call */"
6395 		    "\0return 0;\0return 0;\0/* dead */\0/* dead */"
6396 		    "\0/* dead */\0return bla + 1;\0return bla + 1;"
6397 		    "\0return bla + 1;\0return func(a);\0b+=1;\0return b;"),
6398 	.insns = {
6399 		BPF_MOV64_IMM(BPF_REG_2, 1),
6400 		BPF_JMP_IMM(BPF_JGE, BPF_REG_2, 0, 1),
6401 		BPF_CALL_REL(3),
6402 		BPF_CALL_REL(5),
6403 		BPF_MOV64_IMM(BPF_REG_0, 0),
6404 		BPF_EXIT_INSN(),
6405 		BPF_MOV64_IMM(BPF_REG_0, 0),
6406 		BPF_CALL_REL(1),
6407 		BPF_EXIT_INSN(),
6408 		BPF_MOV64_REG(BPF_REG_0, 2),
6409 		BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 1),
6410 		BPF_EXIT_INSN(),
6411 	},
6412 	.prog_type = BPF_PROG_TYPE_TRACEPOINT,
6413 	.func_info_cnt = 3,
6414 	.func_info_rec_size = 8,
6415 		.func_info = { {0, 4}, {6, 3}, {9, 5} },
6416 	.line_info = {
6417 		BPF_LINE_INFO_ENC(0, 0, NAME_TBD, 1, 10),
6418 		BPF_LINE_INFO_ENC(3, 0, NAME_TBD, 1, 10),
6419 		BPF_LINE_INFO_ENC(4, 0, NAME_TBD, 1, 10),
6420 		BPF_LINE_INFO_ENC(5, 0, NAME_TBD, 1, 10),
6421 		BPF_LINE_INFO_ENC(6, 0, NAME_TBD, 1, 10),
6422 		BPF_LINE_INFO_ENC(7, 0, NAME_TBD, 1, 10),
6423 		BPF_LINE_INFO_ENC(8, 0, NAME_TBD, 1, 10),
6424 		BPF_LINE_INFO_ENC(9, 0, NAME_TBD, 1, 10),
6425 		BPF_LINE_INFO_ENC(10, 0, NAME_TBD, 1, 10),
6426 		BPF_LINE_INFO_ENC(11, 0, NAME_TBD, 2, 9),
6427 		BTF_END_RAW,
6428 	},
6429 	.line_info_rec_size = sizeof(struct bpf_line_info),
6430 	.nr_jited_ksyms = 2,
6431 	.dead_code_cnt = 3,
6432 	.dead_code_mask = 0x70,
6433 	.dead_func_cnt = 1,
6434 	.dead_func_mask = 0x2,
6435 },
6436 
6437 {
6438 	.descr = "line_info (dead last subprog)",
6439 	.raw_types = {
6440 		BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),	/* [1] */
6441 		BTF_FUNC_PROTO_ENC(1, 1),			/* [2] */
6442 			BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
6443 		BTF_FUNC_ENC(NAME_TBD, 2),			/* [3] */
6444 		BTF_FUNC_ENC(NAME_TBD, 2),			/* [5] */
6445 		BTF_END_RAW,
6446 	},
6447 	BTF_STR_SEC("\0int\0x\0dead\0main\0int a=1+1;\0/* live call */"
6448 		    "\0return 0;\0/* dead */\0/* dead */"),
6449 	.insns = {
6450 		BPF_MOV64_IMM(BPF_REG_2, 1),
6451 		BPF_JMP_IMM(BPF_JGE, BPF_REG_2, 0, 1),
6452 		BPF_CALL_REL(2),
6453 		BPF_MOV64_IMM(BPF_REG_0, 0),
6454 		BPF_EXIT_INSN(),
6455 		BPF_MOV64_IMM(BPF_REG_0, 0),
6456 		BPF_EXIT_INSN(),
6457 	},
6458 	.prog_type = BPF_PROG_TYPE_TRACEPOINT,
6459 	.func_info_cnt = 2,
6460 	.func_info_rec_size = 8,
6461 		.func_info = { {0, 4}, {5, 3} },
6462 	.line_info = {
6463 		BPF_LINE_INFO_ENC(0, 0, NAME_TBD, 1, 10),
6464 		BPF_LINE_INFO_ENC(3, 0, NAME_TBD, 1, 10),
6465 		BPF_LINE_INFO_ENC(4, 0, NAME_TBD, 1, 10),
6466 		BPF_LINE_INFO_ENC(5, 0, NAME_TBD, 1, 10),
6467 		BPF_LINE_INFO_ENC(6, 0, NAME_TBD, 1, 10),
6468 		BTF_END_RAW,
6469 	},
6470 	.line_info_rec_size = sizeof(struct bpf_line_info),
6471 	.nr_jited_ksyms = 1,
6472 	.dead_code_cnt = 2,
6473 	.dead_code_mask = 0x18,
6474 	.dead_func_cnt = 1,
6475 	.dead_func_mask = 0x2,
6476 },
6477 
6478 {
6479 	.descr = "line_info (dead subprog + dead start)",
6480 	.raw_types = {
6481 		BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),	/* [1] */
6482 		BTF_FUNC_PROTO_ENC(1, 1),			/* [2] */
6483 			BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
6484 		BTF_FUNC_ENC(NAME_TBD, 2),			/* [3] */
6485 		BTF_FUNC_ENC(NAME_TBD, 2),			/* [4] */
6486 		BTF_FUNC_ENC(NAME_TBD, 2),			/* [5] */
6487 		BTF_END_RAW,
6488 	},
6489 	BTF_STR_SEC("\0int\0x\0dead\0main\0func\0int a=1+1;\0/* dead */"
6490 		    "\0return 0;\0return 0;\0return 0;"
6491 		    "\0/* dead */\0/* dead */\0/* dead */\0/* dead */"
6492 		    "\0return b + 1;\0return b + 1;\0return b + 1;"),
6493 	.insns = {
6494 		BPF_JMP_IMM(BPF_JA, 0, 0, 0),
6495 		BPF_MOV64_IMM(BPF_REG_2, 1),
6496 		BPF_JMP_IMM(BPF_JGE, BPF_REG_2, 0, 1),
6497 		BPF_CALL_REL(3),
6498 		BPF_CALL_REL(5),
6499 		BPF_MOV64_IMM(BPF_REG_0, 0),
6500 		BPF_EXIT_INSN(),
6501 		BPF_MOV64_IMM(BPF_REG_0, 0),
6502 		BPF_CALL_REL(1),
6503 		BPF_EXIT_INSN(),
6504 		BPF_JMP_IMM(BPF_JA, 0, 0, 0),
6505 		BPF_MOV64_REG(BPF_REG_0, 2),
6506 		BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 1),
6507 		BPF_EXIT_INSN(),
6508 	},
6509 	.prog_type = BPF_PROG_TYPE_TRACEPOINT,
6510 	.func_info_cnt = 3,
6511 	.func_info_rec_size = 8,
6512 		.func_info = { {0, 4}, {7, 3}, {10, 5} },
6513 	.line_info = {
6514 		BPF_LINE_INFO_ENC(0, 0, NAME_TBD, 1, 10),
6515 		BPF_LINE_INFO_ENC(3, 0, NAME_TBD, 1, 10),
6516 		BPF_LINE_INFO_ENC(4, 0, NAME_TBD, 1, 10),
6517 		BPF_LINE_INFO_ENC(5, 0, NAME_TBD, 1, 10),
6518 		BPF_LINE_INFO_ENC(6, 0, NAME_TBD, 1, 10),
6519 		BPF_LINE_INFO_ENC(7, 0, NAME_TBD, 1, 10),
6520 		BPF_LINE_INFO_ENC(8, 0, NAME_TBD, 1, 10),
6521 		BPF_LINE_INFO_ENC(9, 0, NAME_TBD, 1, 10),
6522 		BPF_LINE_INFO_ENC(10, 0, NAME_TBD, 1, 10),
6523 		BPF_LINE_INFO_ENC(11, 0, NAME_TBD, 2, 9),
6524 		BPF_LINE_INFO_ENC(12, 0, NAME_TBD, 2, 9),
6525 		BPF_LINE_INFO_ENC(13, 0, NAME_TBD, 2, 9),
6526 		BTF_END_RAW,
6527 	},
6528 	.line_info_rec_size = sizeof(struct bpf_line_info),
6529 	.nr_jited_ksyms = 2,
6530 	.dead_code_cnt = 5,
6531 	.dead_code_mask = 0x1e2,
6532 	.dead_func_cnt = 1,
6533 	.dead_func_mask = 0x2,
6534 },
6535 
6536 {
6537 	.descr = "line_info (dead subprog + dead start w/ move)",
6538 	.raw_types = {
6539 		BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),	/* [1] */
6540 		BTF_FUNC_PROTO_ENC(1, 1),			/* [2] */
6541 			BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
6542 		BTF_FUNC_ENC(NAME_TBD, 2),			/* [3] */
6543 		BTF_FUNC_ENC(NAME_TBD, 2),			/* [4] */
6544 		BTF_FUNC_ENC(NAME_TBD, 2),			/* [5] */
6545 		BTF_END_RAW,
6546 	},
6547 	BTF_STR_SEC("\0int\0x\0dead\0main\0func\0int a=1+1;\0/* live call */"
6548 		    "\0return 0;\0return 0;\0/* dead */\0/* dead */"
6549 		    "\0/* dead */\0return bla + 1;\0return bla + 1;"
6550 		    "\0return bla + 1;\0return func(a);\0b+=1;\0return b;"),
6551 	.insns = {
6552 		BPF_MOV64_IMM(BPF_REG_2, 1),
6553 		BPF_JMP_IMM(BPF_JGE, BPF_REG_2, 0, 1),
6554 		BPF_CALL_REL(3),
6555 		BPF_CALL_REL(5),
6556 		BPF_MOV64_IMM(BPF_REG_0, 0),
6557 		BPF_EXIT_INSN(),
6558 		BPF_MOV64_IMM(BPF_REG_0, 0),
6559 		BPF_CALL_REL(1),
6560 		BPF_EXIT_INSN(),
6561 		BPF_JMP_IMM(BPF_JA, 0, 0, 0),
6562 		BPF_MOV64_REG(BPF_REG_0, 2),
6563 		BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 1),
6564 		BPF_EXIT_INSN(),
6565 	},
6566 	.prog_type = BPF_PROG_TYPE_TRACEPOINT,
6567 	.func_info_cnt = 3,
6568 	.func_info_rec_size = 8,
6569 		.func_info = { {0, 4}, {6, 3}, {9, 5} },
6570 	.line_info = {
6571 		BPF_LINE_INFO_ENC(0, 0, NAME_TBD, 1, 10),
6572 		BPF_LINE_INFO_ENC(3, 0, NAME_TBD, 1, 10),
6573 		BPF_LINE_INFO_ENC(4, 0, NAME_TBD, 1, 10),
6574 		BPF_LINE_INFO_ENC(5, 0, NAME_TBD, 1, 10),
6575 		BPF_LINE_INFO_ENC(6, 0, NAME_TBD, 1, 10),
6576 		BPF_LINE_INFO_ENC(7, 0, NAME_TBD, 1, 10),
6577 		BPF_LINE_INFO_ENC(8, 0, NAME_TBD, 1, 10),
6578 		BPF_LINE_INFO_ENC(9, 0, NAME_TBD, 1, 10),
6579 		BPF_LINE_INFO_ENC(11, 0, NAME_TBD, 1, 10),
6580 		BPF_LINE_INFO_ENC(12, 0, NAME_TBD, 2, 9),
6581 		BTF_END_RAW,
6582 	},
6583 	.line_info_rec_size = sizeof(struct bpf_line_info),
6584 	.nr_jited_ksyms = 2,
6585 	.dead_code_cnt = 3,
6586 	.dead_code_mask = 0x70,
6587 	.dead_func_cnt = 1,
6588 	.dead_func_mask = 0x2,
6589 },
6590 
6591 {
6592 	.descr = "line_info (dead end + subprog start w/ no linfo)",
6593 	.raw_types = {
6594 		BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),	/* [1] */
6595 		BTF_FUNC_PROTO_ENC(1, 1),			/* [2] */
6596 			BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
6597 		BTF_FUNC_ENC(NAME_TBD, 2),			/* [3] */
6598 		BTF_FUNC_ENC(NAME_TBD, 2),			/* [4] */
6599 		BTF_END_RAW,
6600 	},
6601 	BTF_STR_SEC("\0int\0x\0main\0func\0/* main linfo */\0/* func linfo */"),
6602 	.insns = {
6603 		BPF_MOV64_IMM(BPF_REG_0, 0),
6604 		BPF_JMP_IMM(BPF_JGE, BPF_REG_0, 1, 3),
6605 		BPF_CALL_REL(3),
6606 		BPF_MOV64_IMM(BPF_REG_0, 0),
6607 		BPF_EXIT_INSN(),
6608 		BPF_EXIT_INSN(),
6609 		BPF_JMP_IMM(BPF_JA, 0, 0, 0),
6610 		BPF_EXIT_INSN(),
6611 	},
6612 	.prog_type = BPF_PROG_TYPE_TRACEPOINT,
6613 	.func_info_cnt = 2,
6614 	.func_info_rec_size = 8,
6615 	.func_info = { {0, 3}, {6, 4}, },
6616 	.line_info = {
6617 		BPF_LINE_INFO_ENC(0, 0, NAME_TBD, 1, 10),
6618 		BPF_LINE_INFO_ENC(6, 0, NAME_TBD, 1, 10),
6619 		BTF_END_RAW,
6620 	},
6621 	.line_info_rec_size = sizeof(struct bpf_line_info),
6622 	.nr_jited_ksyms = 2,
6623 },
6624 
6625 };
6626 
6627 static size_t probe_prog_length(const struct bpf_insn *fp)
6628 {
6629 	size_t len;
6630 
6631 	for (len = MAX_INSNS - 1; len > 0; --len)
6632 		if (fp[len].code != 0 || fp[len].imm != 0)
6633 			break;
6634 	return len + 1;
6635 }
6636 
6637 static __u32 *patch_name_tbd(const __u32 *raw_u32,
6638 			     const char *str, __u32 str_off,
6639 			     unsigned int str_sec_size,
6640 			     unsigned int *ret_size)
6641 {
6642 	int i, raw_u32_size = get_raw_sec_size(raw_u32);
6643 	const char *end_str = str + str_sec_size;
6644 	const char *next_str = str + str_off;
6645 	__u32 *new_u32 = NULL;
6646 
6647 	if (raw_u32_size == -1)
6648 		return ERR_PTR(-EINVAL);
6649 
6650 	if (!raw_u32_size) {
6651 		*ret_size = 0;
6652 		return NULL;
6653 	}
6654 
6655 	new_u32 = malloc(raw_u32_size);
6656 	if (!new_u32)
6657 		return ERR_PTR(-ENOMEM);
6658 
6659 	for (i = 0; i < raw_u32_size / sizeof(raw_u32[0]); i++) {
6660 		if (raw_u32[i] == NAME_TBD) {
6661 			next_str = get_next_str(next_str, end_str);
6662 			if (CHECK(!next_str, "Error in getting next_str\n")) {
6663 				free(new_u32);
6664 				return ERR_PTR(-EINVAL);
6665 			}
6666 			new_u32[i] = next_str - str;
6667 			next_str += strlen(next_str);
6668 		} else {
6669 			new_u32[i] = raw_u32[i];
6670 		}
6671 	}
6672 
6673 	*ret_size = raw_u32_size;
6674 	return new_u32;
6675 }
6676 
6677 static int test_get_finfo(const struct prog_info_raw_test *test,
6678 			  int prog_fd)
6679 {
6680 	struct bpf_prog_info info = {};
6681 	struct bpf_func_info *finfo;
6682 	__u32 info_len, rec_size, i;
6683 	void *func_info = NULL;
6684 	__u32 nr_func_info;
6685 	int err;
6686 
6687 	/* get necessary lens */
6688 	info_len = sizeof(struct bpf_prog_info);
6689 	err = bpf_prog_get_info_by_fd(prog_fd, &info, &info_len);
6690 	if (CHECK(err < 0, "invalid get info (1st) errno:%d", errno)) {
6691 		fprintf(stderr, "%s\n", btf_log_buf);
6692 		return -1;
6693 	}
6694 	nr_func_info = test->func_info_cnt - test->dead_func_cnt;
6695 	if (CHECK(info.nr_func_info != nr_func_info,
6696 		  "incorrect info.nr_func_info (1st) %d",
6697 		  info.nr_func_info)) {
6698 		return -1;
6699 	}
6700 
6701 	rec_size = info.func_info_rec_size;
6702 	if (CHECK(rec_size != sizeof(struct bpf_func_info),
6703 		  "incorrect info.func_info_rec_size (1st) %d", rec_size)) {
6704 		return -1;
6705 	}
6706 
6707 	if (!info.nr_func_info)
6708 		return 0;
6709 
6710 	func_info = malloc(info.nr_func_info * rec_size);
6711 	if (CHECK(!func_info, "out of memory"))
6712 		return -1;
6713 
6714 	/* reset info to only retrieve func_info related data */
6715 	memset(&info, 0, sizeof(info));
6716 	info.nr_func_info = nr_func_info;
6717 	info.func_info_rec_size = rec_size;
6718 	info.func_info = ptr_to_u64(func_info);
6719 	err = bpf_prog_get_info_by_fd(prog_fd, &info, &info_len);
6720 	if (CHECK(err < 0, "invalid get info (2nd) errno:%d", errno)) {
6721 		fprintf(stderr, "%s\n", btf_log_buf);
6722 		err = -1;
6723 		goto done;
6724 	}
6725 	if (CHECK(info.nr_func_info != nr_func_info,
6726 		  "incorrect info.nr_func_info (2nd) %d",
6727 		  info.nr_func_info)) {
6728 		err = -1;
6729 		goto done;
6730 	}
6731 	if (CHECK(info.func_info_rec_size != rec_size,
6732 		  "incorrect info.func_info_rec_size (2nd) %d",
6733 		  info.func_info_rec_size)) {
6734 		err = -1;
6735 		goto done;
6736 	}
6737 
6738 	finfo = func_info;
6739 	for (i = 0; i < nr_func_info; i++) {
6740 		if (test->dead_func_mask & (1 << i))
6741 			continue;
6742 		if (CHECK(finfo->type_id != test->func_info[i][1],
6743 			  "incorrect func_type %u expected %u",
6744 			  finfo->type_id, test->func_info[i][1])) {
6745 			err = -1;
6746 			goto done;
6747 		}
6748 		finfo = (void *)finfo + rec_size;
6749 	}
6750 
6751 	err = 0;
6752 
6753 done:
6754 	free(func_info);
6755 	return err;
6756 }
6757 
6758 static int test_get_linfo(const struct prog_info_raw_test *test,
6759 			  const void *patched_linfo,
6760 			  __u32 cnt, int prog_fd)
6761 {
6762 	__u32 i, info_len, nr_jited_ksyms, nr_jited_func_lens;
6763 	__u64 *jited_linfo = NULL, *jited_ksyms = NULL;
6764 	__u32 rec_size, jited_rec_size, jited_cnt;
6765 	struct bpf_line_info *linfo = NULL;
6766 	__u32 cur_func_len, ksyms_found;
6767 	struct bpf_prog_info info = {};
6768 	__u32 *jited_func_lens = NULL;
6769 	__u64 cur_func_ksyms;
6770 	__u32 dead_insns;
6771 	int err;
6772 
6773 	jited_cnt = cnt;
6774 	rec_size = sizeof(*linfo);
6775 	jited_rec_size = sizeof(*jited_linfo);
6776 	if (test->nr_jited_ksyms)
6777 		nr_jited_ksyms = test->nr_jited_ksyms;
6778 	else
6779 		nr_jited_ksyms = test->func_info_cnt - test->dead_func_cnt;
6780 	nr_jited_func_lens = nr_jited_ksyms;
6781 
6782 	info_len = sizeof(struct bpf_prog_info);
6783 	err = bpf_prog_get_info_by_fd(prog_fd, &info, &info_len);
6784 	if (CHECK(err < 0, "err:%d errno:%d", err, errno)) {
6785 		err = -1;
6786 		goto done;
6787 	}
6788 
6789 	if (!info.jited_prog_len) {
6790 		/* prog is not jited */
6791 		jited_cnt = 0;
6792 		nr_jited_ksyms = 1;
6793 		nr_jited_func_lens = 1;
6794 	}
6795 
6796 	if (CHECK(info.nr_line_info != cnt ||
6797 		  info.nr_jited_line_info != jited_cnt ||
6798 		  info.nr_jited_ksyms != nr_jited_ksyms ||
6799 		  info.nr_jited_func_lens != nr_jited_func_lens ||
6800 		  (!info.nr_line_info && info.nr_jited_line_info),
6801 		  "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)",
6802 		  info.nr_line_info, cnt,
6803 		  info.nr_jited_line_info, jited_cnt,
6804 		  info.nr_jited_ksyms, nr_jited_ksyms,
6805 		  info.nr_jited_func_lens, nr_jited_func_lens)) {
6806 		err = -1;
6807 		goto done;
6808 	}
6809 
6810 	if (CHECK(info.line_info_rec_size != sizeof(struct bpf_line_info) ||
6811 		  info.jited_line_info_rec_size != sizeof(__u64),
6812 		  "info: line_info_rec_size:%u(userspace expected:%u) jited_line_info_rec_size:%u(userspace expected:%u)",
6813 		  info.line_info_rec_size, rec_size,
6814 		  info.jited_line_info_rec_size, jited_rec_size)) {
6815 		err = -1;
6816 		goto done;
6817 	}
6818 
6819 	if (!cnt)
6820 		return 0;
6821 
6822 	rec_size = info.line_info_rec_size;
6823 	jited_rec_size = info.jited_line_info_rec_size;
6824 
6825 	memset(&info, 0, sizeof(info));
6826 
6827 	linfo = calloc(cnt, rec_size);
6828 	if (CHECK(!linfo, "!linfo")) {
6829 		err = -1;
6830 		goto done;
6831 	}
6832 	info.nr_line_info = cnt;
6833 	info.line_info_rec_size = rec_size;
6834 	info.line_info = ptr_to_u64(linfo);
6835 
6836 	if (jited_cnt) {
6837 		jited_linfo = calloc(jited_cnt, jited_rec_size);
6838 		jited_ksyms = calloc(nr_jited_ksyms, sizeof(*jited_ksyms));
6839 		jited_func_lens = calloc(nr_jited_func_lens,
6840 					 sizeof(*jited_func_lens));
6841 		if (CHECK(!jited_linfo || !jited_ksyms || !jited_func_lens,
6842 			  "jited_linfo:%p jited_ksyms:%p jited_func_lens:%p",
6843 			  jited_linfo, jited_ksyms, jited_func_lens)) {
6844 			err = -1;
6845 			goto done;
6846 		}
6847 
6848 		info.nr_jited_line_info = jited_cnt;
6849 		info.jited_line_info_rec_size = jited_rec_size;
6850 		info.jited_line_info = ptr_to_u64(jited_linfo);
6851 		info.nr_jited_ksyms = nr_jited_ksyms;
6852 		info.jited_ksyms = ptr_to_u64(jited_ksyms);
6853 		info.nr_jited_func_lens = nr_jited_func_lens;
6854 		info.jited_func_lens = ptr_to_u64(jited_func_lens);
6855 	}
6856 
6857 	err = bpf_prog_get_info_by_fd(prog_fd, &info, &info_len);
6858 
6859 	/*
6860 	 * Only recheck the info.*line_info* fields.
6861 	 * Other fields are not the concern of this test.
6862 	 */
6863 	if (CHECK(err < 0 ||
6864 		  info.nr_line_info != cnt ||
6865 		  (jited_cnt && !info.jited_line_info) ||
6866 		  info.nr_jited_line_info != jited_cnt ||
6867 		  info.line_info_rec_size != rec_size ||
6868 		  info.jited_line_info_rec_size != jited_rec_size,
6869 		  "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",
6870 		  err, errno,
6871 		  info.nr_line_info, cnt,
6872 		  info.nr_jited_line_info, jited_cnt,
6873 		  info.line_info_rec_size, rec_size,
6874 		  info.jited_line_info_rec_size, jited_rec_size,
6875 		  (void *)(long)info.line_info,
6876 		  (void *)(long)info.jited_line_info)) {
6877 		err = -1;
6878 		goto done;
6879 	}
6880 
6881 	dead_insns = 0;
6882 	while (test->dead_code_mask & (1 << dead_insns))
6883 		dead_insns++;
6884 
6885 	CHECK(linfo[0].insn_off, "linfo[0].insn_off:%u",
6886 	      linfo[0].insn_off);
6887 	for (i = 1; i < cnt; i++) {
6888 		const struct bpf_line_info *expected_linfo;
6889 
6890 		while (test->dead_code_mask & (1 << (i + dead_insns)))
6891 			dead_insns++;
6892 
6893 		expected_linfo = patched_linfo +
6894 			((i + dead_insns) * test->line_info_rec_size);
6895 		if (CHECK(linfo[i].insn_off <= linfo[i - 1].insn_off,
6896 			  "linfo[%u].insn_off:%u <= linfo[%u].insn_off:%u",
6897 			  i, linfo[i].insn_off,
6898 			  i - 1, linfo[i - 1].insn_off)) {
6899 			err = -1;
6900 			goto done;
6901 		}
6902 		if (CHECK(linfo[i].file_name_off != expected_linfo->file_name_off ||
6903 			  linfo[i].line_off != expected_linfo->line_off ||
6904 			  linfo[i].line_col != expected_linfo->line_col,
6905 			  "linfo[%u] (%u, %u, %u) != (%u, %u, %u)", i,
6906 			  linfo[i].file_name_off,
6907 			  linfo[i].line_off,
6908 			  linfo[i].line_col,
6909 			  expected_linfo->file_name_off,
6910 			  expected_linfo->line_off,
6911 			  expected_linfo->line_col)) {
6912 			err = -1;
6913 			goto done;
6914 		}
6915 	}
6916 
6917 	if (!jited_cnt) {
6918 		fprintf(stderr, "not jited. skipping jited_line_info check. ");
6919 		err = 0;
6920 		goto done;
6921 	}
6922 
6923 	if (CHECK(jited_linfo[0] != jited_ksyms[0],
6924 		  "jited_linfo[0]:%lx != jited_ksyms[0]:%lx",
6925 		  (long)(jited_linfo[0]), (long)(jited_ksyms[0]))) {
6926 		err = -1;
6927 		goto done;
6928 	}
6929 
6930 	ksyms_found = 1;
6931 	cur_func_len = jited_func_lens[0];
6932 	cur_func_ksyms = jited_ksyms[0];
6933 	for (i = 1; i < jited_cnt; i++) {
6934 		if (ksyms_found < nr_jited_ksyms &&
6935 		    jited_linfo[i] == jited_ksyms[ksyms_found]) {
6936 			cur_func_ksyms = jited_ksyms[ksyms_found];
6937 			cur_func_len = jited_ksyms[ksyms_found];
6938 			ksyms_found++;
6939 			continue;
6940 		}
6941 
6942 		if (CHECK(jited_linfo[i] <= jited_linfo[i - 1],
6943 			  "jited_linfo[%u]:%lx <= jited_linfo[%u]:%lx",
6944 			  i, (long)jited_linfo[i],
6945 			  i - 1, (long)(jited_linfo[i - 1]))) {
6946 			err = -1;
6947 			goto done;
6948 		}
6949 
6950 		if (CHECK(jited_linfo[i] - cur_func_ksyms > cur_func_len,
6951 			  "jited_linfo[%u]:%lx - %lx > %u",
6952 			  i, (long)jited_linfo[i], (long)cur_func_ksyms,
6953 			  cur_func_len)) {
6954 			err = -1;
6955 			goto done;
6956 		}
6957 	}
6958 
6959 	if (CHECK(ksyms_found != nr_jited_ksyms,
6960 		  "ksyms_found:%u != nr_jited_ksyms:%u",
6961 		  ksyms_found, nr_jited_ksyms)) {
6962 		err = -1;
6963 		goto done;
6964 	}
6965 
6966 	err = 0;
6967 
6968 done:
6969 	free(linfo);
6970 	free(jited_linfo);
6971 	free(jited_ksyms);
6972 	free(jited_func_lens);
6973 	return err;
6974 }
6975 
6976 static void do_test_info_raw(unsigned int test_num)
6977 {
6978 	const struct prog_info_raw_test *test = &info_raw_tests[test_num - 1];
6979 	unsigned int raw_btf_size, linfo_str_off, linfo_size = 0;
6980 	int btf_fd = -1, prog_fd = -1, err = 0;
6981 	void *raw_btf, *patched_linfo = NULL;
6982 	const char *ret_next_str;
6983 	union bpf_attr attr = {};
6984 
6985 	if (!test__start_subtest(test->descr))
6986 		return;
6987 
6988 	raw_btf = btf_raw_create(&hdr_tmpl, test->raw_types,
6989 				 test->str_sec, test->str_sec_size,
6990 				 &raw_btf_size, &ret_next_str);
6991 	if (!raw_btf)
6992 		return;
6993 
6994 	*btf_log_buf = '\0';
6995 	btf_fd = load_raw_btf(raw_btf, raw_btf_size);
6996 	free(raw_btf);
6997 
6998 	if (CHECK(btf_fd < 0, "invalid btf_fd errno:%d", errno)) {
6999 		err = -1;
7000 		goto done;
7001 	}
7002 
7003 	if (*btf_log_buf && always_log)
7004 		fprintf(stderr, "\n%s", btf_log_buf);
7005 	*btf_log_buf = '\0';
7006 
7007 	linfo_str_off = ret_next_str - test->str_sec;
7008 	patched_linfo = patch_name_tbd(test->line_info,
7009 				       test->str_sec, linfo_str_off,
7010 				       test->str_sec_size, &linfo_size);
7011 	err = libbpf_get_error(patched_linfo);
7012 	if (err) {
7013 		fprintf(stderr, "error in creating raw bpf_line_info");
7014 		err = -1;
7015 		goto done;
7016 	}
7017 
7018 	attr.prog_type = test->prog_type;
7019 	attr.insns = ptr_to_u64(test->insns);
7020 	attr.insn_cnt = probe_prog_length(test->insns);
7021 	attr.license = ptr_to_u64("GPL");
7022 	attr.prog_btf_fd = btf_fd;
7023 	attr.func_info_rec_size = test->func_info_rec_size;
7024 	attr.func_info_cnt = test->func_info_cnt;
7025 	attr.func_info = ptr_to_u64(test->func_info);
7026 	attr.log_buf = ptr_to_u64(btf_log_buf);
7027 	attr.log_size = BTF_LOG_BUF_SIZE;
7028 	attr.log_level = 1;
7029 	if (linfo_size) {
7030 		attr.line_info_rec_size = test->line_info_rec_size;
7031 		attr.line_info = ptr_to_u64(patched_linfo);
7032 		attr.line_info_cnt = linfo_size / attr.line_info_rec_size;
7033 	}
7034 
7035 	prog_fd = syscall(__NR_bpf, BPF_PROG_LOAD, &attr, sizeof(attr));
7036 	err = ((prog_fd < 0) != test->expected_prog_load_failure);
7037 	if (CHECK(err, "prog_fd:%d expected_prog_load_failure:%u errno:%d",
7038 		  prog_fd, test->expected_prog_load_failure, errno) ||
7039 	    CHECK(test->err_str && !strstr(btf_log_buf, test->err_str),
7040 		  "expected err_str:%s", test->err_str)) {
7041 		err = -1;
7042 		goto done;
7043 	}
7044 
7045 	if (prog_fd < 0)
7046 		goto done;
7047 
7048 	err = test_get_finfo(test, prog_fd);
7049 	if (err)
7050 		goto done;
7051 
7052 	err = test_get_linfo(test, patched_linfo,
7053 			     attr.line_info_cnt - test->dead_code_cnt,
7054 			     prog_fd);
7055 	if (err)
7056 		goto done;
7057 
7058 done:
7059 	if (*btf_log_buf && (err || always_log))
7060 		fprintf(stderr, "\n%s", btf_log_buf);
7061 
7062 	if (btf_fd >= 0)
7063 		close(btf_fd);
7064 	if (prog_fd >= 0)
7065 		close(prog_fd);
7066 
7067 	if (!libbpf_get_error(patched_linfo))
7068 		free(patched_linfo);
7069 }
7070 
7071 struct btf_raw_data {
7072 	__u32 raw_types[MAX_NR_RAW_U32];
7073 	const char *str_sec;
7074 	__u32 str_sec_size;
7075 };
7076 
7077 struct btf_dedup_test {
7078 	const char *descr;
7079 	struct btf_raw_data input;
7080 	struct btf_raw_data expect;
7081 	struct btf_dedup_opts opts;
7082 };
7083 
7084 static struct btf_dedup_test dedup_tests[] = {
7085 
7086 {
7087 	.descr = "dedup: unused strings filtering",
7088 	.input = {
7089 		.raw_types = {
7090 			BTF_TYPE_INT_ENC(NAME_NTH(2), BTF_INT_SIGNED, 0, 32, 4),
7091 			BTF_TYPE_INT_ENC(NAME_NTH(5), BTF_INT_SIGNED, 0, 64, 8),
7092 			BTF_END_RAW,
7093 		},
7094 		BTF_STR_SEC("\0unused\0int\0foo\0bar\0long"),
7095 	},
7096 	.expect = {
7097 		.raw_types = {
7098 			BTF_TYPE_INT_ENC(NAME_NTH(1), BTF_INT_SIGNED, 0, 32, 4),
7099 			BTF_TYPE_INT_ENC(NAME_NTH(2), BTF_INT_SIGNED, 0, 64, 8),
7100 			BTF_END_RAW,
7101 		},
7102 		BTF_STR_SEC("\0int\0long"),
7103 	},
7104 },
7105 {
7106 	.descr = "dedup: strings deduplication",
7107 	.input = {
7108 		.raw_types = {
7109 			BTF_TYPE_INT_ENC(NAME_NTH(1), BTF_INT_SIGNED, 0, 32, 4),
7110 			BTF_TYPE_INT_ENC(NAME_NTH(2), BTF_INT_SIGNED, 0, 64, 8),
7111 			BTF_TYPE_INT_ENC(NAME_NTH(3), BTF_INT_SIGNED, 0, 32, 4),
7112 			BTF_TYPE_INT_ENC(NAME_NTH(4), BTF_INT_SIGNED, 0, 64, 8),
7113 			BTF_TYPE_INT_ENC(NAME_NTH(5), BTF_INT_SIGNED, 0, 32, 4),
7114 			BTF_END_RAW,
7115 		},
7116 		BTF_STR_SEC("\0int\0long int\0int\0long int\0int"),
7117 	},
7118 	.expect = {
7119 		.raw_types = {
7120 			BTF_TYPE_INT_ENC(NAME_NTH(1), BTF_INT_SIGNED, 0, 32, 4),
7121 			BTF_TYPE_INT_ENC(NAME_NTH(2), BTF_INT_SIGNED, 0, 64, 8),
7122 			BTF_END_RAW,
7123 		},
7124 		BTF_STR_SEC("\0int\0long int"),
7125 	},
7126 },
7127 {
7128 	.descr = "dedup: array element comparison",
7129 	.input = {
7130 		.raw_types = {
7131 			/* signed int */
7132 			BTF_TYPE_INT_ENC(NAME_NTH(1), BTF_INT_SIGNED, 0, 32, 4), /* [1] */
7133 			/* unsigned int */
7134 			BTF_TYPE_INT_ENC(NAME_NTH(2), 0, 0, 32, 4),		/* [2] */
7135 			/* signed int[1] */
7136 			BTF_TYPE_ARRAY_ENC(1, 1, 1),				/* [3] */
7137 			/* duplicate signed int[1] */
7138 			BTF_TYPE_ARRAY_ENC(1, 1, 1),				/* [4] */
7139 			/* unsigned int[1] */
7140 			BTF_TYPE_ARRAY_ENC(2, 2, 1),				/* [5] */
7141 			/* struct s { signed int a[1]; signed int b[1]; } */
7142 			BTF_STRUCT_ENC(NAME_NTH(3), 2, 8),			/* [6] */
7143 			BTF_MEMBER_ENC(NAME_NTH(4), 3, 0),
7144 			BTF_MEMBER_ENC(NAME_NTH(5), 3, 32),
7145 			/* struct s { signed int a[1]; unsigned int b[1]; } */
7146 			BTF_STRUCT_ENC(NAME_NTH(3), 2, 8),			/* [7] */
7147 			BTF_MEMBER_ENC(NAME_NTH(4), 4, 0),
7148 			BTF_MEMBER_ENC(NAME_NTH(5), 5, 32),
7149 			BTF_END_RAW,
7150 		},
7151 		BTF_STR_SEC("\0int\0unsigned int\0s\0a\0b"),
7152 	},
7153 	.expect = {
7154 		.raw_types = {
7155 			BTF_TYPE_INT_ENC(NAME_NTH(1), BTF_INT_SIGNED, 0, 32, 4), /* [1] */
7156 			BTF_TYPE_INT_ENC(NAME_NTH(2), 0, 0, 32, 4),		/* [2] */
7157 			BTF_TYPE_ARRAY_ENC(1, 1, 1),				/* [3] */
7158 			BTF_TYPE_ARRAY_ENC(2, 2, 1),				/* [4] */
7159 			BTF_STRUCT_ENC(NAME_NTH(3), 2, 8),			/* [5] */
7160 			BTF_MEMBER_ENC(NAME_NTH(4), 3, 0),
7161 			BTF_MEMBER_ENC(NAME_NTH(5), 3, 32),
7162 			BTF_STRUCT_ENC(NAME_NTH(3), 2, 8),			/* [6] */
7163 			BTF_MEMBER_ENC(NAME_NTH(4), 3, 0),
7164 			BTF_MEMBER_ENC(NAME_NTH(5), 4, 32),
7165 			BTF_END_RAW,
7166 		},
7167 		BTF_STR_SEC("\0int\0unsigned int\0s\0a\0b"),
7168 	},
7169 },
7170 {
7171 	.descr = "dedup: array element comparison with same index type",
7172 	.input = {
7173 		.raw_types = {
7174 			BTF_TYPE_INT_ENC(NAME_NTH(1), BTF_INT_SIGNED, 0, 32, 4), /* [1] */
7175 			BTF_TYPE_INT_ENC(NAME_NTH(2), 0, 0, 32, 4),		/* [2] */
7176 			BTF_TYPE_ARRAY_ENC(1, 1, 1),				/* [3] */
7177 			BTF_TYPE_ARRAY_ENC(1, 1, 1),				/* [4] */
7178 			BTF_TYPE_ARRAY_ENC(2, 1, 1),				/* [5] */
7179 			/* struct s { int a[1]; int b[1]; } */
7180 			BTF_STRUCT_ENC(NAME_NTH(3), 2, 8),			/* [6] */
7181 			BTF_MEMBER_ENC(NAME_NTH(4), 3, 0),
7182 			BTF_MEMBER_ENC(NAME_NTH(5), 3, 32),
7183 			/* struct s { int a[1]; unsigned int b[1]; } */
7184 			BTF_STRUCT_ENC(NAME_NTH(3), 2, 8),			/* [7] */
7185 			BTF_MEMBER_ENC(NAME_NTH(4), 4, 0),
7186 			BTF_MEMBER_ENC(NAME_NTH(5), 5, 32),
7187 			BTF_END_RAW,
7188 		},
7189 		BTF_STR_SEC("\0int\0unsigned int\0s\0a\0b"),
7190 	},
7191 	.expect = {
7192 		.raw_types = {
7193 			BTF_TYPE_INT_ENC(NAME_NTH(1), BTF_INT_SIGNED, 0, 32, 4), /* [1] */
7194 			BTF_TYPE_INT_ENC(NAME_NTH(2), 0, 0, 32, 4),		/* [2] */
7195 			BTF_TYPE_ARRAY_ENC(1, 1, 1),				/* [3] */
7196 			BTF_TYPE_ARRAY_ENC(2, 1, 1),				/* [4] */
7197 			BTF_STRUCT_ENC(NAME_NTH(3), 2, 8),			/* [5] */
7198 			BTF_MEMBER_ENC(NAME_NTH(4), 3, 0),
7199 			BTF_MEMBER_ENC(NAME_NTH(5), 3, 32),
7200 			BTF_STRUCT_ENC(NAME_NTH(3), 2, 8),			/* [6] */
7201 			BTF_MEMBER_ENC(NAME_NTH(4), 3, 0),
7202 			BTF_MEMBER_ENC(NAME_NTH(5), 4, 32),
7203 			BTF_END_RAW,
7204 		},
7205 		BTF_STR_SEC("\0int\0unsigned int\0s\0a\0b"),
7206 	},
7207 },
7208 {
7209 	.descr = "dedup: identical array element comparison",
7210 	.input = {
7211 		.raw_types = {
7212 			/* int */
7213 			BTF_TYPE_INT_ENC(NAME_NTH(1), BTF_INT_SIGNED, 0, 32, 4), /* [1] */
7214 			/* struct container { struct elem first[1]; struct elem second[1]; } */
7215 			BTF_STRUCT_ENC(NAME_NTH(2), 2, 8),			/* [2] */
7216 			BTF_MEMBER_ENC(NAME_NTH(3), 3, 0),
7217 			BTF_MEMBER_ENC(NAME_NTH(4), 3, 32),
7218 			/* struct elem[1] */
7219 			BTF_TYPE_ARRAY_ENC(4, 1, 1),				/* [3] */
7220 			/* struct elem { int x; } */
7221 			BTF_STRUCT_ENC(NAME_NTH(5), 1, 4),			/* [4] */
7222 			BTF_MEMBER_ENC(NAME_NTH(6), 1, 0),
7223 			/* duplicate struct container */
7224 			BTF_STRUCT_ENC(NAME_NTH(2), 2, 8),			/* [5] */
7225 			BTF_MEMBER_ENC(NAME_NTH(3), 6, 0),
7226 			BTF_MEMBER_ENC(NAME_NTH(4), 7, 32),
7227 			/* duplicate struct elem[1] */
7228 			BTF_TYPE_ARRAY_ENC(8, 1, 1),				/* [6] */
7229 			BTF_TYPE_ARRAY_ENC(9, 1, 1),				/* [7] */
7230 			/* duplicate struct elem */
7231 			BTF_STRUCT_ENC(NAME_NTH(5), 1, 4),			/* [8] */
7232 			BTF_MEMBER_ENC(NAME_NTH(6), 1, 0),
7233 			BTF_STRUCT_ENC(NAME_NTH(5), 1, 4),			/* [9] */
7234 			BTF_MEMBER_ENC(NAME_NTH(6), 1, 0),
7235 			BTF_END_RAW,
7236 		},
7237 		BTF_STR_SEC("\0int\0container\0first\0second\0elem\0x"),
7238 	},
7239 	.expect = {
7240 		.raw_types = {
7241 			BTF_TYPE_INT_ENC(NAME_NTH(1), BTF_INT_SIGNED, 0, 32, 4), /* [1] */
7242 			BTF_STRUCT_ENC(NAME_NTH(2), 2, 8),			/* [2] */
7243 			BTF_MEMBER_ENC(NAME_NTH(3), 3, 0),
7244 			BTF_MEMBER_ENC(NAME_NTH(4), 3, 32),
7245 			BTF_TYPE_ARRAY_ENC(4, 1, 1),				/* [3] */
7246 			BTF_STRUCT_ENC(NAME_NTH(5), 1, 4),			/* [4] */
7247 			BTF_MEMBER_ENC(NAME_NTH(6), 1, 0),
7248 			BTF_END_RAW,
7249 		},
7250 		BTF_STR_SEC("\0int\0container\0first\0second\0elem\0x"),
7251 	},
7252 },
7253 {
7254 	.descr = "dedup: struct example #1",
7255 	/*
7256 	 * struct s {
7257 	 *	struct s *next;
7258 	 *	const int *a;
7259 	 *	int b[16];
7260 	 *	int c;
7261 	 * }
7262 	 */
7263 	.input = {
7264 		.raw_types = {
7265 			/* int */
7266 			BTF_TYPE_INT_ENC(NAME_NTH(1), BTF_INT_SIGNED, 0, 32, 4),	/* [1] */
7267 			/* int[16] */
7268 			BTF_TYPE_ARRAY_ENC(1, 1, 16),					/* [2] */
7269 			/* struct s { */
7270 			BTF_STRUCT_ENC(NAME_NTH(2), 5, 88),				/* [3] */
7271 				BTF_MEMBER_ENC(NAME_NTH(3), 4, 0),	/* struct s *next;	*/
7272 				BTF_MEMBER_ENC(NAME_NTH(4), 5, 64),	/* const int *a;	*/
7273 				BTF_MEMBER_ENC(NAME_NTH(5), 2, 128),	/* int b[16];		*/
7274 				BTF_MEMBER_ENC(NAME_NTH(6), 1, 640),	/* int c;		*/
7275 				BTF_MEMBER_ENC(NAME_NTH(8), 15, 672),	/* float d;		*/
7276 			/* ptr -> [3] struct s */
7277 			BTF_PTR_ENC(3),							/* [4] */
7278 			/* ptr -> [6] const int */
7279 			BTF_PTR_ENC(6),							/* [5] */
7280 			/* const -> [1] int */
7281 			BTF_CONST_ENC(1),						/* [6] */
7282 			/* tag -> [3] struct s */
7283 			BTF_DECL_TAG_ENC(NAME_NTH(2), 3, -1),				/* [7] */
7284 			/* tag -> [3] struct s, member 1 */
7285 			BTF_DECL_TAG_ENC(NAME_NTH(2), 3, 1),				/* [8] */
7286 
7287 			/* full copy of the above */
7288 			BTF_TYPE_INT_ENC(NAME_NTH(1), BTF_INT_SIGNED, 0, 32, 4),	/* [9] */
7289 			BTF_TYPE_ARRAY_ENC(9, 9, 16),					/* [10] */
7290 			BTF_STRUCT_ENC(NAME_NTH(2), 5, 88),				/* [11] */
7291 				BTF_MEMBER_ENC(NAME_NTH(3), 12, 0),
7292 				BTF_MEMBER_ENC(NAME_NTH(4), 13, 64),
7293 				BTF_MEMBER_ENC(NAME_NTH(5), 10, 128),
7294 				BTF_MEMBER_ENC(NAME_NTH(6), 9, 640),
7295 				BTF_MEMBER_ENC(NAME_NTH(8), 15, 672),
7296 			BTF_PTR_ENC(11),						/* [12] */
7297 			BTF_PTR_ENC(14),						/* [13] */
7298 			BTF_CONST_ENC(9),						/* [14] */
7299 			BTF_TYPE_FLOAT_ENC(NAME_NTH(7), 4),				/* [15] */
7300 			BTF_DECL_TAG_ENC(NAME_NTH(2), 11, -1),				/* [16] */
7301 			BTF_DECL_TAG_ENC(NAME_NTH(2), 11, 1),				/* [17] */
7302 			BTF_END_RAW,
7303 		},
7304 		BTF_STR_SEC("\0int\0s\0next\0a\0b\0c\0float\0d"),
7305 	},
7306 	.expect = {
7307 		.raw_types = {
7308 			/* int */
7309 			BTF_TYPE_INT_ENC(NAME_NTH(5), BTF_INT_SIGNED, 0, 32, 4),	/* [1] */
7310 			/* int[16] */
7311 			BTF_TYPE_ARRAY_ENC(1, 1, 16),					/* [2] */
7312 			/* struct s { */
7313 			BTF_STRUCT_ENC(NAME_NTH(8), 5, 88),				/* [3] */
7314 				BTF_MEMBER_ENC(NAME_NTH(7), 4, 0),	/* struct s *next;	*/
7315 				BTF_MEMBER_ENC(NAME_NTH(1), 5, 64),	/* const int *a;	*/
7316 				BTF_MEMBER_ENC(NAME_NTH(2), 2, 128),	/* int b[16];		*/
7317 				BTF_MEMBER_ENC(NAME_NTH(3), 1, 640),	/* int c;		*/
7318 				BTF_MEMBER_ENC(NAME_NTH(4), 9, 672),	/* float d;		*/
7319 			/* ptr -> [3] struct s */
7320 			BTF_PTR_ENC(3),							/* [4] */
7321 			/* ptr -> [6] const int */
7322 			BTF_PTR_ENC(6),							/* [5] */
7323 			/* const -> [1] int */
7324 			BTF_CONST_ENC(1),						/* [6] */
7325 			BTF_DECL_TAG_ENC(NAME_NTH(2), 3, -1),				/* [7] */
7326 			BTF_DECL_TAG_ENC(NAME_NTH(2), 3, 1),				/* [8] */
7327 			BTF_TYPE_FLOAT_ENC(NAME_NTH(7), 4),				/* [9] */
7328 			BTF_END_RAW,
7329 		},
7330 		BTF_STR_SEC("\0a\0b\0c\0d\0int\0float\0next\0s"),
7331 	},
7332 },
7333 {
7334 	.descr = "dedup: struct <-> fwd resolution w/ hash collision",
7335 	/*
7336 	 * // CU 1:
7337 	 * struct x;
7338 	 * struct s {
7339 	 *	struct x *x;
7340 	 * };
7341 	 * // CU 2:
7342 	 * struct x {};
7343 	 * struct s {
7344 	 *	struct x *x;
7345 	 * };
7346 	 */
7347 	.input = {
7348 		.raw_types = {
7349 			/* CU 1 */
7350 			BTF_FWD_ENC(NAME_TBD, 0 /* struct fwd */),	/* [1] fwd x      */
7351 			BTF_PTR_ENC(1),					/* [2] ptr -> [1] */
7352 			BTF_STRUCT_ENC(NAME_TBD, 1, 8),			/* [3] struct s   */
7353 				BTF_MEMBER_ENC(NAME_TBD, 2, 0),
7354 			/* CU 2 */
7355 			BTF_STRUCT_ENC(NAME_TBD, 0, 0),			/* [4] struct x   */
7356 			BTF_PTR_ENC(4),					/* [5] ptr -> [4] */
7357 			BTF_STRUCT_ENC(NAME_TBD, 1, 8),			/* [6] struct s   */
7358 				BTF_MEMBER_ENC(NAME_TBD, 5, 0),
7359 			BTF_END_RAW,
7360 		},
7361 		BTF_STR_SEC("\0x\0s\0x\0x\0s\0x\0"),
7362 	},
7363 	.expect = {
7364 		.raw_types = {
7365 			BTF_PTR_ENC(3),					/* [1] ptr -> [3] */
7366 			BTF_STRUCT_ENC(NAME_TBD, 1, 8),			/* [2] struct s   */
7367 				BTF_MEMBER_ENC(NAME_TBD, 1, 0),
7368 			BTF_STRUCT_ENC(NAME_NTH(2), 0, 0),		/* [3] struct x   */
7369 			BTF_END_RAW,
7370 		},
7371 		BTF_STR_SEC("\0s\0x"),
7372 	},
7373 	.opts = {
7374 		.force_collisions = true, /* force hash collisions */
7375 	},
7376 },
7377 {
7378 	.descr = "dedup: void equiv check",
7379 	/*
7380 	 * // CU 1:
7381 	 * struct s {
7382 	 *	struct {} *x;
7383 	 * };
7384 	 * // CU 2:
7385 	 * struct s {
7386 	 *	int *x;
7387 	 * };
7388 	 */
7389 	.input = {
7390 		.raw_types = {
7391 			/* CU 1 */
7392 			BTF_STRUCT_ENC(0, 0, 1),				/* [1] struct {}  */
7393 			BTF_PTR_ENC(1),						/* [2] ptr -> [1] */
7394 			BTF_STRUCT_ENC(NAME_NTH(1), 1, 8),			/* [3] struct s   */
7395 				BTF_MEMBER_ENC(NAME_NTH(2), 2, 0),
7396 			/* CU 2 */
7397 			BTF_PTR_ENC(0),						/* [4] ptr -> void */
7398 			BTF_STRUCT_ENC(NAME_NTH(1), 1, 8),			/* [5] struct s   */
7399 				BTF_MEMBER_ENC(NAME_NTH(2), 4, 0),
7400 			BTF_END_RAW,
7401 		},
7402 		BTF_STR_SEC("\0s\0x"),
7403 	},
7404 	.expect = {
7405 		.raw_types = {
7406 			/* CU 1 */
7407 			BTF_STRUCT_ENC(0, 0, 1),				/* [1] struct {}  */
7408 			BTF_PTR_ENC(1),						/* [2] ptr -> [1] */
7409 			BTF_STRUCT_ENC(NAME_NTH(1), 1, 8),			/* [3] struct s   */
7410 				BTF_MEMBER_ENC(NAME_NTH(2), 2, 0),
7411 			/* CU 2 */
7412 			BTF_PTR_ENC(0),						/* [4] ptr -> void */
7413 			BTF_STRUCT_ENC(NAME_NTH(1), 1, 8),			/* [5] struct s   */
7414 				BTF_MEMBER_ENC(NAME_NTH(2), 4, 0),
7415 			BTF_END_RAW,
7416 		},
7417 		BTF_STR_SEC("\0s\0x"),
7418 	},
7419 	.opts = {
7420 		.force_collisions = true, /* force hash collisions */
7421 	},
7422 },
7423 {
7424 	.descr = "dedup: all possible kinds (no duplicates)",
7425 	.input = {
7426 		.raw_types = {
7427 			BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 8),		/* [1] int */
7428 			BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_ENUM, 0, 2), 4),	/* [2] enum */
7429 				BTF_ENUM_ENC(NAME_TBD, 0),
7430 				BTF_ENUM_ENC(NAME_TBD, 1),
7431 			BTF_FWD_ENC(NAME_TBD, 1 /* union kind_flag */),			/* [3] fwd */
7432 			BTF_TYPE_ARRAY_ENC(2, 1, 7),					/* [4] array */
7433 			BTF_STRUCT_ENC(NAME_TBD, 1, 4),					/* [5] struct */
7434 				BTF_MEMBER_ENC(NAME_TBD, 1, 0),
7435 			BTF_UNION_ENC(NAME_TBD, 1, 4),					/* [6] union */
7436 				BTF_MEMBER_ENC(NAME_TBD, 1, 0),
7437 			BTF_TYPEDEF_ENC(NAME_TBD, 1),					/* [7] typedef */
7438 			BTF_PTR_ENC(0),							/* [8] ptr */
7439 			BTF_CONST_ENC(8),						/* [9] const */
7440 			BTF_VOLATILE_ENC(8),						/* [10] volatile */
7441 			BTF_RESTRICT_ENC(8),						/* [11] restrict */
7442 			BTF_FUNC_PROTO_ENC(1, 2),					/* [12] func_proto */
7443 				BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
7444 				BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 18),
7445 			BTF_FUNC_ENC(NAME_TBD, 12),					/* [13] func */
7446 			BTF_TYPE_FLOAT_ENC(NAME_TBD, 2),				/* [14] float */
7447 			BTF_DECL_TAG_ENC(NAME_TBD, 13, -1),				/* [15] decl_tag */
7448 			BTF_DECL_TAG_ENC(NAME_TBD, 13, 1),				/* [16] decl_tag */
7449 			BTF_DECL_TAG_ENC(NAME_TBD, 7, -1),				/* [17] decl_tag */
7450 			BTF_TYPE_TAG_ENC(NAME_TBD, 8),					/* [18] type_tag */
7451 			BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_ENUM64, 0, 2), 8),	/* [19] enum64 */
7452 				BTF_ENUM64_ENC(NAME_TBD, 0, 0),
7453 				BTF_ENUM64_ENC(NAME_TBD, 1, 1),
7454 			BTF_END_RAW,
7455 		},
7456 		BTF_STR_SEC("\0A\0B\0C\0D\0E\0F\0G\0H\0I\0J\0K\0L\0M\0N\0O\0P\0Q\0R\0S\0T\0U"),
7457 	},
7458 	.expect = {
7459 		.raw_types = {
7460 			BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 8),		/* [1] int */
7461 			BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_ENUM, 0, 2), 4),	/* [2] enum */
7462 				BTF_ENUM_ENC(NAME_TBD, 0),
7463 				BTF_ENUM_ENC(NAME_TBD, 1),
7464 			BTF_FWD_ENC(NAME_TBD, 1 /* union kind_flag */),			/* [3] fwd */
7465 			BTF_TYPE_ARRAY_ENC(2, 1, 7),					/* [4] array */
7466 			BTF_STRUCT_ENC(NAME_TBD, 1, 4),					/* [5] struct */
7467 				BTF_MEMBER_ENC(NAME_TBD, 1, 0),
7468 			BTF_UNION_ENC(NAME_TBD, 1, 4),					/* [6] union */
7469 				BTF_MEMBER_ENC(NAME_TBD, 1, 0),
7470 			BTF_TYPEDEF_ENC(NAME_TBD, 1),					/* [7] typedef */
7471 			BTF_PTR_ENC(0),							/* [8] ptr */
7472 			BTF_CONST_ENC(8),						/* [9] const */
7473 			BTF_VOLATILE_ENC(8),						/* [10] volatile */
7474 			BTF_RESTRICT_ENC(8),						/* [11] restrict */
7475 			BTF_FUNC_PROTO_ENC(1, 2),					/* [12] func_proto */
7476 				BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
7477 				BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 18),
7478 			BTF_FUNC_ENC(NAME_TBD, 12),					/* [13] func */
7479 			BTF_TYPE_FLOAT_ENC(NAME_TBD, 2),				/* [14] float */
7480 			BTF_DECL_TAG_ENC(NAME_TBD, 13, -1),				/* [15] decl_tag */
7481 			BTF_DECL_TAG_ENC(NAME_TBD, 13, 1),				/* [16] decl_tag */
7482 			BTF_DECL_TAG_ENC(NAME_TBD, 7, -1),				/* [17] decl_tag */
7483 			BTF_TYPE_TAG_ENC(NAME_TBD, 8),					/* [18] type_tag */
7484 			BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_ENUM64, 0, 2), 8),	/* [19] enum64 */
7485 				BTF_ENUM64_ENC(NAME_TBD, 0, 0),
7486 				BTF_ENUM64_ENC(NAME_TBD, 1, 1),
7487 			BTF_END_RAW,
7488 		},
7489 		BTF_STR_SEC("\0A\0B\0C\0D\0E\0F\0G\0H\0I\0J\0K\0L\0M\0N\0O\0P\0Q\0R\0S\0T\0U"),
7490 	},
7491 },
7492 {
7493 	.descr = "dedup: no int/float duplicates",
7494 	.input = {
7495 		.raw_types = {
7496 			BTF_TYPE_INT_ENC(NAME_NTH(1), BTF_INT_SIGNED, 0, 32, 8),
7497 			/* different name */
7498 			BTF_TYPE_INT_ENC(NAME_NTH(2), BTF_INT_SIGNED, 0, 32, 8),
7499 			/* different encoding */
7500 			BTF_TYPE_INT_ENC(NAME_NTH(1), BTF_INT_CHAR, 0, 32, 8),
7501 			BTF_TYPE_INT_ENC(NAME_NTH(1), BTF_INT_BOOL, 0, 32, 8),
7502 			/* different bit offset */
7503 			BTF_TYPE_INT_ENC(NAME_NTH(1), BTF_INT_SIGNED, 8, 32, 8),
7504 			/* different bit size */
7505 			BTF_TYPE_INT_ENC(NAME_NTH(1), BTF_INT_SIGNED, 0, 27, 8),
7506 			/* different byte size */
7507 			BTF_TYPE_INT_ENC(NAME_NTH(1), BTF_INT_SIGNED, 0, 32, 4),
7508 			/* all allowed sizes */
7509 			BTF_TYPE_FLOAT_ENC(NAME_NTH(3), 2),
7510 			BTF_TYPE_FLOAT_ENC(NAME_NTH(3), 4),
7511 			BTF_TYPE_FLOAT_ENC(NAME_NTH(3), 8),
7512 			BTF_TYPE_FLOAT_ENC(NAME_NTH(3), 12),
7513 			BTF_TYPE_FLOAT_ENC(NAME_NTH(3), 16),
7514 			BTF_END_RAW,
7515 		},
7516 		BTF_STR_SEC("\0int\0some other int\0float"),
7517 	},
7518 	.expect = {
7519 		.raw_types = {
7520 			BTF_TYPE_INT_ENC(NAME_NTH(1), BTF_INT_SIGNED, 0, 32, 8),
7521 			/* different name */
7522 			BTF_TYPE_INT_ENC(NAME_NTH(2), BTF_INT_SIGNED, 0, 32, 8),
7523 			/* different encoding */
7524 			BTF_TYPE_INT_ENC(NAME_NTH(1), BTF_INT_CHAR, 0, 32, 8),
7525 			BTF_TYPE_INT_ENC(NAME_NTH(1), BTF_INT_BOOL, 0, 32, 8),
7526 			/* different bit offset */
7527 			BTF_TYPE_INT_ENC(NAME_NTH(1), BTF_INT_SIGNED, 8, 32, 8),
7528 			/* different bit size */
7529 			BTF_TYPE_INT_ENC(NAME_NTH(1), BTF_INT_SIGNED, 0, 27, 8),
7530 			/* different byte size */
7531 			BTF_TYPE_INT_ENC(NAME_NTH(1), BTF_INT_SIGNED, 0, 32, 4),
7532 			/* all allowed sizes */
7533 			BTF_TYPE_FLOAT_ENC(NAME_NTH(3), 2),
7534 			BTF_TYPE_FLOAT_ENC(NAME_NTH(3), 4),
7535 			BTF_TYPE_FLOAT_ENC(NAME_NTH(3), 8),
7536 			BTF_TYPE_FLOAT_ENC(NAME_NTH(3), 12),
7537 			BTF_TYPE_FLOAT_ENC(NAME_NTH(3), 16),
7538 			BTF_END_RAW,
7539 		},
7540 		BTF_STR_SEC("\0int\0some other int\0float"),
7541 	},
7542 },
7543 {
7544 	.descr = "dedup: enum fwd resolution",
7545 	.input = {
7546 		.raw_types = {
7547 			/* [1] fwd enum 'e1' before full enum */
7548 			BTF_TYPE_ENC(NAME_NTH(1), BTF_INFO_ENC(BTF_KIND_ENUM, 0, 0), 4),
7549 			/* [2] full enum 'e1' after fwd */
7550 			BTF_TYPE_ENC(NAME_NTH(1), BTF_INFO_ENC(BTF_KIND_ENUM, 0, 1), 4),
7551 				BTF_ENUM_ENC(NAME_NTH(2), 123),
7552 			/* [3] full enum 'e2' before fwd */
7553 			BTF_TYPE_ENC(NAME_NTH(3), BTF_INFO_ENC(BTF_KIND_ENUM, 0, 1), 4),
7554 				BTF_ENUM_ENC(NAME_NTH(4), 456),
7555 			/* [4] fwd enum 'e2' after full enum */
7556 			BTF_TYPE_ENC(NAME_NTH(3), BTF_INFO_ENC(BTF_KIND_ENUM, 0, 0), 4),
7557 			/* [5] fwd enum with different size, size does not matter for fwd */
7558 			BTF_TYPE_ENC(NAME_NTH(1), BTF_INFO_ENC(BTF_KIND_ENUM, 0, 0), 1),
7559 			/* [6] incompatible full enum with different value */
7560 			BTF_TYPE_ENC(NAME_NTH(1), BTF_INFO_ENC(BTF_KIND_ENUM, 0, 1), 4),
7561 				BTF_ENUM_ENC(NAME_NTH(2), 321),
7562 			BTF_END_RAW,
7563 		},
7564 		BTF_STR_SEC("\0e1\0e1_val\0e2\0e2_val"),
7565 	},
7566 	.expect = {
7567 		.raw_types = {
7568 			/* [1] full enum 'e1' */
7569 			BTF_TYPE_ENC(NAME_NTH(1), BTF_INFO_ENC(BTF_KIND_ENUM, 0, 1), 4),
7570 				BTF_ENUM_ENC(NAME_NTH(2), 123),
7571 			/* [2] full enum 'e2' */
7572 			BTF_TYPE_ENC(NAME_NTH(3), BTF_INFO_ENC(BTF_KIND_ENUM, 0, 1), 4),
7573 				BTF_ENUM_ENC(NAME_NTH(4), 456),
7574 			/* [3] incompatible full enum with different value */
7575 			BTF_TYPE_ENC(NAME_NTH(1), BTF_INFO_ENC(BTF_KIND_ENUM, 0, 1), 4),
7576 				BTF_ENUM_ENC(NAME_NTH(2), 321),
7577 			BTF_END_RAW,
7578 		},
7579 		BTF_STR_SEC("\0e1\0e1_val\0e2\0e2_val"),
7580 	},
7581 },
7582 {
7583 	.descr = "dedup: datasec and vars pass-through",
7584 	.input = {
7585 		.raw_types = {
7586 			/* int */
7587 			BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),	/* [1] */
7588 			/* static int t */
7589 			BTF_VAR_ENC(NAME_NTH(2), 1, 0),			/* [2] */
7590 			/* .bss section */				/* [3] */
7591 			BTF_TYPE_ENC(NAME_NTH(1), BTF_INFO_ENC(BTF_KIND_DATASEC, 0, 1), 4),
7592 			BTF_VAR_SECINFO_ENC(2, 0, 4),
7593 			/* int, referenced from [5] */
7594 			BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),	/* [4] */
7595 			/* another static int t */
7596 			BTF_VAR_ENC(NAME_NTH(2), 4, 0),			/* [5] */
7597 			/* another .bss section */			/* [6] */
7598 			BTF_TYPE_ENC(NAME_NTH(1), BTF_INFO_ENC(BTF_KIND_DATASEC, 0, 1), 4),
7599 			BTF_VAR_SECINFO_ENC(5, 0, 4),
7600 			BTF_END_RAW,
7601 		},
7602 		BTF_STR_SEC("\0.bss\0t"),
7603 	},
7604 	.expect = {
7605 		.raw_types = {
7606 			/* int */
7607 			BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),	/* [1] */
7608 			/* static int t */
7609 			BTF_VAR_ENC(NAME_NTH(2), 1, 0),			/* [2] */
7610 			/* .bss section */				/* [3] */
7611 			BTF_TYPE_ENC(NAME_NTH(1), BTF_INFO_ENC(BTF_KIND_DATASEC, 0, 1), 4),
7612 			BTF_VAR_SECINFO_ENC(2, 0, 4),
7613 			/* another static int t */
7614 			BTF_VAR_ENC(NAME_NTH(2), 1, 0),			/* [4] */
7615 			/* another .bss section */			/* [5] */
7616 			BTF_TYPE_ENC(NAME_NTH(1), BTF_INFO_ENC(BTF_KIND_DATASEC, 0, 1), 4),
7617 			BTF_VAR_SECINFO_ENC(4, 0, 4),
7618 			BTF_END_RAW,
7619 		},
7620 		BTF_STR_SEC("\0.bss\0t"),
7621 	},
7622 	.opts = {
7623 		.force_collisions = true
7624 	},
7625 },
7626 {
7627 	.descr = "dedup: func/func_arg/var tags",
7628 	.input = {
7629 		.raw_types = {
7630 			/* int */
7631 			BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),	/* [1] */
7632 			/* static int t */
7633 			BTF_VAR_ENC(NAME_NTH(1), 1, 0),			/* [2] */
7634 			/* void f(int a1, int a2) */
7635 			BTF_FUNC_PROTO_ENC(0, 2),			/* [3] */
7636 				BTF_FUNC_PROTO_ARG_ENC(NAME_NTH(2), 1),
7637 				BTF_FUNC_PROTO_ARG_ENC(NAME_NTH(3), 1),
7638 			BTF_FUNC_ENC(NAME_NTH(4), 3),			/* [4] */
7639 			/* tag -> t */
7640 			BTF_DECL_TAG_ENC(NAME_NTH(5), 2, -1),		/* [5] */
7641 			BTF_DECL_TAG_ENC(NAME_NTH(5), 2, -1),		/* [6] */
7642 			/* tag -> func */
7643 			BTF_DECL_TAG_ENC(NAME_NTH(5), 4, -1),		/* [7] */
7644 			BTF_DECL_TAG_ENC(NAME_NTH(5), 4, -1),		/* [8] */
7645 			/* tag -> func arg a1 */
7646 			BTF_DECL_TAG_ENC(NAME_NTH(5), 4, 1),		/* [9] */
7647 			BTF_DECL_TAG_ENC(NAME_NTH(5), 4, 1),		/* [10] */
7648 			BTF_END_RAW,
7649 		},
7650 		BTF_STR_SEC("\0t\0a1\0a2\0f\0tag"),
7651 	},
7652 	.expect = {
7653 		.raw_types = {
7654 			BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),	/* [1] */
7655 			BTF_VAR_ENC(NAME_NTH(1), 1, 0),			/* [2] */
7656 			BTF_FUNC_PROTO_ENC(0, 2),			/* [3] */
7657 				BTF_FUNC_PROTO_ARG_ENC(NAME_NTH(2), 1),
7658 				BTF_FUNC_PROTO_ARG_ENC(NAME_NTH(3), 1),
7659 			BTF_FUNC_ENC(NAME_NTH(4), 3),			/* [4] */
7660 			BTF_DECL_TAG_ENC(NAME_NTH(5), 2, -1),		/* [5] */
7661 			BTF_DECL_TAG_ENC(NAME_NTH(5), 4, -1),		/* [6] */
7662 			BTF_DECL_TAG_ENC(NAME_NTH(5), 4, 1),		/* [7] */
7663 			BTF_END_RAW,
7664 		},
7665 		BTF_STR_SEC("\0t\0a1\0a2\0f\0tag"),
7666 	},
7667 },
7668 {
7669 	.descr = "dedup: func/func_param tags",
7670 	.input = {
7671 		.raw_types = {
7672 			/* int */
7673 			BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),	/* [1] */
7674 			/* void f(int a1, int a2) */
7675 			BTF_FUNC_PROTO_ENC(0, 2),			/* [2] */
7676 				BTF_FUNC_PROTO_ARG_ENC(NAME_NTH(1), 1),
7677 				BTF_FUNC_PROTO_ARG_ENC(NAME_NTH(2), 1),
7678 			BTF_FUNC_ENC(NAME_NTH(3), 2),			/* [3] */
7679 			/* void f(int a1, int a2) */
7680 			BTF_FUNC_PROTO_ENC(0, 2),			/* [4] */
7681 				BTF_FUNC_PROTO_ARG_ENC(NAME_NTH(1), 1),
7682 				BTF_FUNC_PROTO_ARG_ENC(NAME_NTH(2), 1),
7683 			BTF_FUNC_ENC(NAME_NTH(3), 4),			/* [5] */
7684 			/* tag -> f: tag1, tag2 */
7685 			BTF_DECL_TAG_ENC(NAME_NTH(4), 3, -1),		/* [6] */
7686 			BTF_DECL_TAG_ENC(NAME_NTH(5), 3, -1),		/* [7] */
7687 			/* tag -> f/a2: tag1, tag2 */
7688 			BTF_DECL_TAG_ENC(NAME_NTH(4), 3, 1),		/* [8] */
7689 			BTF_DECL_TAG_ENC(NAME_NTH(5), 3, 1),		/* [9] */
7690 			/* tag -> f: tag1, tag3 */
7691 			BTF_DECL_TAG_ENC(NAME_NTH(4), 5, -1),		/* [10] */
7692 			BTF_DECL_TAG_ENC(NAME_NTH(6), 5, -1),		/* [11] */
7693 			/* tag -> f/a2: tag1, tag3 */
7694 			BTF_DECL_TAG_ENC(NAME_NTH(4), 5, 1),		/* [12] */
7695 			BTF_DECL_TAG_ENC(NAME_NTH(6), 5, 1),		/* [13] */
7696 			BTF_END_RAW,
7697 		},
7698 		BTF_STR_SEC("\0a1\0a2\0f\0tag1\0tag2\0tag3"),
7699 	},
7700 	.expect = {
7701 		.raw_types = {
7702 			BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),	/* [1] */
7703 			BTF_FUNC_PROTO_ENC(0, 2),			/* [2] */
7704 				BTF_FUNC_PROTO_ARG_ENC(NAME_NTH(1), 1),
7705 				BTF_FUNC_PROTO_ARG_ENC(NAME_NTH(2), 1),
7706 			BTF_FUNC_ENC(NAME_NTH(3), 2),			/* [3] */
7707 			BTF_DECL_TAG_ENC(NAME_NTH(4), 3, -1),		/* [4] */
7708 			BTF_DECL_TAG_ENC(NAME_NTH(5), 3, -1),		/* [5] */
7709 			BTF_DECL_TAG_ENC(NAME_NTH(6), 3, -1),		/* [6] */
7710 			BTF_DECL_TAG_ENC(NAME_NTH(4), 3, 1),		/* [7] */
7711 			BTF_DECL_TAG_ENC(NAME_NTH(5), 3, 1),		/* [8] */
7712 			BTF_DECL_TAG_ENC(NAME_NTH(6), 3, 1),		/* [9] */
7713 			BTF_END_RAW,
7714 		},
7715 		BTF_STR_SEC("\0a1\0a2\0f\0tag1\0tag2\0tag3"),
7716 	},
7717 },
7718 {
7719 	.descr = "dedup: struct/struct_member tags",
7720 	.input = {
7721 		.raw_types = {
7722 			/* int */
7723 			BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),	/* [1] */
7724 			BTF_STRUCT_ENC(NAME_NTH(1), 2, 8),		/* [2] */
7725 				BTF_MEMBER_ENC(NAME_NTH(2), 1, 0),
7726 				BTF_MEMBER_ENC(NAME_NTH(3), 1, 32),
7727 			BTF_STRUCT_ENC(NAME_NTH(1), 2, 8),		/* [3] */
7728 				BTF_MEMBER_ENC(NAME_NTH(2), 1, 0),
7729 				BTF_MEMBER_ENC(NAME_NTH(3), 1, 32),
7730 			/* tag -> t: tag1, tag2 */
7731 			BTF_DECL_TAG_ENC(NAME_NTH(4), 2, -1),		/* [4] */
7732 			BTF_DECL_TAG_ENC(NAME_NTH(5), 2, -1),		/* [5] */
7733 			/* tag -> t/m2: tag1, tag2 */
7734 			BTF_DECL_TAG_ENC(NAME_NTH(4), 2, 1),		/* [6] */
7735 			BTF_DECL_TAG_ENC(NAME_NTH(5), 2, 1),		/* [7] */
7736 			/* tag -> t: tag1, tag3 */
7737 			BTF_DECL_TAG_ENC(NAME_NTH(4), 3, -1),		/* [8] */
7738 			BTF_DECL_TAG_ENC(NAME_NTH(6), 3, -1),		/* [9] */
7739 			/* tag -> t/m2: tag1, tag3 */
7740 			BTF_DECL_TAG_ENC(NAME_NTH(4), 3, 1),		/* [10] */
7741 			BTF_DECL_TAG_ENC(NAME_NTH(6), 3, 1),		/* [11] */
7742 			BTF_END_RAW,
7743 		},
7744 		BTF_STR_SEC("\0t\0m1\0m2\0tag1\0tag2\0tag3"),
7745 	},
7746 	.expect = {
7747 		.raw_types = {
7748 			BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),	/* [1] */
7749 			BTF_STRUCT_ENC(NAME_NTH(1), 2, 8),		/* [2] */
7750 				BTF_MEMBER_ENC(NAME_NTH(2), 1, 0),
7751 				BTF_MEMBER_ENC(NAME_NTH(3), 1, 32),
7752 			BTF_DECL_TAG_ENC(NAME_NTH(4), 2, -1),		/* [3] */
7753 			BTF_DECL_TAG_ENC(NAME_NTH(5), 2, -1),		/* [4] */
7754 			BTF_DECL_TAG_ENC(NAME_NTH(6), 2, -1),		/* [5] */
7755 			BTF_DECL_TAG_ENC(NAME_NTH(4), 2, 1),		/* [6] */
7756 			BTF_DECL_TAG_ENC(NAME_NTH(5), 2, 1),		/* [7] */
7757 			BTF_DECL_TAG_ENC(NAME_NTH(6), 2, 1),		/* [8] */
7758 			BTF_END_RAW,
7759 		},
7760 		BTF_STR_SEC("\0t\0m1\0m2\0tag1\0tag2\0tag3"),
7761 	},
7762 },
7763 {
7764 	.descr = "dedup: recursive typedef",
7765 	/*
7766 	 * This test simulates a recursive typedef, which in GO is defined as such:
7767 	 *
7768 	 *   type Foo func() Foo
7769 	 *
7770 	 * In BTF terms, this is represented as a TYPEDEF referencing
7771 	 * a FUNC_PROTO that returns the same TYPEDEF.
7772 	 */
7773 	.input = {
7774 		.raw_types = {
7775 			/*
7776 			 * [1] typedef Foo -> func() Foo
7777 			 * [2] func_proto() -> Foo
7778 			 * [3] typedef Foo -> func() Foo
7779 			 * [4] func_proto() -> Foo
7780 			 */
7781 			BTF_TYPEDEF_ENC(NAME_NTH(1), 2),	/* [1] */
7782 			BTF_FUNC_PROTO_ENC(1, 0),		/* [2] */
7783 			BTF_TYPEDEF_ENC(NAME_NTH(1), 4),	/* [3] */
7784 			BTF_FUNC_PROTO_ENC(3, 0),		/* [4] */
7785 			BTF_END_RAW,
7786 		},
7787 		BTF_STR_SEC("\0Foo"),
7788 	},
7789 	.expect = {
7790 		.raw_types = {
7791 			BTF_TYPEDEF_ENC(NAME_NTH(1), 2),	/* [1] */
7792 			BTF_FUNC_PROTO_ENC(1, 0),		/* [2] */
7793 			BTF_END_RAW,
7794 		},
7795 		BTF_STR_SEC("\0Foo"),
7796 	},
7797 },
7798 {
7799 	.descr = "dedup: typedef",
7800     /*
7801      * // CU 1:
7802      * typedef int foo;
7803      *
7804      * // CU 2:
7805      * typedef int foo;
7806      */
7807 	.input = {
7808 		.raw_types = {
7809 			/* CU 1 */
7810 			BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),	/* [1] */
7811 			BTF_TYPEDEF_ENC(NAME_NTH(1), 1),		/* [2] */
7812 			/* CU 2 */
7813 			BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),	/* [3] */
7814 			BTF_TYPEDEF_ENC(NAME_NTH(1), 3),		/* [4] */
7815 			BTF_END_RAW,
7816 		},
7817 		BTF_STR_SEC("\0foo"),
7818 	},
7819 	.expect = {
7820 		.raw_types = {
7821 			BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),	/* [1] */
7822 			BTF_TYPEDEF_ENC(NAME_NTH(1), 1),		/* [2] */
7823 			BTF_END_RAW,
7824 		},
7825 		BTF_STR_SEC("\0foo"),
7826 	},
7827 },
7828 {
7829 	.descr = "dedup: typedef tags",
7830 	.input = {
7831 		.raw_types = {
7832 			/* int */
7833 			BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),	/* [1] */
7834 			BTF_TYPEDEF_ENC(NAME_NTH(1), 1),		/* [2] */
7835 			BTF_TYPEDEF_ENC(NAME_NTH(1), 1),		/* [3] */
7836 			/* tag -> t: tag1, tag2 */
7837 			BTF_DECL_TAG_ENC(NAME_NTH(2), 2, -1),		/* [4] */
7838 			BTF_DECL_TAG_ENC(NAME_NTH(3), 2, -1),		/* [5] */
7839 			/* tag -> t: tag1, tag3 */
7840 			BTF_DECL_TAG_ENC(NAME_NTH(2), 3, -1),		/* [6] */
7841 			BTF_DECL_TAG_ENC(NAME_NTH(4), 3, -1),		/* [7] */
7842 			BTF_END_RAW,
7843 		},
7844 		BTF_STR_SEC("\0t\0tag1\0tag2\0tag3"),
7845 	},
7846 	.expect = {
7847 		.raw_types = {
7848 			BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),	/* [1] */
7849 			BTF_TYPEDEF_ENC(NAME_NTH(1), 1),		/* [2] */
7850 			BTF_DECL_TAG_ENC(NAME_NTH(2), 2, -1),		/* [3] */
7851 			BTF_DECL_TAG_ENC(NAME_NTH(3), 2, -1),		/* [4] */
7852 			BTF_DECL_TAG_ENC(NAME_NTH(4), 2, -1),		/* [5] */
7853 			BTF_END_RAW,
7854 		},
7855 		BTF_STR_SEC("\0t\0tag1\0tag2\0tag3"),
7856 	},
7857 },
7858 {
7859 	.descr = "dedup: btf_type_tag #1",
7860 	.input = {
7861 		.raw_types = {
7862 			/* ptr -> tag2 -> tag1 -> int */
7863 			BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),	/* [1] */
7864 			BTF_TYPE_TAG_ENC(NAME_NTH(1), 1),		/* [2] */
7865 			BTF_TYPE_TAG_ENC(NAME_NTH(2), 2),		/* [3] */
7866 			BTF_PTR_ENC(3),					/* [4] */
7867 			/* ptr -> tag2 -> tag1 -> int */
7868 			BTF_TYPE_TAG_ENC(NAME_NTH(1), 1),		/* [5] */
7869 			BTF_TYPE_TAG_ENC(NAME_NTH(2), 5),		/* [6] */
7870 			BTF_PTR_ENC(6),					/* [7] */
7871 			/* ptr -> tag1 -> int */
7872 			BTF_TYPE_TAG_ENC(NAME_NTH(1), 1),		/* [8] */
7873 			BTF_PTR_ENC(8),					/* [9] */
7874 			BTF_END_RAW,
7875 		},
7876 		BTF_STR_SEC("\0tag1\0tag2"),
7877 	},
7878 	.expect = {
7879 		.raw_types = {
7880 			/* ptr -> tag2 -> tag1 -> int */
7881 			BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),	/* [1] */
7882 			BTF_TYPE_TAG_ENC(NAME_NTH(1), 1),		/* [2] */
7883 			BTF_TYPE_TAG_ENC(NAME_NTH(2), 2),		/* [3] */
7884 			BTF_PTR_ENC(3),					/* [4] */
7885 			/* ptr -> tag1 -> int */
7886 			BTF_PTR_ENC(2),					/* [5] */
7887 			BTF_END_RAW,
7888 		},
7889 		BTF_STR_SEC("\0tag1\0tag2"),
7890 	},
7891 },
7892 {
7893 	.descr = "dedup: btf_type_tag #2",
7894 	.input = {
7895 		.raw_types = {
7896 			/* ptr -> tag2 -> tag1 -> int */
7897 			BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),	/* [1] */
7898 			BTF_TYPE_TAG_ENC(NAME_NTH(1), 1),		/* [2] */
7899 			BTF_TYPE_TAG_ENC(NAME_NTH(2), 2),		/* [3] */
7900 			BTF_PTR_ENC(3),					/* [4] */
7901 			/* ptr -> tag2 -> int */
7902 			BTF_TYPE_TAG_ENC(NAME_NTH(2), 1),		/* [5] */
7903 			BTF_PTR_ENC(5),					/* [6] */
7904 			BTF_END_RAW,
7905 		},
7906 		BTF_STR_SEC("\0tag1\0tag2"),
7907 	},
7908 	.expect = {
7909 		.raw_types = {
7910 			/* ptr -> tag2 -> tag1 -> int */
7911 			BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),	/* [1] */
7912 			BTF_TYPE_TAG_ENC(NAME_NTH(1), 1),		/* [2] */
7913 			BTF_TYPE_TAG_ENC(NAME_NTH(2), 2),		/* [3] */
7914 			BTF_PTR_ENC(3),					/* [4] */
7915 			/* ptr -> tag2 -> int */
7916 			BTF_TYPE_TAG_ENC(NAME_NTH(2), 1),		/* [5] */
7917 			BTF_PTR_ENC(5),					/* [6] */
7918 			BTF_END_RAW,
7919 		},
7920 		BTF_STR_SEC("\0tag1\0tag2"),
7921 	},
7922 },
7923 {
7924 	.descr = "dedup: btf_type_tag #3",
7925 	.input = {
7926 		.raw_types = {
7927 			/* ptr -> tag2 -> tag1 -> int */
7928 			BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),	/* [1] */
7929 			BTF_TYPE_TAG_ENC(NAME_NTH(1), 1),		/* [2] */
7930 			BTF_TYPE_TAG_ENC(NAME_NTH(2), 2),		/* [3] */
7931 			BTF_PTR_ENC(3),					/* [4] */
7932 			/* ptr -> tag1 -> tag2 -> int */
7933 			BTF_TYPE_TAG_ENC(NAME_NTH(2), 1),		/* [5] */
7934 			BTF_TYPE_TAG_ENC(NAME_NTH(1), 5),		/* [6] */
7935 			BTF_PTR_ENC(6),					/* [7] */
7936 			BTF_END_RAW,
7937 		},
7938 		BTF_STR_SEC("\0tag1\0tag2"),
7939 	},
7940 	.expect = {
7941 		.raw_types = {
7942 			/* ptr -> tag2 -> tag1 -> int */
7943 			BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),	/* [1] */
7944 			BTF_TYPE_TAG_ENC(NAME_NTH(1), 1),		/* [2] */
7945 			BTF_TYPE_TAG_ENC(NAME_NTH(2), 2),		/* [3] */
7946 			BTF_PTR_ENC(3),					/* [4] */
7947 			/* ptr -> tag1 -> tag2 -> int */
7948 			BTF_TYPE_TAG_ENC(NAME_NTH(2), 1),		/* [5] */
7949 			BTF_TYPE_TAG_ENC(NAME_NTH(1), 5),		/* [6] */
7950 			BTF_PTR_ENC(6),					/* [7] */
7951 			BTF_END_RAW,
7952 		},
7953 		BTF_STR_SEC("\0tag1\0tag2"),
7954 	},
7955 },
7956 {
7957 	.descr = "dedup: btf_type_tag #4",
7958 	.input = {
7959 		.raw_types = {
7960 			/* ptr -> tag1 -> int */
7961 			BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),	/* [1] */
7962 			BTF_TYPE_TAG_ENC(NAME_NTH(1), 1),		/* [2] */
7963 			BTF_PTR_ENC(2),					/* [3] */
7964 			/* ptr -> tag1 -> long */
7965 			BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 64, 8),	/* [4] */
7966 			BTF_TYPE_TAG_ENC(NAME_NTH(1), 4),		/* [5] */
7967 			BTF_PTR_ENC(5),					/* [6] */
7968 			BTF_END_RAW,
7969 		},
7970 		BTF_STR_SEC("\0tag1"),
7971 	},
7972 	.expect = {
7973 		.raw_types = {
7974 			/* ptr -> tag1 -> int */
7975 			BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),	/* [1] */
7976 			BTF_TYPE_TAG_ENC(NAME_NTH(1), 1),		/* [2] */
7977 			BTF_PTR_ENC(2),					/* [3] */
7978 			/* ptr -> tag1 -> long */
7979 			BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 64, 8),	/* [4] */
7980 			BTF_TYPE_TAG_ENC(NAME_NTH(1), 4),		/* [5] */
7981 			BTF_PTR_ENC(5),					/* [6] */
7982 			BTF_END_RAW,
7983 		},
7984 		BTF_STR_SEC("\0tag1"),
7985 	},
7986 },
7987 {
7988 	.descr = "dedup: btf_type_tag #5, struct",
7989 	.input = {
7990 		.raw_types = {
7991 			BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),				/* [1] */
7992 			BTF_TYPE_TAG_ENC(NAME_NTH(1), 1),					/* [2] */
7993 			BTF_TYPE_ENC(NAME_NTH(2), BTF_INFO_ENC(BTF_KIND_STRUCT, 1, 1), 4),	/* [3] */
7994 			BTF_MEMBER_ENC(NAME_NTH(3), 2, BTF_MEMBER_OFFSET(0, 0)),
7995 			BTF_TYPE_TAG_ENC(NAME_NTH(1), 1),					/* [4] */
7996 			BTF_TYPE_ENC(NAME_NTH(2), BTF_INFO_ENC(BTF_KIND_STRUCT, 1, 1), 4),	/* [5] */
7997 			BTF_MEMBER_ENC(NAME_NTH(3), 4, BTF_MEMBER_OFFSET(0, 0)),
7998 			BTF_END_RAW,
7999 		},
8000 		BTF_STR_SEC("\0tag1\0t\0m"),
8001 	},
8002 	.expect = {
8003 		.raw_types = {
8004 			BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),				/* [1] */
8005 			BTF_TYPE_TAG_ENC(NAME_NTH(1), 1),					/* [2] */
8006 			BTF_TYPE_ENC(NAME_NTH(2), BTF_INFO_ENC(BTF_KIND_STRUCT, 1, 1), 4),	/* [3] */
8007 			BTF_MEMBER_ENC(NAME_NTH(3), 2, BTF_MEMBER_OFFSET(0, 0)),
8008 			BTF_END_RAW,
8009 		},
8010 		BTF_STR_SEC("\0tag1\0t\0m"),
8011 	},
8012 },
8013 {
8014 	.descr = "dedup: enum64, standalone",
8015 	.input = {
8016 		.raw_types = {
8017 			BTF_TYPE_ENC(NAME_NTH(1), BTF_INFO_ENC(BTF_KIND_ENUM64, 0, 1), 8),
8018 				BTF_ENUM64_ENC(NAME_NTH(2), 1, 123),
8019 			BTF_TYPE_ENC(NAME_NTH(1), BTF_INFO_ENC(BTF_KIND_ENUM64, 0, 1), 8),
8020 				BTF_ENUM64_ENC(NAME_NTH(2), 1, 123),
8021 			BTF_END_RAW,
8022 		},
8023 		BTF_STR_SEC("\0e1\0e1_val"),
8024 	},
8025 	.expect = {
8026 		.raw_types = {
8027 			BTF_TYPE_ENC(NAME_NTH(1), BTF_INFO_ENC(BTF_KIND_ENUM64, 0, 1), 8),
8028 				BTF_ENUM64_ENC(NAME_NTH(2), 1, 123),
8029 			BTF_END_RAW,
8030 		},
8031 		BTF_STR_SEC("\0e1\0e1_val"),
8032 	},
8033 },
8034 {
8035 	.descr = "dedup: enum64, fwd resolution",
8036 	.input = {
8037 		.raw_types = {
8038 			/* [1] fwd enum64 'e1' before full enum */
8039 			BTF_TYPE_ENC(NAME_NTH(1), BTF_INFO_ENC(BTF_KIND_ENUM64, 0, 0), 8),
8040 			/* [2] full enum64 'e1' after fwd */
8041 			BTF_TYPE_ENC(NAME_NTH(1), BTF_INFO_ENC(BTF_KIND_ENUM64, 0, 1), 8),
8042 				BTF_ENUM64_ENC(NAME_NTH(2), 1, 123),
8043 			/* [3] full enum64 'e2' before fwd */
8044 			BTF_TYPE_ENC(NAME_NTH(3), BTF_INFO_ENC(BTF_KIND_ENUM64, 0, 1), 8),
8045 				BTF_ENUM64_ENC(NAME_NTH(4), 0, 456),
8046 			/* [4] fwd enum64 'e2' after full enum */
8047 			BTF_TYPE_ENC(NAME_NTH(3), BTF_INFO_ENC(BTF_KIND_ENUM64, 0, 0), 8),
8048 			/* [5] incompatible full enum64 with different value */
8049 			BTF_TYPE_ENC(NAME_NTH(1), BTF_INFO_ENC(BTF_KIND_ENUM64, 0, 1), 8),
8050 				BTF_ENUM64_ENC(NAME_NTH(2), 0, 321),
8051 			BTF_END_RAW,
8052 		},
8053 		BTF_STR_SEC("\0e1\0e1_val\0e2\0e2_val"),
8054 	},
8055 	.expect = {
8056 		.raw_types = {
8057 			/* [1] full enum64 'e1' */
8058 			BTF_TYPE_ENC(NAME_NTH(1), BTF_INFO_ENC(BTF_KIND_ENUM64, 0, 1), 8),
8059 				BTF_ENUM64_ENC(NAME_NTH(2), 1, 123),
8060 			/* [2] full enum64 'e2' */
8061 			BTF_TYPE_ENC(NAME_NTH(3), BTF_INFO_ENC(BTF_KIND_ENUM64, 0, 1), 8),
8062 				BTF_ENUM64_ENC(NAME_NTH(4), 0, 456),
8063 			/* [3] incompatible full enum64 with different value */
8064 			BTF_TYPE_ENC(NAME_NTH(1), BTF_INFO_ENC(BTF_KIND_ENUM64, 0, 1), 8),
8065 				BTF_ENUM64_ENC(NAME_NTH(2), 0, 321),
8066 			BTF_END_RAW,
8067 		},
8068 		BTF_STR_SEC("\0e1\0e1_val\0e2\0e2_val"),
8069 	},
8070 },
8071 {
8072 	.descr = "dedup: enum and enum64, no dedup",
8073 	.input = {
8074 		.raw_types = {
8075 			/* [1] enum 'e1' */
8076 			BTF_TYPE_ENC(NAME_NTH(1), BTF_INFO_ENC(BTF_KIND_ENUM, 0, 1), 4),
8077 				BTF_ENUM_ENC(NAME_NTH(2), 1),
8078 			/* [2] enum64 'e1' */
8079 			BTF_TYPE_ENC(NAME_NTH(1), BTF_INFO_ENC(BTF_KIND_ENUM64, 0, 1), 4),
8080 				BTF_ENUM64_ENC(NAME_NTH(2), 1, 0),
8081 			BTF_END_RAW,
8082 		},
8083 		BTF_STR_SEC("\0e1\0e1_val"),
8084 	},
8085 	.expect = {
8086 		.raw_types = {
8087 			/* [1] enum 'e1' */
8088 			BTF_TYPE_ENC(NAME_NTH(1), BTF_INFO_ENC(BTF_KIND_ENUM, 0, 1), 4),
8089 				BTF_ENUM_ENC(NAME_NTH(2), 1),
8090 			/* [2] enum64 'e1' */
8091 			BTF_TYPE_ENC(NAME_NTH(1), BTF_INFO_ENC(BTF_KIND_ENUM64, 0, 1), 4),
8092 				BTF_ENUM64_ENC(NAME_NTH(2), 1, 0),
8093 			BTF_END_RAW,
8094 		},
8095 		BTF_STR_SEC("\0e1\0e1_val"),
8096 	},
8097 },
8098 {
8099 	.descr = "dedup: enum of different size: no dedup",
8100 	.input = {
8101 		.raw_types = {
8102 			/* [1] enum 'e1' */
8103 			BTF_TYPE_ENC(NAME_NTH(1), BTF_INFO_ENC(BTF_KIND_ENUM, 0, 1), 4),
8104 				BTF_ENUM_ENC(NAME_NTH(2), 1),
8105 			/* [2] enum 'e1' */
8106 			BTF_TYPE_ENC(NAME_NTH(1), BTF_INFO_ENC(BTF_KIND_ENUM, 0, 1), 2),
8107 				BTF_ENUM_ENC(NAME_NTH(2), 1),
8108 			BTF_END_RAW,
8109 		},
8110 		BTF_STR_SEC("\0e1\0e1_val"),
8111 	},
8112 	.expect = {
8113 		.raw_types = {
8114 			/* [1] enum 'e1' */
8115 			BTF_TYPE_ENC(NAME_NTH(1), BTF_INFO_ENC(BTF_KIND_ENUM, 0, 1), 4),
8116 				BTF_ENUM_ENC(NAME_NTH(2), 1),
8117 			/* [2] enum 'e1' */
8118 			BTF_TYPE_ENC(NAME_NTH(1), BTF_INFO_ENC(BTF_KIND_ENUM, 0, 1), 2),
8119 				BTF_ENUM_ENC(NAME_NTH(2), 1),
8120 			BTF_END_RAW,
8121 		},
8122 		BTF_STR_SEC("\0e1\0e1_val"),
8123 	},
8124 },
8125 {
8126 	.descr = "dedup: enum fwd to enum64",
8127 	.input = {
8128 		.raw_types = {
8129 			/* [1] enum64 'e1' */
8130 			BTF_TYPE_ENC(NAME_NTH(1), BTF_INFO_ENC(BTF_KIND_ENUM64, 0, 1), 8),
8131 				BTF_ENUM64_ENC(NAME_NTH(2), 1, 0),
8132 			/* [2] enum 'e1' fwd */
8133 			BTF_TYPE_ENC(NAME_NTH(1), BTF_INFO_ENC(BTF_KIND_ENUM, 0, 0), 4),
8134 			/* [3] typedef enum 'e1' td */
8135 			BTF_TYPE_ENC(NAME_NTH(3), BTF_INFO_ENC(BTF_KIND_TYPEDEF, 0, 0), 2),
8136 			BTF_END_RAW,
8137 		},
8138 		BTF_STR_SEC("\0e1\0e1_val\0td"),
8139 	},
8140 	.expect = {
8141 		.raw_types = {
8142 			/* [1] enum64 'e1' */
8143 			BTF_TYPE_ENC(NAME_NTH(1), BTF_INFO_ENC(BTF_KIND_ENUM64, 0, 1), 8),
8144 				BTF_ENUM64_ENC(NAME_NTH(2), 1, 0),
8145 			/* [2] typedef enum 'e1' td */
8146 			BTF_TYPE_ENC(NAME_NTH(3), BTF_INFO_ENC(BTF_KIND_TYPEDEF, 0, 0), 1),
8147 			BTF_END_RAW,
8148 		},
8149 		BTF_STR_SEC("\0e1\0e1_val\0td"),
8150 	},
8151 },
8152 {
8153 	.descr = "dedup: enum64 fwd to enum",
8154 	.input = {
8155 		.raw_types = {
8156 			/* [1] enum 'e1' */
8157 			BTF_TYPE_ENC(NAME_NTH(1), BTF_INFO_ENC(BTF_KIND_ENUM, 0, 1), 4),
8158 				BTF_ENUM_ENC(NAME_NTH(2), 1),
8159 			/* [2] enum64 'e1' fwd */
8160 			BTF_TYPE_ENC(NAME_NTH(1), BTF_INFO_ENC(BTF_KIND_ENUM64, 0, 0), 8),
8161 			/* [3] typedef enum 'e1' td */
8162 			BTF_TYPE_ENC(NAME_NTH(3), BTF_INFO_ENC(BTF_KIND_TYPEDEF, 0, 0), 2),
8163 			BTF_END_RAW,
8164 		},
8165 		BTF_STR_SEC("\0e1\0e1_val\0td"),
8166 	},
8167 	.expect = {
8168 		.raw_types = {
8169 			/* [1] enum 'e1' */
8170 			BTF_TYPE_ENC(NAME_NTH(1), BTF_INFO_ENC(BTF_KIND_ENUM, 0, 1), 4),
8171 				BTF_ENUM_ENC(NAME_NTH(2), 1),
8172 			/* [2] typedef enum 'e1' td */
8173 			BTF_TYPE_ENC(NAME_NTH(3), BTF_INFO_ENC(BTF_KIND_TYPEDEF, 0, 0), 1),
8174 			BTF_END_RAW,
8175 		},
8176 		BTF_STR_SEC("\0e1\0e1_val\0td"),
8177 	},
8178 },
8179 {
8180 	.descr = "dedup: standalone fwd declaration struct",
8181 	/*
8182 	 * Verify that CU1:foo and CU2:foo would be unified and that
8183 	 * typedef/ptr would be updated to point to CU1:foo.
8184 	 *
8185 	 * // CU 1:
8186 	 * struct foo { int x; };
8187 	 *
8188 	 * // CU 2:
8189 	 * struct foo;
8190 	 * typedef struct foo *foo_ptr;
8191 	 */
8192 	.input = {
8193 		.raw_types = {
8194 			/* CU 1 */
8195 			BTF_STRUCT_ENC(NAME_NTH(1), 1, 4),             /* [1] */
8196 			BTF_MEMBER_ENC(NAME_NTH(2), 2, 0),
8197 			BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [2] */
8198 			/* CU 2 */
8199 			BTF_FWD_ENC(NAME_NTH(1), 0),                   /* [3] */
8200 			BTF_PTR_ENC(3),                                /* [4] */
8201 			BTF_TYPEDEF_ENC(NAME_NTH(3), 4),               /* [5] */
8202 			BTF_END_RAW,
8203 		},
8204 		BTF_STR_SEC("\0foo\0x\0foo_ptr"),
8205 	},
8206 	.expect = {
8207 		.raw_types = {
8208 			BTF_STRUCT_ENC(NAME_NTH(1), 1, 4),             /* [1] */
8209 			BTF_MEMBER_ENC(NAME_NTH(2), 2, 0),
8210 			BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [2] */
8211 			BTF_PTR_ENC(1),                                /* [3] */
8212 			BTF_TYPEDEF_ENC(NAME_NTH(3), 3),               /* [4] */
8213 			BTF_END_RAW,
8214 		},
8215 		BTF_STR_SEC("\0foo\0x\0foo_ptr"),
8216 	},
8217 },
8218 {
8219 	.descr = "dedup: standalone fwd declaration union",
8220 	/*
8221 	 * Verify that CU1:foo and CU2:foo would be unified and that
8222 	 * typedef/ptr would be updated to point to CU1:foo.
8223 	 * Same as "dedup: standalone fwd declaration struct" but for unions.
8224 	 *
8225 	 * // CU 1:
8226 	 * union foo { int x; };
8227 	 *
8228 	 * // CU 2:
8229 	 * union foo;
8230 	 * typedef union foo *foo_ptr;
8231 	 */
8232 	.input = {
8233 		.raw_types = {
8234 			/* CU 1 */
8235 			BTF_UNION_ENC(NAME_NTH(1), 1, 4),              /* [1] */
8236 			BTF_MEMBER_ENC(NAME_NTH(2), 2, 0),
8237 			BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [2] */
8238 			/* CU 2 */
8239 			BTF_FWD_ENC(NAME_TBD, 1),                      /* [3] */
8240 			BTF_PTR_ENC(3),                                /* [4] */
8241 			BTF_TYPEDEF_ENC(NAME_NTH(3), 4),               /* [5] */
8242 			BTF_END_RAW,
8243 		},
8244 		BTF_STR_SEC("\0foo\0x\0foo_ptr"),
8245 	},
8246 	.expect = {
8247 		.raw_types = {
8248 			BTF_UNION_ENC(NAME_NTH(1), 1, 4),              /* [1] */
8249 			BTF_MEMBER_ENC(NAME_NTH(2), 2, 0),
8250 			BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [2] */
8251 			BTF_PTR_ENC(1),                                /* [3] */
8252 			BTF_TYPEDEF_ENC(NAME_NTH(3), 3),               /* [4] */
8253 			BTF_END_RAW,
8254 		},
8255 		BTF_STR_SEC("\0foo\0x\0foo_ptr"),
8256 	},
8257 },
8258 {
8259 	.descr = "dedup: standalone fwd declaration wrong kind",
8260 	/*
8261 	 * Negative test for btf_dedup_resolve_fwds:
8262 	 * - CU1:foo is a struct, C2:foo is a union, thus CU2:foo is not deduped;
8263 	 * - typedef/ptr should remain unchanged as well.
8264 	 *
8265 	 * // CU 1:
8266 	 * struct foo { int x; };
8267 	 *
8268 	 * // CU 2:
8269 	 * union foo;
8270 	 * typedef union foo *foo_ptr;
8271 	 */
8272 	.input = {
8273 		.raw_types = {
8274 			/* CU 1 */
8275 			BTF_STRUCT_ENC(NAME_NTH(1), 1, 4),             /* [1] */
8276 			BTF_MEMBER_ENC(NAME_NTH(2), 2, 0),
8277 			BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [2] */
8278 			/* CU 2 */
8279 			BTF_FWD_ENC(NAME_NTH(3), 1),                   /* [3] */
8280 			BTF_PTR_ENC(3),                                /* [4] */
8281 			BTF_TYPEDEF_ENC(NAME_NTH(3), 4),               /* [5] */
8282 			BTF_END_RAW,
8283 		},
8284 		BTF_STR_SEC("\0foo\0x\0foo_ptr"),
8285 	},
8286 	.expect = {
8287 		.raw_types = {
8288 			/* CU 1 */
8289 			BTF_STRUCT_ENC(NAME_NTH(1), 1, 4),             /* [1] */
8290 			BTF_MEMBER_ENC(NAME_NTH(2), 2, 0),
8291 			BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [2] */
8292 			/* CU 2 */
8293 			BTF_FWD_ENC(NAME_NTH(3), 1),                   /* [3] */
8294 			BTF_PTR_ENC(3),                                /* [4] */
8295 			BTF_TYPEDEF_ENC(NAME_NTH(3), 4),               /* [5] */
8296 			BTF_END_RAW,
8297 		},
8298 		BTF_STR_SEC("\0foo\0x\0foo_ptr"),
8299 	},
8300 },
8301 {
8302 	.descr = "dedup: standalone fwd declaration name conflict",
8303 	/*
8304 	 * Negative test for btf_dedup_resolve_fwds:
8305 	 * - two candidates for CU2:foo dedup, thus it is unchanged;
8306 	 * - typedef/ptr should remain unchanged as well.
8307 	 *
8308 	 * // CU 1:
8309 	 * struct foo { int x; };
8310 	 *
8311 	 * // CU 2:
8312 	 * struct foo;
8313 	 * typedef struct foo *foo_ptr;
8314 	 *
8315 	 * // CU 3:
8316 	 * struct foo { int x; int y; };
8317 	 */
8318 	.input = {
8319 		.raw_types = {
8320 			/* CU 1 */
8321 			BTF_STRUCT_ENC(NAME_NTH(1), 1, 4),             /* [1] */
8322 			BTF_MEMBER_ENC(NAME_NTH(2), 2, 0),
8323 			BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [2] */
8324 			/* CU 2 */
8325 			BTF_FWD_ENC(NAME_NTH(1), 0),                   /* [3] */
8326 			BTF_PTR_ENC(3),                                /* [4] */
8327 			BTF_TYPEDEF_ENC(NAME_NTH(4), 4),               /* [5] */
8328 			/* CU 3 */
8329 			BTF_STRUCT_ENC(NAME_NTH(1), 2, 8),             /* [6] */
8330 			BTF_MEMBER_ENC(NAME_NTH(2), 2, 0),
8331 			BTF_MEMBER_ENC(NAME_NTH(3), 2, 0),
8332 			BTF_END_RAW,
8333 		},
8334 		BTF_STR_SEC("\0foo\0x\0y\0foo_ptr"),
8335 	},
8336 	.expect = {
8337 		.raw_types = {
8338 			/* CU 1 */
8339 			BTF_STRUCT_ENC(NAME_NTH(1), 1, 4),             /* [1] */
8340 			BTF_MEMBER_ENC(NAME_NTH(2), 2, 0),
8341 			BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [2] */
8342 			/* CU 2 */
8343 			BTF_FWD_ENC(NAME_NTH(1), 0),                   /* [3] */
8344 			BTF_PTR_ENC(3),                                /* [4] */
8345 			BTF_TYPEDEF_ENC(NAME_NTH(4), 4),               /* [5] */
8346 			/* CU 3 */
8347 			BTF_STRUCT_ENC(NAME_NTH(1), 2, 8),             /* [6] */
8348 			BTF_MEMBER_ENC(NAME_NTH(2), 2, 0),
8349 			BTF_MEMBER_ENC(NAME_NTH(3), 2, 0),
8350 			BTF_END_RAW,
8351 		},
8352 		BTF_STR_SEC("\0foo\0x\0y\0foo_ptr"),
8353 	},
8354 },
8355 };
8356 
8357 static int btf_type_size(const struct btf_type *t)
8358 {
8359 	int base_size = sizeof(struct btf_type);
8360 	__u32 vlen = BTF_INFO_VLEN(t->info);
8361 	__u16 kind = BTF_INFO_KIND(t->info);
8362 
8363 	switch (kind) {
8364 	case BTF_KIND_FWD:
8365 	case BTF_KIND_CONST:
8366 	case BTF_KIND_VOLATILE:
8367 	case BTF_KIND_RESTRICT:
8368 	case BTF_KIND_PTR:
8369 	case BTF_KIND_TYPEDEF:
8370 	case BTF_KIND_FUNC:
8371 	case BTF_KIND_FLOAT:
8372 	case BTF_KIND_TYPE_TAG:
8373 		return base_size;
8374 	case BTF_KIND_INT:
8375 		return base_size + sizeof(__u32);
8376 	case BTF_KIND_ENUM:
8377 		return base_size + vlen * sizeof(struct btf_enum);
8378 	case BTF_KIND_ENUM64:
8379 		return base_size + vlen * sizeof(struct btf_enum64);
8380 	case BTF_KIND_ARRAY:
8381 		return base_size + sizeof(struct btf_array);
8382 	case BTF_KIND_STRUCT:
8383 	case BTF_KIND_UNION:
8384 		return base_size + vlen * sizeof(struct btf_member);
8385 	case BTF_KIND_FUNC_PROTO:
8386 		return base_size + vlen * sizeof(struct btf_param);
8387 	case BTF_KIND_VAR:
8388 		return base_size + sizeof(struct btf_var);
8389 	case BTF_KIND_DATASEC:
8390 		return base_size + vlen * sizeof(struct btf_var_secinfo);
8391 	case BTF_KIND_DECL_TAG:
8392 		return base_size + sizeof(struct btf_decl_tag);
8393 	default:
8394 		fprintf(stderr, "Unsupported BTF_KIND:%u\n", kind);
8395 		return -EINVAL;
8396 	}
8397 }
8398 
8399 static void dump_btf_strings(const char *strs, __u32 len)
8400 {
8401 	const char *cur = strs;
8402 	int i = 0;
8403 
8404 	while (cur < strs + len) {
8405 		fprintf(stderr, "string #%d: '%s'\n", i, cur);
8406 		cur += strlen(cur) + 1;
8407 		i++;
8408 	}
8409 }
8410 
8411 static void do_test_dedup(unsigned int test_num)
8412 {
8413 	struct btf_dedup_test *test = &dedup_tests[test_num - 1];
8414 	__u32 test_nr_types, expect_nr_types, test_btf_size, expect_btf_size;
8415 	const struct btf_header *test_hdr, *expect_hdr;
8416 	struct btf *test_btf = NULL, *expect_btf = NULL;
8417 	const void *test_btf_data, *expect_btf_data;
8418 	const char *ret_test_next_str, *ret_expect_next_str;
8419 	const char *test_strs, *expect_strs;
8420 	const char *test_str_cur;
8421 	const char *expect_str_cur, *expect_str_end;
8422 	unsigned int raw_btf_size;
8423 	void *raw_btf;
8424 	int err = 0, i;
8425 
8426 	if (!test__start_subtest(test->descr))
8427 		return;
8428 
8429 	raw_btf = btf_raw_create(&hdr_tmpl, test->input.raw_types,
8430 				 test->input.str_sec, test->input.str_sec_size,
8431 				 &raw_btf_size, &ret_test_next_str);
8432 	if (!raw_btf)
8433 		return;
8434 
8435 	test_btf = btf__new((__u8 *)raw_btf, raw_btf_size);
8436 	err = libbpf_get_error(test_btf);
8437 	free(raw_btf);
8438 	if (CHECK(err, "invalid test_btf errno:%d", err)) {
8439 		err = -1;
8440 		goto done;
8441 	}
8442 
8443 	raw_btf = btf_raw_create(&hdr_tmpl, test->expect.raw_types,
8444 				 test->expect.str_sec,
8445 				 test->expect.str_sec_size,
8446 				 &raw_btf_size, &ret_expect_next_str);
8447 	if (!raw_btf)
8448 		return;
8449 	expect_btf = btf__new((__u8 *)raw_btf, raw_btf_size);
8450 	err = libbpf_get_error(expect_btf);
8451 	free(raw_btf);
8452 	if (CHECK(err, "invalid expect_btf errno:%d", err)) {
8453 		err = -1;
8454 		goto done;
8455 	}
8456 
8457 	test->opts.sz = sizeof(test->opts);
8458 	err = btf__dedup(test_btf, &test->opts);
8459 	if (CHECK(err, "btf_dedup failed errno:%d", err)) {
8460 		err = -1;
8461 		goto done;
8462 	}
8463 
8464 	test_btf_data = btf__raw_data(test_btf, &test_btf_size);
8465 	expect_btf_data = btf__raw_data(expect_btf, &expect_btf_size);
8466 	if (CHECK(test_btf_size != expect_btf_size,
8467 		  "test_btf_size:%u != expect_btf_size:%u",
8468 		  test_btf_size, expect_btf_size)) {
8469 		err = -1;
8470 		goto done;
8471 	}
8472 
8473 	test_hdr = test_btf_data;
8474 	test_strs = test_btf_data + sizeof(*test_hdr) + test_hdr->str_off;
8475 	expect_hdr = expect_btf_data;
8476 	expect_strs = expect_btf_data + sizeof(*test_hdr) + expect_hdr->str_off;
8477 	if (CHECK(test_hdr->str_len != expect_hdr->str_len,
8478 		  "test_hdr->str_len:%u != expect_hdr->str_len:%u",
8479 		  test_hdr->str_len, expect_hdr->str_len)) {
8480 		fprintf(stderr, "\ntest strings:\n");
8481 		dump_btf_strings(test_strs, test_hdr->str_len);
8482 		fprintf(stderr, "\nexpected strings:\n");
8483 		dump_btf_strings(expect_strs, expect_hdr->str_len);
8484 		err = -1;
8485 		goto done;
8486 	}
8487 
8488 	expect_str_cur = expect_strs;
8489 	expect_str_end = expect_strs + expect_hdr->str_len;
8490 	while (expect_str_cur < expect_str_end) {
8491 		size_t test_len, expect_len;
8492 		int off;
8493 
8494 		off = btf__find_str(test_btf, expect_str_cur);
8495 		if (CHECK(off < 0, "exp str '%s' not found: %d\n", expect_str_cur, off)) {
8496 			err = -1;
8497 			goto done;
8498 		}
8499 		test_str_cur = btf__str_by_offset(test_btf, off);
8500 
8501 		test_len = strlen(test_str_cur);
8502 		expect_len = strlen(expect_str_cur);
8503 		if (CHECK(test_len != expect_len,
8504 			  "test_len:%zu != expect_len:%zu "
8505 			  "(test_str:%s, expect_str:%s)",
8506 			  test_len, expect_len, test_str_cur, expect_str_cur)) {
8507 			err = -1;
8508 			goto done;
8509 		}
8510 		if (CHECK(strcmp(test_str_cur, expect_str_cur),
8511 			  "test_str:%s != expect_str:%s",
8512 			  test_str_cur, expect_str_cur)) {
8513 			err = -1;
8514 			goto done;
8515 		}
8516 		expect_str_cur += expect_len + 1;
8517 	}
8518 
8519 	test_nr_types = btf__type_cnt(test_btf);
8520 	expect_nr_types = btf__type_cnt(expect_btf);
8521 	if (CHECK(test_nr_types != expect_nr_types,
8522 		  "test_nr_types:%u != expect_nr_types:%u",
8523 		  test_nr_types, expect_nr_types)) {
8524 		err = -1;
8525 		goto done;
8526 	}
8527 
8528 	for (i = 1; i < test_nr_types; i++) {
8529 		const struct btf_type *test_type, *expect_type;
8530 		int test_size, expect_size;
8531 
8532 		test_type = btf__type_by_id(test_btf, i);
8533 		expect_type = btf__type_by_id(expect_btf, i);
8534 		test_size = btf_type_size(test_type);
8535 		expect_size = btf_type_size(expect_type);
8536 
8537 		if (CHECK(test_size != expect_size,
8538 			  "type #%d: test_size:%d != expect_size:%u",
8539 			  i, test_size, expect_size)) {
8540 			err = -1;
8541 			goto done;
8542 		}
8543 		if (CHECK(btf_kind(test_type) != btf_kind(expect_type),
8544 			  "type %d kind: exp %d != got %u\n",
8545 			  i, btf_kind(expect_type), btf_kind(test_type))) {
8546 			err = -1;
8547 			goto done;
8548 		}
8549 		if (CHECK(test_type->info != expect_type->info,
8550 			  "type %d info: exp %d != got %u\n",
8551 			  i, expect_type->info, test_type->info)) {
8552 			err = -1;
8553 			goto done;
8554 		}
8555 		if (CHECK(test_type->size != expect_type->size,
8556 			  "type %d size/type: exp %d != got %u\n",
8557 			  i, expect_type->size, test_type->size)) {
8558 			err = -1;
8559 			goto done;
8560 		}
8561 	}
8562 
8563 done:
8564 	btf__free(test_btf);
8565 	btf__free(expect_btf);
8566 }
8567 
8568 void test_btf(void)
8569 {
8570 	int i;
8571 
8572 	always_log = env.verbosity > VERBOSE_NONE;
8573 
8574 	for (i = 1; i <= ARRAY_SIZE(raw_tests); i++)
8575 		do_test_raw(i);
8576 	for (i = 1; i <= ARRAY_SIZE(get_info_tests); i++)
8577 		do_test_get_info(i);
8578 	for (i = 1; i <= ARRAY_SIZE(file_tests); i++)
8579 		do_test_file(i);
8580 	for (i = 1; i <= ARRAY_SIZE(info_raw_tests); i++)
8581 		do_test_info_raw(i);
8582 	for (i = 1; i <= ARRAY_SIZE(dedup_tests); i++)
8583 		do_test_dedup(i);
8584 	test_pprint();
8585 }
8586