1
2
3
4#include <test_progs.h>
5#include <bpf/btf.h>
6
7
8
9struct test_struct___real {
10 unsigned int ptr;
11 unsigned int val2;
12 unsigned long long val1;
13 unsigned short val3;
14 unsigned char val4;
15 unsigned char _pad;
16};
17
18#include "test_core_autosize.skel.h"
19
20static int duration = 0;
21
22static struct {
23 unsigned long long ptr_samesized;
24 unsigned long long val1_samesized;
25 unsigned long long val2_samesized;
26 unsigned long long val3_samesized;
27 unsigned long long val4_samesized;
28 struct test_struct___real output_samesized;
29
30 unsigned long long ptr_downsized;
31 unsigned long long val1_downsized;
32 unsigned long long val2_downsized;
33 unsigned long long val3_downsized;
34 unsigned long long val4_downsized;
35 struct test_struct___real output_downsized;
36
37 unsigned long long ptr_probed;
38 unsigned long long val1_probed;
39 unsigned long long val2_probed;
40 unsigned long long val3_probed;
41 unsigned long long val4_probed;
42
43 unsigned long long ptr_signed;
44 unsigned long long val1_signed;
45 unsigned long long val2_signed;
46 unsigned long long val3_signed;
47 unsigned long long val4_signed;
48 struct test_struct___real output_signed;
49} out;
50
51void test_core_autosize(void)
52{
53 char btf_file[] = "/tmp/core_autosize.btf.XXXXXX";
54 int err, fd = -1, zero = 0;
55 int char_id, short_id, int_id, long_long_id, void_ptr_id, id;
56 struct test_core_autosize* skel = NULL;
57 struct bpf_object_load_attr load_attr = {};
58 struct bpf_program *prog;
59 struct bpf_map *bss_map;
60 struct btf *btf = NULL;
61 size_t written;
62 const void *raw_data;
63 __u32 raw_sz;
64 FILE *f = NULL;
65
66 btf = btf__new_empty();
67 if (!ASSERT_OK_PTR(btf, "empty_btf"))
68 return;
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85 btf__set_pointer_size(btf, 4);
86
87 char_id = btf__add_int(btf, "unsigned char", 1, 0);
88 ASSERT_EQ(char_id, 1, "char_id");
89 short_id = btf__add_int(btf, "unsigned short", 2, 0);
90 ASSERT_EQ(short_id, 2, "short_id");
91
92 int_id = btf__add_int(btf, "long unsigned int", 4, 0);
93 ASSERT_EQ(int_id, 3, "int_id");
94 long_long_id = btf__add_int(btf, "unsigned long long", 8, 0);
95 ASSERT_EQ(long_long_id, 4, "long_long_id");
96 void_ptr_id = btf__add_ptr(btf, 0);
97 ASSERT_EQ(void_ptr_id, 5, "void_ptr_id");
98
99 id = btf__add_struct(btf, "test_struct", 20 );
100 ASSERT_EQ(id, 6, "struct_id");
101 err = btf__add_field(btf, "ptr", void_ptr_id, 0, 0);
102 err = err ?: btf__add_field(btf, "val2", int_id, 32, 0);
103 err = err ?: btf__add_field(btf, "val1", long_long_id, 64, 0);
104 err = err ?: btf__add_field(btf, "val3", short_id, 128, 0);
105 err = err ?: btf__add_field(btf, "val4", char_id, 144, 0);
106 ASSERT_OK(err, "struct_fields");
107
108 fd = mkstemp(btf_file);
109 if (CHECK(fd < 0, "btf_tmp", "failed to create file: %d\n", fd))
110 goto cleanup;
111 f = fdopen(fd, "w");
112 if (!ASSERT_OK_PTR(f, "btf_fdopen"))
113 goto cleanup;
114
115 raw_data = btf__get_raw_data(btf, &raw_sz);
116 if (!ASSERT_OK_PTR(raw_data, "raw_data"))
117 goto cleanup;
118 written = fwrite(raw_data, 1, raw_sz, f);
119 if (CHECK(written != raw_sz, "btf_write", "written: %zu, errno: %d\n", written, errno))
120 goto cleanup;
121 fflush(f);
122 fclose(f);
123 f = NULL;
124 close(fd);
125 fd = -1;
126
127
128 skel = test_core_autosize__open();
129 if (!ASSERT_OK_PTR(skel, "skel_open"))
130 return;
131
132
133 prog = bpf_object__find_program_by_name(skel->obj, "handle_signed");
134 if (!ASSERT_OK_PTR(prog, "prog_find"))
135 goto cleanup;
136 bpf_program__set_autoload(prog, false);
137
138 load_attr.obj = skel->obj;
139 load_attr.target_btf_path = btf_file;
140 err = bpf_object__load_xattr(&load_attr);
141 if (!ASSERT_OK(err, "prog_load"))
142 goto cleanup;
143
144 prog = bpf_object__find_program_by_name(skel->obj, "handle_samesize");
145 if (!ASSERT_OK_PTR(prog, "prog_find"))
146 goto cleanup;
147 skel->links.handle_samesize = bpf_program__attach(prog);
148 if (!ASSERT_OK_PTR(skel->links.handle_samesize, "prog_attach"))
149 goto cleanup;
150
151 prog = bpf_object__find_program_by_name(skel->obj, "handle_downsize");
152 if (!ASSERT_OK_PTR(prog, "prog_find"))
153 goto cleanup;
154 skel->links.handle_downsize = bpf_program__attach(prog);
155 if (!ASSERT_OK_PTR(skel->links.handle_downsize, "prog_attach"))
156 goto cleanup;
157
158 prog = bpf_object__find_program_by_name(skel->obj, "handle_probed");
159 if (!ASSERT_OK_PTR(prog, "prog_find"))
160 goto cleanup;
161 skel->links.handle_probed = bpf_program__attach(prog);
162 if (!ASSERT_OK_PTR(skel->links.handle_probed, "prog_attach"))
163 goto cleanup;
164
165 usleep(1);
166
167 bss_map = bpf_object__find_map_by_name(skel->obj, "test_cor.bss");
168 if (!ASSERT_OK_PTR(bss_map, "bss_map_find"))
169 goto cleanup;
170
171 err = bpf_map_lookup_elem(bpf_map__fd(bss_map), &zero, (void *)&out);
172 if (!ASSERT_OK(err, "bss_lookup"))
173 goto cleanup;
174
175 ASSERT_EQ(out.ptr_samesized, 0x01020304, "ptr_samesized");
176 ASSERT_EQ(out.val1_samesized, 0x1020304050607080, "val1_samesized");
177 ASSERT_EQ(out.val2_samesized, 0x0a0b0c0d, "val2_samesized");
178 ASSERT_EQ(out.val3_samesized, 0xfeed, "val3_samesized");
179 ASSERT_EQ(out.val4_samesized, 0xb9, "val4_samesized");
180 ASSERT_EQ(out.output_samesized.ptr, 0x01020304, "ptr_samesized");
181 ASSERT_EQ(out.output_samesized.val1, 0x1020304050607080, "val1_samesized");
182 ASSERT_EQ(out.output_samesized.val2, 0x0a0b0c0d, "val2_samesized");
183 ASSERT_EQ(out.output_samesized.val3, 0xfeed, "val3_samesized");
184 ASSERT_EQ(out.output_samesized.val4, 0xb9, "val4_samesized");
185
186 ASSERT_EQ(out.ptr_downsized, 0x01020304, "ptr_downsized");
187 ASSERT_EQ(out.val1_downsized, 0x1020304050607080, "val1_downsized");
188 ASSERT_EQ(out.val2_downsized, 0x0a0b0c0d, "val2_downsized");
189 ASSERT_EQ(out.val3_downsized, 0xfeed, "val3_downsized");
190 ASSERT_EQ(out.val4_downsized, 0xb9, "val4_downsized");
191 ASSERT_EQ(out.output_downsized.ptr, 0x01020304, "ptr_downsized");
192 ASSERT_EQ(out.output_downsized.val1, 0x1020304050607080, "val1_downsized");
193 ASSERT_EQ(out.output_downsized.val2, 0x0a0b0c0d, "val2_downsized");
194 ASSERT_EQ(out.output_downsized.val3, 0xfeed, "val3_downsized");
195 ASSERT_EQ(out.output_downsized.val4, 0xb9, "val4_downsized");
196
197 ASSERT_EQ(out.ptr_probed, 0x01020304, "ptr_probed");
198 ASSERT_EQ(out.val1_probed, 0x1020304050607080, "val1_probed");
199 ASSERT_EQ(out.val2_probed, 0x0a0b0c0d, "val2_probed");
200 ASSERT_EQ(out.val3_probed, 0xfeed, "val3_probed");
201 ASSERT_EQ(out.val4_probed, 0xb9, "val4_probed");
202
203 test_core_autosize__destroy(skel);
204 skel = NULL;
205
206
207 skel = test_core_autosize__open();
208 if (!ASSERT_OK_PTR(skel, "skel_open"))
209 return;
210
211 load_attr.obj = skel->obj;
212 load_attr.target_btf_path = btf_file;
213 err = bpf_object__load_xattr(&load_attr);
214 if (!ASSERT_ERR(err, "bad_prog_load"))
215 goto cleanup;
216
217cleanup:
218 if (f)
219 fclose(f);
220 if (fd >= 0)
221 close(fd);
222 remove(btf_file);
223 btf__free(btf);
224 test_core_autosize__destroy(skel);
225}
226