xref: /linux/tools/testing/selftests/bpf/prog_tests/subskeleton.c (revision c34e9ab9a612ee8b18273398ef75c207b01f516d)
1 // SPDX-License-Identifier: GPL-2.0
2 /* Copyright (c) Meta Platforms, Inc. and affiliates. */
3 
4 #include <test_progs.h>
5 #include "test_subskeleton.skel.h"
6 #include "test_subskeleton_lib.subskel.h"
7 
8 static void subskeleton_lib_setup(struct bpf_object *obj)
9 {
10 	struct test_subskeleton_lib *lib = test_subskeleton_lib__open(obj);
11 
12 	if (!ASSERT_OK_PTR(lib, "open subskeleton"))
13 		return;
14 
15 	*lib->rodata.var1 = 1;
16 	*lib->data.var2 = 2;
17 	lib->bss.var3->var3_1 = 3;
18 	lib->bss.var3->var3_2 = 4;
19 
20 	test_subskeleton_lib__destroy(lib);
21 }
22 
23 static int subskeleton_lib_subresult(struct bpf_object *obj)
24 {
25 	struct test_subskeleton_lib *lib = test_subskeleton_lib__open(obj);
26 	int result;
27 
28 	if (!ASSERT_OK_PTR(lib, "open subskeleton"))
29 		return -EINVAL;
30 
31 	result = *lib->bss.libout1;
32 	ASSERT_EQ(result, 1 + 2 + 3 + 4 + 5 + 6, "lib subresult");
33 
34 	ASSERT_OK_PTR(lib->progs.lib_perf_handler, "lib_perf_handler");
35 	ASSERT_STREQ(bpf_program__name(lib->progs.lib_perf_handler),
36 		     "lib_perf_handler", "program name");
37 
38 	ASSERT_OK_PTR(lib->maps.map1, "map1");
39 	ASSERT_STREQ(bpf_map__name(lib->maps.map1), "map1", "map name");
40 
41 	ASSERT_EQ(*lib->data.var5, 5, "__weak var5");
42 	ASSERT_EQ(*lib->data.var6, 6, "extern var6");
43 	ASSERT_TRUE(*lib->kconfig.CONFIG_BPF_SYSCALL, "CONFIG_BPF_SYSCALL");
44 
45 	test_subskeleton_lib__destroy(lib);
46 	return result;
47 }
48 
49 /* initialize and load through skeleton, then instantiate subskeleton out of it */
50 static void subtest_skel_subskeleton(void)
51 {
52 	int err, result;
53 	struct test_subskeleton *skel;
54 
55 	skel = test_subskeleton__open();
56 	if (!ASSERT_OK_PTR(skel, "skel_open"))
57 		return;
58 
59 	skel->rodata->rovar1 = 10;
60 	skel->rodata->var1 = 1;
61 	subskeleton_lib_setup(skel->obj);
62 
63 	err = test_subskeleton__load(skel);
64 	if (!ASSERT_OK(err, "skel_load"))
65 		goto cleanup;
66 
67 	err = test_subskeleton__attach(skel);
68 	if (!ASSERT_OK(err, "skel_attach"))
69 		goto cleanup;
70 
71 	/* trigger tracepoint */
72 	usleep(1);
73 
74 	result = subskeleton_lib_subresult(skel->obj) * 10;
75 	ASSERT_EQ(skel->bss->out1, result, "unexpected calculation");
76 
77 cleanup:
78 	test_subskeleton__destroy(skel);
79 }
80 
81 /* initialize and load through generic bpf_object API, then instantiate subskeleton out of it */
82 static void subtest_obj_subskeleton(void)
83 {
84 	int err, result;
85 	const void *elf_bytes;
86 	size_t elf_bytes_sz = 0, rodata_sz = 0, bss_sz = 0;
87 	struct bpf_object *obj;
88 	const struct bpf_map *map;
89 	const struct bpf_program *prog;
90 	struct bpf_link *link = NULL;
91 	struct test_subskeleton__rodata *rodata;
92 	struct test_subskeleton__bss *bss;
93 
94 	elf_bytes = test_subskeleton__elf_bytes(&elf_bytes_sz);
95 	if (!ASSERT_OK_PTR(elf_bytes, "elf_bytes"))
96 		return;
97 
98 	obj = bpf_object__open_mem(elf_bytes, elf_bytes_sz, NULL);
99 	if (!ASSERT_OK_PTR(obj, "obj_open_mem"))
100 		return;
101 
102 	map = bpf_object__find_map_by_name(obj, ".rodata");
103 	if (!ASSERT_OK_PTR(map, "rodata_map_by_name"))
104 		goto cleanup;
105 
106 	rodata = bpf_map__initial_value(map, &rodata_sz);
107 	if (!ASSERT_OK_PTR(rodata, "rodata_get"))
108 		goto cleanup;
109 
110 	rodata->rovar1 = 10;
111 	rodata->var1 = 1;
112 	subskeleton_lib_setup(obj);
113 
114 	err = bpf_object__load(obj);
115 	if (!ASSERT_OK(err, "obj_load"))
116 		goto cleanup;
117 
118 	prog = bpf_object__find_program_by_name(obj, "handler1");
119 	if (!ASSERT_OK_PTR(prog, "prog_by_name"))
120 		goto cleanup;
121 
122 	link = bpf_program__attach(prog);
123 	if (!ASSERT_OK_PTR(link, "prog_attach"))
124 		goto cleanup;
125 
126 	/* trigger tracepoint */
127 	usleep(1);
128 
129 	map = bpf_object__find_map_by_name(obj, ".bss");
130 	if (!ASSERT_OK_PTR(map, "bss_map_by_name"))
131 		goto cleanup;
132 
133 	bss = bpf_map__initial_value(map, &bss_sz);
134 	if (!ASSERT_OK_PTR(rodata, "rodata_get"))
135 		goto cleanup;
136 
137 	result = subskeleton_lib_subresult(obj) * 10;
138 	ASSERT_EQ(bss->out1, result, "out1");
139 
140 cleanup:
141 	bpf_link__destroy(link);
142 	bpf_object__close(obj);
143 }
144 
145 
146 void test_subskeleton(void)
147 {
148 	if (test__start_subtest("skel_subskel"))
149 		subtest_skel_subskeleton();
150 	if (test__start_subtest("obj_subskel"))
151 		subtest_obj_subskeleton();
152 }
153