~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/tools/testing/selftests/bpf/prog_tests/btf_distill.c

Version: ~ [ linux-6.11.5 ] ~ [ linux-6.10.14 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.58 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.114 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.169 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.228 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.284 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.322 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.9 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  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 void test_btf_distill(void)
539 {
540         if (test__start_subtest("distilled_base"))
541                 test_distilled_base();
542         if (test__start_subtest("distilled_base_multi"))
543                 test_distilled_base_multi();
544         if (test__start_subtest("distilled_base_missing_err"))
545                 test_distilled_base_missing_err();
546         if (test__start_subtest("distilled_base_multi_err"))
547                 test_distilled_base_multi_err();
548         if (test__start_subtest("distilled_base_multi_err2"))
549                 test_distilled_base_multi_err2();
550         if (test__start_subtest("distilled_base_vmlinux"))
551                 test_distilled_base_vmlinux();
552 }
553 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php