diff options
Diffstat (limited to 'tools/lib/bpf')
| -rw-r--r-- | tools/lib/bpf/Build | 2 | ||||
| -rw-r--r-- | tools/lib/bpf/btf.c | 162 | ||||
| -rw-r--r-- | tools/lib/bpf/btf_iter.c | 169 | 
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; +} | 
