From patchwork Mon Jun 3 23:17:15 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andrii Nakryiko X-Patchwork-Id: 13684463 X-Patchwork-Delegate: bpf@iogearbox.net Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 1CC9C1E49B for ; Mon, 3 Jun 2024 23:17:28 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1717456649; cv=none; b=h0LgjJk3HkEIqqxTo6vGWS9omBcX8yA/YIYx353+A4iinC7WkucBnlccAnr0oekk4ENyUb+WDcGB0dl7pXk70BN5djxj649Hvj8OzIqwgsUC9JL1uwaVctMYqNveA/73Sm2BPJ/9zVVMR3T6Kl6xDoqp4EFQ1cxlEp+iVxKpS64= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1717456649; c=relaxed/simple; bh=wgURctIi1LwJjXH+1P6dh8Khp9vi/0PcWH7V5U3i9dE=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=aHSwCd4xNWVqteKEl1bLHAhY69/3N1KwqCIrN7Gte475MmSIdGjFyEEo/TJs5cuFwOe1vGbywe0TtUxe8BPGgwmTrbFnLy4BD+8qA908tgjStFQteaICXD8wIx45kiQbr5dQ6+hzdJ7rw+FgZS4b1hxLImLIVBoK/O484ApUFhY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=eLv9Qfxa; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="eLv9Qfxa" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 836CFC2BD10; Mon, 3 Jun 2024 23:17:28 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1717456648; bh=wgURctIi1LwJjXH+1P6dh8Khp9vi/0PcWH7V5U3i9dE=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=eLv9Qfxah1+LrnZ6FzM9k4uUA7qPhWiSBpWXAxiD/fNQS8e6w61/5Yh+DufSyuDHQ kESs4MjIS6fbOBMimE0jIU0hgLcyuXszoSiji61ekcsrj9Iv4fF49ZVha/kJcP9JAA HifDp0hELkTgbS+qpbJY5WfvKhqovMGGitBEMCrClI+LS7x7JhYo+mx7JOW83KSJVv uJML9ZmSFBFHu1SU6SF2ZubAf5GdPSuv+t3daI8jkS11iaF5x5kwPfwX17URfSYRoX zy30h0LGiolEEg6KFAXdKrnsR+Kr6zqdhbN8iIBGrlJNByiGIob+lnVztr1iwWeI6a LbhvUUO0mbSxw== From: Andrii Nakryiko To: bpf@vger.kernel.org, ast@kernel.org, daniel@iogearbox.net, martin.lau@kernel.org Cc: alan.maguire@oracle.com, eddyz87@gmail.com, jolsa@kernel.org, Andrii Nakryiko Subject: [PATCH bpf-next 1/5] libbpf: add BTF field iterator Date: Mon, 3 Jun 2024 16:17:15 -0700 Message-ID: <20240603231720.1893487-2-andrii@kernel.org> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20240603231720.1893487-1-andrii@kernel.org> References: <20240603231720.1893487-1-andrii@kernel.org> Precedence: bulk X-Mailing-List: bpf@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Patchwork-Delegate: bpf@iogearbox.net Implement iterator-based type ID and string offset BTF field iterator. This is used extensively in BTF-handling code and BPF linker code for various sanity checks, rewriting IDs/offsets, etc. Currently this is implemented as visitor pattern calling custom callbacks, which makes the logic (especially in simple cases) unnecessarily obscure and harder to follow. Having equivalent functionality using iterator pattern makes for simpler to understand and maintain code. As we add more code for BTF processing logic in libbpf, it's best to switch to iterator pattern before adding more callback-based code. The idea for iterator-based implementation is to record offsets of necessary fields within fixed btf_type parts (which should be iterated just once), and, for kinds that have multiple members (based on vlen field), record where in each member necessary fields are located. Generic iteration code then just keeps track of last offset that was returned and handles N members correctly. Return type is just u32 pointer, where NULL is returned when all relevant fields were already iterated. Signed-off-by: Andrii Nakryiko Acked-by: Eduard Zingerman --- tools/lib/bpf/btf.c | 162 ++++++++++++++++++++++++++++++++ tools/lib/bpf/libbpf_internal.h | 24 +++++ 2 files changed, 186 insertions(+) diff --git a/tools/lib/bpf/btf.c b/tools/lib/bpf/btf.c index 2d0840ef599a..50ff8b6eaf36 100644 --- a/tools/lib/bpf/btf.c +++ b/tools/lib/bpf/btf.c @@ -5133,6 +5133,168 @@ int btf_type_visit_str_offs(struct btf_type *t, str_off_visit_fn visit, void *ct return 0; } +int btf_field_iter_init(struct btf_field_iter *it, struct btf_type *t, enum btf_field_iter_kind iter_kind) +{ + it->p = NULL; + it->m_idx = -1; + it->off_idx = 0; + it->vlen = 0; + + switch (iter_kind) { + case BTF_FIELD_ITER_IDS: + switch (btf_kind(t)) { + case BTF_KIND_UNKN: + case BTF_KIND_INT: + case BTF_KIND_FLOAT: + case BTF_KIND_ENUM: + case BTF_KIND_ENUM64: + it->desc = (struct btf_field_desc) {}; + break; + case BTF_KIND_FWD: + case BTF_KIND_CONST: + case BTF_KIND_VOLATILE: + case BTF_KIND_RESTRICT: + case BTF_KIND_PTR: + case BTF_KIND_TYPEDEF: + case BTF_KIND_FUNC: + case BTF_KIND_VAR: + case BTF_KIND_DECL_TAG: + case BTF_KIND_TYPE_TAG: + it->desc = (struct btf_field_desc) { 1, {offsetof(struct btf_type, type)} }; + break; + case BTF_KIND_ARRAY: + it->desc = (struct btf_field_desc) { + 2, {sizeof(struct btf_type) + offsetof(struct btf_array, type), + sizeof(struct btf_type) + offsetof(struct btf_array, index_type)} + }; + break; + case BTF_KIND_STRUCT: + case BTF_KIND_UNION: + it->desc = (struct btf_field_desc) { + 0, {}, + sizeof(struct btf_member), + 1, {offsetof(struct btf_member, type)} + }; + break; + case BTF_KIND_FUNC_PROTO: + it->desc = (struct btf_field_desc) { + 1, {offsetof(struct btf_type, type)}, + sizeof(struct btf_param), + 1, {offsetof(struct btf_param, type)} + }; + break; + case BTF_KIND_DATASEC: + it->desc = (struct btf_field_desc) { + 0, {}, + sizeof(struct btf_var_secinfo), + 1, {offsetof(struct btf_var_secinfo, type)} + }; + break; + default: + return -EINVAL; + } + break; + case BTF_FIELD_ITER_STRS: + switch (btf_kind(t)) { + case BTF_KIND_UNKN: + it->desc = (struct btf_field_desc) {}; + break; + case BTF_KIND_INT: + case BTF_KIND_FLOAT: + case BTF_KIND_FWD: + case BTF_KIND_ARRAY: + case BTF_KIND_CONST: + case BTF_KIND_VOLATILE: + case BTF_KIND_RESTRICT: + case BTF_KIND_PTR: + case BTF_KIND_TYPEDEF: + case BTF_KIND_FUNC: + case BTF_KIND_VAR: + case BTF_KIND_DECL_TAG: + case BTF_KIND_TYPE_TAG: + case BTF_KIND_DATASEC: + it->desc = (struct btf_field_desc) { + 1, {offsetof(struct btf_type, name_off)} + }; + break; + case BTF_KIND_ENUM: + it->desc = (struct btf_field_desc) { + 1, {offsetof(struct btf_type, name_off)}, + sizeof(struct btf_enum), + 1, {offsetof(struct btf_enum, name_off)} + }; + break; + case BTF_KIND_ENUM64: + it->desc = (struct btf_field_desc) { + 1, {offsetof(struct btf_type, name_off)}, + sizeof(struct btf_enum64), + 1, {offsetof(struct btf_enum64, name_off)} + }; + break; + case BTF_KIND_STRUCT: + case BTF_KIND_UNION: + it->desc = (struct btf_field_desc) { + 1, {offsetof(struct btf_type, name_off)}, + sizeof(struct btf_member), + 1, {offsetof(struct btf_member, name_off)} + }; + break; + case BTF_KIND_FUNC_PROTO: + it->desc = (struct btf_field_desc) { + 1, {offsetof(struct btf_type, name_off)}, + sizeof(struct btf_param), + 1, {offsetof(struct btf_param, name_off)} + }; + break; + default: + return -EINVAL; + } + break; + default: + return -EINVAL; + } + + if (it->desc.m_sz) + it->vlen = btf_vlen(t); + + it->p = t; + return 0; +} + +__u32 *btf_field_iter_next(struct btf_field_iter *it) +{ + if (!it->p) + return NULL; + + if (it->m_idx < 0) { + if (it->off_idx < it->desc.t_cnt) + return it->p + it->desc.t_offs[it->off_idx++]; + /* move to per-member iteration */ + it->m_idx = 0; + it->p += sizeof(struct btf_type); + it->off_idx = 0; + } + + /* if type doesn't have members, stop */ + if (it->desc.m_sz == 0) { + it->p = NULL; + return NULL; + } + + if (it->off_idx >= it->desc.m_cnt) { + /* exhausted this member's fields, go to the next member */ + it->m_idx++; + it->p += it->desc.m_sz; + it->off_idx = 0; + } + + if (it->m_idx < it->vlen) + return it->p + it->desc.m_offs[it->off_idx++]; + + it->p = NULL; + return NULL; +} + int btf_ext_visit_type_ids(struct btf_ext *btf_ext, type_id_visit_fn visit, void *ctx) { const struct btf_ext_info *seg; diff --git a/tools/lib/bpf/libbpf_internal.h b/tools/lib/bpf/libbpf_internal.h index 7e7e686008c6..80f3d346db33 100644 --- a/tools/lib/bpf/libbpf_internal.h +++ b/tools/lib/bpf/libbpf_internal.h @@ -508,6 +508,30 @@ struct bpf_line_info_min { __u32 line_col; }; +enum btf_field_iter_kind { + BTF_FIELD_ITER_IDS, + BTF_FIELD_ITER_STRS, +}; + +struct btf_field_desc { + /* once-per-type offsets */ + int t_cnt, t_offs[2]; + /* member struct size, or zero, if no members */ + int m_sz; + /* repeated per-member offsets */ + int m_cnt, m_offs[1]; +}; + +struct btf_field_iter { + struct btf_field_desc desc; + void *p; + int m_idx; + int off_idx; + int vlen; +}; + +int btf_field_iter_init(struct btf_field_iter *it, struct btf_type *t, enum btf_field_iter_kind iter_kind); +__u32 *btf_field_iter_next(struct btf_field_iter *it); typedef int (*type_id_visit_fn)(__u32 *type_id, void *ctx); typedef int (*str_off_visit_fn)(__u32 *str_off, void *ctx); From patchwork Mon Jun 3 23:17:16 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andrii Nakryiko X-Patchwork-Id: 13684464 X-Patchwork-Delegate: bpf@iogearbox.net Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 768881E49B for ; Mon, 3 Jun 2024 23:17:32 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1717456652; cv=none; b=R22eqxX3WcSgNHDjmNiE26DxR0tPBQ2peFLNfyNu2KdJMR4aIjYDONCix21qgXWhWb7nRHQ6yDYWZZr2GKNH/QtTyapUOo4JUfYJGVholKDPzl/hkVjomWH5xT+YSxOthAh3p8amHLbO5HzQc6LxHKVDD5iFks1kwb+f2jnkOuY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1717456652; c=relaxed/simple; bh=oTVSjxR+jA2OgYfl8Msx3bwXu90sHWszDziL9fwBy3A=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=uu928kCIBPjxGPe0uOZSktv5hJsfn+k9ZBDu+nWLkfq95N5CwrbgcFQl9YkEz1In72ZdA19HxQIII/EIC+5XHfpbU6iiVDsYhuRKMhIYUisN9Myzsux/Dnj0uzh5oDIIVPk6wrAypXWyt7AZ4dA02BGbyoRbOXqzWW/IUE8graQ= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=P2mf6lFK; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="P2mf6lFK" Received: by smtp.kernel.org (Postfix) with ESMTPSA id CBE82C32782; Mon, 3 Jun 2024 23:17:31 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1717456652; bh=oTVSjxR+jA2OgYfl8Msx3bwXu90sHWszDziL9fwBy3A=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=P2mf6lFKX/MR45XeqxZYeKkPmdZT109LFXBA36gmN7HQrmXNAPZ4j2XSfVu6V8/MR NYUtk15fC3CN3zz1PUgydyLuF0ft2Ym4Oc3FGHA4jyBNkrX7QSSquPAHIkjnQ1Y3fk KpaR++VSP02Y8iYfMa62qYvc1fPhQ5JQ9TKS3YJ1faFoorQtd489cDDdqdLa3S5/PO o7NATCeqwo7V2gAYI/awIEzfdySCAoHShTsU+uWdfp8NlDsf0RyAkAdFlPhuME0Cmj fwv5GPmbpDdLHE1/zRzLAT2C+qOj/HQGDbAqpgmUts/9Kxr5H0GEeIlChqruthfIDA eWHhLnl7KUQVw== From: Andrii Nakryiko To: bpf@vger.kernel.org, ast@kernel.org, daniel@iogearbox.net, martin.lau@kernel.org Cc: alan.maguire@oracle.com, eddyz87@gmail.com, jolsa@kernel.org, Andrii Nakryiko Subject: [PATCH bpf-next 2/5] libbpf: make use of BTF field iterator in BPF linker code Date: Mon, 3 Jun 2024 16:17:16 -0700 Message-ID: <20240603231720.1893487-3-andrii@kernel.org> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20240603231720.1893487-1-andrii@kernel.org> References: <20240603231720.1893487-1-andrii@kernel.org> Precedence: bulk X-Mailing-List: bpf@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Patchwork-Delegate: bpf@iogearbox.net Switch all BPF linker code dealing with iterating BTF type ID and string offset fields to new btf_field_iter facilities. Signed-off-by: Andrii Nakryiko Acked-by: Jiri Olsa --- tools/lib/bpf/linker.c | 60 ++++++++++++++++++++++++++---------------- 1 file changed, 38 insertions(+), 22 deletions(-) diff --git a/tools/lib/bpf/linker.c b/tools/lib/bpf/linker.c index 0d4be829551b..be6539e59cf6 100644 --- a/tools/lib/bpf/linker.c +++ b/tools/lib/bpf/linker.c @@ -957,19 +957,35 @@ static int check_btf_str_off(__u32 *str_off, void *ctx) static int linker_sanity_check_btf(struct src_obj *obj) { struct btf_type *t; - int i, n, err = 0; + int i, n, err; if (!obj->btf) return 0; n = btf__type_cnt(obj->btf); for (i = 1; i < n; i++) { + struct btf_field_iter it; + __u32 *type_id, *str_off; + const char *s; + t = btf_type_by_id(obj->btf, i); - err = err ?: btf_type_visit_type_ids(t, check_btf_type_id, obj->btf); - err = err ?: btf_type_visit_str_offs(t, check_btf_str_off, obj->btf); + err = btf_field_iter_init(&it, t, BTF_FIELD_ITER_IDS); if (err) return err; + while ((type_id = btf_field_iter_next(&it))) { + if (*type_id >= n) + return -EINVAL; + } + + err = btf_field_iter_init(&it, t, BTF_FIELD_ITER_STRS); + if (err) + return err; + while ((str_off = btf_field_iter_next(&it))) { + s = btf__str_by_offset(obj->btf, *str_off); + if (!s) + return -EINVAL; + } } return 0; @@ -2234,26 +2250,10 @@ static int linker_fixup_btf(struct src_obj *obj) return 0; } -static int remap_type_id(__u32 *type_id, void *ctx) -{ - int *id_map = ctx; - int new_id = id_map[*type_id]; - - /* Error out if the type wasn't remapped. Ignore VOID which stays VOID. */ - if (new_id == 0 && *type_id != 0) { - pr_warn("failed to find new ID mapping for original BTF type ID %u\n", *type_id); - return -EINVAL; - } - - *type_id = id_map[*type_id]; - - return 0; -} - static int linker_append_btf(struct bpf_linker *linker, struct src_obj *obj) { const struct btf_type *t; - int i, j, n, start_id, id; + int i, j, n, start_id, id, err; const char *name; if (!obj->btf) @@ -2324,9 +2324,25 @@ static int linker_append_btf(struct bpf_linker *linker, struct src_obj *obj) n = btf__type_cnt(linker->btf); for (i = start_id; i < n; i++) { struct btf_type *dst_t = btf_type_by_id(linker->btf, i); + struct btf_field_iter it; + __u32 *type_id; - if (btf_type_visit_type_ids(dst_t, remap_type_id, obj->btf_type_map)) - return -EINVAL; + err = btf_field_iter_init(&it, dst_t, BTF_FIELD_ITER_IDS); + if (err) + return err; + + while ((type_id = btf_field_iter_next(&it))) { + int new_id = obj->btf_type_map[*type_id]; + + /* Error out if the type wasn't remapped. Ignore VOID which stays VOID. */ + if (new_id == 0 && *type_id != 0) { + pr_warn("failed to find new ID mapping for original BTF type ID %u\n", + *type_id); + return -EINVAL; + } + + *type_id = obj->btf_type_map[*type_id]; + } } /* Rewrite VAR/FUNC underlying types (i.e., FUNC's FUNC_PROTO and VAR's From patchwork Mon Jun 3 23:17:17 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andrii Nakryiko X-Patchwork-Id: 13684465 X-Patchwork-Delegate: bpf@iogearbox.net Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id A87EB84055 for ; Mon, 3 Jun 2024 23:17:35 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1717456655; cv=none; b=R/6rtJJslX4tocDeuHrOr5cMjTE4m8+nKqzq50lNy3C9iP6GTfT+YAxB5lWosEbMtJCQD9f8IEmgIyzXmqyEZMZWBtqt2kgpts4CXdhCHiYqjorvYpP90lfQ2fo+9wR8LbBQlQ49OgsuC8zcJ44VTMy87rHGIrmcwiUIcxb0Flg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1717456655; c=relaxed/simple; bh=DAbruQv5kKT15Q4Uucq3RZAxlQHuTATCqOHNs7CR+v0=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=TP/RZI1PiwB4nE8azrYLF8vTUEj0jfyHrxm1tTGBxQfJjZorQQn8GVeOGUTVjQLFw1GgdclhJgLMJ/+pawysYujh4r0AGNmkmEFM2zWQEoCOoVhyJWRLNi7G8kGbuIG4mbkTe623WnbkRgvVojTDr1s/kXT+H5zPH5aFrI5pqRM= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=IS3kGMPH; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="IS3kGMPH" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 11D43C2BD10; Mon, 3 Jun 2024 23:17:35 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1717456655; bh=DAbruQv5kKT15Q4Uucq3RZAxlQHuTATCqOHNs7CR+v0=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=IS3kGMPHNoaY7+XvaDbqRfBPVbJMgKSanhuqVGQXorZr3OJAFM7Mg1B570AlbjQza JXrq70+4YmhVRVfgQlltMdKJEDNOP27kbRi5sxiuZT4zRTXkgdzHxJye72zwb9cwAx /Sqkf/NU4fyBkw475EqTQFqT89ZaeI7kGakJ6p01mpxXhsy04hpYbuvXdmaatqcHzI 0g+YN8TmnBJtw/D2vIUx7aRSOOPVPh+oqaaDQxJpRhrlYuZbVrKr0iNzh3HzCoY4Wh i3HeMqtq7LE+2z7orcr7SdZgejjWe2JpeFw/KlpAYkKcLJAyuV/K3lQdfOhWDg6pZz N9l57s9geAruA== From: Andrii Nakryiko To: bpf@vger.kernel.org, ast@kernel.org, daniel@iogearbox.net, martin.lau@kernel.org Cc: alan.maguire@oracle.com, eddyz87@gmail.com, jolsa@kernel.org, Andrii Nakryiko Subject: [PATCH bpf-next 3/5] libbpf: make use of BTF field iterator in BTF handling code Date: Mon, 3 Jun 2024 16:17:17 -0700 Message-ID: <20240603231720.1893487-4-andrii@kernel.org> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20240603231720.1893487-1-andrii@kernel.org> References: <20240603231720.1893487-1-andrii@kernel.org> Precedence: bulk X-Mailing-List: bpf@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Patchwork-Delegate: bpf@iogearbox.net Use new BTF field iterator logic to replace all the callback-based visitor calls. There is still a .BTF.ext callback-based visitor APIs that should be converted, which will happens as a follow up. Signed-off-by: Andrii Nakryiko --- tools/lib/bpf/btf.c | 76 ++++++++++++++++++++++++++++++++------------- 1 file changed, 54 insertions(+), 22 deletions(-) diff --git a/tools/lib/bpf/btf.c b/tools/lib/bpf/btf.c index 50ff8b6eaf36..3fe20a902b42 100644 --- a/tools/lib/bpf/btf.c +++ b/tools/lib/bpf/btf.c @@ -1739,9 +1739,8 @@ struct btf_pipe { struct hashmap *str_off_map; /* map string offsets from src to dst */ }; -static int btf_rewrite_str(__u32 *str_off, void *ctx) +static int btf_rewrite_str(struct btf_pipe *p, __u32 *str_off) { - struct btf_pipe *p = ctx; long mapped_off; int off, err; @@ -1774,7 +1773,9 @@ static int btf_rewrite_str(__u32 *str_off, void *ctx) int btf__add_type(struct btf *btf, const struct btf *src_btf, const struct btf_type *src_type) { struct btf_pipe p = { .src = src_btf, .dst = btf }; + struct btf_field_iter it; struct btf_type *t; + __u32 *str_off; int sz, err; sz = btf_type_size(src_type); @@ -1791,26 +1792,17 @@ int btf__add_type(struct btf *btf, const struct btf *src_btf, const struct btf_t memcpy(t, src_type, sz); - err = btf_type_visit_str_offs(t, btf_rewrite_str, &p); + err = btf_field_iter_init(&it, t, BTF_FIELD_ITER_STRS); if (err) return libbpf_err(err); - return btf_commit_type(btf, sz); -} - -static int btf_rewrite_type_ids(__u32 *type_id, void *ctx) -{ - struct btf *btf = ctx; - - if (!*type_id) /* nothing to do for VOID references */ - return 0; + while ((str_off = btf_field_iter_next(&it))) { + err = btf_rewrite_str(&p, str_off); + if (err) + return libbpf_err(err); + } - /* we haven't updated btf's type count yet, so - * btf->start_id + btf->nr_types - 1 is the type ID offset we should - * add to all newly added BTF types - */ - *type_id += btf->start_id + btf->nr_types - 1; - return 0; + return btf_commit_type(btf, sz); } static size_t btf_dedup_identity_hash_fn(long key, void *ctx); @@ -1858,6 +1850,9 @@ int btf__add_btf(struct btf *btf, const struct btf *src_btf) memcpy(t, src_btf->types_data, data_sz); for (i = 0; i < cnt; i++) { + struct btf_field_iter it; + __u32 *type_id, *str_off; + sz = btf_type_size(t); if (sz < 0) { /* unlikely, has to be corrupted src_btf */ @@ -1869,15 +1864,31 @@ int btf__add_btf(struct btf *btf, const struct btf *src_btf) *off = t - btf->types_data; /* add, dedup, and remap strings referenced by this BTF type */ - err = btf_type_visit_str_offs(t, btf_rewrite_str, &p); + err = btf_field_iter_init(&it, t, BTF_FIELD_ITER_STRS); if (err) goto err_out; + while ((str_off = btf_field_iter_next(&it))) { + err = btf_rewrite_str(&p, str_off); + if (err) + goto err_out; + } /* remap all type IDs referenced from this BTF type */ - err = btf_type_visit_type_ids(t, btf_rewrite_type_ids, btf); + err = btf_field_iter_init(&it, t, BTF_FIELD_ITER_IDS); if (err) goto err_out; + while ((type_id = btf_field_iter_next(&it))) { + if (!*type_id) /* nothing to do for VOID references */ + continue; + + /* we haven't updated btf's type count yet, so + * btf->start_id + btf->nr_types - 1 is the type ID offset we should + * add to all newly added BTF types + */ + *type_id += btf->start_id + btf->nr_types - 1; + } + /* go to next type data and type offset index entry */ t += sz; off++; @@ -3453,11 +3464,19 @@ static int btf_for_each_str_off(struct btf_dedup *d, str_off_visit_fn fn, void * int i, r; for (i = 0; i < d->btf->nr_types; i++) { + struct btf_field_iter it; struct btf_type *t = btf_type_by_id(d->btf, d->btf->start_id + i); + __u32 *str_off; - r = btf_type_visit_str_offs(t, fn, ctx); + r = btf_field_iter_init(&it, t, BTF_FIELD_ITER_STRS); if (r) return r; + + while ((str_off = btf_field_iter_next(&it))) { + r = fn(str_off, ctx); + if (r) + return r; + } } if (!d->btf_ext) @@ -4919,10 +4938,23 @@ static int btf_dedup_remap_types(struct btf_dedup *d) for (i = 0; i < d->btf->nr_types; i++) { struct btf_type *t = btf_type_by_id(d->btf, d->btf->start_id + i); + struct btf_field_iter it; + __u32 *type_id; - r = btf_type_visit_type_ids(t, btf_dedup_remap_type_id, d); + r = btf_field_iter_init(&it, t, BTF_FIELD_ITER_IDS); if (r) return r; + + while ((type_id = btf_field_iter_next(&it))) { + __u32 resolved_id, new_id; + + resolved_id = resolve_type_id(d, *type_id); + new_id = d->hypot_map[resolved_id]; + if (new_id > BTF_MAX_NR_TYPES) + return -EINVAL; + + *type_id = new_id; + } } if (!d->btf_ext) From patchwork Mon Jun 3 23:17:18 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andrii Nakryiko X-Patchwork-Id: 13684466 X-Patchwork-Delegate: bpf@iogearbox.net Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 9E17F1E49B for ; Mon, 3 Jun 2024 23:17:38 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1717456658; cv=none; b=m8HWK2EvLq7Rg0SzwZCltda8v5h6NSQPNBpsWs+a3UVOArfI4jUQlCzZDzarkQOqvNbg/6xj+5yiMOHo5MofqM8F6iufMVYqseFJFWS4sG9/CTepUfA8f/poyDJJrHuqSwI+ZEBiB5viRiMA3h9FCfM9HM1BONlRIX8wEmwnvdU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1717456658; c=relaxed/simple; bh=ZY6Zk9/nmbAxgm3FKkaBtYgNAaDWbv7PsePRVgeWcxE=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=thxzstJoKHnPzXvTqe+0oODY0E7bnJNxIgRL/R6O9pFOe5yCfpw8dCOHknrqIACeH1L47JqwnnKTX8pgIpHSu3bbzAJytuDLK4XZmv/0sXWc7NCOtZtsPq6eAuswVd4V6X1UntPIW4YaHv+6rZLNxOyQ/3XfNDZ0F8nEOZ6AR2Q= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=c2eSj/az; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="c2eSj/az" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 545CDC2BD10; Mon, 3 Jun 2024 23:17:38 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1717456658; bh=ZY6Zk9/nmbAxgm3FKkaBtYgNAaDWbv7PsePRVgeWcxE=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=c2eSj/azJPbiUNjWb0TX/U8NZ4w6epwD1YeI/bYSv1+9q+FPR9Dl5HHm1IbENPa1s TwOgfxV3n6LE6Dti4QfIW1RyiIjAkL30M3kKUKyZDUqsdPtXdK3IglFzWOJ4gZjufY rvbvCzeIeC2kc7mBy0/WR28Csz2Ci5bSMq/DgnUqHxgq3fPsyfqrtnSIFf/ZBYyvA5 0jUxfc9m+yQC0Yl9n4JHAYiSRFAgYj5rA9ylCHDNpcnrztlYU8ynzGtHhKmPTN6L8P 43OwcWOXUI76A1fYWH1Td9InRoubc6DJPoZJ8RqujWlFUJik0BGhrx1KahUo3RIULo NaD55Q14+aZGQ== From: Andrii Nakryiko To: bpf@vger.kernel.org, ast@kernel.org, daniel@iogearbox.net, martin.lau@kernel.org Cc: alan.maguire@oracle.com, eddyz87@gmail.com, jolsa@kernel.org, Andrii Nakryiko Subject: [PATCH bpf-next 4/5] bpftool: use BTF field iterator in btfgen Date: Mon, 3 Jun 2024 16:17:18 -0700 Message-ID: <20240603231720.1893487-5-andrii@kernel.org> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20240603231720.1893487-1-andrii@kernel.org> References: <20240603231720.1893487-1-andrii@kernel.org> Precedence: bulk X-Mailing-List: bpf@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Patchwork-Delegate: bpf@iogearbox.net Switch bpftool's code which is using libbpf-internal btf_type_visit_type_ids() helper to new btf_field_iter functionality. This makes bpftool code simpler, but also unblocks removing libbpf's btf_type_visit_type_ids() helper completely. Signed-off-by: Andrii Nakryiko Reviewed-by: Quentin Monnet --- tools/bpf/bpftool/gen.c | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/tools/bpf/bpftool/gen.c b/tools/bpf/bpftool/gen.c index b3979ddc0189..d244a7de387e 100644 --- a/tools/bpf/bpftool/gen.c +++ b/tools/bpf/bpftool/gen.c @@ -2379,15 +2379,6 @@ static int btfgen_record_obj(struct btfgen_info *info, const char *obj_path) return err; } -static int btfgen_remap_id(__u32 *type_id, void *ctx) -{ - unsigned int *ids = ctx; - - *type_id = ids[*type_id]; - - return 0; -} - /* Generate BTF from relocation information previously recorded */ static struct btf *btfgen_get_btf(struct btfgen_info *info) { @@ -2467,10 +2458,15 @@ static struct btf *btfgen_get_btf(struct btfgen_info *info) /* second pass: fix up type ids */ for (i = 1; i < btf__type_cnt(btf_new); i++) { struct btf_type *btf_type = (struct btf_type *) btf__type_by_id(btf_new, i); + struct btf_field_iter it; + __u32 *type_id; - err = btf_type_visit_type_ids(btf_type, btfgen_remap_id, ids); + err = btf_field_iter_init(&it, btf_type, BTF_FIELD_ITER_IDS); if (err) goto err_out; + + while ((type_id = btf_field_iter_next(&it))) + *type_id = ids[*type_id]; } free(ids); From patchwork Mon Jun 3 23:17:19 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andrii Nakryiko X-Patchwork-Id: 13684467 X-Patchwork-Delegate: bpf@iogearbox.net Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 21C6B8288C for ; Mon, 3 Jun 2024 23:17:41 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1717456662; cv=none; b=PZ6PV2wfVC3xyXNrkWqauuk3GR/9MROABubsCFZ2J4bGW6RrTUMM9TXfzLgDTTPoT0swFQKjDqtK6K/BIHdRLtsK5XTPnwQh0we5cTREevv/5hT30zDi39oscXm/G26IfL4yQ3PtvvNaS+vQpQU3buDPSHgJFRIB9aVoevXy6o0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1717456662; c=relaxed/simple; bh=ggdkdBldqpULad9DarJ0PtFEQgMPEPDUz5Ll1eNrAqw=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=tYepT59N9+fIzC60AkA1SxNVLxRe4JRQCMdG7CC2Q015Ogg47qb50XVafCVXe50l0YAoaB/sz4iW0JUMG1DemCLZiti3FgoMXNC+IShBtaLoUrIOBwcTIiMb5k1d4N7sm+OVFtBCabqeMcFtuv/jgv3uX87H1qw0/ARWLaEu7PQ= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=CqQsb26/; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="CqQsb26/" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 9EDB6C2BD10; Mon, 3 Jun 2024 23:17:41 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1717456661; bh=ggdkdBldqpULad9DarJ0PtFEQgMPEPDUz5Ll1eNrAqw=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=CqQsb26/7OliP/IWm3pHWOf3kAabR5YfMtvgjoT3tta5UNRW7v5KDRqkLoOAnZVbv IfDgtzZR1K6B5QY6WMRoATZJ4A4ScIilEuFQ3CdEt4rK+2OPWqkZADxlW8t303+rvi 4AS2S1oXk/rFF0TfWKajyOIAiTZyAOY92XgERmixweWDC/F5w0OPsoboiTIV684zyu Pqa7Tp1QNnSoJSG67BS1v3PxQSuILAukrvuxns7CKU2bIb3v4tPkmkngfb6s3aoqr6 +bbCmGcR8E6CR2GYsYQInC1EExwRartndrcUggAt4eoUyLZB8E9A4mAI30pPiCPvyv JgpXL4sUZKZ4A== From: Andrii Nakryiko To: bpf@vger.kernel.org, ast@kernel.org, daniel@iogearbox.net, martin.lau@kernel.org Cc: alan.maguire@oracle.com, eddyz87@gmail.com, jolsa@kernel.org, Andrii Nakryiko Subject: [PATCH bpf-next 5/5] libbpf: remove callback-based type/string BTF field visitor helpers Date: Mon, 3 Jun 2024 16:17:19 -0700 Message-ID: <20240603231720.1893487-6-andrii@kernel.org> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20240603231720.1893487-1-andrii@kernel.org> References: <20240603231720.1893487-1-andrii@kernel.org> Precedence: bulk X-Mailing-List: bpf@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Patchwork-Delegate: bpf@iogearbox.net Now that all libbpf/bpftool code switched to btf_field_iter, remove btf_type_visit_type_ids() and btf_type_visit_str_offs() callback-based helpers as not needed anymore. Signed-off-by: Andrii Nakryiko --- tools/lib/bpf/btf.c | 130 -------------------------------- tools/lib/bpf/libbpf_internal.h | 2 - 2 files changed, 132 deletions(-) diff --git a/tools/lib/bpf/btf.c b/tools/lib/bpf/btf.c index 3fe20a902b42..1de7579f2a08 100644 --- a/tools/lib/bpf/btf.c +++ b/tools/lib/bpf/btf.c @@ -5035,136 +5035,6 @@ struct btf *btf__load_module_btf(const char *module_name, struct btf *vmlinux_bt return btf__parse_split(path, vmlinux_btf); } -int btf_type_visit_type_ids(struct btf_type *t, type_id_visit_fn visit, void *ctx) -{ - int i, n, err; - - switch (btf_kind(t)) { - case BTF_KIND_INT: - case BTF_KIND_FLOAT: - case BTF_KIND_ENUM: - case BTF_KIND_ENUM64: - return 0; - - case BTF_KIND_FWD: - case BTF_KIND_CONST: - case BTF_KIND_VOLATILE: - case BTF_KIND_RESTRICT: - case BTF_KIND_PTR: - case BTF_KIND_TYPEDEF: - case BTF_KIND_FUNC: - case BTF_KIND_VAR: - case BTF_KIND_DECL_TAG: - case BTF_KIND_TYPE_TAG: - return visit(&t->type, ctx); - - case BTF_KIND_ARRAY: { - struct btf_array *a = btf_array(t); - - err = visit(&a->type, ctx); - err = err ?: visit(&a->index_type, ctx); - return err; - } - - case BTF_KIND_STRUCT: - case BTF_KIND_UNION: { - struct btf_member *m = btf_members(t); - - for (i = 0, n = btf_vlen(t); i < n; i++, m++) { - err = visit(&m->type, ctx); - if (err) - return err; - } - return 0; - } - - case BTF_KIND_FUNC_PROTO: { - struct btf_param *m = btf_params(t); - - err = visit(&t->type, ctx); - if (err) - return err; - for (i = 0, n = btf_vlen(t); i < n; i++, m++) { - err = visit(&m->type, ctx); - if (err) - return err; - } - return 0; - } - - case BTF_KIND_DATASEC: { - struct btf_var_secinfo *m = btf_var_secinfos(t); - - for (i = 0, n = btf_vlen(t); i < n; i++, m++) { - err = visit(&m->type, ctx); - if (err) - return err; - } - return 0; - } - - default: - return -EINVAL; - } -} - -int btf_type_visit_str_offs(struct btf_type *t, str_off_visit_fn visit, void *ctx) -{ - int i, n, err; - - err = visit(&t->name_off, ctx); - if (err) - return err; - - switch (btf_kind(t)) { - case BTF_KIND_STRUCT: - case BTF_KIND_UNION: { - struct btf_member *m = btf_members(t); - - for (i = 0, n = btf_vlen(t); i < n; i++, m++) { - err = visit(&m->name_off, ctx); - if (err) - return err; - } - break; - } - case BTF_KIND_ENUM: { - struct btf_enum *m = btf_enum(t); - - for (i = 0, n = btf_vlen(t); i < n; i++, m++) { - err = visit(&m->name_off, ctx); - if (err) - return err; - } - break; - } - case BTF_KIND_ENUM64: { - struct btf_enum64 *m = btf_enum64(t); - - for (i = 0, n = btf_vlen(t); i < n; i++, m++) { - err = visit(&m->name_off, ctx); - if (err) - return err; - } - break; - } - case BTF_KIND_FUNC_PROTO: { - struct btf_param *m = btf_params(t); - - for (i = 0, n = btf_vlen(t); i < n; i++, m++) { - err = visit(&m->name_off, ctx); - if (err) - return err; - } - break; - } - default: - break; - } - - return 0; -} - int btf_field_iter_init(struct btf_field_iter *it, struct btf_type *t, enum btf_field_iter_kind iter_kind) { it->p = NULL; diff --git a/tools/lib/bpf/libbpf_internal.h b/tools/lib/bpf/libbpf_internal.h index 80f3d346db33..9f4a04367287 100644 --- a/tools/lib/bpf/libbpf_internal.h +++ b/tools/lib/bpf/libbpf_internal.h @@ -535,8 +535,6 @@ __u32 *btf_field_iter_next(struct btf_field_iter *it); typedef int (*type_id_visit_fn)(__u32 *type_id, void *ctx); typedef int (*str_off_visit_fn)(__u32 *str_off, void *ctx); -int btf_type_visit_type_ids(struct btf_type *t, type_id_visit_fn visit, void *ctx); -int btf_type_visit_str_offs(struct btf_type *t, str_off_visit_fn visit, void *ctx); int btf_ext_visit_type_ids(struct btf_ext *btf_ext, type_id_visit_fn visit, void *ctx); int btf_ext_visit_str_offs(struct btf_ext *btf_ext, str_off_visit_fn visit, void *ctx); __s32 btf__find_by_name_kind_own(const struct btf *btf, const char *type_name,