153 lines
3.8 KiB
C
153 lines
3.8 KiB
C
// SPDX-License-Identifier: GPL-2.0
|
|
/* Copyright (c) Meta Platforms, Inc. and affiliates. */
|
|
|
|
#include <test_progs.h>
|
|
#include "test_subskeleton.skel.h"
|
|
#include "test_subskeleton_lib.subskel.h"
|
|
|
|
static void subskeleton_lib_setup(struct bpf_object *obj)
|
|
{
|
|
struct test_subskeleton_lib *lib = test_subskeleton_lib__open(obj);
|
|
|
|
if (!ASSERT_OK_PTR(lib, "open subskeleton"))
|
|
return;
|
|
|
|
*lib->rodata.var1 = 1;
|
|
*lib->data.var2 = 2;
|
|
lib->bss.var3->var3_1 = 3;
|
|
lib->bss.var3->var3_2 = 4;
|
|
|
|
test_subskeleton_lib__destroy(lib);
|
|
}
|
|
|
|
static int subskeleton_lib_subresult(struct bpf_object *obj)
|
|
{
|
|
struct test_subskeleton_lib *lib = test_subskeleton_lib__open(obj);
|
|
int result;
|
|
|
|
if (!ASSERT_OK_PTR(lib, "open subskeleton"))
|
|
return -EINVAL;
|
|
|
|
result = *lib->bss.libout1;
|
|
ASSERT_EQ(result, 1 + 2 + 3 + 4 + 5 + 6, "lib subresult");
|
|
|
|
ASSERT_OK_PTR(lib->progs.lib_perf_handler, "lib_perf_handler");
|
|
ASSERT_STREQ(bpf_program__name(lib->progs.lib_perf_handler),
|
|
"lib_perf_handler", "program name");
|
|
|
|
ASSERT_OK_PTR(lib->maps.map1, "map1");
|
|
ASSERT_STREQ(bpf_map__name(lib->maps.map1), "map1", "map name");
|
|
|
|
ASSERT_EQ(*lib->data.var5, 5, "__weak var5");
|
|
ASSERT_EQ(*lib->data.var6, 6, "extern var6");
|
|
ASSERT_TRUE(*lib->kconfig.CONFIG_BPF_SYSCALL, "CONFIG_BPF_SYSCALL");
|
|
|
|
test_subskeleton_lib__destroy(lib);
|
|
return result;
|
|
}
|
|
|
|
/* initialize and load through skeleton, then instantiate subskeleton out of it */
|
|
static void subtest_skel_subskeleton(void)
|
|
{
|
|
int err, result;
|
|
struct test_subskeleton *skel;
|
|
|
|
skel = test_subskeleton__open();
|
|
if (!ASSERT_OK_PTR(skel, "skel_open"))
|
|
return;
|
|
|
|
skel->rodata->rovar1 = 10;
|
|
skel->rodata->var1 = 1;
|
|
subskeleton_lib_setup(skel->obj);
|
|
|
|
err = test_subskeleton__load(skel);
|
|
if (!ASSERT_OK(err, "skel_load"))
|
|
goto cleanup;
|
|
|
|
err = test_subskeleton__attach(skel);
|
|
if (!ASSERT_OK(err, "skel_attach"))
|
|
goto cleanup;
|
|
|
|
/* trigger tracepoint */
|
|
usleep(1);
|
|
|
|
result = subskeleton_lib_subresult(skel->obj) * 10;
|
|
ASSERT_EQ(skel->bss->out1, result, "unexpected calculation");
|
|
|
|
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();
|
|
}
|