]> Git Repo - linux.git/blob - tools/testing/selftests/bpf/prog_tests/resolve_btfids.c
Merge tag 'scsi-misc' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi
[linux.git] / tools / testing / selftests / bpf / prog_tests / resolve_btfids.c
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 #define CONFIG_DEBUG_INFO_BTF
10 #include <linux/btf_ids.h>
11 #include "test_progs.h"
12
13 static int duration;
14
15 struct symbol {
16         const char      *name;
17         int              type;
18         int              id;
19 };
20
21 struct symbol test_symbols[] = {
22         { "unused",  BTF_KIND_UNKN,     0 },
23         { "S",       BTF_KIND_TYPEDEF, -1 },
24         { "T",       BTF_KIND_TYPEDEF, -1 },
25         { "U",       BTF_KIND_TYPEDEF, -1 },
26         { "S",       BTF_KIND_STRUCT,  -1 },
27         { "U",       BTF_KIND_UNION,   -1 },
28         { "func",    BTF_KIND_FUNC,    -1 },
29 };
30
31 /* Align the .BTF_ids section to 4 bytes */
32 asm (
33 ".pushsection " BTF_IDS_SECTION " ,\"a\"; \n"
34 ".balign 4, 0;                            \n"
35 ".popsection;                             \n");
36
37 BTF_ID_LIST(test_list_local)
38 BTF_ID_UNUSED
39 BTF_ID(typedef, S)
40 BTF_ID(typedef, T)
41 BTF_ID(typedef, U)
42 BTF_ID(struct,  S)
43 BTF_ID(union,   U)
44 BTF_ID(func,    func)
45
46 extern __u32 test_list_global[];
47 BTF_ID_LIST_GLOBAL(test_list_global, 1)
48 BTF_ID_UNUSED
49 BTF_ID(typedef, S)
50 BTF_ID(typedef, T)
51 BTF_ID(typedef, U)
52 BTF_ID(struct,  S)
53 BTF_ID(union,   U)
54 BTF_ID(func,    func)
55
56 BTF_SET_START(test_set)
57 BTF_ID(typedef, S)
58 BTF_ID(typedef, T)
59 BTF_ID(typedef, U)
60 BTF_ID(struct,  S)
61 BTF_ID(union,   U)
62 BTF_ID(func,    func)
63 BTF_SET_END(test_set)
64
65 static int
66 __resolve_symbol(struct btf *btf, int type_id)
67 {
68         const struct btf_type *type;
69         const char *str;
70         unsigned int i;
71
72         type = btf__type_by_id(btf, type_id);
73         if (!type) {
74                 PRINT_FAIL("Failed to get type for ID %d\n", type_id);
75                 return -1;
76         }
77
78         for (i = 0; i < ARRAY_SIZE(test_symbols); i++) {
79                 if (test_symbols[i].id >= 0)
80                         continue;
81
82                 if (BTF_INFO_KIND(type->info) != test_symbols[i].type)
83                         continue;
84
85                 str = btf__name_by_offset(btf, type->name_off);
86                 if (!str) {
87                         PRINT_FAIL("Failed to get name for BTF ID %d\n", type_id);
88                         return -1;
89                 }
90
91                 if (!strcmp(str, test_symbols[i].name))
92                         test_symbols[i].id = type_id;
93         }
94
95         return 0;
96 }
97
98 static int resolve_symbols(void)
99 {
100         struct btf *btf;
101         int type_id;
102         __u32 nr;
103
104         btf = btf__parse_elf("btf_data.o", NULL);
105         if (CHECK(libbpf_get_error(btf), "resolve",
106                   "Failed to load BTF from btf_data.o\n"))
107                 return -1;
108
109         nr = btf__type_cnt(btf);
110
111         for (type_id = 1; type_id < nr; type_id++) {
112                 if (__resolve_symbol(btf, type_id))
113                         break;
114         }
115
116         btf__free(btf);
117         return 0;
118 }
119
120 void test_resolve_btfids(void)
121 {
122         __u32 *test_list, *test_lists[] = { test_list_local, test_list_global };
123         unsigned int i, j;
124         int ret = 0;
125
126         if (resolve_symbols())
127                 return;
128
129         /* Check BTF_ID_LIST(test_list_local) and
130          * BTF_ID_LIST_GLOBAL(test_list_global) IDs
131          */
132         for (j = 0; j < ARRAY_SIZE(test_lists); j++) {
133                 test_list = test_lists[j];
134                 for (i = 0; i < ARRAY_SIZE(test_symbols); i++) {
135                         ret = CHECK(test_list[i] != test_symbols[i].id,
136                                     "id_check",
137                                     "wrong ID for %s (%d != %d)\n",
138                                     test_symbols[i].name,
139                                     test_list[i], test_symbols[i].id);
140                         if (ret)
141                                 return;
142                 }
143         }
144
145         /* Check BTF_SET_START(test_set) IDs */
146         for (i = 0; i < test_set.cnt; i++) {
147                 bool found = false;
148
149                 for (j = 0; j < ARRAY_SIZE(test_symbols); j++) {
150                         if (test_symbols[j].id != test_set.ids[i])
151                                 continue;
152                         found = true;
153                         break;
154                 }
155
156                 ret = CHECK(!found, "id_check",
157                             "ID %d not found in test_symbols\n",
158                             test_set.ids[i]);
159                 if (ret)
160                         break;
161
162                 if (i > 0) {
163                         if (!ASSERT_LE(test_set.ids[i - 1], test_set.ids[i], "sort_check"))
164                                 return;
165                 }
166         }
167 }
This page took 0.045482 seconds and 4 git commands to generate.