summaryrefslogtreecommitdiffstats
path: root/tools/lib
diff options
context:
space:
mode:
authorAlan Maguire <alan.maguire@oracle.com>2024-06-20 11:17:30 +0200
committerAndrii Nakryiko <andrii@kernel.org>2024-06-21 23:45:07 +0200
commite7ac331b30555cf1a0826784a346f36dbf800451 (patch)
tree954e49699d647af7a1139b9d4879fc1a1ea52cd8 /tools/lib
parentmodule, bpf: Store BTF base pointer in struct module (diff)
downloadlinux-e7ac331b30555cf1a0826784a346f36dbf800451.tar.xz
linux-e7ac331b30555cf1a0826784a346f36dbf800451.zip
libbpf: Split field iter code into its own file kernel
This will allow it to be shared with the kernel. No functional change. Suggested-by: Andrii Nakryiko <andrii@kernel.org> Signed-off-by: Alan Maguire <alan.maguire@oracle.com> Signed-off-by: Andrii Nakryiko <andrii@kernel.org> Link: https://lore.kernel.org/bpf/20240620091733.1967885-4-alan.maguire@oracle.com
Diffstat (limited to 'tools/lib')
-rw-r--r--tools/lib/bpf/Build2
-rw-r--r--tools/lib/bpf/btf.c162
-rw-r--r--tools/lib/bpf/btf_iter.c169
3 files changed, 170 insertions, 163 deletions
diff --git a/tools/lib/bpf/Build b/tools/lib/bpf/Build
index 336da6844d42..e2cd558ca0b4 100644
--- a/tools/lib/bpf/Build
+++ b/tools/lib/bpf/Build
@@ -1,4 +1,4 @@
libbpf-y := libbpf.o bpf.o nlattr.o btf.o libbpf_errno.o str_error.o \
netlink.o bpf_prog_linfo.o libbpf_probes.o hashmap.o \
btf_dump.o ringbuf.o strset.o linker.o gen_loader.o relo_core.o \
- usdt.o zip.o elf.o features.o btf_relocate.o
+ usdt.o zip.o elf.o features.o btf_iter.o btf_relocate.o
diff --git a/tools/lib/bpf/btf.c b/tools/lib/bpf/btf.c
index ef1b2f573c1b..0c0f60cad769 100644
--- a/tools/lib/bpf/btf.c
+++ b/tools/lib/bpf/btf.c
@@ -5093,168 +5093,6 @@ struct btf *btf__load_module_btf(const char *module_name, struct btf *vmlinux_bt
return btf__parse_split(path, vmlinux_btf);
}
-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_off_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_off_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/btf_iter.c b/tools/lib/bpf/btf_iter.c
new file mode 100644
index 000000000000..c308aa60285d
--- /dev/null
+++ b/tools/lib/bpf/btf_iter.c
@@ -0,0 +1,169 @@
+// SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause)
+/* Copyright (c) 2021 Facebook */
+/* Copyright (c) 2024, Oracle and/or its affiliates. */
+
+#include "btf.h"
+#include "libbpf_internal.h"
+
+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_off_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_off_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;
+}