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