From patchwork Fri Apr 23 18:53:52 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andrii Nakryiko X-Patchwork-Id: 426653 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-17.0 required=3.0 tests=BAYES_00, INCLUDES_CR_TRAILER, INCLUDES_PATCH, MAILING_LIST_MULTI, SPF_HELO_NONE, SPF_PASS, USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id BB689C43461 for ; Fri, 23 Apr 2021 18:54:05 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 8A5E26145A for ; Fri, 23 Apr 2021 18:54:05 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S243532AbhDWSyl convert rfc822-to-8bit (ORCPT ); Fri, 23 Apr 2021 14:54:41 -0400 Received: from mx0b-00082601.pphosted.com ([67.231.153.30]:59004 "EHLO mx0b-00082601.pphosted.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231735AbhDWSyk (ORCPT ); Fri, 23 Apr 2021 14:54:40 -0400 Received: from pps.filterd (m0109332.ppops.net [127.0.0.1]) by mx0a-00082601.pphosted.com (8.16.0.43/8.16.0.43) with SMTP id 13NIPPGE032277 for ; Fri, 23 Apr 2021 11:54:03 -0700 Received: from mail.thefacebook.com ([163.114.132.120]) by mx0a-00082601.pphosted.com with ESMTP id 3839usrt90-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NOT) for ; Fri, 23 Apr 2021 11:54:03 -0700 Received: from intmgw001.06.ash9.facebook.com (2620:10d:c085:208::11) by mail.thefacebook.com (2620:10d:c085:11d::5) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2176.2; Fri, 23 Apr 2021 11:54:02 -0700 Received: by devbig012.ftw2.facebook.com (Postfix, from userid 137359) id 4A33E2ED5CA8; Fri, 23 Apr 2021 11:54:01 -0700 (PDT) From: Andrii Nakryiko To: , , , CC: , Subject: [PATCH v2 bpf-next 1/6] bpftool: strip const/volatile/restrict modifiers from .bss and .data vars Date: Fri, 23 Apr 2021 11:53:52 -0700 Message-ID: <20210423185357.1992756-2-andrii@kernel.org> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20210423185357.1992756-1-andrii@kernel.org> References: <20210423185357.1992756-1-andrii@kernel.org> MIME-Version: 1.0 X-FB-Internal: Safe X-Proofpoint-GUID: GagLfQvJ2_SB_BzSCOwep09MRYiNy2DW X-Proofpoint-ORIG-GUID: GagLfQvJ2_SB_BzSCOwep09MRYiNy2DW X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10434:6.0.391, 18.0.761 definitions=2021-04-23_07:2021-04-23,2021-04-23 signatures=0 X-Proofpoint-Spam-Details: rule=fb_default_notspam policy=fb_default score=0 priorityscore=1501 impostorscore=0 adultscore=0 mlxlogscore=784 clxscore=1015 lowpriorityscore=0 mlxscore=0 malwarescore=0 suspectscore=0 spamscore=0 phishscore=0 bulkscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2104060000 definitions=main-2104230121 X-FB-Internal: deliver Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org Similarly to .rodata, strip any const/volatile/restrict modifiers when generating BPF skeleton. They are not helpful and actually just get in the way. Signed-off-by: Andrii Nakryiko Acked-by: Yonghong Song --- tools/bpf/bpftool/gen.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tools/bpf/bpftool/gen.c b/tools/bpf/bpftool/gen.c index 31ade77f5ef8..440a2fcb6441 100644 --- a/tools/bpf/bpftool/gen.c +++ b/tools/bpf/bpftool/gen.c @@ -106,8 +106,10 @@ static int codegen_datasec_def(struct bpf_object *obj, if (strcmp(sec_name, ".data") == 0) { sec_ident = "data"; + strip_mods = true; } else if (strcmp(sec_name, ".bss") == 0) { sec_ident = "bss"; + strip_mods = true; } else if (strcmp(sec_name, ".rodata") == 0) { sec_ident = "rodata"; strip_mods = true; From patchwork Fri Apr 23 18:53:53 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andrii Nakryiko X-Patchwork-Id: 426652 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-17.0 required=3.0 tests=BAYES_00, INCLUDES_CR_TRAILER, INCLUDES_PATCH, MAILING_LIST_MULTI, SPF_HELO_NONE, SPF_PASS, USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 52190C433ED for ; Fri, 23 Apr 2021 18:54:14 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 3471C6145A for ; Fri, 23 Apr 2021 18:54:14 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S243698AbhDWSyu convert rfc822-to-8bit (ORCPT ); Fri, 23 Apr 2021 14:54:50 -0400 Received: from mx0b-00082601.pphosted.com ([67.231.153.30]:33578 "EHLO mx0a-00082601.pphosted.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S243582AbhDWSyp (ORCPT ); Fri, 23 Apr 2021 14:54:45 -0400 Received: from pps.filterd (m0089730.ppops.net [127.0.0.1]) by m0089730.ppops.net (8.16.0.43/8.16.0.43) with SMTP id 13NIPeB8025210 for ; Fri, 23 Apr 2021 11:54:08 -0700 Received: from maileast.thefacebook.com ([163.114.130.16]) by m0089730.ppops.net with ESMTP id 383h1unsyh-3 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NOT) for ; Fri, 23 Apr 2021 11:54:08 -0700 Received: from intmgw006.03.ash8.facebook.com (2620:10d:c0a8:1b::d) by mail.thefacebook.com (2620:10d:c0a8:82::e) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2176.2; Fri, 23 Apr 2021 11:54:06 -0700 Received: by devbig012.ftw2.facebook.com (Postfix, from userid 137359) id 567682ED5CA8; Fri, 23 Apr 2021 11:54:03 -0700 (PDT) From: Andrii Nakryiko To: , , , CC: , Subject: [PATCH v2 bpf-next 2/6] libbpf: rename static variables during linking Date: Fri, 23 Apr 2021 11:53:53 -0700 Message-ID: <20210423185357.1992756-3-andrii@kernel.org> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20210423185357.1992756-1-andrii@kernel.org> References: <20210423185357.1992756-1-andrii@kernel.org> MIME-Version: 1.0 X-FB-Internal: Safe X-Proofpoint-GUID: BLSQUCS3UjZX8kFTJBsc3El1M-ht7EMN X-Proofpoint-ORIG-GUID: BLSQUCS3UjZX8kFTJBsc3El1M-ht7EMN X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10434:6.0.391, 18.0.761 definitions=2021-04-23_07:2021-04-23,2021-04-23 signatures=0 X-Proofpoint-Spam-Details: rule=fb_default_notspam policy=fb_default score=0 clxscore=1015 adultscore=0 malwarescore=0 mlxscore=0 spamscore=0 bulkscore=0 phishscore=0 impostorscore=0 priorityscore=1501 lowpriorityscore=0 mlxlogscore=999 suspectscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2104060000 definitions=main-2104230121 X-FB-Internal: deliver Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org Prepend .. prefix to each static variable in BTF info during static linking. This makes them uniquely named for the sake of BPF skeleton use, allowing to read/write static BPF variables from user-space. This uniqueness guarantee depends on each linked file name uniqueness, of course. Double dots separator was chosen both to be different (but similar) to the separator that Clang is currently using for static variables defined inside functions as well as to generate a natural (in libbpf parlance, at least) obj__var naming pattern in BPF skeleton. Static linker also checks for static variable to already contain ".." separator and skips the rename to allow multi-pass linking and not keep making variable name ever increasing, if derived object name is changing on each pass (as is the case for selftests). This patch also adds opts to bpf_linker__add_file() API, which currently allows to override object name for a given file and could be extended with other per-file options in the future. This is not a breaking change because bpf_linker__add_file() isn't yet released officially. This patch also includes fixes to few selftests that are already using static variables. They have to go in in the same patch to not break selftest build. Keep in mind, this static variable rename only happens during static linking. For any existing user of BPF skeleton using static variables nothing changes, because those use cases are using variable names generated by Clang. Only new users utilizing static linker might need to adjust BPF skeleton use, which currently will be always new use cases. So ther is no risk of breakage. static_linked selftests is modified to also validate conflicting static variable names are handled correctly both during static linking and in BPF skeleton. Signed-off-by: Andrii Nakryiko --- tools/bpf/bpftool/gen.c | 2 +- tools/lib/bpf/libbpf.h | 12 +- tools/lib/bpf/linker.c | 121 +++++++++++++++++- .../selftests/bpf/prog_tests/skeleton.c | 8 +- .../selftests/bpf/prog_tests/static_linked.c | 8 +- .../selftests/bpf/progs/bpf_iter_test_kern4.c | 4 +- .../selftests/bpf/progs/test_check_mtu.c | 4 +- .../selftests/bpf/progs/test_cls_redirect.c | 4 +- .../bpf/progs/test_snprintf_single.c | 2 +- .../selftests/bpf/progs/test_sockmap_listen.c | 4 +- .../selftests/bpf/progs/test_static_linked1.c | 6 +- .../selftests/bpf/progs/test_static_linked2.c | 4 +- 12 files changed, 151 insertions(+), 28 deletions(-) diff --git a/tools/bpf/bpftool/gen.c b/tools/bpf/bpftool/gen.c index 440a2fcb6441..06fee4a2910a 100644 --- a/tools/bpf/bpftool/gen.c +++ b/tools/bpf/bpftool/gen.c @@ -638,7 +638,7 @@ static int do_object(int argc, char **argv) while (argc) { file = GET_ARG(); - err = bpf_linker__add_file(linker, file); + err = bpf_linker__add_file(linker, file, NULL); if (err) { p_err("failed to link '%s': %s (%d)", file, strerror(err), err); goto out; diff --git a/tools/lib/bpf/libbpf.h b/tools/lib/bpf/libbpf.h index bec4e6a6e31d..67505030c8d1 100644 --- a/tools/lib/bpf/libbpf.h +++ b/tools/lib/bpf/libbpf.h @@ -768,10 +768,20 @@ struct bpf_linker_opts { }; #define bpf_linker_opts__last_field sz +struct bpf_linker_file_opts { + /* size of this struct, for forward/backward compatiblity */ + size_t sz; + /* object name override, similar to the one in bpf_object_open_opts */ + const char *object_name; +}; +#define bpf_linker_file_opts__last_field sz + struct bpf_linker; LIBBPF_API struct bpf_linker *bpf_linker__new(const char *filename, struct bpf_linker_opts *opts); -LIBBPF_API int bpf_linker__add_file(struct bpf_linker *linker, const char *filename); +LIBBPF_API int bpf_linker__add_file(struct bpf_linker *linker, + const char *filename, + const struct bpf_linker_file_opts *opts); LIBBPF_API int bpf_linker__finalize(struct bpf_linker *linker); LIBBPF_API void bpf_linker__free(struct bpf_linker *linker); diff --git a/tools/lib/bpf/linker.c b/tools/lib/bpf/linker.c index 9de084b1c699..adc3aa9ce040 100644 --- a/tools/lib/bpf/linker.c +++ b/tools/lib/bpf/linker.c @@ -4,6 +4,8 @@ * * Copyright (c) 2021 Facebook */ +#define _GNU_SOURCE +#include #include #include #include @@ -47,6 +49,16 @@ struct src_sec { int sec_type_id; }; +#define MAX_OBJ_NAME_LEN 64 + +/* According to C standard, only first 63 characters of C identifiers are + * guaranteed to be significant. So for transformed static variables of the most + * verbose form ('...') we need to reserve extra + * 64 (function name and dot) + 63 (variable name) + 2 (for .. separator) + * characters. + */ +#define MAX_VAR_NAME_LEN (MAX_OBJ_NAME_LEN + 2 + 63 + 1 + 63) + struct src_obj { const char *filename; int fd; @@ -67,6 +79,10 @@ struct src_obj { int *sym_map; /* mapping from the src BTF type IDs to dst ones */ int *btf_type_map; + + /* BPF object name used for static variable prefixing */ + char obj_name[MAX_OBJ_NAME_LEN]; + size_t obj_name_len; }; /* single .BTF.ext data section */ @@ -158,7 +174,9 @@ struct bpf_linker { static int init_output_elf(struct bpf_linker *linker, const char *file); -static int linker_load_obj_file(struct bpf_linker *linker, const char *filename, struct src_obj *obj); +static int linker_load_obj_file(struct bpf_linker *linker, const char *filename, + const struct bpf_linker_file_opts *opts, + struct src_obj *obj); static int linker_sanity_check_elf(struct src_obj *obj); static int linker_sanity_check_elf_symtab(struct src_obj *obj, struct src_sec *sec); static int linker_sanity_check_elf_relos(struct src_obj *obj, struct src_sec *sec); @@ -435,15 +453,19 @@ static int init_output_elf(struct bpf_linker *linker, const char *file) return 0; } -int bpf_linker__add_file(struct bpf_linker *linker, const char *filename) +int bpf_linker__add_file(struct bpf_linker *linker, const char *filename, + const struct bpf_linker_file_opts *opts) { struct src_obj obj = {}; int err = 0; + if (!OPTS_VALID(opts, bpf_linker_file_opts)) + return -EINVAL; + if (!linker->elf) return -EINVAL; - err = err ?: linker_load_obj_file(linker, filename, &obj); + err = err ?: linker_load_obj_file(linker, filename, opts, &obj); err = err ?: linker_append_sec_data(linker, &obj); err = err ?: linker_append_elf_syms(linker, &obj); err = err ?: linker_append_elf_relos(linker, &obj); @@ -529,7 +551,49 @@ static struct src_sec *add_src_sec(struct src_obj *obj, const char *sec_name) return sec; } -static int linker_load_obj_file(struct bpf_linker *linker, const char *filename, struct src_obj *obj) +static void sanitize_obj_name(char *name) +{ + int i; + + for (i = 0; name[i]; i++) { + if (name[i] == '_') + continue; + if (i == 0 && isalpha(name[i])) + continue; + if (i > 0 && isalnum(name[i])) + continue; + + name[i] = '_'; + } +} + +static bool str_has_suffix(const char *str, const char *suffix) +{ + size_t n1 = strlen(str), n2 = strlen(suffix); + + if (n1 < n2) + return false; + + return strcmp(str + n1 - n2, suffix) == 0; +} + +static void get_obj_name(char *name, const char *file) +{ + /* Using basename() GNU version which doesn't modify arg. */ + strncpy(name, basename(file), MAX_OBJ_NAME_LEN - 1); + name[MAX_OBJ_NAME_LEN - 1] = '\0'; + + if (str_has_suffix(name, ".bpf.o")) + name[strlen(name) - sizeof(".bpf.o") + 1] = '\0'; + else if (str_has_suffix(name, ".o")) + name[strlen(name) - sizeof(".o") + 1] = '\0'; + + sanitize_obj_name(name); +} + +static int linker_load_obj_file(struct bpf_linker *linker, const char *filename, + const struct bpf_linker_file_opts *opts, + struct src_obj *obj) { #if __BYTE_ORDER == __LITTLE_ENDIAN const int host_endianness = ELFDATA2LSB; @@ -549,6 +613,14 @@ static int linker_load_obj_file(struct bpf_linker *linker, const char *filename, obj->filename = filename; + if (OPTS_GET(opts, object_name, NULL)) { + strncpy(obj->obj_name, opts->object_name, MAX_OBJ_NAME_LEN); + obj->obj_name[MAX_OBJ_NAME_LEN - 1] = '\0'; + } else { + get_obj_name(obj->obj_name, filename); + } + obj->obj_name_len = strlen(obj->obj_name); + obj->fd = open(filename, O_RDONLY); if (obj->fd < 0) { err = -errno; @@ -2264,6 +2336,47 @@ static int linker_append_btf(struct bpf_linker *linker, struct src_obj *obj) obj->btf_type_map[i] = glob_sym->btf_id; continue; } + } else if (btf_is_var(t) && btf_var(t)->linkage == BTF_VAR_STATIC) { + /* Static variables are renamed to include + * ".." prefix (note double dots), similarly + * to how static variables inside functions are named + * "." by compiler. This allows to + * have unique identifiers for static variables across + * all linked object files (assuming unique filenames, + * of course), which BPF skeleton relies on. + * + * So worst case static variable inside the function + * will have the form "...___ + * name. Typical static variable will have a + * __ name, implying arguably nice + * per-file scoping. + * + * If static var name already contains '..', though, + * don't rename it, because it was already renamed by + * previous linker passes. + */ + name = btf__str_by_offset(obj->btf, t->name_off); + if (!strstr(name, "..")) { + char new_name[MAX_VAR_NAME_LEN]; + + memcpy(new_name, obj->obj_name, obj->obj_name_len); + new_name[obj->obj_name_len] = '.'; + new_name[obj->obj_name_len + 1] = '.'; + new_name[obj->obj_name_len + 2] = '\0'; + /* -3 is for '..' separator and terminating '\0' */ + strncat(new_name, name, MAX_VAR_NAME_LEN - obj->obj_name_len - 3); + + id = btf__add_str(obj->btf, new_name); + if (id < 0) + return id; + + /* btf__add_str() might invalidate t, so re-fetch */ + t = btf__type_by_id(obj->btf, i); + + ((struct btf_type *)t)->name_off = id; + } } id = btf__add_type(linker->btf, obj->btf, t); diff --git a/tools/testing/selftests/bpf/prog_tests/skeleton.c b/tools/testing/selftests/bpf/prog_tests/skeleton.c index fe87b77af459..bbade99fa544 100644 --- a/tools/testing/selftests/bpf/prog_tests/skeleton.c +++ b/tools/testing/selftests/bpf/prog_tests/skeleton.c @@ -82,10 +82,10 @@ void test_skeleton(void) CHECK(data->out2 != 2, "res2", "got %lld != exp %d\n", data->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); + CHECK(bss->test_skeleton__handler_out5.a != 5, "res5", "got %d != exp %d\n", + bss->test_skeleton__handler_out5.a, 5); + CHECK(bss->test_skeleton__handler_out5.b != 6, "res6", "got %lld != exp %d\n", + bss->test_skeleton__handler_out5.b, 6); CHECK(bss->out6 != 14, "res7", "got %d != exp %d\n", bss->out6, 14); CHECK(bss->bpf_syscall != kcfg->CONFIG_BPF_SYSCALL, "ext1", diff --git a/tools/testing/selftests/bpf/prog_tests/static_linked.c b/tools/testing/selftests/bpf/prog_tests/static_linked.c index 46556976dccc..f16736eab900 100644 --- a/tools/testing/selftests/bpf/prog_tests/static_linked.c +++ b/tools/testing/selftests/bpf/prog_tests/static_linked.c @@ -14,12 +14,12 @@ void test_static_linked(void) return; skel->rodata->rovar1 = 1; - skel->bss->static_var1 = 2; - skel->bss->static_var11 = 3; + skel->bss->test_static_linked1__static_var = 2; + skel->bss->test_static_linked1__static_var1 = 3; skel->rodata->rovar2 = 4; - skel->bss->static_var2 = 5; - skel->bss->static_var22 = 6; + skel->bss->test_static_linked2__static_var = 5; + skel->bss->test_static_linked2__static_var2 = 6; err = test_static_linked__load(skel); if (!ASSERT_OK(err, "skel_load")) diff --git a/tools/testing/selftests/bpf/progs/bpf_iter_test_kern4.c b/tools/testing/selftests/bpf/progs/bpf_iter_test_kern4.c index ee49493dc125..43bf8ec8ae79 100644 --- a/tools/testing/selftests/bpf/progs/bpf_iter_test_kern4.c +++ b/tools/testing/selftests/bpf/progs/bpf_iter_test_kern4.c @@ -9,8 +9,8 @@ __u32 map1_id = 0, map2_id = 0; __u32 map1_accessed = 0, map2_accessed = 0; __u64 map1_seqnum = 0, map2_seqnum1 = 0, map2_seqnum2 = 0; -static volatile const __u32 print_len; -static volatile const __u32 ret1; +volatile const __u32 print_len = 0; +volatile const __u32 ret1 = 0; SEC("iter/bpf_map") int dump_bpf_map(struct bpf_iter__bpf_map *ctx) diff --git a/tools/testing/selftests/bpf/progs/test_check_mtu.c b/tools/testing/selftests/bpf/progs/test_check_mtu.c index c4a9bae96e75..71184af57749 100644 --- a/tools/testing/selftests/bpf/progs/test_check_mtu.c +++ b/tools/testing/selftests/bpf/progs/test_check_mtu.c @@ -11,8 +11,8 @@ char _license[] SEC("license") = "GPL"; /* Userspace will update with MTU it can see on device */ -static volatile const int GLOBAL_USER_MTU; -static volatile const __u32 GLOBAL_USER_IFINDEX; +volatile const int GLOBAL_USER_MTU; +volatile const __u32 GLOBAL_USER_IFINDEX; /* BPF-prog will update these with MTU values it can see */ __u32 global_bpf_mtu_xdp = 0; diff --git a/tools/testing/selftests/bpf/progs/test_cls_redirect.c b/tools/testing/selftests/bpf/progs/test_cls_redirect.c index 3c1e042962e6..e2a5acc4785c 100644 --- a/tools/testing/selftests/bpf/progs/test_cls_redirect.c +++ b/tools/testing/selftests/bpf/progs/test_cls_redirect.c @@ -39,8 +39,8 @@ char _license[] SEC("license") = "Dual BSD/GPL"; /** * Destination port and IP used for UDP encapsulation. */ -static volatile const __be16 ENCAPSULATION_PORT; -static volatile const __be32 ENCAPSULATION_IP; +volatile const __be16 ENCAPSULATION_PORT; +volatile const __be32 ENCAPSULATION_IP; typedef struct { uint64_t processed_packets_total; diff --git a/tools/testing/selftests/bpf/progs/test_snprintf_single.c b/tools/testing/selftests/bpf/progs/test_snprintf_single.c index 402adaf344f9..6b63ba86b409 100644 --- a/tools/testing/selftests/bpf/progs/test_snprintf_single.c +++ b/tools/testing/selftests/bpf/progs/test_snprintf_single.c @@ -5,7 +5,7 @@ #include /* The format string is filled from the userspace such that loading fails */ -static const char fmt[10]; +const char fmt[10] = {}; SEC("raw_tp/sys_enter") int handler(const void *ctx) diff --git a/tools/testing/selftests/bpf/progs/test_sockmap_listen.c b/tools/testing/selftests/bpf/progs/test_sockmap_listen.c index a39eba9f5201..a1cc58b10c7c 100644 --- a/tools/testing/selftests/bpf/progs/test_sockmap_listen.c +++ b/tools/testing/selftests/bpf/progs/test_sockmap_listen.c @@ -28,8 +28,8 @@ struct { __type(value, unsigned int); } verdict_map SEC(".maps"); -static volatile bool test_sockmap; /* toggled by user-space */ -static volatile bool test_ingress; /* toggled by user-space */ +bool test_sockmap = false; /* toggled by user-space */ +bool test_ingress = false; /* toggled by user-space */ SEC("sk_skb/stream_parser") int prog_stream_parser(struct __sk_buff *skb) diff --git a/tools/testing/selftests/bpf/progs/test_static_linked1.c b/tools/testing/selftests/bpf/progs/test_static_linked1.c index ea1a6c4c7172..7e15d05888e7 100644 --- a/tools/testing/selftests/bpf/progs/test_static_linked1.c +++ b/tools/testing/selftests/bpf/progs/test_static_linked1.c @@ -5,8 +5,8 @@ #include /* 8-byte aligned .bss */ -static volatile long static_var1; -static volatile int static_var11; +static volatile long static_var; +static volatile int static_var1; int var1 = 0; /* 4-byte aligned .rodata */ const volatile int rovar1; @@ -21,7 +21,7 @@ static __noinline int subprog(int x) SEC("raw_tp/sys_enter") int handler1(const void *ctx) { - var1 = subprog(rovar1) + static_var1 + static_var11; + var1 = subprog(rovar1) + static_var + static_var1; return 0; } diff --git a/tools/testing/selftests/bpf/progs/test_static_linked2.c b/tools/testing/selftests/bpf/progs/test_static_linked2.c index 54d8d1ab577c..0d37c05d508e 100644 --- a/tools/testing/selftests/bpf/progs/test_static_linked2.c +++ b/tools/testing/selftests/bpf/progs/test_static_linked2.c @@ -5,8 +5,8 @@ #include /* 4-byte aligned .bss */ +static volatile int static_var; static volatile int static_var2; -static volatile int static_var22; int var2 = 0; /* 8-byte aligned .rodata */ const volatile long rovar2; @@ -21,7 +21,7 @@ static __noinline int subprog(int x) SEC("raw_tp/sys_enter") int handler2(const void *ctx) { - var2 = subprog(rovar2) + static_var2 + static_var22; + var2 = subprog(rovar2) + static_var + static_var2; return 0; } From patchwork Fri Apr 23 18:53:54 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andrii Nakryiko X-Patchwork-Id: 426651 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-17.0 required=3.0 tests=BAYES_00, INCLUDES_CR_TRAILER, INCLUDES_PATCH, MAILING_LIST_MULTI, SPF_HELO_NONE, SPF_PASS, USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 70FCDC433B4 for ; Fri, 23 Apr 2021 18:54:19 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 3EA9461463 for ; Fri, 23 Apr 2021 18:54:19 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S243768AbhDWSyy convert rfc822-to-8bit (ORCPT ); Fri, 23 Apr 2021 14:54:54 -0400 Received: from mx0a-00082601.pphosted.com ([67.231.145.42]:56922 "EHLO mx0a-00082601.pphosted.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S243750AbhDWSyw (ORCPT ); Fri, 23 Apr 2021 14:54:52 -0400 Received: from pps.filterd (m0148461.ppops.net [127.0.0.1]) by mx0a-00082601.pphosted.com (8.16.0.43/8.16.0.43) with SMTP id 13NIsF8j005629 for ; Fri, 23 Apr 2021 11:54:15 -0700 Received: from mail.thefacebook.com ([163.114.132.120]) by mx0a-00082601.pphosted.com with ESMTP id 383kvnmtqk-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NOT) for ; Fri, 23 Apr 2021 11:54:15 -0700 Received: from intmgw001.06.ash9.facebook.com (2620:10d:c085:208::11) by mail.thefacebook.com (2620:10d:c085:11d::7) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2176.2; Fri, 23 Apr 2021 11:54:06 -0700 Received: by devbig012.ftw2.facebook.com (Postfix, from userid 137359) id 5E3342ED5CA8; Fri, 23 Apr 2021 11:54:05 -0700 (PDT) From: Andrii Nakryiko To: , , , CC: , Subject: [PATCH v2 bpf-next 3/6] libbpf: support static map definitions Date: Fri, 23 Apr 2021 11:53:54 -0700 Message-ID: <20210423185357.1992756-4-andrii@kernel.org> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20210423185357.1992756-1-andrii@kernel.org> References: <20210423185357.1992756-1-andrii@kernel.org> MIME-Version: 1.0 X-FB-Internal: Safe X-Proofpoint-GUID: ZDx9zkKvqw9XbJ1tL7BTUXKU0cKltTKB X-Proofpoint-ORIG-GUID: ZDx9zkKvqw9XbJ1tL7BTUXKU0cKltTKB X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10434:6.0.391, 18.0.761 definitions=2021-04-23_07:2021-04-23,2021-04-23 signatures=0 X-Proofpoint-Spam-Details: rule=fb_default_notspam policy=fb_default score=0 phishscore=0 bulkscore=0 malwarescore=0 clxscore=1015 suspectscore=0 spamscore=0 priorityscore=1501 impostorscore=0 mlxlogscore=994 mlxscore=0 lowpriorityscore=0 adultscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2104060000 definitions=main-2104230122 X-FB-Internal: deliver Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org Change libbpf relocation logic to support references to static map definitions. This allows to use static maps and, combined with static linking, hide internal maps from other files, just like static variables. User-space will still be able to look up and modify static maps. Signed-off-by: Andrii Nakryiko --- tools/lib/bpf/libbpf.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c index a1cddd17af7d..6c755c5f037d 100644 --- a/tools/lib/bpf/libbpf.c +++ b/tools/lib/bpf/libbpf.c @@ -3633,6 +3633,8 @@ static int bpf_program__record_reloc(struct bpf_program *prog, /* generic map reference relocation */ if (type == LIBBPF_MAP_UNSPEC) { + size_t map_offset = sym->st_value + insn->imm; + if (!bpf_object__shndx_is_maps(obj, shdr_idx)) { pr_warn("prog '%s': bad map relo against '%s' in section '%s'\n", prog->name, sym_name, sym_sec_name); @@ -3642,7 +3644,7 @@ static int bpf_program__record_reloc(struct bpf_program *prog, map = &obj->maps[map_idx]; if (map->libbpf_type != type || map->sec_idx != sym->st_shndx || - map->sec_offset != sym->st_value) + map->sec_offset != map_offset) continue; pr_debug("prog '%s': found map %zd (%s, sec %d, off %zu) for insn #%u\n", prog->name, map_idx, map->name, map->sec_idx, @@ -3657,7 +3659,8 @@ static int bpf_program__record_reloc(struct bpf_program *prog, reloc_desc->type = RELO_LD64; reloc_desc->insn_idx = insn_idx; reloc_desc->map_idx = map_idx; - reloc_desc->sym_off = 0; /* sym->st_value determines map_idx */ + /* sym->st_value + insn->imm determines map_idx */ + reloc_desc->sym_off = 0; return 0; } From patchwork Fri Apr 23 18:53:57 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andrii Nakryiko X-Patchwork-Id: 426650 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-17.0 required=3.0 tests=BAYES_00, INCLUDES_CR_TRAILER, INCLUDES_PATCH, MAILING_LIST_MULTI, SPF_HELO_NONE, SPF_PASS, USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 1D68DC43460 for ; Fri, 23 Apr 2021 18:54:32 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id DD6D9613F5 for ; Fri, 23 Apr 2021 18:54:31 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S243838AbhDWSzG convert rfc822-to-8bit (ORCPT ); Fri, 23 Apr 2021 14:55:06 -0400 Received: from mx0b-00082601.pphosted.com ([67.231.153.30]:53682 "EHLO mx0a-00082601.pphosted.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S243760AbhDWSy4 (ORCPT ); Fri, 23 Apr 2021 14:54:56 -0400 Received: from pps.filterd (m0089730.ppops.net [127.0.0.1]) by m0089730.ppops.net (8.16.0.43/8.16.0.43) with SMTP id 13NIPx9q025504 for ; Fri, 23 Apr 2021 11:54:19 -0700 Received: from maileast.thefacebook.com ([163.114.130.16]) by m0089730.ppops.net with ESMTP id 383h1unt0t-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NOT) for ; Fri, 23 Apr 2021 11:54:19 -0700 Received: from intmgw001.37.frc1.facebook.com (2620:10d:c0a8:1b::d) by mail.thefacebook.com (2620:10d:c0a8:82::e) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2176.2; Fri, 23 Apr 2021 11:54:18 -0700 Received: by devbig012.ftw2.facebook.com (Postfix, from userid 137359) id 7F5202ED5CA8; Fri, 23 Apr 2021 11:54:11 -0700 (PDT) From: Andrii Nakryiko To: , , , CC: , Subject: [PATCH v2 bpf-next 6/6] selftests/bpf: extend linked_maps selftests with static maps Date: Fri, 23 Apr 2021 11:53:57 -0700 Message-ID: <20210423185357.1992756-7-andrii@kernel.org> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20210423185357.1992756-1-andrii@kernel.org> References: <20210423185357.1992756-1-andrii@kernel.org> MIME-Version: 1.0 X-FB-Internal: Safe X-Proofpoint-GUID: 1m0r_wPSlEuy9CUf3TxAJDo-qyLX6jbu X-Proofpoint-ORIG-GUID: 1m0r_wPSlEuy9CUf3TxAJDo-qyLX6jbu X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10434:6.0.391, 18.0.761 definitions=2021-04-23_07:2021-04-23,2021-04-23 signatures=0 X-Proofpoint-Spam-Details: rule=fb_default_notspam policy=fb_default score=0 clxscore=1015 adultscore=0 malwarescore=0 mlxscore=0 spamscore=0 bulkscore=0 phishscore=0 impostorscore=0 priorityscore=1501 lowpriorityscore=0 mlxlogscore=867 suspectscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2104060000 definitions=main-2104230121 X-FB-Internal: deliver Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org Add static maps to linked_maps selftests, validating that static maps with the same name can co-exists in separate files and local references to such maps are resolved correctly within each individual file. Signed-off-by: Andrii Nakryiko Acked-by: Yonghong Song --- .../selftests/bpf/prog_tests/linked_maps.c | 20 ++++++++++++++++++- .../selftests/bpf/progs/linked_maps1.c | 13 ++++++++++++ .../selftests/bpf/progs/linked_maps2.c | 18 +++++++++++++++++ 3 files changed, 50 insertions(+), 1 deletion(-) diff --git a/tools/testing/selftests/bpf/prog_tests/linked_maps.c b/tools/testing/selftests/bpf/prog_tests/linked_maps.c index 85dcaaaf2775..6f51dae65b44 100644 --- a/tools/testing/selftests/bpf/prog_tests/linked_maps.c +++ b/tools/testing/selftests/bpf/prog_tests/linked_maps.c @@ -7,13 +7,21 @@ void test_linked_maps(void) { - int err; + int key1 = 1, key2 = 2; + int val1 = 42, val2 = 24, val; + int err, map_fd1, map_fd2; struct linked_maps *skel; skel = linked_maps__open_and_load(); if (!ASSERT_OK_PTR(skel, "skel_open")) return; + map_fd1 = bpf_map__fd(skel->maps.linked_maps1__map_static); + ASSERT_OK(bpf_map_update_elem(map_fd1, &key2, &val2, 0), "static_map1_update"); + + map_fd2 = bpf_map__fd(skel->maps.linked_maps2__map_static); + ASSERT_OK(bpf_map_update_elem(map_fd2, &key1, &val1, 0), "static_map2_update"); + err = linked_maps__attach(skel); if (!ASSERT_OK(err, "skel_attach")) goto cleanup; @@ -24,6 +32,16 @@ void test_linked_maps(void) ASSERT_EQ(skel->bss->output_first1, 2000, "output_first1"); ASSERT_EQ(skel->bss->output_second1, 2, "output_second1"); ASSERT_EQ(skel->bss->output_weak1, 2, "output_weak1"); + ASSERT_EQ(skel->bss->output_static1, val2, "output_static1"); + ASSERT_OK(bpf_map_lookup_elem(map_fd1, &key1, &val), "static_map1_lookup"); + ASSERT_EQ(val, 1, "static_map1_key1"); + + ASSERT_EQ(skel->bss->output_first2, 1000, "output_first2"); + ASSERT_EQ(skel->bss->output_second2, 1, "output_second2"); + ASSERT_EQ(skel->bss->output_weak2, 1, "output_weak2"); + ASSERT_EQ(skel->bss->output_static2, val1, "output_static2"); + ASSERT_OK(bpf_map_lookup_elem(map_fd2, &key2, &val), "static_map2_lookup"); + ASSERT_EQ(val, 2, "static_map2_key2"); cleanup: linked_maps__destroy(skel); diff --git a/tools/testing/selftests/bpf/progs/linked_maps1.c b/tools/testing/selftests/bpf/progs/linked_maps1.c index 52291515cc72..308a13f865ef 100644 --- a/tools/testing/selftests/bpf/progs/linked_maps1.c +++ b/tools/testing/selftests/bpf/progs/linked_maps1.c @@ -37,9 +37,17 @@ struct { __uint(max_entries, 16); } map_weak __weak SEC(".maps"); +static struct { + __uint(type, BPF_MAP_TYPE_HASH); + __type(key, int); + __type(value, int); + __uint(max_entries, 4); +} map_static SEC(".maps"); + int output_first1; int output_second1; int output_weak1; +int output_static1; SEC("raw_tp/sys_enter") int BPF_PROG(handler_enter1) @@ -52,6 +60,7 @@ int BPF_PROG(handler_enter1) bpf_map_update_elem(&map1, &key_struct, &val_struct, 0); bpf_map_update_elem(&map2, &key, &val, 0); bpf_map_update_elem(&map_weak, &key, &val, 0); + bpf_map_update_elem(&map_static, &key, &val, 0); return 0; } @@ -76,6 +85,10 @@ int BPF_PROG(handler_exit1) if (val) output_weak1 = *val; + val = bpf_map_lookup_elem(&map_static, &key); + if (val) + output_static1 = *val; + return 0; } diff --git a/tools/testing/selftests/bpf/progs/linked_maps2.c b/tools/testing/selftests/bpf/progs/linked_maps2.c index 0693687474ed..840554d5e484 100644 --- a/tools/testing/selftests/bpf/progs/linked_maps2.c +++ b/tools/testing/selftests/bpf/progs/linked_maps2.c @@ -31,9 +31,22 @@ struct { __uint(max_entries, 16); } map_weak __weak SEC(".maps"); +static struct { + /* different type */ + __uint(type, BPF_MAP_TYPE_ARRAY); + /* key and value are kept int for convenience, they don't have to + * match with map_static in linked_maps1 + */ + __type(key, int); + __type(value, int); + /* different max_entries */ + __uint(max_entries, 20); +} map_static SEC(".maps"); + int output_first2; int output_second2; int output_weak2; +int output_static2; SEC("raw_tp/sys_enter") int BPF_PROG(handler_enter2) @@ -46,6 +59,7 @@ int BPF_PROG(handler_enter2) bpf_map_update_elem(&map1, &key_struct, &val_struct, 0); bpf_map_update_elem(&map2, &key, &val, 0); bpf_map_update_elem(&map_weak, &key, &val, 0); + bpf_map_update_elem(&map_static, &key, &val, 0); return 0; } @@ -70,6 +84,10 @@ int BPF_PROG(handler_exit2) if (val) output_weak2 = *val; + val = bpf_map_lookup_elem(&map_static, &key); + if (val) + output_static2 = *val; + return 0; }