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