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