]> Git Repo - J-linux.git/blob - tools/testing/selftests/bpf/prog_tests/btf_distill.c
Merge tag 'vfs-6.13-rc7.fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs
[J-linux.git] / tools / testing / selftests / bpf / prog_tests / btf_distill.c
1 // SPDX-License-Identifier: GPL-2.0
2 /* Copyright (c) 2024, Oracle and/or its affiliates. */
3
4 #include <test_progs.h>
5 #include <bpf/btf.h>
6 #include "btf_helpers.h"
7
8 /* Fabricate base, split BTF with references to base types needed; then create
9  * split BTF with distilled base BTF and ensure expectations are met:
10  *  - only referenced base types from split BTF are present
11  *  - struct/union/enum are represented as empty unless anonymous, when they
12  *    are represented in full in split BTF
13  */
14 static void test_distilled_base(void)
15 {
16         struct btf *btf1 = NULL, *btf2 = NULL, *btf3 = NULL, *btf4 = NULL;
17
18         btf1 = btf__new_empty();
19         if (!ASSERT_OK_PTR(btf1, "empty_main_btf"))
20                 return;
21
22         btf__add_int(btf1, "int", 4, BTF_INT_SIGNED);   /* [1] int */
23         btf__add_ptr(btf1, 1);                          /* [2] ptr to int */
24         btf__add_struct(btf1, "s1", 8);                 /* [3] struct s1 { */
25         btf__add_field(btf1, "f1", 2, 0, 0);            /*      int *f1; */
26                                                         /* } */
27         btf__add_struct(btf1, "", 12);                  /* [4] struct { */
28         btf__add_field(btf1, "f1", 1, 0, 0);            /*      int f1; */
29         btf__add_field(btf1, "f2", 3, 32, 0);           /*      struct s1 f2; */
30                                                         /* } */
31         btf__add_int(btf1, "unsigned int", 4, 0);       /* [5] unsigned int */
32         btf__add_union(btf1, "u1", 12);                 /* [6] union u1 { */
33         btf__add_field(btf1, "f1", 1, 0, 0);            /*      int f1; */
34         btf__add_field(btf1, "f2", 2, 0, 0);            /*      int *f2; */
35                                                         /* } */
36         btf__add_union(btf1, "", 4);                    /* [7] union { */
37         btf__add_field(btf1, "f1", 1, 0, 0);            /*      int f1; */
38                                                         /* } */
39         btf__add_enum(btf1, "e1", 4);                   /* [8] enum e1 { */
40         btf__add_enum_value(btf1, "v1", 1);             /*      v1 = 1; */
41                                                         /* } */
42         btf__add_enum(btf1, "", 4);                     /* [9] enum { */
43         btf__add_enum_value(btf1, "av1", 2);            /*      av1 = 2; */
44                                                         /* } */
45         btf__add_enum64(btf1, "e641", 8, true);         /* [10] enum64 { */
46         btf__add_enum64_value(btf1, "v1", 1024);        /*      v1 = 1024; */
47                                                         /* } */
48         btf__add_enum64(btf1, "", 8, true);             /* [11] enum64 { */
49         btf__add_enum64_value(btf1, "v1", 1025);        /*      v1 = 1025; */
50                                                         /* } */
51         btf__add_struct(btf1, "unneeded", 4);           /* [12] struct unneeded { */
52         btf__add_field(btf1, "f1", 1, 0, 0);            /*      int f1; */
53                                                         /* } */
54         btf__add_struct(btf1, "embedded", 4);           /* [13] struct embedded { */
55         btf__add_field(btf1, "f1", 1, 0, 0);            /*      int f1; */
56                                                         /* } */
57         btf__add_func_proto(btf1, 1);                   /* [14] int (*)(int *p1); */
58         btf__add_func_param(btf1, "p1", 1);
59
60         btf__add_array(btf1, 1, 1, 3);                  /* [15] int [3]; */
61
62         btf__add_struct(btf1, "from_proto", 4);         /* [16] struct from_proto { */
63         btf__add_field(btf1, "f1", 1, 0, 0);            /*      int f1; */
64                                                         /* } */
65         btf__add_union(btf1, "u1", 4);                  /* [17] union u1 { */
66         btf__add_field(btf1, "f1", 1, 0, 0);            /*       int f1; */
67                                                         /* } */
68         VALIDATE_RAW_BTF(
69                 btf1,
70                 "[1] INT 'int' size=4 bits_offset=0 nr_bits=32 encoding=SIGNED",
71                 "[2] PTR '(anon)' type_id=1",
72                 "[3] STRUCT 's1' size=8 vlen=1\n"
73                 "\t'f1' type_id=2 bits_offset=0",
74                 "[4] STRUCT '(anon)' size=12 vlen=2\n"
75                 "\t'f1' type_id=1 bits_offset=0\n"
76                 "\t'f2' type_id=3 bits_offset=32",
77                 "[5] INT 'unsigned int' size=4 bits_offset=0 nr_bits=32 encoding=(none)",
78                 "[6] UNION 'u1' size=12 vlen=2\n"
79                 "\t'f1' type_id=1 bits_offset=0\n"
80                 "\t'f2' type_id=2 bits_offset=0",
81                 "[7] UNION '(anon)' size=4 vlen=1\n"
82                 "\t'f1' type_id=1 bits_offset=0",
83                 "[8] ENUM 'e1' encoding=UNSIGNED size=4 vlen=1\n"
84                 "\t'v1' val=1",
85                 "[9] ENUM '(anon)' encoding=UNSIGNED size=4 vlen=1\n"
86                 "\t'av1' val=2",
87                 "[10] ENUM64 'e641' encoding=SIGNED size=8 vlen=1\n"
88                 "\t'v1' val=1024",
89                 "[11] ENUM64 '(anon)' encoding=SIGNED size=8 vlen=1\n"
90                 "\t'v1' val=1025",
91                 "[12] STRUCT 'unneeded' size=4 vlen=1\n"
92                 "\t'f1' type_id=1 bits_offset=0",
93                 "[13] STRUCT 'embedded' size=4 vlen=1\n"
94                 "\t'f1' type_id=1 bits_offset=0",
95                 "[14] FUNC_PROTO '(anon)' ret_type_id=1 vlen=1\n"
96                 "\t'p1' type_id=1",
97                 "[15] ARRAY '(anon)' type_id=1 index_type_id=1 nr_elems=3",
98                 "[16] STRUCT 'from_proto' size=4 vlen=1\n"
99                 "\t'f1' type_id=1 bits_offset=0",
100                 "[17] UNION 'u1' size=4 vlen=1\n"
101                 "\t'f1' type_id=1 bits_offset=0");
102
103         btf2 = btf__new_empty_split(btf1);
104         if (!ASSERT_OK_PTR(btf2, "empty_split_btf"))
105                 goto cleanup;
106
107         btf__add_ptr(btf2, 3);                          /* [18] ptr to struct s1 */
108         /* add ptr to struct anon */
109         btf__add_ptr(btf2, 4);                          /* [19] ptr to struct (anon) */
110         btf__add_const(btf2, 6);                        /* [20] const union u1 */
111         btf__add_restrict(btf2, 7);                     /* [21] restrict union (anon) */
112         btf__add_volatile(btf2, 8);                     /* [22] volatile enum e1 */
113         btf__add_typedef(btf2, "et", 9);                /* [23] typedef enum (anon) */
114         btf__add_const(btf2, 10);                       /* [24] const enum64 e641 */
115         btf__add_ptr(btf2, 11);                         /* [25] restrict enum64 (anon) */
116         btf__add_struct(btf2, "with_embedded", 4);      /* [26] struct with_embedded { */
117         btf__add_field(btf2, "f1", 13, 0, 0);           /*      struct embedded f1; */
118                                                         /* } */
119         btf__add_func(btf2, "fn", BTF_FUNC_STATIC, 14); /* [27] int fn(int p1); */
120         btf__add_typedef(btf2, "arraytype", 15);        /* [28] typedef int[3] foo; */
121         btf__add_func_proto(btf2, 1);                   /* [29] int (*)(struct from proto p1); */
122         btf__add_func_param(btf2, "p1", 16);
123
124         VALIDATE_RAW_BTF(
125                 btf2,
126                 "[1] INT 'int' size=4 bits_offset=0 nr_bits=32 encoding=SIGNED",
127                 "[2] PTR '(anon)' type_id=1",
128                 "[3] STRUCT 's1' size=8 vlen=1\n"
129                 "\t'f1' type_id=2 bits_offset=0",
130                 "[4] STRUCT '(anon)' size=12 vlen=2\n"
131                 "\t'f1' type_id=1 bits_offset=0\n"
132                 "\t'f2' type_id=3 bits_offset=32",
133                 "[5] INT 'unsigned int' size=4 bits_offset=0 nr_bits=32 encoding=(none)",
134                 "[6] UNION 'u1' size=12 vlen=2\n"
135                 "\t'f1' type_id=1 bits_offset=0\n"
136                 "\t'f2' type_id=2 bits_offset=0",
137                 "[7] UNION '(anon)' size=4 vlen=1\n"
138                 "\t'f1' type_id=1 bits_offset=0",
139                 "[8] ENUM 'e1' encoding=UNSIGNED size=4 vlen=1\n"
140                 "\t'v1' val=1",
141                 "[9] ENUM '(anon)' encoding=UNSIGNED size=4 vlen=1\n"
142                 "\t'av1' val=2",
143                 "[10] ENUM64 'e641' encoding=SIGNED size=8 vlen=1\n"
144                 "\t'v1' val=1024",
145                 "[11] ENUM64 '(anon)' encoding=SIGNED size=8 vlen=1\n"
146                 "\t'v1' val=1025",
147                 "[12] STRUCT 'unneeded' size=4 vlen=1\n"
148                 "\t'f1' type_id=1 bits_offset=0",
149                 "[13] STRUCT 'embedded' size=4 vlen=1\n"
150                 "\t'f1' type_id=1 bits_offset=0",
151                 "[14] FUNC_PROTO '(anon)' ret_type_id=1 vlen=1\n"
152                 "\t'p1' type_id=1",
153                 "[15] ARRAY '(anon)' type_id=1 index_type_id=1 nr_elems=3",
154                 "[16] STRUCT 'from_proto' size=4 vlen=1\n"
155                 "\t'f1' type_id=1 bits_offset=0",
156                 "[17] UNION 'u1' size=4 vlen=1\n"
157                 "\t'f1' type_id=1 bits_offset=0",
158                 "[18] PTR '(anon)' type_id=3",
159                 "[19] PTR '(anon)' type_id=4",
160                 "[20] CONST '(anon)' type_id=6",
161                 "[21] RESTRICT '(anon)' type_id=7",
162                 "[22] VOLATILE '(anon)' type_id=8",
163                 "[23] TYPEDEF 'et' type_id=9",
164                 "[24] CONST '(anon)' type_id=10",
165                 "[25] PTR '(anon)' type_id=11",
166                 "[26] STRUCT 'with_embedded' size=4 vlen=1\n"
167                 "\t'f1' type_id=13 bits_offset=0",
168                 "[27] FUNC 'fn' type_id=14 linkage=static",
169                 "[28] TYPEDEF 'arraytype' type_id=15",
170                 "[29] FUNC_PROTO '(anon)' ret_type_id=1 vlen=1\n"
171                 "\t'p1' type_id=16");
172
173         if (!ASSERT_EQ(0, btf__distill_base(btf2, &btf3, &btf4),
174                        "distilled_base") ||
175             !ASSERT_OK_PTR(btf3, "distilled_base") ||
176             !ASSERT_OK_PTR(btf4, "distilled_split") ||
177             !ASSERT_EQ(8, btf__type_cnt(btf3), "distilled_base_type_cnt"))
178                 goto cleanup;
179
180         VALIDATE_RAW_BTF(
181                 btf4,
182                 "[1] INT 'int' size=4 bits_offset=0 nr_bits=32 encoding=SIGNED",
183                 "[2] STRUCT 's1' size=8 vlen=0",
184                 "[3] UNION 'u1' size=12 vlen=0",
185                 "[4] ENUM 'e1' encoding=UNSIGNED size=4 vlen=0",
186                 "[5] ENUM 'e641' encoding=UNSIGNED size=8 vlen=0",
187                 "[6] STRUCT 'embedded' size=4 vlen=0",
188                 "[7] STRUCT 'from_proto' size=4 vlen=0",
189                 /* split BTF; these types should match split BTF above from 17-28, with
190                  * updated type id references
191                  */
192                 "[8] PTR '(anon)' type_id=2",
193                 "[9] PTR '(anon)' type_id=20",
194                 "[10] CONST '(anon)' type_id=3",
195                 "[11] RESTRICT '(anon)' type_id=21",
196                 "[12] VOLATILE '(anon)' type_id=4",
197                 "[13] TYPEDEF 'et' type_id=22",
198                 "[14] CONST '(anon)' type_id=5",
199                 "[15] PTR '(anon)' type_id=23",
200                 "[16] STRUCT 'with_embedded' size=4 vlen=1\n"
201                 "\t'f1' type_id=6 bits_offset=0",
202                 "[17] FUNC 'fn' type_id=24 linkage=static",
203                 "[18] TYPEDEF 'arraytype' type_id=25",
204                 "[19] FUNC_PROTO '(anon)' ret_type_id=1 vlen=1\n"
205                 "\t'p1' type_id=7",
206                 /* split BTF types added from original base BTF below */
207                 "[20] STRUCT '(anon)' size=12 vlen=2\n"
208                 "\t'f1' type_id=1 bits_offset=0\n"
209                 "\t'f2' type_id=2 bits_offset=32",
210                 "[21] UNION '(anon)' size=4 vlen=1\n"
211                 "\t'f1' type_id=1 bits_offset=0",
212                 "[22] ENUM '(anon)' encoding=UNSIGNED size=4 vlen=1\n"
213                 "\t'av1' val=2",
214                 "[23] ENUM64 '(anon)' encoding=SIGNED size=8 vlen=1\n"
215                 "\t'v1' val=1025",
216                 "[24] FUNC_PROTO '(anon)' ret_type_id=1 vlen=1\n"
217                 "\t'p1' type_id=1",
218                 "[25] ARRAY '(anon)' type_id=1 index_type_id=1 nr_elems=3");
219
220         if (!ASSERT_EQ(btf__relocate(btf4, btf1), 0, "relocate_split"))
221                 goto cleanup;
222
223         VALIDATE_RAW_BTF(
224                 btf4,
225                 "[1] INT 'int' size=4 bits_offset=0 nr_bits=32 encoding=SIGNED",
226                 "[2] PTR '(anon)' type_id=1",
227                 "[3] STRUCT 's1' size=8 vlen=1\n"
228                 "\t'f1' type_id=2 bits_offset=0",
229                 "[4] STRUCT '(anon)' size=12 vlen=2\n"
230                 "\t'f1' type_id=1 bits_offset=0\n"
231                 "\t'f2' type_id=3 bits_offset=32",
232                 "[5] INT 'unsigned int' size=4 bits_offset=0 nr_bits=32 encoding=(none)",
233                 "[6] UNION 'u1' size=12 vlen=2\n"
234                 "\t'f1' type_id=1 bits_offset=0\n"
235                 "\t'f2' type_id=2 bits_offset=0",
236                 "[7] UNION '(anon)' size=4 vlen=1\n"
237                 "\t'f1' type_id=1 bits_offset=0",
238                 "[8] ENUM 'e1' encoding=UNSIGNED size=4 vlen=1\n"
239                 "\t'v1' val=1",
240                 "[9] ENUM '(anon)' encoding=UNSIGNED size=4 vlen=1\n"
241                 "\t'av1' val=2",
242                 "[10] ENUM64 'e641' encoding=SIGNED size=8 vlen=1\n"
243                 "\t'v1' val=1024",
244                 "[11] ENUM64 '(anon)' encoding=SIGNED size=8 vlen=1\n"
245                 "\t'v1' val=1025",
246                 "[12] STRUCT 'unneeded' size=4 vlen=1\n"
247                 "\t'f1' type_id=1 bits_offset=0",
248                 "[13] STRUCT 'embedded' size=4 vlen=1\n"
249                 "\t'f1' type_id=1 bits_offset=0",
250                 "[14] FUNC_PROTO '(anon)' ret_type_id=1 vlen=1\n"
251                 "\t'p1' type_id=1",
252                 "[15] ARRAY '(anon)' type_id=1 index_type_id=1 nr_elems=3",
253                 "[16] STRUCT 'from_proto' size=4 vlen=1\n"
254                 "\t'f1' type_id=1 bits_offset=0",
255                 "[17] UNION 'u1' size=4 vlen=1\n"
256                 "\t'f1' type_id=1 bits_offset=0",
257                 "[18] PTR '(anon)' type_id=3",
258                 "[19] PTR '(anon)' type_id=30",
259                 "[20] CONST '(anon)' type_id=6",
260                 "[21] RESTRICT '(anon)' type_id=31",
261                 "[22] VOLATILE '(anon)' type_id=8",
262                 "[23] TYPEDEF 'et' type_id=32",
263                 "[24] CONST '(anon)' type_id=10",
264                 "[25] PTR '(anon)' type_id=33",
265                 "[26] STRUCT 'with_embedded' size=4 vlen=1\n"
266                 "\t'f1' type_id=13 bits_offset=0",
267                 "[27] FUNC 'fn' type_id=34 linkage=static",
268                 "[28] TYPEDEF 'arraytype' type_id=35",
269                 "[29] FUNC_PROTO '(anon)' ret_type_id=1 vlen=1\n"
270                 "\t'p1' type_id=16",
271                 /* below here are (duplicate) anon base types added by distill
272                  * process to split BTF.
273                  */
274                 "[30] STRUCT '(anon)' size=12 vlen=2\n"
275                 "\t'f1' type_id=1 bits_offset=0\n"
276                 "\t'f2' type_id=3 bits_offset=32",
277                 "[31] UNION '(anon)' size=4 vlen=1\n"
278                 "\t'f1' type_id=1 bits_offset=0",
279                 "[32] ENUM '(anon)' encoding=UNSIGNED size=4 vlen=1\n"
280                 "\t'av1' val=2",
281                 "[33] ENUM64 '(anon)' encoding=SIGNED size=8 vlen=1\n"
282                 "\t'v1' val=1025",
283                 "[34] FUNC_PROTO '(anon)' ret_type_id=1 vlen=1\n"
284                 "\t'p1' type_id=1",
285                 "[35] ARRAY '(anon)' type_id=1 index_type_id=1 nr_elems=3");
286
287 cleanup:
288         btf__free(btf4);
289         btf__free(btf3);
290         btf__free(btf2);
291         btf__free(btf1);
292 }
293
294 /* ensure we can cope with multiple types with the same name in
295  * distilled base BTF.  In this case because sizes are different,
296  * we can still disambiguate them.
297  */
298 static void test_distilled_base_multi(void)
299 {
300         struct btf *btf1 = NULL, *btf2 = NULL, *btf3 = NULL, *btf4 = NULL;
301
302         btf1 = btf__new_empty();
303         if (!ASSERT_OK_PTR(btf1, "empty_main_btf"))
304                 return;
305         btf__add_int(btf1, "int", 4, BTF_INT_SIGNED);   /* [1] int */
306         btf__add_int(btf1, "int", 8, BTF_INT_SIGNED);   /* [2] int */
307         VALIDATE_RAW_BTF(
308                 btf1,
309                 "[1] INT 'int' size=4 bits_offset=0 nr_bits=32 encoding=SIGNED",
310                 "[2] INT 'int' size=8 bits_offset=0 nr_bits=64 encoding=SIGNED");
311         btf2 = btf__new_empty_split(btf1);
312         if (!ASSERT_OK_PTR(btf2, "empty_split_btf"))
313                 goto cleanup;
314         btf__add_ptr(btf2, 1);
315         btf__add_const(btf2, 2);
316         VALIDATE_RAW_BTF(
317                 btf2,
318                 "[1] INT 'int' size=4 bits_offset=0 nr_bits=32 encoding=SIGNED",
319                 "[2] INT 'int' size=8 bits_offset=0 nr_bits=64 encoding=SIGNED",
320                 "[3] PTR '(anon)' type_id=1",
321                 "[4] CONST '(anon)' type_id=2");
322         if (!ASSERT_EQ(0, btf__distill_base(btf2, &btf3, &btf4),
323                        "distilled_base") ||
324             !ASSERT_OK_PTR(btf3, "distilled_base") ||
325             !ASSERT_OK_PTR(btf4, "distilled_split") ||
326             !ASSERT_EQ(3, btf__type_cnt(btf3), "distilled_base_type_cnt"))
327                 goto cleanup;
328         VALIDATE_RAW_BTF(
329                 btf3,
330                 "[1] INT 'int' size=4 bits_offset=0 nr_bits=32 encoding=SIGNED",
331                 "[2] INT 'int' size=8 bits_offset=0 nr_bits=64 encoding=SIGNED");
332         if (!ASSERT_EQ(btf__relocate(btf4, btf1), 0, "relocate_split"))
333                 goto cleanup;
334
335         VALIDATE_RAW_BTF(
336                 btf4,
337                 "[1] INT 'int' size=4 bits_offset=0 nr_bits=32 encoding=SIGNED",
338                 "[2] INT 'int' size=8 bits_offset=0 nr_bits=64 encoding=SIGNED",
339                 "[3] PTR '(anon)' type_id=1",
340                 "[4] CONST '(anon)' type_id=2");
341
342 cleanup:
343         btf__free(btf4);
344         btf__free(btf3);
345         btf__free(btf2);
346         btf__free(btf1);
347 }
348
349 /* If a needed type is not present in the base BTF we wish to relocate
350  * with, btf__relocate() should error our.
351  */
352 static void test_distilled_base_missing_err(void)
353 {
354         struct btf *btf1 = NULL, *btf2 = NULL, *btf3 = NULL, *btf4 = NULL, *btf5 = NULL;
355
356         btf1 = btf__new_empty();
357         if (!ASSERT_OK_PTR(btf1, "empty_main_btf"))
358                 return;
359         btf__add_int(btf1, "int", 4, BTF_INT_SIGNED);   /* [1] int */
360         btf__add_int(btf1, "int", 8, BTF_INT_SIGNED);   /* [2] int */
361         VALIDATE_RAW_BTF(
362                 btf1,
363                 "[1] INT 'int' size=4 bits_offset=0 nr_bits=32 encoding=SIGNED",
364                 "[2] INT 'int' size=8 bits_offset=0 nr_bits=64 encoding=SIGNED");
365         btf2 = btf__new_empty_split(btf1);
366         if (!ASSERT_OK_PTR(btf2, "empty_split_btf"))
367                 goto cleanup;
368         btf__add_ptr(btf2, 1);
369         btf__add_const(btf2, 2);
370         VALIDATE_RAW_BTF(
371                 btf2,
372                 "[1] INT 'int' size=4 bits_offset=0 nr_bits=32 encoding=SIGNED",
373                 "[2] INT 'int' size=8 bits_offset=0 nr_bits=64 encoding=SIGNED",
374                 "[3] PTR '(anon)' type_id=1",
375                 "[4] CONST '(anon)' type_id=2");
376         if (!ASSERT_EQ(0, btf__distill_base(btf2, &btf3, &btf4),
377                        "distilled_base") ||
378             !ASSERT_OK_PTR(btf3, "distilled_base") ||
379             !ASSERT_OK_PTR(btf4, "distilled_split") ||
380             !ASSERT_EQ(3, btf__type_cnt(btf3), "distilled_base_type_cnt"))
381                 goto cleanup;
382         VALIDATE_RAW_BTF(
383                 btf3,
384                 "[1] INT 'int' size=4 bits_offset=0 nr_bits=32 encoding=SIGNED",
385                 "[2] INT 'int' size=8 bits_offset=0 nr_bits=64 encoding=SIGNED");
386         btf5 = btf__new_empty();
387         if (!ASSERT_OK_PTR(btf5, "empty_reloc_btf"))
388                 return;
389         btf__add_int(btf5, "int", 4, BTF_INT_SIGNED);   /* [1] int */
390         VALIDATE_RAW_BTF(
391                 btf5,
392                 "[1] INT 'int' size=4 bits_offset=0 nr_bits=32 encoding=SIGNED");
393         ASSERT_EQ(btf__relocate(btf4, btf5), -EINVAL, "relocate_split");
394
395 cleanup:
396         btf__free(btf5);
397         btf__free(btf4);
398         btf__free(btf3);
399         btf__free(btf2);
400         btf__free(btf1);
401 }
402
403 /* With 2 types of same size in distilled base BTF, relocation should
404  * fail as we have no means to choose between them.
405  */
406 static void test_distilled_base_multi_err(void)
407 {
408         struct btf *btf1 = NULL, *btf2 = NULL, *btf3 = NULL, *btf4 = NULL;
409
410         btf1 = btf__new_empty();
411         if (!ASSERT_OK_PTR(btf1, "empty_main_btf"))
412                 return;
413         btf__add_int(btf1, "int", 4, BTF_INT_SIGNED);   /* [1] int */
414         btf__add_int(btf1, "int", 4, BTF_INT_SIGNED);   /* [2] int */
415         VALIDATE_RAW_BTF(
416                 btf1,
417                 "[1] INT 'int' size=4 bits_offset=0 nr_bits=32 encoding=SIGNED",
418                 "[2] INT 'int' size=4 bits_offset=0 nr_bits=32 encoding=SIGNED");
419         btf2 = btf__new_empty_split(btf1);
420         if (!ASSERT_OK_PTR(btf2, "empty_split_btf"))
421                 goto cleanup;
422         btf__add_ptr(btf2, 1);
423         btf__add_const(btf2, 2);
424         VALIDATE_RAW_BTF(
425                 btf2,
426                 "[1] INT 'int' size=4 bits_offset=0 nr_bits=32 encoding=SIGNED",
427                 "[2] INT 'int' size=4 bits_offset=0 nr_bits=32 encoding=SIGNED",
428                 "[3] PTR '(anon)' type_id=1",
429                 "[4] CONST '(anon)' type_id=2");
430         if (!ASSERT_EQ(0, btf__distill_base(btf2, &btf3, &btf4),
431                        "distilled_base") ||
432             !ASSERT_OK_PTR(btf3, "distilled_base") ||
433             !ASSERT_OK_PTR(btf4, "distilled_split") ||
434             !ASSERT_EQ(3, btf__type_cnt(btf3), "distilled_base_type_cnt"))
435                 goto cleanup;
436         VALIDATE_RAW_BTF(
437                 btf3,
438                 "[1] INT 'int' size=4 bits_offset=0 nr_bits=32 encoding=SIGNED",
439                 "[2] INT 'int' size=4 bits_offset=0 nr_bits=32 encoding=SIGNED");
440         ASSERT_EQ(btf__relocate(btf4, btf1), -EINVAL, "relocate_split");
441 cleanup:
442         btf__free(btf4);
443         btf__free(btf3);
444         btf__free(btf2);
445         btf__free(btf1);
446 }
447
448 /* With 2 types of same size in base BTF, relocation should
449  * fail as we have no means to choose between them.
450  */
451 static void test_distilled_base_multi_err2(void)
452 {
453         struct btf *btf1 = NULL, *btf2 = NULL, *btf3 = NULL, *btf4 = NULL, *btf5 = NULL;
454
455         btf1 = btf__new_empty();
456         if (!ASSERT_OK_PTR(btf1, "empty_main_btf"))
457                 return;
458         btf__add_int(btf1, "int", 4, BTF_INT_SIGNED);   /* [1] int */
459         VALIDATE_RAW_BTF(
460                 btf1,
461                 "[1] INT 'int' size=4 bits_offset=0 nr_bits=32 encoding=SIGNED");
462         btf2 = btf__new_empty_split(btf1);
463         if (!ASSERT_OK_PTR(btf2, "empty_split_btf"))
464                 goto cleanup;
465         btf__add_ptr(btf2, 1);
466         VALIDATE_RAW_BTF(
467                 btf2,
468                 "[1] INT 'int' size=4 bits_offset=0 nr_bits=32 encoding=SIGNED",
469                 "[2] PTR '(anon)' type_id=1");
470         if (!ASSERT_EQ(0, btf__distill_base(btf2, &btf3, &btf4),
471                        "distilled_base") ||
472             !ASSERT_OK_PTR(btf3, "distilled_base") ||
473             !ASSERT_OK_PTR(btf4, "distilled_split") ||
474             !ASSERT_EQ(2, btf__type_cnt(btf3), "distilled_base_type_cnt"))
475                 goto cleanup;
476         VALIDATE_RAW_BTF(
477                 btf3,
478                 "[1] INT 'int' size=4 bits_offset=0 nr_bits=32 encoding=SIGNED");
479         btf5 = btf__new_empty();
480         if (!ASSERT_OK_PTR(btf5, "empty_reloc_btf"))
481                 return;
482         btf__add_int(btf5, "int", 4, BTF_INT_SIGNED);   /* [1] int */
483         btf__add_int(btf5, "int", 4, BTF_INT_SIGNED);   /* [2] int */
484         VALIDATE_RAW_BTF(
485                 btf5,
486                 "[1] INT 'int' size=4 bits_offset=0 nr_bits=32 encoding=SIGNED",
487                 "[2] INT 'int' size=4 bits_offset=0 nr_bits=32 encoding=SIGNED");
488         ASSERT_EQ(btf__relocate(btf4, btf5), -EINVAL, "relocate_split");
489 cleanup:
490         btf__free(btf5);
491         btf__free(btf4);
492         btf__free(btf3);
493         btf__free(btf2);
494         btf__free(btf1);
495 }
496
497 /* create split reference BTF from vmlinux + split BTF with a few type references;
498  * ensure the resultant split reference BTF is as expected, containing only types
499  * needed to disambiguate references from split BTF.
500  */
501 static void test_distilled_base_vmlinux(void)
502 {
503         struct btf *split_btf = NULL, *vmlinux_btf = btf__load_vmlinux_btf();
504         struct btf *split_dist = NULL, *base_dist = NULL;
505         __s32 int_id, myint_id;
506
507         if (!ASSERT_OK_PTR(vmlinux_btf, "load_vmlinux"))
508                 return;
509         int_id = btf__find_by_name_kind(vmlinux_btf, "int", BTF_KIND_INT);
510         if (!ASSERT_GT(int_id, 0, "find_int"))
511                 goto cleanup;
512         split_btf = btf__new_empty_split(vmlinux_btf);
513         if (!ASSERT_OK_PTR(split_btf, "new_split"))
514                 goto cleanup;
515         myint_id = btf__add_typedef(split_btf, "myint", int_id);
516         btf__add_ptr(split_btf, myint_id);
517
518         if (!ASSERT_EQ(btf__distill_base(split_btf, &base_dist, &split_dist), 0,
519                        "distill_vmlinux_base"))
520                 goto cleanup;
521
522         if (!ASSERT_OK_PTR(split_dist, "split_distilled") ||
523             !ASSERT_OK_PTR(base_dist, "base_dist"))
524                 goto cleanup;
525         VALIDATE_RAW_BTF(
526                 split_dist,
527                 "[1] INT 'int' size=4 bits_offset=0 nr_bits=32 encoding=SIGNED",
528                 "[2] TYPEDEF 'myint' type_id=1",
529                 "[3] PTR '(anon)' type_id=2");
530
531 cleanup:
532         btf__free(split_dist);
533         btf__free(base_dist);
534         btf__free(split_btf);
535         btf__free(vmlinux_btf);
536 }
537
538 /* Split and new base BTFs should inherit endianness from source BTF. */
539 static void test_distilled_endianness(void)
540 {
541         struct btf *base = NULL, *split = NULL, *new_base = NULL, *new_split = NULL;
542         struct btf *new_base1 = NULL, *new_split1 = NULL;
543         enum btf_endianness inverse_endianness;
544         const void *raw_data;
545         __u32 size;
546
547         base = btf__new_empty();
548         if (!ASSERT_OK_PTR(base, "empty_main_btf"))
549                 return;
550         inverse_endianness = btf__endianness(base) == BTF_LITTLE_ENDIAN ? BTF_BIG_ENDIAN
551                                                                         : BTF_LITTLE_ENDIAN;
552         btf__set_endianness(base, inverse_endianness);
553         btf__add_int(base, "int", 4, BTF_INT_SIGNED);   /* [1] int */
554         VALIDATE_RAW_BTF(
555                 base,
556                 "[1] INT 'int' size=4 bits_offset=0 nr_bits=32 encoding=SIGNED");
557         split = btf__new_empty_split(base);
558         if (!ASSERT_OK_PTR(split, "empty_split_btf"))
559                 goto cleanup;
560         btf__add_ptr(split, 1);
561         VALIDATE_RAW_BTF(
562                 split,
563                 "[1] INT 'int' size=4 bits_offset=0 nr_bits=32 encoding=SIGNED",
564                 "[2] PTR '(anon)' type_id=1");
565         if (!ASSERT_EQ(0, btf__distill_base(split, &new_base, &new_split),
566                        "distilled_base") ||
567             !ASSERT_OK_PTR(new_base, "distilled_base") ||
568             !ASSERT_OK_PTR(new_split, "distilled_split") ||
569             !ASSERT_EQ(2, btf__type_cnt(new_base), "distilled_base_type_cnt"))
570                 goto cleanup;
571         VALIDATE_RAW_BTF(
572                 new_split,
573                 "[1] INT 'int' size=4 bits_offset=0 nr_bits=32 encoding=SIGNED",
574                 "[2] PTR '(anon)' type_id=1");
575
576         raw_data = btf__raw_data(new_base, &size);
577         if (!ASSERT_OK_PTR(raw_data, "btf__raw_data #1"))
578                 goto cleanup;
579         new_base1 = btf__new(raw_data, size);
580         if (!ASSERT_OK_PTR(new_base1, "new_base1 = btf__new()"))
581                 goto cleanup;
582         raw_data = btf__raw_data(new_split, &size);
583         if (!ASSERT_OK_PTR(raw_data, "btf__raw_data #2"))
584                 goto cleanup;
585         new_split1 = btf__new_split(raw_data, size, new_base1);
586         if (!ASSERT_OK_PTR(new_split1, "new_split1 = btf__new()"))
587                 goto cleanup;
588
589         ASSERT_EQ(btf__endianness(new_base1), inverse_endianness, "new_base1 endianness");
590         ASSERT_EQ(btf__endianness(new_split1), inverse_endianness, "new_split1 endianness");
591         VALIDATE_RAW_BTF(
592                 new_split1,
593                 "[1] INT 'int' size=4 bits_offset=0 nr_bits=32 encoding=SIGNED",
594                 "[2] PTR '(anon)' type_id=1");
595 cleanup:
596         btf__free(new_split1);
597         btf__free(new_base1);
598         btf__free(new_split);
599         btf__free(new_base);
600         btf__free(split);
601         btf__free(base);
602 }
603
604 void test_btf_distill(void)
605 {
606         if (test__start_subtest("distilled_base"))
607                 test_distilled_base();
608         if (test__start_subtest("distilled_base_multi"))
609                 test_distilled_base_multi();
610         if (test__start_subtest("distilled_base_missing_err"))
611                 test_distilled_base_missing_err();
612         if (test__start_subtest("distilled_base_multi_err"))
613                 test_distilled_base_multi_err();
614         if (test__start_subtest("distilled_base_multi_err2"))
615                 test_distilled_base_multi_err2();
616         if (test__start_subtest("distilled_base_vmlinux"))
617                 test_distilled_base_vmlinux();
618         if (test__start_subtest("distilled_endianness"))
619                 test_distilled_endianness();
620 }
This page took 0.066109 seconds and 4 git commands to generate.