From 197448eaac1ab330fb485769bccb62346ba1f458 Mon Sep 17 00:00:00 2001 From: Andrii Nakryiko Date: Fri, 13 Dec 2019 17:43:40 -0800 Subject: selftests/bpf: Add test validating data section to struct convertion layout Add a simple selftests validating datasection-to-struct layour dumping. Global variables are constructed in such a way as to cause both natural and artificial padding (through custom alignment requirement). Signed-off-by: Andrii Nakryiko Signed-off-by: Alexei Starovoitov Acked-by: Martin KaFai Lau Link: https://lore.kernel.org/bpf/20191214014341.3442258-17-andriin@fb.com --- tools/testing/selftests/bpf/prog_tests/skeleton.c | 51 +++++++++++++++++++++++ 1 file changed, 51 insertions(+) create mode 100644 tools/testing/selftests/bpf/prog_tests/skeleton.c (limited to 'tools/testing/selftests/bpf/prog_tests/skeleton.c') diff --git a/tools/testing/selftests/bpf/prog_tests/skeleton.c b/tools/testing/selftests/bpf/prog_tests/skeleton.c new file mode 100644 index 000000000000..79f8d13e6740 --- /dev/null +++ b/tools/testing/selftests/bpf/prog_tests/skeleton.c @@ -0,0 +1,51 @@ +// SPDX-License-Identifier: GPL-2.0 +/* Copyright (c) 2019 Facebook */ + +#include + +struct s { + int a; + long long b; +} __attribute__((packed)); + +#include "test_skeleton.skel.h" + +BPF_EMBED_OBJ(skeleton, "test_skeleton.o"); + +void test_skeleton(void) +{ + int duration = 0, err; + struct test_skeleton* skel; + struct test_skeleton__bss *bss; + + skel = test_skeleton__open_and_load(&skeleton_embed); + if (CHECK(!skel, "skel_open", "failed to open skeleton\n")) + return; + + bss = skel->bss; + bss->in1 = 1; + bss->in2 = 2; + bss->in3 = 3; + bss->in4 = 4; + bss->in5.a = 5; + bss->in5.b = 6; + + err = test_skeleton__attach(skel); + if (CHECK(err, "skel_attach", "skeleton attach failed: %d\n", err)) + goto cleanup; + + /* trigger tracepoint */ + usleep(1); + + CHECK(bss->out1 != 1, "res1", "got %d != exp %d\n", bss->out1, 1); + CHECK(bss->out2 != 2, "res2", "got %lld != exp %d\n", bss->out2, 2); + CHECK(bss->out3 != 3, "res3", "got %d != exp %d\n", (int)bss->out3, 3); + CHECK(bss->out4 != 4, "res4", "got %lld != exp %d\n", bss->out4, 4); + CHECK(bss->handler_out5.a != 5, "res5", "got %d != exp %d\n", + bss->handler_out5.a, 5); + CHECK(bss->handler_out5.b != 6, "res6", "got %lld != exp %d\n", + bss->handler_out5.b, 6); + +cleanup: + test_skeleton__destroy(skel); +} -- cgit v1.2.3-70-g09d2 From 330a73a7b6ca93a415de1b7da68d7a0698fe4937 Mon Sep 17 00:00:00 2001 From: Andrii Nakryiko Date: Fri, 13 Dec 2019 17:47:10 -0800 Subject: selftests/bpf: Add tests for libbpf-provided externs Add a set of tests validating libbpf-provided extern variables. One crucial feature that's tested is dead code elimination together with using invalid BPF helper. CONFIG_MISSING is not supposed to exist and should always be specified by libbpf as zero, which allows BPF verifier to correctly do branch pruning and not fail validation, when invalid BPF helper is called from dead if branch. Signed-off-by: Andrii Nakryiko Signed-off-by: Alexei Starovoitov Link: https://lore.kernel.org/bpf/20191214014710.3449601-5-andriin@fb.com --- .../testing/selftests/bpf/prog_tests/core_extern.c | 195 +++++++++++++++++++++ tools/testing/selftests/bpf/prog_tests/skeleton.c | 18 +- .../testing/selftests/bpf/progs/test_core_extern.c | 62 +++++++ tools/testing/selftests/bpf/progs/test_skeleton.c | 9 + 4 files changed, 283 insertions(+), 1 deletion(-) create mode 100644 tools/testing/selftests/bpf/prog_tests/core_extern.c create mode 100644 tools/testing/selftests/bpf/progs/test_core_extern.c (limited to 'tools/testing/selftests/bpf/prog_tests/skeleton.c') diff --git a/tools/testing/selftests/bpf/prog_tests/core_extern.c b/tools/testing/selftests/bpf/prog_tests/core_extern.c new file mode 100644 index 000000000000..30a7972e9012 --- /dev/null +++ b/tools/testing/selftests/bpf/prog_tests/core_extern.c @@ -0,0 +1,195 @@ +// SPDX-License-Identifier: GPL-2.0 +/* Copyright (c) 2019 Facebook */ + +#include +#include +#include +#include +#include "test_core_extern.skel.h" + +static uint32_t get_kernel_version(void) +{ + uint32_t major, minor, patch; + struct utsname info; + + uname(&info); + if (sscanf(info.release, "%u.%u.%u", &major, &minor, &patch) != 3) + return 0; + return KERNEL_VERSION(major, minor, patch); +} + +#define CFG "CONFIG_BPF_SYSCALL=n\n" + +static struct test_case { + const char *name; + const char *cfg; + const char *cfg_path; + bool fails; + struct test_core_extern__data data; +} test_cases[] = { + { .name = "default search path", .cfg_path = NULL, + .data = { .bpf_syscall = true } }, + { .name = "/proc/config.gz", .cfg_path = "/proc/config.gz", + .data = { .bpf_syscall = true } }, + { .name = "missing config", .fails = true, + .cfg_path = "/proc/invalid-config.gz" }, + { + .name = "custom values", + .cfg = "CONFIG_BPF_SYSCALL=y\n" + "CONFIG_TRISTATE=m\n" + "CONFIG_BOOL=y\n" + "CONFIG_CHAR=100\n" + "CONFIG_USHORT=30000\n" + "CONFIG_INT=123456\n" + "CONFIG_ULONG=0xDEADBEEFC0DE\n" + "CONFIG_STR=\"abracad\"\n" + "CONFIG_MISSING=0", + .data = { + .bpf_syscall = true, + .tristate_val = TRI_MODULE, + .bool_val = true, + .char_val = 100, + .ushort_val = 30000, + .int_val = 123456, + .ulong_val = 0xDEADBEEFC0DE, + .str_val = "abracad", + }, + }, + /* TRISTATE */ + { .name = "tristate (y)", .cfg = CFG"CONFIG_TRISTATE=y\n", + .data = { .tristate_val = TRI_YES } }, + { .name = "tristate (n)", .cfg = CFG"CONFIG_TRISTATE=n\n", + .data = { .tristate_val = TRI_NO } }, + { .name = "tristate (m)", .cfg = CFG"CONFIG_TRISTATE=m\n", + .data = { .tristate_val = TRI_MODULE } }, + { .name = "tristate (int)", .fails = 1, .cfg = CFG"CONFIG_TRISTATE=1" }, + { .name = "tristate (bad)", .fails = 1, .cfg = CFG"CONFIG_TRISTATE=M" }, + /* BOOL */ + { .name = "bool (y)", .cfg = CFG"CONFIG_BOOL=y\n", + .data = { .bool_val = true } }, + { .name = "bool (n)", .cfg = CFG"CONFIG_BOOL=n\n", + .data = { .bool_val = false } }, + { .name = "bool (tristate)", .fails = 1, .cfg = CFG"CONFIG_BOOL=m" }, + { .name = "bool (int)", .fails = 1, .cfg = CFG"CONFIG_BOOL=1" }, + /* CHAR */ + { .name = "char (tristate)", .cfg = CFG"CONFIG_CHAR=m\n", + .data = { .char_val = 'm' } }, + { .name = "char (bad)", .fails = 1, .cfg = CFG"CONFIG_CHAR=q\n" }, + { .name = "char (empty)", .fails = 1, .cfg = CFG"CONFIG_CHAR=\n" }, + { .name = "char (str)", .fails = 1, .cfg = CFG"CONFIG_CHAR=\"y\"\n" }, + /* STRING */ + { .name = "str (empty)", .cfg = CFG"CONFIG_STR=\"\"\n", + .data = { .str_val = "\0\0\0\0\0\0\0" } }, + { .name = "str (padded)", .cfg = CFG"CONFIG_STR=\"abra\"\n", + .data = { .str_val = "abra\0\0\0" } }, + { .name = "str (too long)", .cfg = CFG"CONFIG_STR=\"abracada\"\n", + .data = { .str_val = "abracad" } }, + { .name = "str (no value)", .fails = 1, .cfg = CFG"CONFIG_STR=\n" }, + { .name = "str (bad value)", .fails = 1, .cfg = CFG"CONFIG_STR=bla\n" }, + /* INTEGERS */ + { + .name = "integer forms", + .cfg = CFG + "CONFIG_CHAR=0xA\n" + "CONFIG_USHORT=0462\n" + "CONFIG_INT=-100\n" + "CONFIG_ULONG=+1000000000000", + .data = { + .char_val = 0xA, + .ushort_val = 0462, + .int_val = -100, + .ulong_val = 1000000000000, + }, + }, + { .name = "int (bad)", .fails = 1, .cfg = CFG"CONFIG_INT=abc" }, + { .name = "int (str)", .fails = 1, .cfg = CFG"CONFIG_INT=\"abc\"" }, + { .name = "int (empty)", .fails = 1, .cfg = CFG"CONFIG_INT=" }, + { .name = "int (mixed)", .fails = 1, .cfg = CFG"CONFIG_INT=123abc" }, + { .name = "int (max)", .cfg = CFG"CONFIG_INT=2147483647", + .data = { .int_val = 2147483647 } }, + { .name = "int (min)", .cfg = CFG"CONFIG_INT=-2147483648", + .data = { .int_val = -2147483648 } }, + { .name = "int (max+1)", .fails = 1, .cfg = CFG"CONFIG_INT=2147483648" }, + { .name = "int (min-1)", .fails = 1, .cfg = CFG"CONFIG_INT=-2147483649" }, + { .name = "ushort (max)", .cfg = CFG"CONFIG_USHORT=65535", + .data = { .ushort_val = 65535 } }, + { .name = "ushort (min)", .cfg = CFG"CONFIG_USHORT=0", + .data = { .ushort_val = 0 } }, + { .name = "ushort (max+1)", .fails = 1, .cfg = CFG"CONFIG_USHORT=65536" }, + { .name = "ushort (min-1)", .fails = 1, .cfg = CFG"CONFIG_USHORT=-1" }, + { .name = "u64 (max)", .cfg = CFG"CONFIG_ULONG=0xffffffffffffffff", + .data = { .ulong_val = 0xffffffffffffffff } }, + { .name = "u64 (min)", .cfg = CFG"CONFIG_ULONG=0", + .data = { .ulong_val = 0 } }, + { .name = "u64 (max+1)", .fails = 1, .cfg = CFG"CONFIG_ULONG=0x10000000000000000" }, +}; + +BPF_EMBED_OBJ(core_extern, "test_core_extern.o"); + +void test_core_extern(void) +{ + const uint32_t kern_ver = get_kernel_version(); + int err, duration = 0, i, j; + struct test_core_extern *skel = NULL; + uint64_t *got, *exp; + int n = sizeof(*skel->data) / sizeof(uint64_t); + + for (i = 0; i < ARRAY_SIZE(test_cases); i++) { + char tmp_cfg_path[] = "/tmp/test_core_extern_cfg.XXXXXX"; + struct test_case *t = &test_cases[i]; + DECLARE_LIBBPF_OPTS(bpf_object_open_opts, opts, + .kconfig_path = t->cfg_path, + ); + + if (!test__start_subtest(t->name)) + continue; + + if (t->cfg) { + size_t n = strlen(t->cfg) + 1; + int fd = mkstemp(tmp_cfg_path); + int written; + + if (CHECK(fd < 0, "mkstemp", "errno: %d\n", errno)) + continue; + printf("using '%s' as config file\n", tmp_cfg_path); + written = write(fd, t->cfg, n); + close(fd); + if (CHECK_FAIL(written != n)) + goto cleanup; + opts.kconfig_path = tmp_cfg_path; + } + + skel = test_core_extern__open_opts(&core_extern_embed, &opts); + if (CHECK(!skel, "skel_open", "skeleton open failed\n")) + goto cleanup; + err = test_core_extern__load(skel); + if (t->fails) { + CHECK(!err, "skel_load", + "shouldn't succeed open/load of skeleton\n"); + goto cleanup; + } else if (CHECK(err, "skel_load", + "failed to open/load skeleton\n")) { + goto cleanup; + } + err = test_core_extern__attach(skel); + if (CHECK(err, "attach_raw_tp", "failed attach: %d\n", err)) + goto cleanup; + + usleep(1); + + t->data.kern_ver = kern_ver; + t->data.missing_val = 0xDEADC0DE; + got = (uint64_t *)skel->data; + exp = (uint64_t *)&t->data; + for (j = 0; j < n; j++) { + CHECK(got[j] != exp[j], "check_res", + "result #%d: expected %lx, but got %lx\n", + j, exp[j], got[j]); + } +cleanup: + if (t->cfg) + unlink(tmp_cfg_path); + test_core_extern__destroy(skel); + skel = NULL; + } +} diff --git a/tools/testing/selftests/bpf/prog_tests/skeleton.c b/tools/testing/selftests/bpf/prog_tests/skeleton.c index 79f8d13e6740..151cdad3ad0d 100644 --- a/tools/testing/selftests/bpf/prog_tests/skeleton.c +++ b/tools/testing/selftests/bpf/prog_tests/skeleton.c @@ -17,11 +17,21 @@ void test_skeleton(void) int duration = 0, err; struct test_skeleton* skel; struct test_skeleton__bss *bss; + struct test_skeleton__externs *exts; - skel = test_skeleton__open_and_load(&skeleton_embed); + skel = test_skeleton__open(&skeleton_embed); if (CHECK(!skel, "skel_open", "failed to open skeleton\n")) return; + printf("EXTERNS BEFORE: %p\n", skel->externs); + if (CHECK(skel->externs, "skel_externs", "externs are mmaped()!\n")) + goto cleanup; + + err = test_skeleton__load(skel); + if (CHECK(err, "skel_load", "failed to load skeleton: %d\n", err)) + goto cleanup; + printf("EXTERNS AFTER: %p\n", skel->externs); + bss = skel->bss; bss->in1 = 1; bss->in2 = 2; @@ -29,6 +39,7 @@ void test_skeleton(void) bss->in4 = 4; bss->in5.a = 5; bss->in5.b = 6; + exts = skel->externs; err = test_skeleton__attach(skel); if (CHECK(err, "skel_attach", "skeleton attach failed: %d\n", err)) @@ -46,6 +57,11 @@ void test_skeleton(void) CHECK(bss->handler_out5.b != 6, "res6", "got %lld != exp %d\n", bss->handler_out5.b, 6); + CHECK(bss->bpf_syscall != exts->CONFIG_BPF_SYSCALL, "ext1", + "got %d != exp %d\n", bss->bpf_syscall, exts->CONFIG_BPF_SYSCALL); + CHECK(bss->kern_ver != exts->LINUX_KERNEL_VERSION, "ext2", + "got %d != exp %d\n", bss->kern_ver, exts->LINUX_KERNEL_VERSION); + cleanup: test_skeleton__destroy(skel); } diff --git a/tools/testing/selftests/bpf/progs/test_core_extern.c b/tools/testing/selftests/bpf/progs/test_core_extern.c new file mode 100644 index 000000000000..e12f09f9e881 --- /dev/null +++ b/tools/testing/selftests/bpf/progs/test_core_extern.c @@ -0,0 +1,62 @@ +// SPDX-License-Identifier: GPL-2.0 +/* Copyright (c) 2019 Facebook */ + +#include +#include +#include +#include +#include "bpf_helpers.h" + +/* non-existing BPF helper, to test dead code elimination */ +static int (*bpf_missing_helper)(const void *arg1, int arg2) = (void *) 999; + +extern int LINUX_KERNEL_VERSION; +extern bool CONFIG_BPF_SYSCALL; /* strong */ +extern enum libbpf_tristate CONFIG_TRISTATE __weak; +extern bool CONFIG_BOOL __weak; +extern char CONFIG_CHAR __weak; +extern uint16_t CONFIG_USHORT __weak; +extern int CONFIG_INT __weak; +extern uint64_t CONFIG_ULONG __weak; +extern const char CONFIG_STR[8] __weak; +extern uint64_t CONFIG_MISSING __weak; + +uint64_t kern_ver = -1; +uint64_t bpf_syscall = -1; +uint64_t tristate_val = -1; +uint64_t bool_val = -1; +uint64_t char_val = -1; +uint64_t ushort_val = -1; +uint64_t int_val = -1; +uint64_t ulong_val = -1; +char str_val[8] = {-1, -1, -1, -1, -1, -1, -1, -1}; +uint64_t missing_val = -1; + +SEC("raw_tp/sys_enter") +int handle_sys_enter(struct pt_regs *ctx) +{ + int i; + + kern_ver = LINUX_KERNEL_VERSION; + bpf_syscall = CONFIG_BPF_SYSCALL; + tristate_val = CONFIG_TRISTATE; + bool_val = CONFIG_BOOL; + char_val = CONFIG_CHAR; + ushort_val = CONFIG_USHORT; + int_val = CONFIG_INT; + ulong_val = CONFIG_ULONG; + + for (i = 0; i < sizeof(CONFIG_STR); i++) { + str_val[i] = CONFIG_STR[i]; + } + + if (CONFIG_MISSING) + /* invalid, but dead code - never executed */ + missing_val = bpf_missing_helper(ctx, 123); + else + missing_val = 0xDEADC0DE; + + return 0; +} + +char _license[] SEC("license") = "GPL"; diff --git a/tools/testing/selftests/bpf/progs/test_skeleton.c b/tools/testing/selftests/bpf/progs/test_skeleton.c index c0013d2e16f2..9caa44758ea2 100644 --- a/tools/testing/selftests/bpf/progs/test_skeleton.c +++ b/tools/testing/selftests/bpf/progs/test_skeleton.c @@ -1,6 +1,7 @@ // SPDX-License-Identifier: GPL-2.0 /* Copyright (c) 2019 Facebook */ +#include #include #include "bpf_helpers.h" @@ -20,6 +21,10 @@ char out3 = 0; long long out4 = 0; int out1 = 0; +extern bool CONFIG_BPF_SYSCALL; +extern int LINUX_KERNEL_VERSION; +bool bpf_syscall = 0; +int kern_ver = 0; SEC("raw_tp/sys_enter") int handler(const void *ctx) @@ -31,6 +36,10 @@ int handler(const void *ctx) out3 = in3; out4 = in4; out5 = in5; + + bpf_syscall = CONFIG_BPF_SYSCALL; + kern_ver = LINUX_KERNEL_VERSION; + return 0; } -- cgit v1.2.3-70-g09d2 From 5dc7a8b2114479fd945956ece9875f747a996a8e Mon Sep 17 00:00:00 2001 From: Andrii Nakryiko Date: Tue, 17 Dec 2019 21:25:50 -0800 Subject: bpftool, selftests/bpf: Embed object file inside skeleton Embed contents of BPF object file used for BPF skeleton generation inside skeleton itself. This allows to keep BPF object file and its skeleton in sync at all times, and simpifies skeleton instantiation. Also switch existing selftests to not require BPF_EMBED_OBJ anymore. Signed-off-by: Andrii Nakryiko Signed-off-by: Alexei Starovoitov Acked-by: Yonghong Song Link: https://lore.kernel.org/bpf/20191218052552.2915188-2-andriin@fb.com --- tools/bpf/bpftool/gen.c | 232 +++++++++++++-------- .../selftests/bpf/prog_tests/attach_probe.c | 4 +- .../testing/selftests/bpf/prog_tests/core_extern.c | 4 +- .../selftests/bpf/prog_tests/fentry_fexit.c | 10 +- .../testing/selftests/bpf/prog_tests/fentry_test.c | 7 +- tools/testing/selftests/bpf/prog_tests/mmap.c | 4 +- tools/testing/selftests/bpf/prog_tests/skeleton.c | 4 +- .../selftests/bpf/prog_tests/stacktrace_build_id.c | 4 +- .../bpf/prog_tests/stacktrace_build_id_nmi.c | 4 +- 9 files changed, 154 insertions(+), 119 deletions(-) (limited to 'tools/testing/selftests/bpf/prog_tests/skeleton.c') diff --git a/tools/bpf/bpftool/gen.c b/tools/bpf/bpftool/gen.c index f70088b4c19b..8d93c8f90f82 100644 --- a/tools/bpf/bpftool/gen.c +++ b/tools/bpf/bpftool/gen.c @@ -16,6 +16,7 @@ #include #include #include +#include #include #include "btf.h" @@ -261,14 +262,16 @@ static int codegen(const char *template, ...) static int do_skeleton(int argc, char **argv) { char header_guard[MAX_OBJ_NAME_LEN + sizeof("__SKEL_H__")]; - size_t i, map_cnt = 0, prog_cnt = 0; - char obj_name[MAX_OBJ_NAME_LEN]; + size_t i, map_cnt = 0, prog_cnt = 0, file_sz, mmap_sz; + DECLARE_LIBBPF_OPTS(bpf_object_open_opts, opts); + char obj_name[MAX_OBJ_NAME_LEN], *obj_data; + struct bpf_object *obj = NULL; const char *file, *ident; struct bpf_program *prog; - struct bpf_object *obj; + int fd, len, err = -1; struct bpf_map *map; struct btf *btf; - int err = -1; + struct stat st; if (!REQ_ARGS(1)) { usage(); @@ -281,14 +284,31 @@ static int do_skeleton(int argc, char **argv) return -1; } - obj = bpf_object__open_file(file, NULL); - if (IS_ERR(obj)) { - p_err("failed to open BPF object file: %ld", PTR_ERR(obj)); + if (stat(file, &st)) { + p_err("failed to stat() %s: %s", file, strerror(errno)); return -1; } - + file_sz = st.st_size; + mmap_sz = roundup(file_sz, sysconf(_SC_PAGE_SIZE)); + fd = open(file, O_RDONLY); + if (fd < 0) { + p_err("failed to open() %s: %s", file, strerror(errno)); + return -1; + } + obj_data = mmap(NULL, mmap_sz, PROT_READ, MAP_PRIVATE, fd, 0); + if (obj_data == MAP_FAILED) { + obj_data = NULL; + p_err("failed to mmap() %s: %s", file, strerror(errno)); + goto out; + } get_obj_name(obj_name, file); - get_header_guard(header_guard, obj_name); + opts.object_name = obj_name; + obj = bpf_object__open_mem(obj_data, file_sz, &opts); + if (IS_ERR(obj)) { + obj = NULL; + p_err("failed to open BPF object file: %ld", PTR_ERR(obj)); + goto out; + } bpf_object__for_each_map(map, obj) { ident = get_map_ident(map); @@ -303,8 +323,11 @@ static int do_skeleton(int argc, char **argv) prog_cnt++; } + get_header_guard(header_guard, obj_name); codegen("\ \n\ + /* SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause) */ \n\ + \n\ /* THIS FILE IS AUTOGENERATED! */ \n\ #ifndef %2$s \n\ #define %2$s \n\ @@ -356,19 +379,95 @@ static int do_skeleton(int argc, char **argv) \n\ }; \n\ \n\ - static inline struct bpf_object_skeleton * \n\ - %1$s__create_skeleton(struct %1$s *obj, struct bpf_embed_data *embed)\n\ + static void \n\ + %1$s__destroy(struct %1$s *obj) \n\ + { \n\ + if (!obj) \n\ + return; \n\ + if (obj->skeleton) \n\ + bpf_object__destroy_skeleton(obj->skeleton);\n\ + free(obj); \n\ + } \n\ + \n\ + static inline int \n\ + %1$s__create_skeleton(struct %1$s *obj); \n\ + \n\ + static inline struct %1$s * \n\ + %1$s__open_opts(const struct bpf_object_open_opts *opts) \n\ + { \n\ + struct %1$s *obj; \n\ + \n\ + obj = calloc(1, sizeof(*obj)); \n\ + if (!obj) \n\ + return NULL; \n\ + if (%1$s__create_skeleton(obj)) \n\ + goto err; \n\ + if (bpf_object__open_skeleton(obj->skeleton, opts)) \n\ + goto err; \n\ + \n\ + return obj; \n\ + err: \n\ + %1$s__destroy(obj); \n\ + return NULL; \n\ + } \n\ + \n\ + static inline struct %1$s * \n\ + %1$s__open(void) \n\ + { \n\ + return %1$s__open_opts(NULL); \n\ + } \n\ + \n\ + static inline int \n\ + %1$s__load(struct %1$s *obj) \n\ + { \n\ + return bpf_object__load_skeleton(obj->skeleton); \n\ + } \n\ + \n\ + static inline struct %1$s * \n\ + %1$s__open_and_load(void) \n\ + { \n\ + struct %1$s *obj; \n\ + \n\ + obj = %1$s__open(); \n\ + if (!obj) \n\ + return NULL; \n\ + if (%1$s__load(obj)) { \n\ + %1$s__destroy(obj); \n\ + return NULL; \n\ + } \n\ + return obj; \n\ + } \n\ + \n\ + static inline int \n\ + %1$s__attach(struct %1$s *obj) \n\ + { \n\ + return bpf_object__attach_skeleton(obj->skeleton); \n\ + } \n\ + \n\ + static inline void \n\ + %1$s__detach(struct %1$s *obj) \n\ + { \n\ + return bpf_object__detach_skeleton(obj->skeleton); \n\ + } \n\ + ", + obj_name + ); + + codegen("\ + \n\ + \n\ + static inline int \n\ + %1$s__create_skeleton(struct %1$s *obj) \n\ { \n\ struct bpf_object_skeleton *s; \n\ \n\ s = calloc(1, sizeof(*s)); \n\ if (!s) \n\ - return NULL; \n\ + return -1; \n\ + obj->skeleton = s; \n\ \n\ s->sz = sizeof(*s); \n\ s->name = \"%1$s\"; \n\ - s->data = embed->data; \n\ - s->data_sz = embed->size; \n\ s->obj = &obj->obj; \n\ ", obj_name @@ -438,90 +537,45 @@ static int do_skeleton(int argc, char **argv) codegen("\ \n\ \n\ - return s; \n\ - err: \n\ - bpf_object__destroy_skeleton(s); \n\ - return NULL; \n\ - } \n\ - \n\ - static void \n\ - %1$s__destroy(struct %1$s *obj) \n\ - { \n\ - if (!obj) \n\ - return; \n\ - if (obj->skeleton) \n\ - bpf_object__destroy_skeleton(obj->skeleton);\n\ - free(obj); \n\ - } \n\ - \n\ - static inline struct %1$s * \n\ - %1$s__open_opts(struct bpf_embed_data *embed, const struct bpf_object_open_opts *opts)\n\ - { \n\ - struct %1$s *obj; \n\ - \n\ - obj = calloc(1, sizeof(*obj)); \n\ - if (!obj) \n\ - return NULL; \n\ - \n\ - obj->skeleton = %1$s__create_skeleton(obj, embed); \n\ - if (!obj->skeleton) \n\ - goto err; \n\ - \n\ - if (bpf_object__open_skeleton(obj->skeleton, opts)) \n\ - goto err; \n\ + s->data_sz = %d; \n\ + s->data = \"\\ \n\ + ", + file_sz); + + /* embed contents of BPF object file */ + for (i = 0, len = 0; i < file_sz; i++) { + int w = obj_data[i] ? 4 : 2; + + len += w; + if (len > 78) { + printf("\\\n"); + len = w; + } + if (!obj_data[i]) + printf("\\0"); + else + printf("\\x%02x", (unsigned char)obj_data[i]); + } + + codegen("\ + \n\ + \"; \n\ \n\ - return obj; \n\ + return 0; \n\ err: \n\ - %1$s__destroy(obj); \n\ - return NULL; \n\ - } \n\ - \n\ - static inline struct %1$s * \n\ - %1$s__open(struct bpf_embed_data *embed) \n\ - { \n\ - return %1$s__open_opts(embed, NULL); \n\ - } \n\ - \n\ - static inline int \n\ - %1$s__load(struct %1$s *obj) \n\ - { \n\ - return bpf_object__load_skeleton(obj->skeleton); \n\ - } \n\ - \n\ - static inline struct %1$s * \n\ - %1$s__open_and_load(struct bpf_embed_data *embed) \n\ - { \n\ - struct %1$s *obj; \n\ - \n\ - obj = %1$s__open(embed); \n\ - if (!obj) \n\ - return NULL; \n\ - if (%1$s__load(obj)) { \n\ - %1$s__destroy(obj); \n\ - return NULL; \n\ - } \n\ - return obj; \n\ - } \n\ - \n\ - static inline int \n\ - %1$s__attach(struct %1$s *obj) \n\ - { \n\ - return bpf_object__attach_skeleton(obj->skeleton); \n\ - } \n\ - \n\ - static inline void \n\ - %1$s__detach(struct %1$s *obj) \n\ - { \n\ - return bpf_object__detach_skeleton(obj->skeleton); \n\ + bpf_object__destroy_skeleton(s); \n\ + return -1; \n\ } \n\ \n\ #endif /* %2$s */ \n\ ", - obj_name, header_guard - ); + obj_name, header_guard); err = 0; out: bpf_object__close(obj); + if (obj_data) + munmap(obj_data, mmap_sz); + close(fd); return err; } diff --git a/tools/testing/selftests/bpf/prog_tests/attach_probe.c b/tools/testing/selftests/bpf/prog_tests/attach_probe.c index 60da1d08daa0..5ed90ede2f1d 100644 --- a/tools/testing/selftests/bpf/prog_tests/attach_probe.c +++ b/tools/testing/selftests/bpf/prog_tests/attach_probe.c @@ -22,8 +22,6 @@ ssize_t get_base_addr() { return -EINVAL; } -BPF_EMBED_OBJ(probe, "test_attach_probe.o"); - void test_attach_probe(void) { int duration = 0; @@ -39,7 +37,7 @@ void test_attach_probe(void) return; uprobe_offset = (size_t)&get_base_addr - base_addr; - skel = test_attach_probe__open_and_load(&probe_embed); + skel = test_attach_probe__open_and_load(); if (CHECK(!skel, "skel_open", "failed to open skeleton\n")) return; if (CHECK(!skel->bss, "check_bss", ".bss wasn't mmap()-ed\n")) diff --git a/tools/testing/selftests/bpf/prog_tests/core_extern.c b/tools/testing/selftests/bpf/prog_tests/core_extern.c index 30a7972e9012..5f03dc1de29e 100644 --- a/tools/testing/selftests/bpf/prog_tests/core_extern.c +++ b/tools/testing/selftests/bpf/prog_tests/core_extern.c @@ -124,8 +124,6 @@ static struct test_case { { .name = "u64 (max+1)", .fails = 1, .cfg = CFG"CONFIG_ULONG=0x10000000000000000" }, }; -BPF_EMBED_OBJ(core_extern, "test_core_extern.o"); - void test_core_extern(void) { const uint32_t kern_ver = get_kernel_version(); @@ -159,7 +157,7 @@ void test_core_extern(void) opts.kconfig_path = tmp_cfg_path; } - skel = test_core_extern__open_opts(&core_extern_embed, &opts); + skel = test_core_extern__open_opts(&opts); if (CHECK(!skel, "skel_open", "skeleton open failed\n")) goto cleanup; err = test_core_extern__load(skel); diff --git a/tools/testing/selftests/bpf/prog_tests/fentry_fexit.c b/tools/testing/selftests/bpf/prog_tests/fentry_fexit.c index 110fcf053fd0..235ac4f67f5b 100644 --- a/tools/testing/selftests/bpf/prog_tests/fentry_fexit.c +++ b/tools/testing/selftests/bpf/prog_tests/fentry_fexit.c @@ -5,10 +5,6 @@ #include "fentry_test.skel.h" #include "fexit_test.skel.h" -BPF_EMBED_OBJ(pkt_access, "test_pkt_access.o"); -BPF_EMBED_OBJ(fentry, "fentry_test.o"); -BPF_EMBED_OBJ(fexit, "fexit_test.o"); - void test_fentry_fexit(void) { struct test_pkt_access *pkt_skel = NULL; @@ -18,13 +14,13 @@ void test_fentry_fexit(void) __u32 duration = 0, retval; int err, pkt_fd, i; - pkt_skel = test_pkt_access__open_and_load(&pkt_access_embed); + pkt_skel = test_pkt_access__open_and_load(); if (CHECK(!pkt_skel, "pkt_skel_load", "pkt_access skeleton failed\n")) return; - fentry_skel = fentry_test__open_and_load(&fentry_embed); + fentry_skel = fentry_test__open_and_load(); if (CHECK(!fentry_skel, "fentry_skel_load", "fentry skeleton failed\n")) goto close_prog; - fexit_skel = fexit_test__open_and_load(&fexit_embed); + fexit_skel = fexit_test__open_and_load(); if (CHECK(!fexit_skel, "fexit_skel_load", "fexit skeleton failed\n")) goto close_prog; diff --git a/tools/testing/selftests/bpf/prog_tests/fentry_test.c b/tools/testing/selftests/bpf/prog_tests/fentry_test.c index 46a4afdf507a..e1a379f5f7d2 100644 --- a/tools/testing/selftests/bpf/prog_tests/fentry_test.c +++ b/tools/testing/selftests/bpf/prog_tests/fentry_test.c @@ -4,9 +4,6 @@ #include "test_pkt_access.skel.h" #include "fentry_test.skel.h" -BPF_EMBED_OBJ_DECLARE(pkt_access); -BPF_EMBED_OBJ_DECLARE(fentry); - void test_fentry_test(void) { struct test_pkt_access *pkt_skel = NULL; @@ -15,10 +12,10 @@ void test_fentry_test(void) __u32 duration, retval; __u64 *result; - pkt_skel = test_pkt_access__open_and_load(&pkt_access_embed); + pkt_skel = test_pkt_access__open_and_load(); if (CHECK(!pkt_skel, "pkt_skel_load", "pkt_access skeleton failed\n")) return; - fentry_skel = fentry_test__open_and_load(&fentry_embed); + fentry_skel = fentry_test__open_and_load(); if (CHECK(!fentry_skel, "fentry_skel_load", "fentry skeleton failed\n")) goto cleanup; diff --git a/tools/testing/selftests/bpf/prog_tests/mmap.c b/tools/testing/selftests/bpf/prog_tests/mmap.c index 95a44d37ccea..16a814eb4d64 100644 --- a/tools/testing/selftests/bpf/prog_tests/mmap.c +++ b/tools/testing/selftests/bpf/prog_tests/mmap.c @@ -13,8 +13,6 @@ static size_t roundup_page(size_t sz) return (sz + page_size - 1) / page_size * page_size; } -BPF_EMBED_OBJ(test_mmap, "test_mmap.o"); - void test_mmap(void) { const size_t bss_sz = roundup_page(sizeof(struct test_mmap__bss)); @@ -30,7 +28,7 @@ void test_mmap(void) __u64 val = 0; - skel = test_mmap__open_and_load(&test_mmap_embed); + skel = test_mmap__open_and_load(); if (CHECK(!skel, "skel_open_and_load", "skeleton open/load failed\n")) return; diff --git a/tools/testing/selftests/bpf/prog_tests/skeleton.c b/tools/testing/selftests/bpf/prog_tests/skeleton.c index 151cdad3ad0d..ec6f2aec3853 100644 --- a/tools/testing/selftests/bpf/prog_tests/skeleton.c +++ b/tools/testing/selftests/bpf/prog_tests/skeleton.c @@ -10,8 +10,6 @@ struct s { #include "test_skeleton.skel.h" -BPF_EMBED_OBJ(skeleton, "test_skeleton.o"); - void test_skeleton(void) { int duration = 0, err; @@ -19,7 +17,7 @@ void test_skeleton(void) struct test_skeleton__bss *bss; struct test_skeleton__externs *exts; - skel = test_skeleton__open(&skeleton_embed); + skel = test_skeleton__open(); if (CHECK(!skel, "skel_open", "failed to open skeleton\n")) return; diff --git a/tools/testing/selftests/bpf/prog_tests/stacktrace_build_id.c b/tools/testing/selftests/bpf/prog_tests/stacktrace_build_id.c index 4af8b8253f25..e8399ae50e77 100644 --- a/tools/testing/selftests/bpf/prog_tests/stacktrace_build_id.c +++ b/tools/testing/selftests/bpf/prog_tests/stacktrace_build_id.c @@ -2,8 +2,6 @@ #include #include "test_stacktrace_build_id.skel.h" -BPF_EMBED_OBJ(stacktrace_build_id, "test_stacktrace_build_id.o"); - void test_stacktrace_build_id(void) { @@ -18,7 +16,7 @@ void test_stacktrace_build_id(void) int retry = 1; retry: - skel = test_stacktrace_build_id__open_and_load(&stacktrace_build_id_embed); + skel = test_stacktrace_build_id__open_and_load(); if (CHECK(!skel, "skel_open_and_load", "skeleton open/load failed\n")) return; diff --git a/tools/testing/selftests/bpf/prog_tests/stacktrace_build_id_nmi.c b/tools/testing/selftests/bpf/prog_tests/stacktrace_build_id_nmi.c index 32fb03881a7b..8974450a4bdb 100644 --- a/tools/testing/selftests/bpf/prog_tests/stacktrace_build_id_nmi.c +++ b/tools/testing/selftests/bpf/prog_tests/stacktrace_build_id_nmi.c @@ -15,8 +15,6 @@ static __u64 read_perf_max_sample_freq(void) return sample_freq; } -BPF_EMBED_OBJ_DECLARE(stacktrace_build_id); - void test_stacktrace_build_id_nmi(void) { int control_map_fd, stackid_hmap_fd, stackmap_fd; @@ -37,7 +35,7 @@ void test_stacktrace_build_id_nmi(void) attr.sample_freq = read_perf_max_sample_freq(); retry: - skel = test_stacktrace_build_id__open(&stacktrace_build_id_embed); + skel = test_stacktrace_build_id__open(); if (CHECK(!skel, "skel_open", "skeleton open failed\n")) return; -- cgit v1.2.3-70-g09d2 From 81bfdd087bf31a87c5ff25cc7004d5308954a35c Mon Sep 17 00:00:00 2001 From: Andrii Nakryiko Date: Wed, 18 Dec 2019 16:28:34 -0800 Subject: libbpf: Put Kconfig externs into .kconfig section Move Kconfig-provided externs into custom .kconfig section. Add __kconfig into bpf_helpers.h for user convenience. Update selftests accordingly. Suggested-by: Daniel Borkmann Signed-off-by: Andrii Nakryiko Signed-off-by: Alexei Starovoitov Link: https://lore.kernel.org/bpf/20191219002837.3074619-2-andriin@fb.com --- tools/bpf/bpftool/gen.c | 8 +-- tools/lib/bpf/bpf_helpers.h | 2 + tools/lib/bpf/libbpf.c | 58 +++++++++++++--------- tools/testing/selftests/bpf/prog_tests/skeleton.c | 16 +++--- .../testing/selftests/bpf/progs/test_core_extern.c | 20 ++++---- tools/testing/selftests/bpf/progs/test_skeleton.c | 4 +- 6 files changed, 60 insertions(+), 48 deletions(-) (limited to 'tools/testing/selftests/bpf/prog_tests/skeleton.c') diff --git a/tools/bpf/bpftool/gen.c b/tools/bpf/bpftool/gen.c index 851c465f99dc..a14d8bc5d31d 100644 --- a/tools/bpf/bpftool/gen.c +++ b/tools/bpf/bpftool/gen.c @@ -83,8 +83,8 @@ static const char *get_map_ident(const struct bpf_map *map) return "rodata"; else if (str_has_suffix(name, ".bss")) return "bss"; - else if (str_has_suffix(name, ".extern")) - return "externs"; /* extern is a C keyword */ + else if (str_has_suffix(name, ".kconfig")) + return "kconfig"; else return NULL; } @@ -112,8 +112,8 @@ static int codegen_datasec_def(struct bpf_object *obj, sec_ident = "bss"; else if (strcmp(sec_name, ".rodata") == 0) sec_ident = "rodata"; - else if (strcmp(sec_name, ".extern") == 0) - sec_ident = "externs"; /* extern is a C keyword */ + else if (strcmp(sec_name, ".kconfig") == 0) + sec_ident = "kconfig"; else return 0; diff --git a/tools/lib/bpf/bpf_helpers.h b/tools/lib/bpf/bpf_helpers.h index aa46700075e1..f69cc208778a 100644 --- a/tools/lib/bpf/bpf_helpers.h +++ b/tools/lib/bpf/bpf_helpers.h @@ -53,4 +53,6 @@ enum libbpf_tristate { TRI_MODULE = 2, }; +#define __kconfig __attribute__((section(".kconfig"))) + #endif diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c index 2a341a5b9f63..0772eb3254e2 100644 --- a/tools/lib/bpf/libbpf.c +++ b/tools/lib/bpf/libbpf.c @@ -231,21 +231,21 @@ struct bpf_program { #define DATA_SEC ".data" #define BSS_SEC ".bss" #define RODATA_SEC ".rodata" -#define EXTERN_SEC ".extern" +#define KCONFIG_SEC ".kconfig" enum libbpf_map_type { LIBBPF_MAP_UNSPEC, LIBBPF_MAP_DATA, LIBBPF_MAP_BSS, LIBBPF_MAP_RODATA, - LIBBPF_MAP_EXTERN, + LIBBPF_MAP_KCONFIG, }; static const char * const libbpf_type_to_btf_name[] = { [LIBBPF_MAP_DATA] = DATA_SEC, [LIBBPF_MAP_BSS] = BSS_SEC, [LIBBPF_MAP_RODATA] = RODATA_SEC, - [LIBBPF_MAP_EXTERN] = EXTERN_SEC, + [LIBBPF_MAP_KCONFIG] = KCONFIG_SEC, }; struct bpf_map { @@ -305,7 +305,7 @@ struct bpf_object { char *kconfig_path; struct extern_desc *externs; int nr_extern; - int extern_map_idx; + int kconfig_map_idx; bool loaded; bool has_pseudo_calls; @@ -606,7 +606,7 @@ static struct bpf_object *bpf_object__new(const char *path, obj->efile.data_shndx = -1; obj->efile.rodata_shndx = -1; obj->efile.bss_shndx = -1; - obj->extern_map_idx = -1; + obj->kconfig_map_idx = -1; obj->kern_version = get_kernel_version(); obj->loaded = false; @@ -902,11 +902,25 @@ static size_t bpf_map_mmap_sz(const struct bpf_map *map) return map_sz; } +static char *internal_map_name(struct bpf_object *obj, + enum libbpf_map_type type) +{ + char map_name[BPF_OBJ_NAME_LEN]; + const char *sfx = libbpf_type_to_btf_name[type]; + int sfx_len = max((size_t)7, strlen(sfx)); + int pfx_len = min((size_t)BPF_OBJ_NAME_LEN - sfx_len - 1, + strlen(obj->name)); + + snprintf(map_name, sizeof(map_name), "%.*s%.*s", pfx_len, obj->name, + sfx_len, libbpf_type_to_btf_name[type]); + + return strdup(map_name); +} + static int bpf_object__init_internal_map(struct bpf_object *obj, enum libbpf_map_type type, int sec_idx, void *data, size_t data_sz) { - char map_name[BPF_OBJ_NAME_LEN]; struct bpf_map_def *def; struct bpf_map *map; int err; @@ -918,9 +932,7 @@ bpf_object__init_internal_map(struct bpf_object *obj, enum libbpf_map_type type, map->libbpf_type = type; map->sec_idx = sec_idx; map->sec_offset = 0; - snprintf(map_name, sizeof(map_name), "%.8s%.7s", obj->name, - libbpf_type_to_btf_name[type]); - map->name = strdup(map_name); + map->name = internal_map_name(obj, type); if (!map->name) { pr_warn("failed to alloc map name\n"); return -ENOMEM; @@ -931,12 +943,12 @@ bpf_object__init_internal_map(struct bpf_object *obj, enum libbpf_map_type type, def->key_size = sizeof(int); def->value_size = data_sz; def->max_entries = 1; - def->map_flags = type == LIBBPF_MAP_RODATA || type == LIBBPF_MAP_EXTERN + def->map_flags = type == LIBBPF_MAP_RODATA || type == LIBBPF_MAP_KCONFIG ? BPF_F_RDONLY_PROG : 0; def->map_flags |= BPF_F_MMAPABLE; pr_debug("map '%s' (global data): at sec_idx %d, offset %zu, flags %x.\n", - map_name, map->sec_idx, map->sec_offset, def->map_flags); + map->name, map->sec_idx, map->sec_offset, def->map_flags); map->mmaped = mmap(NULL, bpf_map_mmap_sz(map), PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS, -1, 0); @@ -1232,7 +1244,7 @@ out: return err; } -static int bpf_object__init_extern_map(struct bpf_object *obj) +static int bpf_object__init_kconfig_map(struct bpf_object *obj) { struct extern_desc *last_ext; size_t map_sz; @@ -1244,13 +1256,13 @@ static int bpf_object__init_extern_map(struct bpf_object *obj) last_ext = &obj->externs[obj->nr_extern - 1]; map_sz = last_ext->data_off + last_ext->sz; - err = bpf_object__init_internal_map(obj, LIBBPF_MAP_EXTERN, + err = bpf_object__init_internal_map(obj, LIBBPF_MAP_KCONFIG, obj->efile.symbols_shndx, NULL, map_sz); if (err) return err; - obj->extern_map_idx = obj->nr_maps - 1; + obj->kconfig_map_idx = obj->nr_maps - 1; return 0; } @@ -1742,7 +1754,7 @@ static int bpf_object__init_maps(struct bpf_object *obj, err = bpf_object__init_user_maps(obj, strict); err = err ?: bpf_object__init_user_btf_maps(obj, strict, pin_root_path); err = err ?: bpf_object__init_global_data_maps(obj); - err = err ?: bpf_object__init_extern_map(obj); + err = err ?: bpf_object__init_kconfig_map(obj); if (err) return err; @@ -2269,9 +2281,9 @@ static int bpf_object__collect_externs(struct bpf_object *obj) i, ext->sym_idx, ext->data_off, ext->name); } - btf_id = btf__find_by_name(obj->btf, EXTERN_SEC); + btf_id = btf__find_by_name(obj->btf, KCONFIG_SEC); if (btf_id <= 0) { - pr_warn("no BTF info found for '%s' datasec\n", EXTERN_SEC); + pr_warn("no BTF info found for '%s' datasec\n", KCONFIG_SEC); return -ESRCH; } @@ -2361,7 +2373,7 @@ bpf_object__section_to_libbpf_map_type(const struct bpf_object *obj, int shndx) else if (shndx == obj->efile.rodata_shndx) return LIBBPF_MAP_RODATA; else if (shndx == obj->efile.symbols_shndx) - return LIBBPF_MAP_EXTERN; + return LIBBPF_MAP_KCONFIG; else return LIBBPF_MAP_UNSPEC; } @@ -2908,8 +2920,8 @@ bpf_object__populate_internal_map(struct bpf_object *obj, struct bpf_map *map) return err; } - /* Freeze .rodata and .extern map as read-only from syscall side. */ - if (map_type == LIBBPF_MAP_RODATA || map_type == LIBBPF_MAP_EXTERN) { + /* Freeze .rodata and .kconfig map as read-only from syscall side. */ + if (map_type == LIBBPF_MAP_RODATA || map_type == LIBBPF_MAP_KCONFIG) { err = bpf_map_freeze(map->fd); if (err) { err = -errno; @@ -4264,7 +4276,7 @@ bpf_program__relocate(struct bpf_program *prog, struct bpf_object *obj) break; case RELO_EXTERN: insn[0].src_reg = BPF_PSEUDO_MAP_VALUE; - insn[0].imm = obj->maps[obj->extern_map_idx].fd; + insn[0].imm = obj->maps[obj->kconfig_map_idx].fd; insn[1].imm = relo->sym_off; break; case RELO_CALL: @@ -4743,7 +4755,7 @@ static int bpf_object__resolve_externs(struct bpf_object *obj, if (obj->nr_extern == 0) return 0; - data = obj->maps[obj->extern_map_idx].mmaped; + data = obj->maps[obj->kconfig_map_idx].mmaped; for (i = 0; i < obj->nr_extern; i++) { ext = &obj->externs[i]; @@ -7546,7 +7558,7 @@ int bpf_object__open_skeleton(struct bpf_object_skeleton *s, } /* externs shouldn't be pre-setup from user code */ - if (mmaped && (*map)->libbpf_type != LIBBPF_MAP_EXTERN) + if (mmaped && (*map)->libbpf_type != LIBBPF_MAP_KCONFIG) *mmaped = (*map)->mmaped; } diff --git a/tools/testing/selftests/bpf/prog_tests/skeleton.c b/tools/testing/selftests/bpf/prog_tests/skeleton.c index ec6f2aec3853..9264a2736018 100644 --- a/tools/testing/selftests/bpf/prog_tests/skeleton.c +++ b/tools/testing/selftests/bpf/prog_tests/skeleton.c @@ -15,20 +15,18 @@ void test_skeleton(void) int duration = 0, err; struct test_skeleton* skel; struct test_skeleton__bss *bss; - struct test_skeleton__externs *exts; + struct test_skeleton__kconfig *kcfg; skel = test_skeleton__open(); if (CHECK(!skel, "skel_open", "failed to open skeleton\n")) return; - printf("EXTERNS BEFORE: %p\n", skel->externs); - if (CHECK(skel->externs, "skel_externs", "externs are mmaped()!\n")) + if (CHECK(skel->kconfig, "skel_kconfig", "kconfig is mmaped()!\n")) goto cleanup; err = test_skeleton__load(skel); if (CHECK(err, "skel_load", "failed to load skeleton: %d\n", err)) goto cleanup; - printf("EXTERNS AFTER: %p\n", skel->externs); bss = skel->bss; bss->in1 = 1; @@ -37,7 +35,7 @@ void test_skeleton(void) bss->in4 = 4; bss->in5.a = 5; bss->in5.b = 6; - exts = skel->externs; + kcfg = skel->kconfig; err = test_skeleton__attach(skel); if (CHECK(err, "skel_attach", "skeleton attach failed: %d\n", err)) @@ -55,10 +53,10 @@ void test_skeleton(void) CHECK(bss->handler_out5.b != 6, "res6", "got %lld != exp %d\n", bss->handler_out5.b, 6); - CHECK(bss->bpf_syscall != exts->CONFIG_BPF_SYSCALL, "ext1", - "got %d != exp %d\n", bss->bpf_syscall, exts->CONFIG_BPF_SYSCALL); - CHECK(bss->kern_ver != exts->LINUX_KERNEL_VERSION, "ext2", - "got %d != exp %d\n", bss->kern_ver, exts->LINUX_KERNEL_VERSION); + CHECK(bss->bpf_syscall != kcfg->CONFIG_BPF_SYSCALL, "ext1", + "got %d != exp %d\n", bss->bpf_syscall, kcfg->CONFIG_BPF_SYSCALL); + CHECK(bss->kern_ver != kcfg->LINUX_KERNEL_VERSION, "ext2", + "got %d != exp %d\n", bss->kern_ver, kcfg->LINUX_KERNEL_VERSION); cleanup: test_skeleton__destroy(skel); diff --git a/tools/testing/selftests/bpf/progs/test_core_extern.c b/tools/testing/selftests/bpf/progs/test_core_extern.c index e12f09f9e881..9bfc91d9d004 100644 --- a/tools/testing/selftests/bpf/progs/test_core_extern.c +++ b/tools/testing/selftests/bpf/progs/test_core_extern.c @@ -10,16 +10,16 @@ /* non-existing BPF helper, to test dead code elimination */ static int (*bpf_missing_helper)(const void *arg1, int arg2) = (void *) 999; -extern int LINUX_KERNEL_VERSION; -extern bool CONFIG_BPF_SYSCALL; /* strong */ -extern enum libbpf_tristate CONFIG_TRISTATE __weak; -extern bool CONFIG_BOOL __weak; -extern char CONFIG_CHAR __weak; -extern uint16_t CONFIG_USHORT __weak; -extern int CONFIG_INT __weak; -extern uint64_t CONFIG_ULONG __weak; -extern const char CONFIG_STR[8] __weak; -extern uint64_t CONFIG_MISSING __weak; +extern int LINUX_KERNEL_VERSION __kconfig; +extern bool CONFIG_BPF_SYSCALL __kconfig; /* strong */ +extern enum libbpf_tristate CONFIG_TRISTATE __kconfig __weak; +extern bool CONFIG_BOOL __kconfig __weak; +extern char CONFIG_CHAR __kconfig __weak; +extern uint16_t CONFIG_USHORT __kconfig __weak; +extern int CONFIG_INT __kconfig __weak; +extern uint64_t CONFIG_ULONG __kconfig __weak; +extern const char CONFIG_STR[8] __kconfig __weak; +extern uint64_t CONFIG_MISSING __kconfig __weak; uint64_t kern_ver = -1; uint64_t bpf_syscall = -1; diff --git a/tools/testing/selftests/bpf/progs/test_skeleton.c b/tools/testing/selftests/bpf/progs/test_skeleton.c index 9caa44758ea2..4f69aac5635f 100644 --- a/tools/testing/selftests/bpf/progs/test_skeleton.c +++ b/tools/testing/selftests/bpf/progs/test_skeleton.c @@ -21,8 +21,8 @@ char out3 = 0; long long out4 = 0; int out1 = 0; -extern bool CONFIG_BPF_SYSCALL; -extern int LINUX_KERNEL_VERSION; +extern bool CONFIG_BPF_SYSCALL __kconfig; +extern int LINUX_KERNEL_VERSION __kconfig; bool bpf_syscall = 0; int kern_ver = 0; -- cgit v1.2.3-70-g09d2