xref: /linux/tools/testing/selftests/bpf/prog_tests/resolve_btfids.c (revision 93a3545d812ae7cfe4426374e00a7d8f64ac02e0)
1 // SPDX-License-Identifier: GPL-2.0
2 
3 #include <linux/err.h>
4 #include <string.h>
5 #include <bpf/btf.h>
6 #include <bpf/libbpf.h>
7 #include <linux/btf.h>
8 #include <linux/kernel.h>
9 #include <linux/btf_ids.h>
10 #include "test_progs.h"
11 
12 static int duration;
13 
14 struct symbol {
15 	const char	*name;
16 	int		 type;
17 	int		 id;
18 };
19 
20 struct symbol test_symbols[] = {
21 	{ "unused",  BTF_KIND_UNKN,     0 },
22 	{ "S",       BTF_KIND_TYPEDEF, -1 },
23 	{ "T",       BTF_KIND_TYPEDEF, -1 },
24 	{ "U",       BTF_KIND_TYPEDEF, -1 },
25 	{ "S",       BTF_KIND_STRUCT,  -1 },
26 	{ "U",       BTF_KIND_UNION,   -1 },
27 	{ "func",    BTF_KIND_FUNC,    -1 },
28 };
29 
30 BTF_ID_LIST(test_list)
31 BTF_ID_UNUSED
32 BTF_ID(typedef, S)
33 BTF_ID(typedef, T)
34 BTF_ID(typedef, U)
35 BTF_ID(struct,  S)
36 BTF_ID(union,   U)
37 BTF_ID(func,    func)
38 
39 static int
40 __resolve_symbol(struct btf *btf, int type_id)
41 {
42 	const struct btf_type *type;
43 	const char *str;
44 	unsigned int i;
45 
46 	type = btf__type_by_id(btf, type_id);
47 	if (!type) {
48 		PRINT_FAIL("Failed to get type for ID %d\n", type_id);
49 		return -1;
50 	}
51 
52 	for (i = 0; i < ARRAY_SIZE(test_symbols); i++) {
53 		if (test_symbols[i].id != -1)
54 			continue;
55 
56 		if (BTF_INFO_KIND(type->info) != test_symbols[i].type)
57 			continue;
58 
59 		str = btf__name_by_offset(btf, type->name_off);
60 		if (!str) {
61 			PRINT_FAIL("Failed to get name for BTF ID %d\n", type_id);
62 			return -1;
63 		}
64 
65 		if (!strcmp(str, test_symbols[i].name))
66 			test_symbols[i].id = type_id;
67 	}
68 
69 	return 0;
70 }
71 
72 static int resolve_symbols(void)
73 {
74 	struct btf *btf;
75 	int type_id;
76 	__u32 nr;
77 
78 	btf = btf__parse_elf("btf_data.o", NULL);
79 	if (CHECK(libbpf_get_error(btf), "resolve",
80 		  "Failed to load BTF from btf_data.o\n"))
81 		return -1;
82 
83 	nr = btf__get_nr_types(btf);
84 
85 	for (type_id = 1; type_id <= nr; type_id++) {
86 		if (__resolve_symbol(btf, type_id))
87 			break;
88 	}
89 
90 	btf__free(btf);
91 	return 0;
92 }
93 
94 int test_resolve_btfids(void)
95 {
96 	unsigned int i;
97 	int ret = 0;
98 
99 	if (resolve_symbols())
100 		return -1;
101 
102 	/* Check BTF_ID_LIST(test_list) IDs */
103 	for (i = 0; i < ARRAY_SIZE(test_symbols) && !ret; i++) {
104 		ret = CHECK(test_list[i] != test_symbols[i].id,
105 			    "id_check",
106 			    "wrong ID for %s (%d != %d)\n", test_symbols[i].name,
107 			    test_list[i], test_symbols[i].id);
108 	}
109 
110 	return ret;
111 }
112