From patchwork Mon Jun 20 23:17:07 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Daniel_M=C3=BCller?= X-Patchwork-Id: 12888588 X-Patchwork-Delegate: bpf@iogearbox.net Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id D17C1C43334 for ; Mon, 20 Jun 2022 23:23:04 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1347421AbiFTXXD (ORCPT ); Mon, 20 Jun 2022 19:23:03 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:45174 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1347552AbiFTXWo (ORCPT ); Mon, 20 Jun 2022 19:22:44 -0400 Received: from mout01.posteo.de (mout01.posteo.de [185.67.36.65]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 292245FF1 for ; Mon, 20 Jun 2022 16:17:52 -0700 (PDT) Received: from submission (posteo.de [185.67.36.169]) by mout01.posteo.de (Postfix) with ESMTPS id 8E54E240028 for ; Tue, 21 Jun 2022 01:17:50 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=posteo.net; s=2017; t=1655767070; bh=99zNdqlo8R46wTYQGC58/P3RDaRr+yek5vt1JniASgA=; h=From:To:Subject:Date:From; b=Pgx5tzVJe1SsBvdeWx29x24+igaRV4p69oYxZo6SbEztkZ2vERFFPrm8cBS77DcSR NfInH17NOnnb7kC7nuKdcAfg+NY4qgqWqUd8l6caVaMyX92jfpv8bnncRlUIc49k6n BaOCXTAs3OztIK1sVMMuG+G5zXTFyuVLt7IF0XlMLmjo6Ks/gRaiBMAaXOCtWAy7Z5 TrN5L1Ntz3/wVT69yA6QNqpJm6l2PiQuga/931G1LOmTAz/9z3Wi5CnhzEEEZQL+2h K26aOGdigc+JOXGFL2QIa9pkHeTUnFIBCJmCwibkkk3AbMevRc1l6fRXoTmq1vzw+H t6erlPSDtDU5g== Received: from customer (localhost [127.0.0.1]) by submission (posteo.de) with ESMTPSA id 4LRltP6lJmz6tmS; Tue, 21 Jun 2022 01:17:49 +0200 (CEST) From: =?utf-8?q?Daniel_M=C3=BCller?= To: bpf@vger.kernel.org, ast@kernel.org, andrii@kernel.org, daniel@iogearbox.net, kernel-team@fb.com Subject: [PATCH bpf-next 1/7] bpf: Introduce TYPE_MATCH related constants/macros Date: Mon, 20 Jun 2022 23:17:07 +0000 Message-Id: <20220620231713.2143355-2-deso@posteo.net> In-Reply-To: <20220620231713.2143355-1-deso@posteo.net> References: <20220620231713.2143355-1-deso@posteo.net> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: bpf@vger.kernel.org X-Patchwork-Delegate: bpf@iogearbox.net In order to provide type match support we require a new type of relocation which, in turn, requires toolchain support. Recent LLVM/Clang versions support a new value for the last argument to the __builtin_preserve_type_info builtin, for example. With this change we introduce the necessary constants into relevant header files, mirroring what the compiler may support. Signed-off-by: Daniel Müller --- include/uapi/linux/bpf.h | 1 + tools/include/uapi/linux/bpf.h | 1 + tools/lib/bpf/bpf_core_read.h | 1 + 3 files changed, 3 insertions(+) diff --git a/include/uapi/linux/bpf.h b/include/uapi/linux/bpf.h index e81362..42605c 100644 --- a/include/uapi/linux/bpf.h +++ b/include/uapi/linux/bpf.h @@ -6782,6 +6782,7 @@ enum bpf_core_relo_kind { BPF_CORE_TYPE_SIZE = 9, /* type size in bytes */ BPF_CORE_ENUMVAL_EXISTS = 10, /* enum value existence in target kernel */ BPF_CORE_ENUMVAL_VALUE = 11, /* enum value integer value */ + BPF_CORE_TYPE_MATCHES = 12, /* type match in target kernel */ }; /* diff --git a/tools/include/uapi/linux/bpf.h b/tools/include/uapi/linux/bpf.h index e81362..42605c 100644 --- a/tools/include/uapi/linux/bpf.h +++ b/tools/include/uapi/linux/bpf.h @@ -6782,6 +6782,7 @@ enum bpf_core_relo_kind { BPF_CORE_TYPE_SIZE = 9, /* type size in bytes */ BPF_CORE_ENUMVAL_EXISTS = 10, /* enum value existence in target kernel */ BPF_CORE_ENUMVAL_VALUE = 11, /* enum value integer value */ + BPF_CORE_TYPE_MATCHES = 12, /* type match in target kernel */ }; /* diff --git a/tools/lib/bpf/bpf_core_read.h b/tools/lib/bpf/bpf_core_read.h index fd48b1..2308f49 100644 --- a/tools/lib/bpf/bpf_core_read.h +++ b/tools/lib/bpf/bpf_core_read.h @@ -29,6 +29,7 @@ enum bpf_type_id_kind { enum bpf_type_info_kind { BPF_TYPE_EXISTS = 0, /* type existence in target kernel */ BPF_TYPE_SIZE = 1, /* type size in target kernel */ + BPF_TYPE_MATCHES = 2, /* type match in target kernel */ }; /* second argument to __builtin_preserve_enum_value() built-in */ From patchwork Mon Jun 20 23:17:08 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Daniel_M=C3=BCller?= X-Patchwork-Id: 12888589 X-Patchwork-Delegate: bpf@iogearbox.net Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id A6773C43334 for ; Mon, 20 Jun 2022 23:23:14 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S245210AbiFTXXN (ORCPT ); Mon, 20 Jun 2022 19:23:13 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:43482 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1346593AbiFTXXB (ORCPT ); Mon, 20 Jun 2022 19:23:01 -0400 Received: from mout02.posteo.de (mout02.posteo.de [185.67.36.66]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id A0E162BB19 for ; Mon, 20 Jun 2022 16:18:05 -0700 (PDT) Received: from submission (posteo.de [185.67.36.169]) by mout02.posteo.de (Postfix) with ESMTPS id E8806240108 for ; Tue, 21 Jun 2022 01:18:03 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=posteo.net; s=2017; t=1655767083; bh=2AXd5CKVR5VYsRxh0WrG33Ue7HtinUs0TiUP2XNxdoQ=; h=From:To:Cc:Subject:Date:From; b=jGf4/IY+lWTuYQRFdh1zyBlfs5gMZvlsiOqwcjYvn514AQjB0uq1ZfSK6KkniV13P IfFrql4om0FS9dZxrQFalA7pMyswBH+BQzYPvp/VGCIclM9T+dD6Bov9xLk/IpMlH2 sUbIVjAqbZtTuiOqyfv7wgJ2D+CgXF5M8iEhIASTJn0eCnjmWv0wMPEwGN4mZONClu jXI9VFaxwwgfUobuJQUlBcFrVz/yY7FWrE2rVtz8lUa/zZf5ezLN3G6VoAiFFScLld m9pD1lKGiYwOP1hsG+IwzEIZRRz7/O1eHqgEW3Ietjv1FjI9T2z15eq9ycLAYtBKGO wDyiu/+sujY1A== Received: from customer (localhost [127.0.0.1]) by submission (posteo.de) with ESMTPSA id 4LRltg0CPkz6tmX; Tue, 21 Jun 2022 01:18:03 +0200 (CEST) From: =?utf-8?q?Daniel_M=C3=BCller?= To: bpf@vger.kernel.org, ast@kernel.org, andrii@kernel.org, daniel@iogearbox.net, kernel-team@fb.com Cc: Quentin Monnet Subject: [PATCH bpf-next 2/7] bpftool: Honor BPF_CORE_TYPE_MATCHES relocation Date: Mon, 20 Jun 2022 23:17:08 +0000 Message-Id: <20220620231713.2143355-3-deso@posteo.net> In-Reply-To: <20220620231713.2143355-1-deso@posteo.net> References: <20220620231713.2143355-1-deso@posteo.net> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: bpf@vger.kernel.org X-Patchwork-Delegate: bpf@iogearbox.net bpftool needs to know about the newly introduced BPF_CORE_TYPE_MATCHES relocation for its 'gen min_core_btf' command to work properly in the present of this relocation. Specifically, we need to make sure to mark types and fields so that they are present in the minimized BTF for "type match" checks to work out. However, contrary to the existing btfgen_record_field_relo, we need to rely on the BTF -- and not the spec -- to find fields. With this change we handle this new variant correctly. The functionality will be tested with follow on changes to BPF selftests, which already run against a minimized BTF created with bpftool. Cc: Quentin Monnet Signed-off-by: Daniel Müller --- tools/bpf/bpftool/gen.c | 106 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 106 insertions(+) diff --git a/tools/bpf/bpftool/gen.c b/tools/bpf/bpftool/gen.c index 480cbd8..cf45ce 100644 --- a/tools/bpf/bpftool/gen.c +++ b/tools/bpf/bpftool/gen.c @@ -1856,6 +1856,110 @@ static int btfgen_record_field_relo(struct btfgen_info *info, struct bpf_core_sp return 0; } +/* Mark types, members, and member types. Compared to btfgen_record_field_relo, + * this function does not rely on the target spec for inferring members, but + * uses the associated BTF. + * + * The `behind_ptr` argument is used to stop marking of composite types reached + * through a pointer. This way, we keep can keep BTF size in check while + * providing reasonable match semantics. + */ +static int btfgen_mark_types_match(struct btfgen_info *info, __u32 type_id, bool behind_ptr) +{ + const struct btf_type *btf_type; + struct btf *btf = info->src_btf; + struct btf_type *cloned_type; + int i, err; + + if (type_id == 0) + return 0; + + btf_type = btf__type_by_id(btf, type_id); + /* mark type on cloned BTF as used */ + cloned_type = (struct btf_type *)btf__type_by_id(info->marked_btf, type_id); + cloned_type->name_off = MARKED; + + switch (btf_kind(btf_type)) { + case BTF_KIND_UNKN: + case BTF_KIND_INT: + case BTF_KIND_FLOAT: + case BTF_KIND_ENUM: + case BTF_KIND_ENUM64: + break; + case BTF_KIND_STRUCT: + case BTF_KIND_UNION: { + struct btf_member *m = btf_members(btf_type); + __u16 vlen = btf_vlen(btf_type); + + if (behind_ptr) + break; + + for (i = 0; i < vlen; i++, m++) { + /* mark member */ + btfgen_mark_member(info, type_id, i); + + /* mark member's type */ + err = btfgen_mark_types_match(info, m->type, false); + if (err) + return err; + } + break; + } + case BTF_KIND_CONST: + case BTF_KIND_VOLATILE: + case BTF_KIND_TYPEDEF: + return btfgen_mark_types_match(info, btf_type->type, false); + case BTF_KIND_PTR: + return btfgen_mark_types_match(info, btf_type->type, true); + case BTF_KIND_ARRAY: { + struct btf_array *array; + + array = btf_array(btf_type); + /* mark array type */ + err = btfgen_mark_types_match(info, array->type, false); + /* mark array's index type */ + err = err ? : btfgen_mark_types_match(info, array->index_type, false); + if (err) + return err; + break; + } + case BTF_KIND_FUNC_PROTO: { + __u16 vlen = btf_vlen(btf_type); + struct btf_param *param; + + /* mark ret type */ + err = btfgen_mark_types_match(info, btf_type->type, false); + if (err) + return err; + + /* mark parameters types */ + param = btf_params(btf_type); + for (i = 0; i < vlen; i++) { + err = btfgen_mark_types_match(info, param->type, false); + if (err) + return err; + param++; + } + break; + } + /* tells if some other type needs to be handled */ + default: + p_err("unsupported kind: %s (%d)", btf_kind_str(btf_type), type_id); + return -EINVAL; + } + + return 0; +} + +/* Mark types, members, and member types. Compared to btfgen_record_field_relo, + * this function does not rely on the target spec for inferring members, but + * uses the associated BTF. + */ +static int btfgen_record_types_match_relo(struct btfgen_info *info, struct bpf_core_spec *targ_spec) +{ + return btfgen_mark_types_match(info, targ_spec->root_type_id, false); +} + static int btfgen_record_type_relo(struct btfgen_info *info, struct bpf_core_spec *targ_spec) { return btfgen_mark_type(info, targ_spec->root_type_id, true); @@ -1882,6 +1986,8 @@ static int btfgen_record_reloc(struct btfgen_info *info, struct bpf_core_spec *r case BPF_CORE_TYPE_EXISTS: case BPF_CORE_TYPE_SIZE: return btfgen_record_type_relo(info, res); + case BPF_CORE_TYPE_MATCHES: + return btfgen_record_types_match_relo(info, res); case BPF_CORE_ENUMVAL_EXISTS: case BPF_CORE_ENUMVAL_VALUE: return btfgen_record_enumval_relo(info, res); From patchwork Mon Jun 20 23:17:09 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Daniel_M=C3=BCller?= X-Patchwork-Id: 12888590 X-Patchwork-Delegate: bpf@iogearbox.net Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 7298DC433EF for ; Mon, 20 Jun 2022 23:23:15 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1346326AbiFTXXN (ORCPT ); Mon, 20 Jun 2022 19:23:13 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:44758 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1347563AbiFTXXE (ORCPT ); Mon, 20 Jun 2022 19:23:04 -0400 Received: from mout01.posteo.de (mout01.posteo.de [185.67.36.65]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 76D5F2BB2A for ; Mon, 20 Jun 2022 16:18:07 -0700 (PDT) Received: from submission (posteo.de [185.67.36.169]) by mout01.posteo.de (Postfix) with ESMTPS id 23673240027 for ; Tue, 21 Jun 2022 01:18:06 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=posteo.net; s=2017; t=1655767086; bh=8Xgm0JYtPy2iGYTc7vM3tB+KvIQuGWFPNKtreZQ37uU=; h=From:To:Subject:Date:From; b=dn6GH8n5OPeTcV0Yav2DEkmf218eQeXNHijEYEu0nbLbykLsS7AOQx4y8kGT8nB/J yAAQLU8iUhsmPrlPXEM3FgcQWZHOGG14Q7e8KXKHPDKL0eCdvpkW25+RSF9TkpfjHC 8/FrQrH5qImA9l2eOfHFWlVtV/yYBju07zlZyx5pHPrWWwkQ4OCx1OipGvbeGh7Fbf g8K2fiJmHjytYzTvJf+IlnlHbsDjibuhoSzwCCaRB6kq2WCUzMh43hIRt46mAu7cPE 5R7P06cqk3BCR+ZU+SLmWM97m0RgGhzBWT5zQBZbMcmN6Q2bN9SklY5ip8+Jjr1qCz tR/1BlS14EwjA== Received: from customer (localhost [127.0.0.1]) by submission (posteo.de) with ESMTPSA id 4LRltj2nC3z6tmX; Tue, 21 Jun 2022 01:18:05 +0200 (CEST) From: =?utf-8?q?Daniel_M=C3=BCller?= To: bpf@vger.kernel.org, ast@kernel.org, andrii@kernel.org, daniel@iogearbox.net, kernel-team@fb.com Subject: [PATCH bpf-next 3/7] bpf: Add type match support Date: Mon, 20 Jun 2022 23:17:09 +0000 Message-Id: <20220620231713.2143355-4-deso@posteo.net> In-Reply-To: <20220620231713.2143355-1-deso@posteo.net> References: <20220620231713.2143355-1-deso@posteo.net> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: bpf@vger.kernel.org X-Patchwork-Delegate: bpf@iogearbox.net This change implements the kernel side of the "type matches" support. Please refer to the next change ("libbpf: Add type match support") for more details on the relation. This one is first in the stack because the follow-on libbpf changes depend on it. Signed-off-by: Daniel Müller --- include/linux/btf.h | 5 + kernel/bpf/btf.c | 267 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 272 insertions(+) diff --git a/include/linux/btf.h b/include/linux/btf.h index 1bfed7..7376934 100644 --- a/include/linux/btf.h +++ b/include/linux/btf.h @@ -242,6 +242,11 @@ static inline u8 btf_int_offset(const struct btf_type *t) return BTF_INT_OFFSET(*(u32 *)(t + 1)); } +static inline u8 btf_int_bits(const struct btf_type *t) +{ + return BTF_INT_BITS(*(__u32 *)(t + 1)); +} + static inline u8 btf_int_encoding(const struct btf_type *t) { return BTF_INT_ENCODING(*(u32 *)(t + 1)); diff --git a/kernel/bpf/btf.c b/kernel/bpf/btf.c index f08037..3790b4 100644 --- a/kernel/bpf/btf.c +++ b/kernel/bpf/btf.c @@ -7524,6 +7524,273 @@ int bpf_core_types_are_compat(const struct btf *local_btf, __u32 local_id, MAX_TYPES_ARE_COMPAT_DEPTH); } +#define MAX_TYPES_MATCH_DEPTH 2 + +static bool bpf_core_names_match(const struct btf *local_btf, u32 local_id, + const struct btf *targ_btf, u32 targ_id) +{ + const struct btf_type *local_t, *targ_t; + const char *local_n, *targ_n; + size_t local_len, targ_len; + + local_t = btf_type_by_id(local_btf, local_id); + targ_t = btf_type_by_id(targ_btf, targ_id); + local_n = btf_str_by_offset(local_btf, local_t->name_off); + targ_n = btf_str_by_offset(targ_btf, targ_t->name_off); + local_len = bpf_core_essential_name_len(local_n); + targ_len = bpf_core_essential_name_len(targ_n); + + return local_len == targ_len && strncmp(local_n, targ_n, local_len) == 0; +} + +static int bpf_core_enums_match(const struct btf *local_btf, const struct btf_type *local_t, + const struct btf *targ_btf, const struct btf_type *targ_t) +{ + u16 local_vlen = btf_vlen(local_t); + u16 targ_vlen = btf_vlen(targ_t); + int i, j; + + if (local_t->size != targ_t->size) + return 0; + + if (local_vlen > targ_vlen) + return 0; + + /* iterate over the local enum's variants and make sure each has + * a symbolic name correspondent in the target + */ + for (i = 0; i < local_vlen; i++) { + bool matched = false; + const char *local_n; + __u32 local_n_off; + size_t local_len; + + local_n_off = btf_is_enum(local_t) ? btf_type_enum(local_t)[i].name_off : + btf_type_enum64(local_t)[i].name_off; + + local_n = btf_name_by_offset(local_btf, local_n_off); + local_len = bpf_core_essential_name_len(local_n); + + for (j = 0; j < targ_vlen; j++) { + const char *targ_n; + __u32 targ_n_off; + size_t targ_len; + + targ_n_off = btf_is_enum(targ_t) ? btf_type_enum(targ_t)[j].name_off : + btf_type_enum64(targ_t)[j].name_off; + targ_n = btf_name_by_offset(targ_btf, targ_n_off); + + if (str_is_empty(targ_n)) + continue; + + targ_len = bpf_core_essential_name_len(targ_n); + + if (local_len == targ_len && strncmp(local_n, targ_n, local_len) == 0) { + matched = true; + break; + } + } + + if (!matched) + return 0; + } + return 1; +} + +static int __bpf_core_types_match(const struct btf *local_btf, u32 local_id, + const struct btf *targ_btf, u32 targ_id, int level); + +static int bpf_core_composites_match(const struct btf *local_btf, const struct btf_type *local_t, + const struct btf *targ_btf, const struct btf_type *targ_t, + int level) +{ + /* check that all local members have a match in the target */ + const struct btf_member *local_m = btf_members(local_t); + u16 local_vlen = btf_vlen(local_t); + u16 targ_vlen = btf_vlen(targ_t); + int i, j, err; + + if (local_vlen > targ_vlen) + return 0; + + for (i = 0; i < local_vlen; i++, local_m++) { + const char *local_n = btf_name_by_offset(local_btf, local_m->name_off); + const struct btf_member *targ_m = btf_members(targ_t); + bool matched = false; + + for (j = 0; j < targ_vlen; j++, targ_m++) { + const char *targ_n = btf_name_by_offset(targ_btf, targ_m->name_off); + + if (str_is_empty(targ_n)) + continue; + + if (strcmp(local_n, targ_n) != 0) + continue; + + err = __bpf_core_types_match(local_btf, local_m->type, targ_btf, + targ_m->type, level - 1); + if (err > 0) { + matched = true; + break; + } + } + + if (!matched) + return 0; + } + return 1; +} + +static int __bpf_core_types_match(const struct btf *local_btf, u32 local_id, + const struct btf *targ_btf, u32 targ_id, int level) +{ + const struct btf_type *local_t, *targ_t, *prev_local_t; + int depth = 32; /* max recursion depth */ + __u16 local_k; + + if (level <= 0) + return -EINVAL; + + local_t = btf_type_by_id(local_btf, local_id); + targ_t = btf_type_by_id(targ_btf, targ_id); + +recur: + depth--; + if (depth < 0) + return -EINVAL; + + prev_local_t = local_t; + + local_t = btf_type_skip_modifiers(local_btf, local_id, &local_id); + targ_t = btf_type_skip_modifiers(targ_btf, targ_id, &targ_id); + if (!local_t || !targ_t) + return -EINVAL; + + if (!bpf_core_names_match(local_btf, local_id, targ_btf, targ_id)) + return 0; + + local_k = btf_kind(local_t); + + switch (local_k) { + case BTF_KIND_UNKN: + return local_k == btf_kind(targ_t); + case BTF_KIND_FWD: { + bool local_f = btf_type_kflag(local_t); + __u16 targ_k = btf_kind(targ_t); + + if (btf_is_ptr(prev_local_t)) { + if (local_k == targ_k) + return local_f == btf_type_kflag(local_t); + + return (targ_k == BTF_KIND_STRUCT && !local_f) || + (targ_k == BTF_KIND_UNION && local_f); + } else { + if (local_k != targ_k) + return 0; + + /* match if the forward declaration is for the same kind */ + return local_f == btf_type_kflag(local_t); + } + } + case BTF_KIND_ENUM: + case BTF_KIND_ENUM64: + if (!btf_is_any_enum(targ_t)) + return 0; + + return bpf_core_enums_match(local_btf, local_t, targ_btf, targ_t); + case BTF_KIND_STRUCT: + case BTF_KIND_UNION: { + __u16 targ_k = btf_kind(targ_t); + + if (btf_is_ptr(prev_local_t)) { + bool targ_f = btf_type_kflag(local_t); + + if (local_k == targ_k) + return 1; + + if (targ_k != BTF_KIND_FWD) + return 0; + + return (local_k == BTF_KIND_UNION) == targ_f; + } else { + if (local_k != targ_k) + return 0; + + return bpf_core_composites_match(local_btf, local_t, targ_btf, targ_t, + level); + } + } + case BTF_KIND_INT: { + __u8 local_sgn; + __u8 targ_sgn; + + if (local_k != btf_kind(targ_t)) + return 0; + + local_sgn = btf_int_encoding(local_t) & BTF_INT_SIGNED; + targ_sgn = btf_int_encoding(targ_t) & BTF_INT_SIGNED; + + return btf_int_bits(local_t) == btf_int_bits(targ_t) && local_sgn == targ_sgn; + } + case BTF_KIND_PTR: + if (local_k != btf_kind(targ_t)) + return 0; + + local_id = local_t->type; + targ_id = targ_t->type; + goto recur; + case BTF_KIND_ARRAY: { + const struct btf_array *local_array = btf_type_array(local_t); + const struct btf_array *targ_array = btf_type_array(targ_t); + + if (local_k != btf_kind(targ_t)) + return 0; + + if (local_array->nelems != targ_array->nelems) + return 0; + + local_id = local_array->type; + targ_id = targ_array->type; + goto recur; + } + case BTF_KIND_FUNC_PROTO: { + struct btf_param *local_p = btf_params(local_t); + struct btf_param *targ_p = btf_params(targ_t); + u16 local_vlen = btf_vlen(local_t); + u16 targ_vlen = btf_vlen(targ_t); + int i, err; + + if (local_k != btf_kind(targ_t)) + return 0; + + if (local_vlen != targ_vlen) + return 0; + + for (i = 0; i < local_vlen; i++, local_p++, targ_p++) { + err = __bpf_core_types_match(local_btf, local_p->type, targ_btf, + targ_p->type, level - 1); + if (err <= 0) + return err; + } + + /* tail recurse for return type check */ + local_id = local_t->type; + targ_id = targ_t->type; + goto recur; + } + default: + return 0; + } +} + +int bpf_core_types_match(const struct btf *local_btf, u32 local_id, + const struct btf *targ_btf, u32 targ_id) +{ + return __bpf_core_types_match(local_btf, local_id, + targ_btf, targ_id, + MAX_TYPES_MATCH_DEPTH); +} + static bool bpf_core_is_flavor_sep(const char *s) { /* check X___Y name pattern, where X and Y are not underscores */ From patchwork Mon Jun 20 23:17:10 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Daniel_M=C3=BCller?= X-Patchwork-Id: 12888591 X-Patchwork-Delegate: bpf@iogearbox.net Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 72C68C433EF for ; Mon, 20 Jun 2022 23:23:17 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S244398AbiFTXXQ (ORCPT ); Mon, 20 Jun 2022 19:23:16 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:44500 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1347409AbiFTXXH (ORCPT ); Mon, 20 Jun 2022 19:23:07 -0400 Received: from mout02.posteo.de (mout02.posteo.de [185.67.36.66]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id EC7DE2C116 for ; Mon, 20 Jun 2022 16:18:09 -0700 (PDT) Received: from submission (posteo.de [185.67.36.169]) by mout02.posteo.de (Postfix) with ESMTPS id 534EA240108 for ; Tue, 21 Jun 2022 01:18:08 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=posteo.net; s=2017; t=1655767088; bh=Cq6Nm8JiuyRCdBvioPzT77BBcV2NbrIR8+spzjI0rRg=; h=From:To:Subject:Date:From; b=MR//u4hBU9KzO6RVrVXWldW8deffV/2wiHuNyp1rkRPdFjPVwpoPrKUfIYyrpyGQ6 RLXbcNC5f7oG4DUHixlZw5geeqMfcDwn2VQTTrZ2K9OV31fwD9POlimjNAXFuPJvbC 1uJ/WtE0AXhJk2xGUiprmG4jDUwKyIHfQ+y3esJkMDIKDl1hRCdLPFe8KvPOGgxsTl EfL40rEiBVVugq90li5eaS6QWQ+haHVenZ+GbTODTDrs9SW3TmLOjn3APaWNZmaou0 yKbh3Jn0vwkRFYkNi8iOsX+3KHypmWUbTAQh3NEMkWaSj2xdxjqKqz4ivEPF0hInd3 9NvlO0pkS3wTw== Received: from customer (localhost [127.0.0.1]) by submission (posteo.de) with ESMTPSA id 4LRltl3lm1z6tmj; Tue, 21 Jun 2022 01:18:07 +0200 (CEST) From: =?utf-8?q?Daniel_M=C3=BCller?= To: bpf@vger.kernel.org, ast@kernel.org, andrii@kernel.org, daniel@iogearbox.net, kernel-team@fb.com Subject: [PATCH bpf-next 4/7] libbpf: Add type match support Date: Mon, 20 Jun 2022 23:17:10 +0000 Message-Id: <20220620231713.2143355-5-deso@posteo.net> In-Reply-To: <20220620231713.2143355-1-deso@posteo.net> References: <20220620231713.2143355-1-deso@posteo.net> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: bpf@vger.kernel.org X-Patchwork-Delegate: bpf@iogearbox.net This patch adds support for the proposed type match relation to libbpf. Support of this relation hinges on the corresponding relocation to be understood by LLVM, which is happening as part of D126838 (https://reviews.llvm.org/D126838). The functionality is present behind the newly introduced bpf_core_type_matches macro (similar to bpf_core_type_exists). This macro can be used to check whether a local type has a "match" in a target BTF. The matching relation is defined as follows (copy from source): - modifiers and typedefs are stripped (and, hence, effectively ignored) - generally speaking types need to be of same kind (struct vs. struct, union vs. union, etc.) - exceptions are struct/union behind a pointer which could also match a forward declaration of a struct or union, respectively, and enum vs. enum64 (see below) Then, depending on type: - integers: - match if size and signedness match - arrays & pointers: - target types are recursively matched - structs & unions: - local members need to exist in target with the same name - for each member we recursively check match unless it is already behind a pointer, in which case we only check matching names and compatible kind - enums: - local variants have to have a match in target by symbolic name (but not numeric value) - size has to match (but enum may match enum64 and vice versa) - function pointers: - number and position of arguments in local type has to match target - for each argument and the return value we recursively check match Signed-off-by: Daniel Müller --- tools/lib/bpf/bpf_core_read.h | 10 ++ tools/lib/bpf/libbpf.c | 277 ++++++++++++++++++++++++++++++++++ tools/lib/bpf/relo_core.c | 16 +- tools/lib/bpf/relo_core.h | 2 + 4 files changed, 301 insertions(+), 4 deletions(-) diff --git a/tools/lib/bpf/bpf_core_read.h b/tools/lib/bpf/bpf_core_read.h index 2308f49..496e6a 100644 --- a/tools/lib/bpf/bpf_core_read.h +++ b/tools/lib/bpf/bpf_core_read.h @@ -184,6 +184,16 @@ enum bpf_enum_value_kind { #define bpf_core_type_exists(type) \ __builtin_preserve_type_info(*(typeof(type) *)0, BPF_TYPE_EXISTS) +/* + * Convenience macro to check that provided named type + * (struct/union/enum/typedef) "matches" that in a target kernel. + * Returns: + * 1, if the type matches in the target kernel's BTF; + * 0, if the type does not match any in the target kernel + */ +#define bpf_core_type_matches(type) \ + __builtin_preserve_type_info(*(typeof(type) *)0, BPF_TYPE_MATCHES) + /* * Convenience macro to get the byte size of a provided named type * (struct/union/enum/typedef) in a target kernel. diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c index 49e359c..8f7674 100644 --- a/tools/lib/bpf/libbpf.c +++ b/tools/lib/bpf/libbpf.c @@ -5805,6 +5805,283 @@ int bpf_core_types_are_compat(const struct btf *local_btf, __u32 local_id, } } +static bool bpf_core_names_match(const struct btf *local_btf, __u32 local_id, + const struct btf *targ_btf, __u32 targ_id) +{ + const struct btf_type *local_t, *targ_t; + const char *local_n, *targ_n; + size_t local_len, targ_len; + + local_t = btf__type_by_id(local_btf, local_id); + targ_t = btf__type_by_id(targ_btf, targ_id); + local_n = btf__str_by_offset(local_btf, local_t->name_off); + targ_n = btf__str_by_offset(targ_btf, targ_t->name_off); + local_len = bpf_core_essential_name_len(local_n); + targ_len = bpf_core_essential_name_len(targ_n); + + return local_len == targ_len && strncmp(local_n, targ_n, local_len) == 0; +} + +static int bpf_core_enums_match(const struct btf *local_btf, const struct btf_type *local_t, + const struct btf *targ_btf, const struct btf_type *targ_t) +{ + __u16 local_vlen = btf_vlen(local_t); + __u16 targ_vlen = btf_vlen(targ_t); + int i, j; + + if (local_t->size != targ_t->size) + return 0; + + if (local_vlen > targ_vlen) + return 0; + + /* iterate over the local enum's variants and make sure each has + * a symbolic name correspondent in the target + */ + for (i = 0; i < local_vlen; i++) { + bool matched = false; + const char *local_n; + __u32 local_n_off; + size_t local_len; + + local_n_off = btf_is_enum(local_t) ? btf_enum(local_t)[i].name_off : + btf_enum64(local_t)[i].name_off; + + local_n = btf__str_by_offset(local_btf, local_n_off); + local_len = bpf_core_essential_name_len(local_n); + + for (j = 0; j < targ_vlen; j++) { + __u32 targ_n_off; + const char *targ_n; + size_t targ_len; + + targ_n_off = btf_is_enum(targ_t) ? btf_enum(targ_t)[j].name_off : + btf_enum64(targ_t)[j].name_off; + targ_n = btf__str_by_offset(targ_btf, targ_n_off); + + if (str_is_empty(targ_n)) + continue; + + targ_len = bpf_core_essential_name_len(targ_n); + + if (local_len == targ_len && strncmp(local_n, targ_n, local_len) == 0) { + matched = true; + break; + } + } + + if (!matched) + return 0; + } + return 1; +} + +static int bpf_core_composites_match(const struct btf *local_btf, const struct btf_type *local_t, + const struct btf *targ_btf, const struct btf_type *targ_t) +{ + const struct btf_member *local_m = btf_members(local_t); + __u16 local_vlen = btf_vlen(local_t); + __u16 targ_vlen = btf_vlen(targ_t); + int i, j, err; + + if (local_vlen > targ_vlen) + return 0; + + /* check that all local members have a match in the target */ + for (i = 0; i < local_vlen; i++, local_m++) { + const char *local_n = btf__str_by_offset(local_btf, local_m->name_off); + const struct btf_member *targ_m = btf_members(targ_t); + bool matched = false; + + for (j = 0; j < targ_vlen; j++, targ_m++) { + const char *targ_n = btf__str_by_offset(targ_btf, targ_m->name_off); + + if (str_is_empty(targ_n)) + continue; + + if (strcmp(local_n, targ_n) != 0) + continue; + + err = bpf_core_types_match(local_btf, local_m->type, targ_btf, + targ_m->type); + if (err > 0) { + matched = true; + break; + } + } + + if (!matched) + return 0; + } + return 1; +} + +/* Check that two types "match". + * + * The matching relation is defined as follows: + * - modifiers and typedefs are stripped (and, hence, effectively ignored) + * - generally speaking types need to be of same kind (struct vs. struct, union + * vs. union, etc.) + * - exceptions are struct/union behind a pointer which could also match a + * forward declaration of a struct or union, respectively, and enum vs. + * enum64 (see below) + * Then, depending on type: + * - integers: + * - match if size and signedness match + * - arrays & pointers: + * - target types are recursively matched + * - structs & unions: + * - local members need to exist in target with the same name + * - for each member we recursively check match unless it is already behind a + * pointer, in which case we only check matching names and compatible kind + * - enums: + * - local variants have to have a match in target by symbolic name (but not + * numeric value) + * - size has to match (but enum may match enum64 and vice versa) + * - function pointers: + * - number and position of arguments in local type has to match target + * - for each argument and the return value we recursively check match + */ +int bpf_core_types_match(const struct btf *local_btf, __u32 local_id, + const struct btf *targ_btf, __u32 targ_id) +{ + const struct btf_type *local_t, *targ_t, *prev_local_t; + int depth = 32; /* max recursion depth */ + __u16 local_k; + + local_t = btf__type_by_id(local_btf, local_id); + targ_t = btf__type_by_id(targ_btf, targ_id); + +recur: + depth--; + if (depth < 0) + return -EINVAL; + + prev_local_t = local_t; + + local_t = skip_mods_and_typedefs(local_btf, local_id, &local_id); + targ_t = skip_mods_and_typedefs(targ_btf, targ_id, &targ_id); + if (!local_t || !targ_t) + return -EINVAL; + + if (!bpf_core_names_match(local_btf, local_id, targ_btf, targ_id)) + return 0; + + local_k = btf_kind(local_t); + + switch (local_k) { + case BTF_KIND_UNKN: + return local_k == btf_kind(targ_t); + case BTF_KIND_FWD: { + bool local_f = btf_kflag(local_t); + __u16 targ_k = btf_kind(targ_t); + + if (btf_is_ptr(prev_local_t)) { + if (local_k == targ_k) + return local_f == btf_kflag(local_t); + + return (targ_k == BTF_KIND_STRUCT && !local_f) || + (targ_k == BTF_KIND_UNION && local_f); + } else { + if (local_k != targ_k) + return 0; + + /* match if the forward declaration is for the same kind */ + return local_f == btf_kflag(local_t); + } + } + case BTF_KIND_ENUM: + case BTF_KIND_ENUM64: + if (!btf_is_any_enum(targ_t)) + return 0; + + return bpf_core_enums_match(local_btf, local_t, targ_btf, targ_t); + case BTF_KIND_STRUCT: + case BTF_KIND_UNION: { + __u16 targ_k = btf_kind(targ_t); + + if (btf_is_ptr(prev_local_t)) { + bool targ_f = btf_kflag(local_t); + + if (local_k == targ_k) + return 1; + + if (targ_k != BTF_KIND_FWD) + return 0; + + return (local_k == BTF_KIND_UNION) == targ_f; + } else { + if (local_k != targ_k) + return 0; + + return bpf_core_composites_match(local_btf, local_t, targ_btf, targ_t); + } + } + case BTF_KIND_INT: { + __u8 local_sgn; + __u8 targ_sgn; + + if (local_k != btf_kind(targ_t)) + return 0; + + local_sgn = btf_int_encoding(local_t) & BTF_INT_SIGNED; + targ_sgn = btf_int_encoding(targ_t) & BTF_INT_SIGNED; + + return btf_int_bits(local_t) == btf_int_bits(targ_t) && local_sgn == targ_sgn; + } + case BTF_KIND_PTR: + if (local_k != btf_kind(targ_t)) + return 0; + + local_id = local_t->type; + targ_id = targ_t->type; + goto recur; + case BTF_KIND_ARRAY: { + const struct btf_array *local_array = btf_array(local_t); + const struct btf_array *targ_array = btf_array(targ_t); + + if (local_k != btf_kind(targ_t)) + return 0; + + if (local_array->nelems != targ_array->nelems) + return 0; + + local_id = local_array->type; + targ_id = targ_array->type; + goto recur; + } + case BTF_KIND_FUNC_PROTO: { + struct btf_param *local_p = btf_params(local_t); + struct btf_param *targ_p = btf_params(targ_t); + __u16 local_vlen = btf_vlen(local_t); + __u16 targ_vlen = btf_vlen(targ_t); + int i, err; + + if (local_k != btf_kind(targ_t)) + return 0; + + if (local_vlen != targ_vlen) + return 0; + + for (i = 0; i < local_vlen; i++, local_p++, targ_p++) { + err = bpf_core_types_match(local_btf, local_p->type, targ_btf, + targ_p->type); + if (err <= 0) + return err; + } + + /* tail recurse for return type check */ + local_id = local_t->type; + targ_id = targ_t->type; + goto recur; + } + default: + pr_warn("unexpected kind %s relocated, local [%d], target [%d]\n", + btf_kind_str(local_t), local_id, targ_id); + return 0; + } +} + static size_t bpf_core_hash_fn(const void *key, void *ctx) { return (size_t)key; diff --git a/tools/lib/bpf/relo_core.c b/tools/lib/bpf/relo_core.c index 6ad3c3..bb9b67a 100644 --- a/tools/lib/bpf/relo_core.c +++ b/tools/lib/bpf/relo_core.c @@ -95,6 +95,7 @@ static const char *core_relo_kind_str(enum bpf_core_relo_kind kind) case BPF_CORE_TYPE_ID_LOCAL: return "local_type_id"; case BPF_CORE_TYPE_ID_TARGET: return "target_type_id"; case BPF_CORE_TYPE_EXISTS: return "type_exists"; + case BPF_CORE_TYPE_MATCHES: return "type_matches"; case BPF_CORE_TYPE_SIZE: return "type_size"; case BPF_CORE_ENUMVAL_EXISTS: return "enumval_exists"; case BPF_CORE_ENUMVAL_VALUE: return "enumval_value"; @@ -123,6 +124,7 @@ static bool core_relo_is_type_based(enum bpf_core_relo_kind kind) case BPF_CORE_TYPE_ID_LOCAL: case BPF_CORE_TYPE_ID_TARGET: case BPF_CORE_TYPE_EXISTS: + case BPF_CORE_TYPE_MATCHES: case BPF_CORE_TYPE_SIZE: return true; default: @@ -171,7 +173,7 @@ static bool core_relo_is_enumval_based(enum bpf_core_relo_kind kind) * - field 'a' access (corresponds to '2' in low-level spec); * - array element #3 access (corresponds to '3' in low-level spec). * - * Type-based relocations (TYPE_EXISTS/TYPE_SIZE, + * Type-based relocations (TYPE_EXISTS/TYPE_MATCHES/TYPE_SIZE, * TYPE_ID_LOCAL/TYPE_ID_TARGET) don't capture any field information. Their * spec and raw_spec are kept empty. * @@ -488,9 +490,14 @@ static int bpf_core_spec_match(struct bpf_core_spec *local_spec, targ_spec->relo_kind = local_spec->relo_kind; if (core_relo_is_type_based(local_spec->relo_kind)) { - return bpf_core_types_are_compat(local_spec->btf, - local_spec->root_type_id, - targ_btf, targ_id); + if (local_spec->relo_kind == BPF_CORE_TYPE_MATCHES) + return bpf_core_types_match(local_spec->btf, + local_spec->root_type_id, + targ_btf, targ_id); + else + return bpf_core_types_are_compat(local_spec->btf, + local_spec->root_type_id, + targ_btf, targ_id); } local_acc = &local_spec->spec[0]; @@ -739,6 +746,7 @@ static int bpf_core_calc_type_relo(const struct bpf_core_relo *relo, *validate = false; break; case BPF_CORE_TYPE_EXISTS: + case BPF_CORE_TYPE_MATCHES: *val = 1; break; case BPF_CORE_TYPE_SIZE: diff --git a/tools/lib/bpf/relo_core.h b/tools/lib/bpf/relo_core.h index 7df0da0..6b6afa 100644 --- a/tools/lib/bpf/relo_core.h +++ b/tools/lib/bpf/relo_core.h @@ -70,6 +70,8 @@ struct bpf_core_relo_res { int bpf_core_types_are_compat(const struct btf *local_btf, __u32 local_id, const struct btf *targ_btf, __u32 targ_id); +int bpf_core_types_match(const struct btf *local_btf, __u32 local_id, + const struct btf *targ_btf, __u32 targ_id); size_t bpf_core_essential_name_len(const char *name); From patchwork Mon Jun 20 23:17:11 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Daniel_M=C3=BCller?= X-Patchwork-Id: 12888592 X-Patchwork-Delegate: bpf@iogearbox.net Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 5C259C43334 for ; Mon, 20 Jun 2022 23:23:19 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1347663AbiFTXXR (ORCPT ); Mon, 20 Jun 2022 19:23:17 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:42998 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1347700AbiFTXXI (ORCPT ); Mon, 20 Jun 2022 19:23:08 -0400 Received: from mout02.posteo.de (mout02.posteo.de [185.67.36.66]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id BF0152C13B for ; Mon, 20 Jun 2022 16:18:11 -0700 (PDT) Received: from submission (posteo.de [185.67.36.169]) by mout02.posteo.de (Postfix) with ESMTPS id 51DE1240107 for ; Tue, 21 Jun 2022 01:18:10 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=posteo.net; s=2017; t=1655767090; bh=BMp9XtfX2kj2mjbA+tVPu764UU6HiuGix3rEwLmc2XE=; h=From:To:Subject:Date:From; b=gGsjo9ZfwBSyQ1/FmID8MyEA5kHBASHjA47mp3kHnAgBGttTEtlemg4n1evvZ4ygf ys/gOINXzlSg0U6iZ1R0FhmnsTReetC2oVi2xe5iRfkCFLwMCZaNxUCD00j6hhkNhs muCwB4kZWx79rN4uadmPlXRKgURufqyeF1zaaj25Wz0XjNL9oBDb6WdwJH8to5Sf01 RA4oWjRlgf/vA4nBWF81Zx737BEJNKmReT5gAW4EXWEfq9ffuRAOTU8XKqrlWO9VVB XtPok/QHJ4xODo1vPLaArSmtYpdEFsYH7Wuiy9n+9lPdfBy7BiWlreHCdX+ihXn0dD Jupu+mlmojBhg== Received: from customer (localhost [127.0.0.1]) by submission (posteo.de) with ESMTPSA id 4LRltn4rVWz6tmX; Tue, 21 Jun 2022 01:18:09 +0200 (CEST) From: =?utf-8?q?Daniel_M=C3=BCller?= To: bpf@vger.kernel.org, ast@kernel.org, andrii@kernel.org, daniel@iogearbox.net, kernel-team@fb.com Subject: [PATCH bpf-next 5/7] selftests/bpf: Add type-match checks to type-based tests Date: Mon, 20 Jun 2022 23:17:11 +0000 Message-Id: <20220620231713.2143355-6-deso@posteo.net> In-Reply-To: <20220620231713.2143355-1-deso@posteo.net> References: <20220620231713.2143355-1-deso@posteo.net> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: bpf@vger.kernel.org X-Patchwork-Delegate: bpf@iogearbox.net Now that we have type-match logic in both libbpf and the kernel, this change adjusts the existing BPF self tests to check this functionality. Specifically, we extend the existing type-based tests to check the previously introduced bpf_core_type_matches macro. Signed-off-by: Daniel Müller --- .../selftests/bpf/prog_tests/core_reloc.c | 31 ++++++++++++++++-- .../selftests/bpf/progs/core_reloc_types.h | 14 +++++++- .../bpf/progs/test_core_reloc_type_based.c | 32 ++++++++++++++++++- 3 files changed, 73 insertions(+), 4 deletions(-) diff --git a/tools/testing/selftests/bpf/prog_tests/core_reloc.c b/tools/testing/selftests/bpf/prog_tests/core_reloc.c index 2f92fe..328dd7 100644 --- a/tools/testing/selftests/bpf/prog_tests/core_reloc.c +++ b/tools/testing/selftests/bpf/prog_tests/core_reloc.c @@ -543,7 +543,6 @@ static int __trigger_module_test_read(const struct core_reloc_test_case *test) return 0; } - static const struct core_reloc_test_case test_cases[] = { /* validate we can find kernel image and use its BTF for relocs */ { @@ -752,7 +751,7 @@ static const struct core_reloc_test_case test_cases[] = { SIZE_CASE(size___diff_offs), SIZE_ERR_CASE(size___err_ambiguous), - /* validate type existence and size relocations */ + /* validate type existence, match, and size relocations */ TYPE_BASED_CASE(type_based, { .struct_exists = 1, .union_exists = 1, @@ -765,6 +764,19 @@ static const struct core_reloc_test_case test_cases[] = { .typedef_void_ptr_exists = 1, .typedef_func_proto_exists = 1, .typedef_arr_exists = 1, + + .struct_matches = 1, + .union_matches = 1, + .enum_matches = 1, + .typedef_named_struct_matches = 1, + .typedef_anon_struct_matches = 1, + .typedef_struct_ptr_matches = 1, + .typedef_int_matches = 1, + .typedef_enum_matches = 1, + .typedef_void_ptr_matches = 1, + .typedef_func_proto_matches = 1, + .typedef_arr_matches = 1, + .struct_sz = sizeof(struct a_struct), .union_sz = sizeof(union a_union), .enum_sz = sizeof(enum an_enum), @@ -792,6 +804,19 @@ static const struct core_reloc_test_case test_cases[] = { .typedef_void_ptr_exists = 1, .typedef_func_proto_exists = 1, .typedef_arr_exists = 1, + + .struct_matches = 0, + .union_matches = 0, + .enum_matches = 0, + .typedef_named_struct_matches = 0, + .typedef_anon_struct_matches = 0, + .typedef_struct_ptr_matches = 1, + .typedef_int_matches = 0, + .typedef_enum_matches = 0, + .typedef_void_ptr_matches = 1, + .typedef_func_proto_matches = 0, + .typedef_arr_matches = 0, + .struct_sz = sizeof(struct a_struct___diff_sz), .union_sz = sizeof(union a_union___diff_sz), .enum_sz = sizeof(enum an_enum___diff_sz), @@ -806,10 +831,12 @@ static const struct core_reloc_test_case test_cases[] = { }), TYPE_BASED_CASE(type_based___incompat, { .enum_exists = 1, + .enum_matches = 1, .enum_sz = sizeof(enum an_enum), }), TYPE_BASED_CASE(type_based___fn_wrong_args, { .struct_exists = 1, + .struct_matches = 1, .struct_sz = sizeof(struct a_struct), }), diff --git a/tools/testing/selftests/bpf/progs/core_reloc_types.h b/tools/testing/selftests/bpf/progs/core_reloc_types.h index 26e1033..6a44f3e 100644 --- a/tools/testing/selftests/bpf/progs/core_reloc_types.h +++ b/tools/testing/selftests/bpf/progs/core_reloc_types.h @@ -860,7 +860,7 @@ struct core_reloc_size___err_ambiguous2 { }; /* - * TYPE EXISTENCE & SIZE + * TYPE EXISTENCE, MATCH & SIZE */ struct core_reloc_type_based_output { bool struct_exists; @@ -875,6 +875,18 @@ struct core_reloc_type_based_output { bool typedef_func_proto_exists; bool typedef_arr_exists; + bool struct_matches; + bool union_matches; + bool enum_matches; + bool typedef_named_struct_matches; + bool typedef_anon_struct_matches; + bool typedef_struct_ptr_matches; + bool typedef_int_matches; + bool typedef_enum_matches; + bool typedef_void_ptr_matches; + bool typedef_func_proto_matches; + bool typedef_arr_matches; + int struct_sz; int union_sz; int enum_sz; diff --git a/tools/testing/selftests/bpf/progs/test_core_reloc_type_based.c b/tools/testing/selftests/bpf/progs/test_core_reloc_type_based.c index fb60f8..325ead 100644 --- a/tools/testing/selftests/bpf/progs/test_core_reloc_type_based.c +++ b/tools/testing/selftests/bpf/progs/test_core_reloc_type_based.c @@ -61,6 +61,18 @@ struct core_reloc_type_based_output { bool typedef_func_proto_exists; bool typedef_arr_exists; + bool struct_matches; + bool union_matches; + bool enum_matches; + bool typedef_named_struct_matches; + bool typedef_anon_struct_matches; + bool typedef_struct_ptr_matches; + bool typedef_int_matches; + bool typedef_enum_matches; + bool typedef_void_ptr_matches; + bool typedef_func_proto_matches; + bool typedef_arr_matches; + int struct_sz; int union_sz; int enum_sz; @@ -77,7 +89,13 @@ struct core_reloc_type_based_output { SEC("raw_tracepoint/sys_enter") int test_core_type_based(void *ctx) { -#if __has_builtin(__builtin_preserve_type_info) + /* Support for the BPF_TYPE_MATCHES argument to the + * __builtin_preserve_type_info builtin was added at some point during + * development of clang 15 and it's what we require for this test. Part of it + * could run with merely __builtin_preserve_type_info (which could be checked + * separately), but we have to find an upper bound. + */ +#if __has_builtin(__builtin_preserve_type_info) && __clang_major__ >= 15 struct core_reloc_type_based_output *out = (void *)&data.out; out->struct_exists = bpf_core_type_exists(struct a_struct); @@ -92,6 +110,18 @@ int test_core_type_based(void *ctx) out->typedef_func_proto_exists = bpf_core_type_exists(func_proto_typedef); out->typedef_arr_exists = bpf_core_type_exists(arr_typedef); + out->struct_matches = bpf_core_type_matches(struct a_struct); + out->union_matches = bpf_core_type_matches(union a_union); + out->enum_matches = bpf_core_type_matches(enum an_enum); + out->typedef_named_struct_matches = bpf_core_type_matches(named_struct_typedef); + out->typedef_anon_struct_matches = bpf_core_type_matches(anon_struct_typedef); + out->typedef_struct_ptr_matches = bpf_core_type_matches(struct_ptr_typedef); + out->typedef_int_matches = bpf_core_type_matches(int_typedef); + out->typedef_enum_matches = bpf_core_type_matches(enum_typedef); + out->typedef_void_ptr_matches = bpf_core_type_matches(void_ptr_typedef); + out->typedef_func_proto_matches = bpf_core_type_matches(func_proto_typedef); + out->typedef_arr_matches = bpf_core_type_matches(arr_typedef); + out->struct_sz = bpf_core_type_size(struct a_struct); out->union_sz = bpf_core_type_size(union a_union); out->enum_sz = bpf_core_type_size(enum an_enum); From patchwork Mon Jun 20 23:17:12 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Daniel_M=C3=BCller?= X-Patchwork-Id: 12888593 X-Patchwork-Delegate: bpf@iogearbox.net Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 72F8ACCA47C for ; Mon, 20 Jun 2022 23:23:20 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1346841AbiFTXXS (ORCPT ); Mon, 20 Jun 2022 19:23:18 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:44514 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1346981AbiFTXXJ (ORCPT ); Mon, 20 Jun 2022 19:23:09 -0400 Received: from mout02.posteo.de (mout02.posteo.de [185.67.36.66]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 006182C649 for ; Mon, 20 Jun 2022 16:18:13 -0700 (PDT) Received: from submission (posteo.de [185.67.36.169]) by mout02.posteo.de (Postfix) with ESMTPS id 7CCC7240109 for ; Tue, 21 Jun 2022 01:18:12 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=posteo.net; s=2017; t=1655767092; bh=8m58aPJqeip5Nyyiy5MvdK2kx7zSbD5M92tegFp7+P4=; h=From:To:Subject:Date:From; b=CjU3i/ofnR6UTc9yuwxaGAg8gkaeKMkdWH3ktcONZL3P8IsSc++rKaoTv9dY137DC D/P/csc4T1MjEwPlDK0ITcxeKplU0n6hZbFlg8Y8rz/sJPqxUevPsZ+SFct0FrVR7u Nm1bPrPSV62bqfRxRNKnMYSWt3YDvnHXcMgp7UC+iJQO4jjgZdWBngBHzzV9SBqt+D p1cAFQaAXSH/FfIDT+bAmMbDe5UNCVBth5S4xLzyaVwVpKvEdnV4fLR4a1lYfzqQt1 OYN2nQoE8D6ywkppAQ6qeEZ0xlS3+jCfRKLMrIUBhqz8MZrldkGIIIi1T0mLk4KRpL nlb4q15n/nSXw== Received: from customer (localhost [127.0.0.1]) by submission (posteo.de) with ESMTPSA id 4LRltq5kkKz6tmX; Tue, 21 Jun 2022 01:18:11 +0200 (CEST) From: =?utf-8?q?Daniel_M=C3=BCller?= To: bpf@vger.kernel.org, ast@kernel.org, andrii@kernel.org, daniel@iogearbox.net, kernel-team@fb.com Subject: [PATCH bpf-next 6/7] selftests/bpf: Add test checking more characteristics Date: Mon, 20 Jun 2022 23:17:12 +0000 Message-Id: <20220620231713.2143355-7-deso@posteo.net> In-Reply-To: <20220620231713.2143355-1-deso@posteo.net> References: <20220620231713.2143355-1-deso@posteo.net> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: bpf@vger.kernel.org X-Patchwork-Delegate: bpf@iogearbox.net This change adds another type-based self-test that specifically aims to test some more characteristics of the TYPE_MATCH logic. Specifically, it covers a few more potential differences between types, such as different orders, enum variant values, and integer signedness. Signed-off-by: Daniel Müller --- .../selftests/bpf/prog_tests/core_reloc.c | 37 ++++++++++++++ .../progs/btf__core_reloc_type_based___diff.c | 3 ++ .../selftests/bpf/progs/core_reloc_types.h | 51 +++++++++++++++++++ 3 files changed, 91 insertions(+) create mode 100644 tools/testing/selftests/bpf/progs/btf__core_reloc_type_based___diff.c diff --git a/tools/testing/selftests/bpf/prog_tests/core_reloc.c b/tools/testing/selftests/bpf/prog_tests/core_reloc.c index 328dd7..eb47bf 100644 --- a/tools/testing/selftests/bpf/prog_tests/core_reloc.c +++ b/tools/testing/selftests/bpf/prog_tests/core_reloc.c @@ -792,6 +792,43 @@ static const struct core_reloc_test_case test_cases[] = { TYPE_BASED_CASE(type_based___all_missing, { /* all zeros */ }), + TYPE_BASED_CASE(type_based___diff, { + .struct_exists = 1, + .union_exists = 1, + .enum_exists = 1, + .typedef_named_struct_exists = 1, + .typedef_anon_struct_exists = 1, + .typedef_struct_ptr_exists = 1, + .typedef_int_exists = 1, + .typedef_enum_exists = 1, + .typedef_void_ptr_exists = 1, + .typedef_func_proto_exists = 1, + .typedef_arr_exists = 1, + + .struct_matches = 1, + .union_matches = 1, + .enum_matches = 1, + .typedef_named_struct_matches = 1, + .typedef_anon_struct_matches = 1, + .typedef_struct_ptr_matches = 1, + .typedef_int_matches = 0, + .typedef_enum_matches = 1, + .typedef_void_ptr_matches = 1, + .typedef_func_proto_matches = 0, + .typedef_arr_matches = 0, + + .struct_sz = sizeof(struct a_struct___diff), + .union_sz = sizeof(union a_union___diff), + .enum_sz = sizeof(enum an_enum___diff), + .typedef_named_struct_sz = sizeof(named_struct_typedef___diff), + .typedef_anon_struct_sz = sizeof(anon_struct_typedef___diff), + .typedef_struct_ptr_sz = sizeof(struct_ptr_typedef___diff), + .typedef_int_sz = sizeof(int_typedef___diff), + .typedef_enum_sz = sizeof(enum_typedef___diff), + .typedef_void_ptr_sz = sizeof(void_ptr_typedef___diff), + .typedef_func_proto_sz = sizeof(func_proto_typedef___diff), + .typedef_arr_sz = sizeof(arr_typedef___diff), + }), TYPE_BASED_CASE(type_based___diff_sz, { .struct_exists = 1, .union_exists = 1, diff --git a/tools/testing/selftests/bpf/progs/btf__core_reloc_type_based___diff.c b/tools/testing/selftests/bpf/progs/btf__core_reloc_type_based___diff.c new file mode 100644 index 0000000..57ae2c --- /dev/null +++ b/tools/testing/selftests/bpf/progs/btf__core_reloc_type_based___diff.c @@ -0,0 +1,3 @@ +#include "core_reloc_types.h" + +void f(struct core_reloc_type_based___diff x) {} diff --git a/tools/testing/selftests/bpf/progs/core_reloc_types.h b/tools/testing/selftests/bpf/progs/core_reloc_types.h index 6a44f3e..e326b6 100644 --- a/tools/testing/selftests/bpf/progs/core_reloc_types.h +++ b/tools/testing/selftests/bpf/progs/core_reloc_types.h @@ -951,6 +951,57 @@ struct core_reloc_type_based { struct core_reloc_type_based___all_missing { }; +/* different member orders, enum variant values, signedness, etc */ +struct a_struct___diff { + int x; + int a; +}; + +union a_union___diff { + int z; + int y; +}; + +typedef struct a_struct___diff named_struct_typedef___diff; + +typedef struct { int z, x, y; } anon_struct_typedef___diff; + +typedef struct { + int c; + int b; + int a; +} *struct_ptr_typedef___diff; + +enum an_enum___diff { + AN_ENUM_VAL2___diff = 0, + AN_ENUM_VAL1___diff = 42, + AN_ENUM_VAL3___diff = 1, +}; + +typedef unsigned int int_typedef___diff; + +typedef enum { TYPEDEF_ENUM_VAL2___diff, TYPEDEF_ENUM_VAL1___diff = 50 } enum_typedef___diff; + +typedef const void *void_ptr_typedef___diff; + +typedef int_typedef___diff (*func_proto_typedef___diff)(long); + +typedef char arr_typedef___diff[3]; + +struct core_reloc_type_based___diff { + struct a_struct___diff f1; + union a_union___diff f2; + enum an_enum___diff f3; + named_struct_typedef___diff f4; + anon_struct_typedef___diff f5; + struct_ptr_typedef___diff f6; + int_typedef___diff f7; + enum_typedef___diff f8; + void_ptr_typedef___diff f9; + func_proto_typedef___diff f10; + arr_typedef___diff f11; +}; + /* different type sizes, extra modifiers, anon vs named enums, etc */ struct a_struct___diff_sz { long x; From patchwork Mon Jun 20 23:17:13 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Daniel_M=C3=BCller?= X-Patchwork-Id: 12888594 X-Patchwork-Delegate: bpf@iogearbox.net Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 676CAC43334 for ; Mon, 20 Jun 2022 23:23:22 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1346531AbiFTXXV (ORCPT ); Mon, 20 Jun 2022 19:23:21 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:44710 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1347369AbiFTXXL (ORCPT ); Mon, 20 Jun 2022 19:23:11 -0400 Received: from mout02.posteo.de (mout02.posteo.de [185.67.36.66]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 1F3492C648 for ; Mon, 20 Jun 2022 16:18:16 -0700 (PDT) Received: from submission (posteo.de [185.67.36.169]) by mout02.posteo.de (Postfix) with ESMTPS id 9B03C240107 for ; Tue, 21 Jun 2022 01:18:14 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=posteo.net; s=2017; t=1655767094; bh=/hvehwMkNSOMape3WP4mwp4pPVa6Y6Eo1bGnnvvrfpw=; h=From:To:Subject:Date:From; b=ZH75+EINTQHhpcmnXhJznzfMnDiU7/YK0+hLaiTEN/OfmzesvmdF9DoDa7PbqRFa/ Mw/+1HCPbyysJceIMNANnSnbFT1EQ/8Ehnc9NtQNNuwDstBOgBPkwF37j6h7eNTiCm IYeyBqhNBZV+fO6G4v2PfvmUSUx8OycV+RIVS3g/S2ogRMAIb8/D/1AMXU+i8RbgsS pKxlI+/BY4trcGWIhj2/qQw5tqPFXaIjQjCmB/hY80gCPEiQN8wkGqbyxE8JkGqyKc YA8ty0GpkJSzUkscA/kQ/i1HeFiq89BlJc97icHuUD3HKuHx84jkTWzazOrpqM2J+9 XgTb3rs/jXReA== Received: from customer (localhost [127.0.0.1]) by submission (posteo.de) with ESMTPSA id 4LRlts62Y0z6tmb; Tue, 21 Jun 2022 01:18:13 +0200 (CEST) From: =?utf-8?q?Daniel_M=C3=BCller?= To: bpf@vger.kernel.org, ast@kernel.org, andrii@kernel.org, daniel@iogearbox.net, kernel-team@fb.com Subject: [PATCH bpf-next 7/7] selftests/bpf: Add nested type to type based tests Date: Mon, 20 Jun 2022 23:17:13 +0000 Message-Id: <20220620231713.2143355-8-deso@posteo.net> In-Reply-To: <20220620231713.2143355-1-deso@posteo.net> References: <20220620231713.2143355-1-deso@posteo.net> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: bpf@vger.kernel.org X-Patchwork-Delegate: bpf@iogearbox.net This change extends the type based tests with another struct type (in addition to a_struct) to check relocations against: a_complex_struct. This type is nested more deeply to provide additional coverage of certain paths in the type match logic. Signed-off-by: Daniel Müller --- .../selftests/bpf/prog_tests/core_reloc.c | 4 ++ .../selftests/bpf/progs/core_reloc_types.h | 62 +++++++++++++------ .../bpf/progs/test_core_reloc_type_based.c | 12 ++++ 3 files changed, 58 insertions(+), 20 deletions(-) diff --git a/tools/testing/selftests/bpf/prog_tests/core_reloc.c b/tools/testing/selftests/bpf/prog_tests/core_reloc.c index eb47bf..8882c9c 100644 --- a/tools/testing/selftests/bpf/prog_tests/core_reloc.c +++ b/tools/testing/selftests/bpf/prog_tests/core_reloc.c @@ -754,6 +754,7 @@ static const struct core_reloc_test_case test_cases[] = { /* validate type existence, match, and size relocations */ TYPE_BASED_CASE(type_based, { .struct_exists = 1, + .complex_struct_exists = 1, .union_exists = 1, .enum_exists = 1, .typedef_named_struct_exists = 1, @@ -766,6 +767,7 @@ static const struct core_reloc_test_case test_cases[] = { .typedef_arr_exists = 1, .struct_matches = 1, + .complex_struct_matches = 1, .union_matches = 1, .enum_matches = 1, .typedef_named_struct_matches = 1, @@ -794,6 +796,7 @@ static const struct core_reloc_test_case test_cases[] = { }), TYPE_BASED_CASE(type_based___diff, { .struct_exists = 1, + .complex_struct_exists = 1, .union_exists = 1, .enum_exists = 1, .typedef_named_struct_exists = 1, @@ -806,6 +809,7 @@ static const struct core_reloc_test_case test_cases[] = { .typedef_arr_exists = 1, .struct_matches = 1, + .complex_struct_matches = 1, .union_matches = 1, .enum_matches = 1, .typedef_named_struct_matches = 1, diff --git a/tools/testing/selftests/bpf/progs/core_reloc_types.h b/tools/testing/selftests/bpf/progs/core_reloc_types.h index e326b6..aa265c3 100644 --- a/tools/testing/selftests/bpf/progs/core_reloc_types.h +++ b/tools/testing/selftests/bpf/progs/core_reloc_types.h @@ -864,6 +864,7 @@ struct core_reloc_size___err_ambiguous2 { */ struct core_reloc_type_based_output { bool struct_exists; + bool complex_struct_exists; bool union_exists; bool enum_exists; bool typedef_named_struct_exists; @@ -876,6 +877,7 @@ struct core_reloc_type_based_output { bool typedef_arr_exists; bool struct_matches; + bool complex_struct_matches; bool union_matches; bool enum_matches; bool typedef_named_struct_matches; @@ -904,6 +906,14 @@ struct a_struct { int x; }; +struct a_complex_struct { + union { + struct a_struct *a; + void *b; + } x; + volatile long y; +}; + union a_union { int y; int z; @@ -935,16 +945,17 @@ typedef char arr_typedef[20]; struct core_reloc_type_based { struct a_struct f1; - union a_union f2; - enum an_enum f3; - named_struct_typedef f4; - anon_struct_typedef f5; - struct_ptr_typedef f6; - int_typedef f7; - enum_typedef f8; - void_ptr_typedef f9; - func_proto_typedef f10; - arr_typedef f11; + struct a_complex_struct f2; + union a_union f3; + enum an_enum f4; + named_struct_typedef f5; + anon_struct_typedef f6; + struct_ptr_typedef f7; + int_typedef f8; + enum_typedef f9; + void_ptr_typedef f10; + func_proto_typedef f11; + arr_typedef f12; }; /* no types in target */ @@ -957,6 +968,16 @@ struct a_struct___diff { int a; }; +struct a_struct___forward; + +struct a_complex_struct___diff { + union { + struct a_struct___forward *a; + void *b; + } x; + volatile long y; +}; + union a_union___diff { int z; int y; @@ -990,16 +1011,17 @@ typedef char arr_typedef___diff[3]; struct core_reloc_type_based___diff { struct a_struct___diff f1; - union a_union___diff f2; - enum an_enum___diff f3; - named_struct_typedef___diff f4; - anon_struct_typedef___diff f5; - struct_ptr_typedef___diff f6; - int_typedef___diff f7; - enum_typedef___diff f8; - void_ptr_typedef___diff f9; - func_proto_typedef___diff f10; - arr_typedef___diff f11; + struct a_complex_struct___diff f2; + union a_union___diff f3; + enum an_enum___diff f4; + named_struct_typedef___diff f5; + anon_struct_typedef___diff f6; + struct_ptr_typedef___diff f7; + int_typedef___diff f8; + enum_typedef___diff f9; + void_ptr_typedef___diff f10; + func_proto_typedef___diff f11; + arr_typedef___diff f12; }; /* different type sizes, extra modifiers, anon vs named enums, etc */ diff --git a/tools/testing/selftests/bpf/progs/test_core_reloc_type_based.c b/tools/testing/selftests/bpf/progs/test_core_reloc_type_based.c index 325ead..d95bc08 100644 --- a/tools/testing/selftests/bpf/progs/test_core_reloc_type_based.c +++ b/tools/testing/selftests/bpf/progs/test_core_reloc_type_based.c @@ -19,6 +19,14 @@ struct a_struct { int x; }; +struct a_complex_struct { + union { + struct a_struct *a; + void *b; + } x; + volatile long y; +}; + union a_union { int y; int z; @@ -50,6 +58,7 @@ typedef char arr_typedef[20]; struct core_reloc_type_based_output { bool struct_exists; + bool complex_struct_exists; bool union_exists; bool enum_exists; bool typedef_named_struct_exists; @@ -62,6 +71,7 @@ struct core_reloc_type_based_output { bool typedef_arr_exists; bool struct_matches; + bool complex_struct_matches; bool union_matches; bool enum_matches; bool typedef_named_struct_matches; @@ -99,6 +109,7 @@ int test_core_type_based(void *ctx) struct core_reloc_type_based_output *out = (void *)&data.out; out->struct_exists = bpf_core_type_exists(struct a_struct); + out->complex_struct_exists = bpf_core_type_exists(struct a_complex_struct); out->union_exists = bpf_core_type_exists(union a_union); out->enum_exists = bpf_core_type_exists(enum an_enum); out->typedef_named_struct_exists = bpf_core_type_exists(named_struct_typedef); @@ -111,6 +122,7 @@ int test_core_type_based(void *ctx) out->typedef_arr_exists = bpf_core_type_exists(arr_typedef); out->struct_matches = bpf_core_type_matches(struct a_struct); + out->complex_struct_matches = bpf_core_type_matches(struct a_complex_struct); out->union_matches = bpf_core_type_matches(union a_union); out->enum_matches = bpf_core_type_matches(enum an_enum); out->typedef_named_struct_matches = bpf_core_type_matches(named_struct_typedef);