Skip to content

Commit 429887d

Browse files
pengdonglinKernel Patches Daemon
authored andcommitted
selftests/bpf: Add test cases for btf__permute functionality
This patch introduces test cases for the btf__permute function to ensure it works correctly with both base BTF and split BTF scenarios. The test suite includes: - test_permute_base: Validates permutation on standalone BTF - test_permute_split: Tests permutation on split BTF with base dependencies Each test verifies that type IDs are correctly rearranged and type references are properly updated after permutation operations. Cc: Eduard Zingerman <[email protected]> Cc: Alexei Starovoitov <[email protected]> Cc: Andrii Nakryiko <[email protected]> Cc: Alan Maguire <[email protected]> Cc: Song Liu <[email protected]> Signed-off-by: pengdonglin <[email protected]> Signed-off-by: Donglin Peng <[email protected]>
1 parent 266fe86 commit 429887d

File tree

1 file changed

+142
-0
lines changed

1 file changed

+142
-0
lines changed
Lines changed: 142 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,142 @@
1+
// SPDX-License-Identifier: GPL-2.0
2+
/* Copyright (c) 2025 Xiaomi */
3+
4+
#include <test_progs.h>
5+
#include <bpf/btf.h>
6+
#include "btf_helpers.h"
7+
8+
/* ensure btf__permute work as expected with base_btf */
9+
static void test_permute_base(void)
10+
{
11+
struct btf *btf;
12+
__u32 permute_ids[6];
13+
int err;
14+
15+
btf = btf__new_empty();
16+
if (!ASSERT_OK_PTR(btf, "empty_main_btf"))
17+
return;
18+
19+
btf__add_int(btf, "int", 4, BTF_INT_SIGNED); /* [1] int */
20+
btf__add_ptr(btf, 1); /* [2] ptr to int */
21+
btf__add_struct(btf, "s1", 4); /* [3] struct s1 { */
22+
btf__add_field(btf, "m", 1, 0, 0); /* int m; */
23+
/* } */
24+
btf__add_struct(btf, "s2", 4); /* [4] struct s2 { */
25+
btf__add_field(btf, "m", 1, 0, 0); /* int m; */
26+
/* } */
27+
btf__add_func_proto(btf, 1); /* [5] int (*)(int *p); */
28+
btf__add_func_param(btf, "p", 2);
29+
btf__add_func(btf, "f", BTF_FUNC_STATIC, 5); /* [6] int f(int *p); */
30+
31+
VALIDATE_RAW_BTF(
32+
btf,
33+
"[1] INT 'int' size=4 bits_offset=0 nr_bits=32 encoding=SIGNED",
34+
"[2] PTR '(anon)' type_id=1",
35+
"[3] STRUCT 's1' size=4 vlen=1\n"
36+
"\t'm' type_id=1 bits_offset=0",
37+
"[4] STRUCT 's2' size=4 vlen=1\n"
38+
"\t'm' type_id=1 bits_offset=0",
39+
"[5] FUNC_PROTO '(anon)' ret_type_id=1 vlen=1\n"
40+
"\t'p' type_id=2",
41+
"[6] FUNC 'f' type_id=5 linkage=static");
42+
43+
permute_ids[0] = 4; /* struct s2 */
44+
permute_ids[1] = 3; /* struct s1 */
45+
permute_ids[2] = 5; /* int (*)(int *p) */
46+
permute_ids[3] = 1; /* int */
47+
permute_ids[4] = 6; /* int f(int *p) */
48+
permute_ids[5] = 2; /* ptr to int */
49+
err = btf__permute(btf, permute_ids, NULL);
50+
if (!ASSERT_OK(err, "btf__permute"))
51+
goto done;
52+
53+
VALIDATE_RAW_BTF(
54+
btf,
55+
"[1] STRUCT 's2' size=4 vlen=1\n"
56+
"\t'm' type_id=4 bits_offset=0",
57+
"[2] STRUCT 's1' size=4 vlen=1\n"
58+
"\t'm' type_id=4 bits_offset=0",
59+
"[3] FUNC_PROTO '(anon)' ret_type_id=4 vlen=1\n"
60+
"\t'p' type_id=6",
61+
"[4] INT 'int' size=4 bits_offset=0 nr_bits=32 encoding=SIGNED",
62+
"[5] FUNC 'f' type_id=3 linkage=static",
63+
"[6] PTR '(anon)' type_id=4");
64+
65+
done:
66+
btf__free(btf);
67+
}
68+
69+
/* ensure btf__permute work as expected with split_btf */
70+
static void test_permute_split(void)
71+
{
72+
struct btf *split_btf = NULL, *base_btf = NULL;
73+
__u32 permute_ids[4];
74+
int err;
75+
76+
base_btf = btf__new_empty();
77+
if (!ASSERT_OK_PTR(base_btf, "empty_main_btf"))
78+
return;
79+
80+
btf__add_int(base_btf, "int", 4, BTF_INT_SIGNED); /* [1] int */
81+
btf__add_ptr(base_btf, 1); /* [2] ptr to int */
82+
VALIDATE_RAW_BTF(
83+
base_btf,
84+
"[1] INT 'int' size=4 bits_offset=0 nr_bits=32 encoding=SIGNED",
85+
"[2] PTR '(anon)' type_id=1");
86+
split_btf = btf__new_empty_split(base_btf);
87+
if (!ASSERT_OK_PTR(split_btf, "empty_split_btf"))
88+
goto cleanup;
89+
btf__add_struct(split_btf, "s1", 4); /* [3] struct s1 { */
90+
btf__add_field(split_btf, "m", 1, 0, 0); /* int m; */
91+
/* } */
92+
btf__add_struct(split_btf, "s2", 4); /* [4] struct s2 { */
93+
btf__add_field(split_btf, "m", 1, 0, 0); /* int m; */
94+
/* } */
95+
btf__add_func_proto(split_btf, 1); /* [5] int (*)(int p); */
96+
btf__add_func_param(split_btf, "p", 2);
97+
btf__add_func(split_btf, "f", BTF_FUNC_STATIC, 5); /* [6] int f(int *p); */
98+
99+
VALIDATE_RAW_BTF(
100+
split_btf,
101+
"[1] INT 'int' size=4 bits_offset=0 nr_bits=32 encoding=SIGNED",
102+
"[2] PTR '(anon)' type_id=1",
103+
"[3] STRUCT 's1' size=4 vlen=1\n"
104+
"\t'm' type_id=1 bits_offset=0",
105+
"[4] STRUCT 's2' size=4 vlen=1\n"
106+
"\t'm' type_id=1 bits_offset=0",
107+
"[5] FUNC_PROTO '(anon)' ret_type_id=1 vlen=1\n"
108+
"\t'p' type_id=2",
109+
"[6] FUNC 'f' type_id=5 linkage=static");
110+
111+
permute_ids[0] = 6; /* int f(int *p) */
112+
permute_ids[1] = 3; /* struct s1 */
113+
permute_ids[2] = 5; /* int (*)(int *p) */
114+
permute_ids[3] = 4; /* struct s2 */
115+
err = btf__permute(split_btf, permute_ids, NULL);
116+
if (!ASSERT_OK(err, "btf__permute"))
117+
goto cleanup;
118+
119+
VALIDATE_RAW_BTF(
120+
split_btf,
121+
"[1] INT 'int' size=4 bits_offset=0 nr_bits=32 encoding=SIGNED",
122+
"[2] PTR '(anon)' type_id=1",
123+
"[3] FUNC 'f' type_id=5 linkage=static",
124+
"[4] STRUCT 's1' size=4 vlen=1\n"
125+
"\t'm' type_id=1 bits_offset=0",
126+
"[5] FUNC_PROTO '(anon)' ret_type_id=1 vlen=1\n"
127+
"\t'p' type_id=2",
128+
"[6] STRUCT 's2' size=4 vlen=1\n"
129+
"\t'm' type_id=1 bits_offset=0");
130+
131+
cleanup:
132+
btf__free(split_btf);
133+
btf__free(base_btf);
134+
}
135+
136+
void test_btf_permute(void)
137+
{
138+
if (test__start_subtest("permute_base"))
139+
test_permute_base();
140+
if (test__start_subtest("permute_split"))
141+
test_permute_split();
142+
}

0 commit comments

Comments
 (0)