Commit 80a54566 authored by Andrii Nakryiko's avatar Andrii Nakryiko Committed by Alexei Starovoitov
Browse files

selftests/bpf: validate generic bpf_object and subskel APIs work together



Add a new subtest validating that bpf_object loaded and initialized
through generic APIs is still interoperable with BPF subskeleton,
including initialization and reading of global variables.

Signed-off-by: default avatarAndrii Nakryiko <andrii@kernel.org>
Link: https://lore.kernel.org/r/20241023043908.3834423-4-andrii@kernel.org


Signed-off-by: default avatarAlexei Starovoitov <ast@kernel.org>
parent 137978f4
Loading
Loading
Loading
Loading
+75 −1
Original line number Diff line number Diff line
@@ -46,7 +46,8 @@ static int subskeleton_lib_subresult(struct bpf_object *obj)
	return result;
}

void test_subskeleton(void)
/* initialize and load through skeleton, then instantiate subskeleton out of it */
static void subtest_skel_subskeleton(void)
{
	int err, result;
	struct test_subskeleton *skel;
@@ -76,3 +77,76 @@ void test_subskeleton(void)
cleanup:
	test_subskeleton__destroy(skel);
}

/* initialize and load through generic bpf_object API, then instantiate subskeleton out of it */
static void subtest_obj_subskeleton(void)
{
	int err, result;
	const void *elf_bytes;
	size_t elf_bytes_sz = 0, rodata_sz = 0, bss_sz = 0;
	struct bpf_object *obj;
	const struct bpf_map *map;
	const struct bpf_program *prog;
	struct bpf_link *link = NULL;
	struct test_subskeleton__rodata *rodata;
	struct test_subskeleton__bss *bss;

	elf_bytes = test_subskeleton__elf_bytes(&elf_bytes_sz);
	if (!ASSERT_OK_PTR(elf_bytes, "elf_bytes"))
		return;

	obj = bpf_object__open_mem(elf_bytes, elf_bytes_sz, NULL);
	if (!ASSERT_OK_PTR(obj, "obj_open_mem"))
		return;

	map = bpf_object__find_map_by_name(obj, ".rodata");
	if (!ASSERT_OK_PTR(map, "rodata_map_by_name"))
		goto cleanup;

	rodata = bpf_map__initial_value(map, &rodata_sz);
	if (!ASSERT_OK_PTR(rodata, "rodata_get"))
		goto cleanup;

	rodata->rovar1 = 10;
	rodata->var1 = 1;
	subskeleton_lib_setup(obj);

	err = bpf_object__load(obj);
	if (!ASSERT_OK(err, "obj_load"))
		goto cleanup;

	prog = bpf_object__find_program_by_name(obj, "handler1");
	if (!ASSERT_OK_PTR(prog, "prog_by_name"))
		goto cleanup;

	link = bpf_program__attach(prog);
	if (!ASSERT_OK_PTR(link, "prog_attach"))
		goto cleanup;

	/* trigger tracepoint */
	usleep(1);

	map = bpf_object__find_map_by_name(obj, ".bss");
	if (!ASSERT_OK_PTR(map, "bss_map_by_name"))
		goto cleanup;

	bss = bpf_map__initial_value(map, &bss_sz);
	if (!ASSERT_OK_PTR(rodata, "rodata_get"))
		goto cleanup;

	result = subskeleton_lib_subresult(obj) * 10;
	ASSERT_EQ(bss->out1, result, "out1");

cleanup:
	bpf_link__destroy(link);
	bpf_object__close(obj);
}


void test_subskeleton(void)
{
	if (test__start_subtest("skel_subskel"))
		subtest_skel_subskeleton();
	if (test__start_subtest("obj_subskel"))
		subtest_obj_subskeleton();
}