Linux Audio

Check our new training course

Loading...
v6.13.7
  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 */
 14static 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
287cleanup:
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 */
298static 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
342cleanup:
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 */
352static 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		goto cleanup;
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
395cleanup:
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 */
406static 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");
441cleanup:
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 */
451static 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		goto cleanup;
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");
489cleanup:
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 */
501static 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
531cleanup:
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. */
539static 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");
595cleanup:
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
604void 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}
v6.13.7
  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 */
 14static 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
287cleanup:
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 */
298static 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
342cleanup:
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 */
352static 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		goto cleanup;
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
395cleanup:
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 */
406static 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");
441cleanup:
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 */
451static 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		goto cleanup;
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");
489cleanup:
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 */
501static 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
531cleanup:
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. */
539static 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");
595cleanup:
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
604void 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}