File Index
Files and directories
Sign in
FILE

core_autosize.c

File preview with syntax highlighting.

linux-6.19.14/tools/testing/selftests/bpf/prog_tests/core_autosize.c C
  1// SPDX-License-Identifier: GPL-2.0
  2/* Copyright (c) 2020 Facebook */
  3
  4#include <test_progs.h>
  5#include <bpf/btf.h>
  6
  7/* real layout and sizes according to test's (32-bit) BTF
  8 * needs to be defined before skeleton is included */
  9struct test_struct___real {
 10	unsigned int ptr; /* can't use `void *`, it is always 8 byte in BPF target */
 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	DECLARE_LIBBPF_OPTS(bpf_object_open_opts, open_opts);
 57	struct test_core_autosize* skel = NULL;
 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	/* Emit the following struct with 32-bit pointer size:
 70	 *
 71	 * struct test_struct {
 72	 *     void *ptr;
 73	 *     unsigned long val2;
 74	 *     unsigned long long val1;
 75	 *     unsigned short val3;
 76	 *     unsigned char val4;
 77	 *     char: 8;
 78	 * };
 79	 *
 80	 * This struct is going to be used as the "kernel BTF" for this test.
 81	 * It's equivalent memory-layout-wise to test_struct__real above.
 82	 */
 83
 84	/* force 32-bit pointer size */
 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	/* "long unsigned int" of 4 byte size tells BTF that sizeof(void *) == 4 */
 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 /* bytes */);
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__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	/* open and load BPF program with custom BTF as the kernel BTF */
128	open_opts.btf_custom_path = btf_file;
129	skel = test_core_autosize__open_opts(&open_opts);
130	if (!ASSERT_OK_PTR(skel, "skel_open"))
131		goto cleanup;
132
133	/* disable handle_signed() for now */
134	prog = bpf_object__find_program_by_name(skel->obj, "handle_signed");
135	if (!ASSERT_OK_PTR(prog, "prog_find"))
136		goto cleanup;
137	bpf_program__set_autoload(prog, false);
138
139	err = bpf_object__load(skel->obj);
140	if (!ASSERT_OK(err, "prog_load"))
141		goto cleanup;
142
143	prog = bpf_object__find_program_by_name(skel->obj, "handle_samesize");
144	if (!ASSERT_OK_PTR(prog, "prog_find"))
145		goto cleanup;
146	skel->links.handle_samesize = bpf_program__attach(prog);
147	if (!ASSERT_OK_PTR(skel->links.handle_samesize, "prog_attach"))
148		goto cleanup;
149
150	prog = bpf_object__find_program_by_name(skel->obj, "handle_downsize");
151	if (!ASSERT_OK_PTR(prog, "prog_find"))
152		goto cleanup;
153	skel->links.handle_downsize = bpf_program__attach(prog);
154	if (!ASSERT_OK_PTR(skel->links.handle_downsize, "prog_attach"))
155		goto cleanup;
156
157	prog = bpf_object__find_program_by_name(skel->obj, "handle_probed");
158	if (!ASSERT_OK_PTR(prog, "prog_find"))
159		goto cleanup;
160	skel->links.handle_probed = bpf_program__attach(prog);
161	if (!ASSERT_OK_PTR(skel->links.handle_probed, "prog_attach"))
162		goto cleanup;
163
164	usleep(1);
165
166	bss_map = bpf_object__find_map_by_name(skel->obj, ".bss");
167	if (!ASSERT_OK_PTR(bss_map, "bss_map_find"))
168		goto cleanup;
169
170	err = bpf_map__lookup_elem(bss_map, &zero, sizeof(zero), &out, sizeof(out), 0);
171	if (!ASSERT_OK(err, "bss_lookup"))
172		goto cleanup;
173
174	ASSERT_EQ(out.ptr_samesized, 0x01020304, "ptr_samesized");
175	ASSERT_EQ(out.val1_samesized, 0x1020304050607080, "val1_samesized");
176	ASSERT_EQ(out.val2_samesized, 0x0a0b0c0d, "val2_samesized");
177	ASSERT_EQ(out.val3_samesized, 0xfeed, "val3_samesized");
178	ASSERT_EQ(out.val4_samesized, 0xb9, "val4_samesized");
179	ASSERT_EQ(out.output_samesized.ptr, 0x01020304, "ptr_samesized");
180	ASSERT_EQ(out.output_samesized.val1, 0x1020304050607080, "val1_samesized");
181	ASSERT_EQ(out.output_samesized.val2, 0x0a0b0c0d, "val2_samesized");
182	ASSERT_EQ(out.output_samesized.val3, 0xfeed, "val3_samesized");
183	ASSERT_EQ(out.output_samesized.val4, 0xb9, "val4_samesized");
184
185	ASSERT_EQ(out.ptr_downsized, 0x01020304, "ptr_downsized");
186	ASSERT_EQ(out.val1_downsized, 0x1020304050607080, "val1_downsized");
187	ASSERT_EQ(out.val2_downsized, 0x0a0b0c0d, "val2_downsized");
188	ASSERT_EQ(out.val3_downsized, 0xfeed, "val3_downsized");
189	ASSERT_EQ(out.val4_downsized, 0xb9, "val4_downsized");
190	ASSERT_EQ(out.output_downsized.ptr, 0x01020304, "ptr_downsized");
191	ASSERT_EQ(out.output_downsized.val1, 0x1020304050607080, "val1_downsized");
192	ASSERT_EQ(out.output_downsized.val2, 0x0a0b0c0d, "val2_downsized");
193	ASSERT_EQ(out.output_downsized.val3, 0xfeed, "val3_downsized");
194	ASSERT_EQ(out.output_downsized.val4, 0xb9, "val4_downsized");
195
196	ASSERT_EQ(out.ptr_probed, 0x01020304, "ptr_probed");
197	ASSERT_EQ(out.val1_probed, 0x1020304050607080, "val1_probed");
198	ASSERT_EQ(out.val2_probed, 0x0a0b0c0d, "val2_probed");
199	ASSERT_EQ(out.val3_probed, 0xfeed, "val3_probed");
200	ASSERT_EQ(out.val4_probed, 0xb9, "val4_probed");
201
202	test_core_autosize__destroy(skel);
203	skel = NULL;
204
205	/* now re-load with handle_signed() enabled, it should fail loading */
206	open_opts.btf_custom_path = btf_file;
207	skel = test_core_autosize__open_opts(&open_opts);
208	if (!ASSERT_OK_PTR(skel, "skel_open"))
209		goto cleanup;
210
211	err = test_core_autosize__load(skel);
212	if (!ASSERT_ERR(err, "skel_load"))
213		goto cleanup;
214
215cleanup:
216	if (f)
217		fclose(f);
218	if (fd >= 0)
219		close(fd);
220	remove(btf_file);
221	btf__free(btf);
222	test_core_autosize__destroy(skel);
223}
~/ Read-only file preview.