Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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

authored by

Alan Maguire and committed by
Andrii Nakryiko
e7ac331b d4e48e3d

+170 -163
+1 -1
tools/lib/bpf/Build
··· 1 1 libbpf-y := libbpf.o bpf.o nlattr.o btf.o libbpf_errno.o str_error.o \ 2 2 netlink.o bpf_prog_linfo.o libbpf_probes.o hashmap.o \ 3 3 btf_dump.o ringbuf.o strset.o linker.o gen_loader.o relo_core.o \ 4 - usdt.o zip.o elf.o features.o btf_relocate.o 4 + usdt.o zip.o elf.o features.o btf_iter.o btf_relocate.o
-162
tools/lib/bpf/btf.c
··· 5093 5093 return btf__parse_split(path, vmlinux_btf); 5094 5094 } 5095 5095 5096 - int btf_field_iter_init(struct btf_field_iter *it, struct btf_type *t, enum btf_field_iter_kind iter_kind) 5097 - { 5098 - it->p = NULL; 5099 - it->m_idx = -1; 5100 - it->off_idx = 0; 5101 - it->vlen = 0; 5102 - 5103 - switch (iter_kind) { 5104 - case BTF_FIELD_ITER_IDS: 5105 - switch (btf_kind(t)) { 5106 - case BTF_KIND_UNKN: 5107 - case BTF_KIND_INT: 5108 - case BTF_KIND_FLOAT: 5109 - case BTF_KIND_ENUM: 5110 - case BTF_KIND_ENUM64: 5111 - it->desc = (struct btf_field_desc) {}; 5112 - break; 5113 - case BTF_KIND_FWD: 5114 - case BTF_KIND_CONST: 5115 - case BTF_KIND_VOLATILE: 5116 - case BTF_KIND_RESTRICT: 5117 - case BTF_KIND_PTR: 5118 - case BTF_KIND_TYPEDEF: 5119 - case BTF_KIND_FUNC: 5120 - case BTF_KIND_VAR: 5121 - case BTF_KIND_DECL_TAG: 5122 - case BTF_KIND_TYPE_TAG: 5123 - it->desc = (struct btf_field_desc) { 1, {offsetof(struct btf_type, type)} }; 5124 - break; 5125 - case BTF_KIND_ARRAY: 5126 - it->desc = (struct btf_field_desc) { 5127 - 2, {sizeof(struct btf_type) + offsetof(struct btf_array, type), 5128 - sizeof(struct btf_type) + offsetof(struct btf_array, index_type)} 5129 - }; 5130 - break; 5131 - case BTF_KIND_STRUCT: 5132 - case BTF_KIND_UNION: 5133 - it->desc = (struct btf_field_desc) { 5134 - 0, {}, 5135 - sizeof(struct btf_member), 5136 - 1, {offsetof(struct btf_member, type)} 5137 - }; 5138 - break; 5139 - case BTF_KIND_FUNC_PROTO: 5140 - it->desc = (struct btf_field_desc) { 5141 - 1, {offsetof(struct btf_type, type)}, 5142 - sizeof(struct btf_param), 5143 - 1, {offsetof(struct btf_param, type)} 5144 - }; 5145 - break; 5146 - case BTF_KIND_DATASEC: 5147 - it->desc = (struct btf_field_desc) { 5148 - 0, {}, 5149 - sizeof(struct btf_var_secinfo), 5150 - 1, {offsetof(struct btf_var_secinfo, type)} 5151 - }; 5152 - break; 5153 - default: 5154 - return -EINVAL; 5155 - } 5156 - break; 5157 - case BTF_FIELD_ITER_STRS: 5158 - switch (btf_kind(t)) { 5159 - case BTF_KIND_UNKN: 5160 - it->desc = (struct btf_field_desc) {}; 5161 - break; 5162 - case BTF_KIND_INT: 5163 - case BTF_KIND_FLOAT: 5164 - case BTF_KIND_FWD: 5165 - case BTF_KIND_ARRAY: 5166 - case BTF_KIND_CONST: 5167 - case BTF_KIND_VOLATILE: 5168 - case BTF_KIND_RESTRICT: 5169 - case BTF_KIND_PTR: 5170 - case BTF_KIND_TYPEDEF: 5171 - case BTF_KIND_FUNC: 5172 - case BTF_KIND_VAR: 5173 - case BTF_KIND_DECL_TAG: 5174 - case BTF_KIND_TYPE_TAG: 5175 - case BTF_KIND_DATASEC: 5176 - it->desc = (struct btf_field_desc) { 5177 - 1, {offsetof(struct btf_type, name_off)} 5178 - }; 5179 - break; 5180 - case BTF_KIND_ENUM: 5181 - it->desc = (struct btf_field_desc) { 5182 - 1, {offsetof(struct btf_type, name_off)}, 5183 - sizeof(struct btf_enum), 5184 - 1, {offsetof(struct btf_enum, name_off)} 5185 - }; 5186 - break; 5187 - case BTF_KIND_ENUM64: 5188 - it->desc = (struct btf_field_desc) { 5189 - 1, {offsetof(struct btf_type, name_off)}, 5190 - sizeof(struct btf_enum64), 5191 - 1, {offsetof(struct btf_enum64, name_off)} 5192 - }; 5193 - break; 5194 - case BTF_KIND_STRUCT: 5195 - case BTF_KIND_UNION: 5196 - it->desc = (struct btf_field_desc) { 5197 - 1, {offsetof(struct btf_type, name_off)}, 5198 - sizeof(struct btf_member), 5199 - 1, {offsetof(struct btf_member, name_off)} 5200 - }; 5201 - break; 5202 - case BTF_KIND_FUNC_PROTO: 5203 - it->desc = (struct btf_field_desc) { 5204 - 1, {offsetof(struct btf_type, name_off)}, 5205 - sizeof(struct btf_param), 5206 - 1, {offsetof(struct btf_param, name_off)} 5207 - }; 5208 - break; 5209 - default: 5210 - return -EINVAL; 5211 - } 5212 - break; 5213 - default: 5214 - return -EINVAL; 5215 - } 5216 - 5217 - if (it->desc.m_sz) 5218 - it->vlen = btf_vlen(t); 5219 - 5220 - it->p = t; 5221 - return 0; 5222 - } 5223 - 5224 - __u32 *btf_field_iter_next(struct btf_field_iter *it) 5225 - { 5226 - if (!it->p) 5227 - return NULL; 5228 - 5229 - if (it->m_idx < 0) { 5230 - if (it->off_idx < it->desc.t_off_cnt) 5231 - return it->p + it->desc.t_offs[it->off_idx++]; 5232 - /* move to per-member iteration */ 5233 - it->m_idx = 0; 5234 - it->p += sizeof(struct btf_type); 5235 - it->off_idx = 0; 5236 - } 5237 - 5238 - /* if type doesn't have members, stop */ 5239 - if (it->desc.m_sz == 0) { 5240 - it->p = NULL; 5241 - return NULL; 5242 - } 5243 - 5244 - if (it->off_idx >= it->desc.m_off_cnt) { 5245 - /* exhausted this member's fields, go to the next member */ 5246 - it->m_idx++; 5247 - it->p += it->desc.m_sz; 5248 - it->off_idx = 0; 5249 - } 5250 - 5251 - if (it->m_idx < it->vlen) 5252 - return it->p + it->desc.m_offs[it->off_idx++]; 5253 - 5254 - it->p = NULL; 5255 - return NULL; 5256 - } 5257 - 5258 5096 int btf_ext_visit_type_ids(struct btf_ext *btf_ext, type_id_visit_fn visit, void *ctx) 5259 5097 { 5260 5098 const struct btf_ext_info *seg;
+169
tools/lib/bpf/btf_iter.c
··· 1 + // SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause) 2 + /* Copyright (c) 2021 Facebook */ 3 + /* Copyright (c) 2024, Oracle and/or its affiliates. */ 4 + 5 + #include "btf.h" 6 + #include "libbpf_internal.h" 7 + 8 + int btf_field_iter_init(struct btf_field_iter *it, struct btf_type *t, 9 + enum btf_field_iter_kind iter_kind) 10 + { 11 + it->p = NULL; 12 + it->m_idx = -1; 13 + it->off_idx = 0; 14 + it->vlen = 0; 15 + 16 + switch (iter_kind) { 17 + case BTF_FIELD_ITER_IDS: 18 + switch (btf_kind(t)) { 19 + case BTF_KIND_UNKN: 20 + case BTF_KIND_INT: 21 + case BTF_KIND_FLOAT: 22 + case BTF_KIND_ENUM: 23 + case BTF_KIND_ENUM64: 24 + it->desc = (struct btf_field_desc) {}; 25 + break; 26 + case BTF_KIND_FWD: 27 + case BTF_KIND_CONST: 28 + case BTF_KIND_VOLATILE: 29 + case BTF_KIND_RESTRICT: 30 + case BTF_KIND_PTR: 31 + case BTF_KIND_TYPEDEF: 32 + case BTF_KIND_FUNC: 33 + case BTF_KIND_VAR: 34 + case BTF_KIND_DECL_TAG: 35 + case BTF_KIND_TYPE_TAG: 36 + it->desc = (struct btf_field_desc) { 1, {offsetof(struct btf_type, type)} }; 37 + break; 38 + case BTF_KIND_ARRAY: 39 + it->desc = (struct btf_field_desc) { 40 + 2, {sizeof(struct btf_type) + offsetof(struct btf_array, type), 41 + sizeof(struct btf_type) + offsetof(struct btf_array, index_type)} 42 + }; 43 + break; 44 + case BTF_KIND_STRUCT: 45 + case BTF_KIND_UNION: 46 + it->desc = (struct btf_field_desc) { 47 + 0, {}, 48 + sizeof(struct btf_member), 49 + 1, {offsetof(struct btf_member, type)} 50 + }; 51 + break; 52 + case BTF_KIND_FUNC_PROTO: 53 + it->desc = (struct btf_field_desc) { 54 + 1, {offsetof(struct btf_type, type)}, 55 + sizeof(struct btf_param), 56 + 1, {offsetof(struct btf_param, type)} 57 + }; 58 + break; 59 + case BTF_KIND_DATASEC: 60 + it->desc = (struct btf_field_desc) { 61 + 0, {}, 62 + sizeof(struct btf_var_secinfo), 63 + 1, {offsetof(struct btf_var_secinfo, type)} 64 + }; 65 + break; 66 + default: 67 + return -EINVAL; 68 + } 69 + break; 70 + case BTF_FIELD_ITER_STRS: 71 + switch (btf_kind(t)) { 72 + case BTF_KIND_UNKN: 73 + it->desc = (struct btf_field_desc) {}; 74 + break; 75 + case BTF_KIND_INT: 76 + case BTF_KIND_FLOAT: 77 + case BTF_KIND_FWD: 78 + case BTF_KIND_ARRAY: 79 + case BTF_KIND_CONST: 80 + case BTF_KIND_VOLATILE: 81 + case BTF_KIND_RESTRICT: 82 + case BTF_KIND_PTR: 83 + case BTF_KIND_TYPEDEF: 84 + case BTF_KIND_FUNC: 85 + case BTF_KIND_VAR: 86 + case BTF_KIND_DECL_TAG: 87 + case BTF_KIND_TYPE_TAG: 88 + case BTF_KIND_DATASEC: 89 + it->desc = (struct btf_field_desc) { 90 + 1, {offsetof(struct btf_type, name_off)} 91 + }; 92 + break; 93 + case BTF_KIND_ENUM: 94 + it->desc = (struct btf_field_desc) { 95 + 1, {offsetof(struct btf_type, name_off)}, 96 + sizeof(struct btf_enum), 97 + 1, {offsetof(struct btf_enum, name_off)} 98 + }; 99 + break; 100 + case BTF_KIND_ENUM64: 101 + it->desc = (struct btf_field_desc) { 102 + 1, {offsetof(struct btf_type, name_off)}, 103 + sizeof(struct btf_enum64), 104 + 1, {offsetof(struct btf_enum64, name_off)} 105 + }; 106 + break; 107 + case BTF_KIND_STRUCT: 108 + case BTF_KIND_UNION: 109 + it->desc = (struct btf_field_desc) { 110 + 1, {offsetof(struct btf_type, name_off)}, 111 + sizeof(struct btf_member), 112 + 1, {offsetof(struct btf_member, name_off)} 113 + }; 114 + break; 115 + case BTF_KIND_FUNC_PROTO: 116 + it->desc = (struct btf_field_desc) { 117 + 1, {offsetof(struct btf_type, name_off)}, 118 + sizeof(struct btf_param), 119 + 1, {offsetof(struct btf_param, name_off)} 120 + }; 121 + break; 122 + default: 123 + return -EINVAL; 124 + } 125 + break; 126 + default: 127 + return -EINVAL; 128 + } 129 + 130 + if (it->desc.m_sz) 131 + it->vlen = btf_vlen(t); 132 + 133 + it->p = t; 134 + return 0; 135 + } 136 + 137 + __u32 *btf_field_iter_next(struct btf_field_iter *it) 138 + { 139 + if (!it->p) 140 + return NULL; 141 + 142 + if (it->m_idx < 0) { 143 + if (it->off_idx < it->desc.t_off_cnt) 144 + return it->p + it->desc.t_offs[it->off_idx++]; 145 + /* move to per-member iteration */ 146 + it->m_idx = 0; 147 + it->p += sizeof(struct btf_type); 148 + it->off_idx = 0; 149 + } 150 + 151 + /* if type doesn't have members, stop */ 152 + if (it->desc.m_sz == 0) { 153 + it->p = NULL; 154 + return NULL; 155 + } 156 + 157 + if (it->off_idx >= it->desc.m_off_cnt) { 158 + /* exhausted this member's fields, go to the next member */ 159 + it->m_idx++; 160 + it->p += it->desc.m_sz; 161 + it->off_idx = 0; 162 + } 163 + 164 + if (it->m_idx < it->vlen) 165 + return it->p + it->desc.m_offs[it->off_idx++]; 166 + 167 + it->p = NULL; 168 + return NULL; 169 + }