History

libbpf: BTF relocation followup fixing naming, loop logic

Use less verbose names in BTF relocation code and fix off-by-one error and typo in btf_relocate.c. Simplify loop over matching distilled types, moving from assigning a _next value in loop body to moving match check conditions into the guard.

Alan Maguire committed 2 years ago

Commit d1cf8401 parent cd387ce1 file · +31 −41Browse files

Unified · Split

tools/lib/bpf/btf_relocate.c+31−41
@@ -160,7 +160,7 @@ static int btf_mark_embedded_composite_type_ids(struct btf_relocate *r, __u32 i) · 159 unmodified lines
160 */160 */
161static int btf_relocate_map_distilled_base(struct btf_relocate *r)161static int btf_relocate_map_distilled_base(struct btf_relocate *r)
162{162{
163 struct btf_name_info *dist_base_info_sorted, *dist_base_info_sorted_end;163 struct btf_name_info *info, *info_end;
164 struct btf_type *base_t, *dist_t;164 struct btf_type *base_t, *dist_t;
165 __u8 *base_name_cnt = NULL;165 __u8 *base_name_cnt = NULL;
166 int err = 0;166 int err = 0;
@@ -169,26 +169,24 @@ static int btf_relocate_map_distilled_base(struct btf_relocate *r) · 2 unmodified lines
169 /* generate a sort index array of name/type ids sorted by name for169 /* generate a sort index array of name/type ids sorted by name for
170 * distilled base BTF to speed name-based lookups.170 * distilled base BTF to speed name-based lookups.
171 */171 */
172 dist_base_info_sorted = calloc(r->nr_dist_base_types, sizeof(*dist_base_info_sorted));172 info = calloc(r->nr_dist_base_types, sizeof(*info));
173 if (!dist_base_info_sorted) {173 if (!info) {
174 err = -ENOMEM;174 err = -ENOMEM;
175 goto done;175 goto done;
176 }176 }
177 dist_base_info_sorted_end = dist_base_info_sorted + r->nr_dist_base_types;177 info_end = info + r->nr_dist_base_types;
178 for (id = 0; id < r->nr_dist_base_types; id++) {178 for (id = 0; id < r->nr_dist_base_types; id++) {
179 dist_t = btf_type_by_id(r->dist_base_btf, id);179 dist_t = btf_type_by_id(r->dist_base_btf, id);
180 dist_base_info_sorted[id].name = btf__name_by_offset(r->dist_base_btf,180 info[id].name = btf__name_by_offset(r->dist_base_btf, dist_t->name_off);
181 dist_t->name_off);181 info[id].id = id;
182 dist_base_info_sorted[id].id = id;182 info[id].size = dist_t->size;
183 dist_base_info_sorted[id].size = dist_t->size;183 info[id].needs_size = true;
184 dist_base_info_sorted[id].needs_size = true;
185 }184 }
186 qsort(dist_base_info_sorted, r->nr_dist_base_types, sizeof(*dist_base_info_sorted),185 qsort(info, r->nr_dist_base_types, sizeof(*info), cmp_btf_name_size);
187 cmp_btf_name_size);
188 186
189 /* Mark distilled base struct/union members of split BTF structs/unions187 /* Mark distilled base struct/union members of split BTF structs/unions
190 * in id_map with BTF_IS_EMBEDDED; this signals that these types188 * in id_map with BTF_IS_EMBEDDED; this signals that these types
191 * need to match both name and size, otherwise embeddding the base189 * need to match both name and size, otherwise embedding the base
192 * struct/union in the split type is invalid.190 * struct/union in the split type is invalid.
193 */191 */
194 for (id = r->nr_dist_base_types; id < r->nr_split_types; id++) {192 for (id = r->nr_dist_base_types; id < r->nr_split_types; id++) {
@@ -216,8 +214,7 @@ static int btf_relocate_map_distilled_base(struct btf_relocate *r) · 21 unmodified lines
216 214
217 /* Now search base BTF for matching distilled base BTF types. */215 /* Now search base BTF for matching distilled base BTF types. */
218 for (id = 1; id < r->nr_base_types; id++) {216 for (id = 1; id < r->nr_base_types; id++) {
219 struct btf_name_info *dist_name_info, *dist_name_info_next = NULL;217 struct btf_name_info *dist_info, base_info = {};
220 struct btf_name_info base_name_info = {};
221 int dist_kind, base_kind;218 int dist_kind, base_kind;
222 219
223 base_t = btf_type_by_id(r->base_btf, id);220 base_t = btf_type_by_id(r->base_btf, id);
@@ -225,16 +222,16 @@ static int btf_relocate_map_distilled_base(struct btf_relocate *r) · 1 unmodified line
225 if (!base_t->name_off)222 if (!base_t->name_off)
226 continue;223 continue;
227 base_kind = btf_kind(base_t);224 base_kind = btf_kind(base_t);
228 base_name_info.id = id;225 base_info.id = id;
229 base_name_info.name = btf__name_by_offset(r->base_btf, base_t->name_off);226 base_info.name = btf__name_by_offset(r->base_btf, base_t->name_off);
230 switch (base_kind) {227 switch (base_kind) {
231 case BTF_KIND_INT:228 case BTF_KIND_INT:
232 case BTF_KIND_FLOAT:229 case BTF_KIND_FLOAT:
233 case BTF_KIND_ENUM:230 case BTF_KIND_ENUM:
234 case BTF_KIND_ENUM64:231 case BTF_KIND_ENUM64:
235 /* These types should match both name and size */232 /* These types should match both name and size */
236 base_name_info.needs_size = true;233 base_info.needs_size = true;
237 base_name_info.size = base_t->size;234 base_info.size = base_t->size;
238 break;235 break;
239 case BTF_KIND_FWD:236 case BTF_KIND_FWD:
240 /* No size considerations for fwds. */237 /* No size considerations for fwds. */
@@ -248,31 +245,24 @@ static int btf_relocate_map_distilled_base(struct btf_relocate *r) · 7 unmodified lines
248 * unless corresponding _base_ types to match them are245 * unless corresponding _base_ types to match them are
249 * missing.246 * missing.
250 */247 */
251 base_name_info.needs_size = base_name_cnt[base_t->name_off] > 1;248 base_info.needs_size = base_name_cnt[base_t->name_off] > 1;
252 base_name_info.size = base_t->size;249 base_info.size = base_t->size;
253 break;250 break;
254 default:251 default:
255 continue;252 continue;
256 }253 }
257 /* iterate over all matching distilled base types */254 /* iterate over all matching distilled base types */
258 for (dist_name_info = search_btf_name_size(&base_name_info, dist_base_info_sorted,255 for (dist_info = search_btf_name_size(&base_info, info, r->nr_dist_base_types);
259 r->nr_dist_base_types);256 dist_info != NULL && dist_info < info_end &&
260 dist_name_info != NULL; dist_name_info = dist_name_info_next) {257 cmp_btf_name_size(&base_info, dist_info) == 0;
261 /* Are there more distilled matches to process after258 dist_info++) {
262 * this one?259 if (!dist_info->id || dist_info->id >= r->nr_dist_base_types) {
263 */
264 dist_name_info_next = dist_name_info + 1;
265 if (dist_name_info_next >= dist_base_info_sorted_end ||
266 cmp_btf_name_size(&base_name_info, dist_name_info_next))
267 dist_name_info_next = NULL;
268
269 if (!dist_name_info->id || dist_name_info->id > r->nr_dist_base_types) {
270 pr_warn("base BTF id [%d] maps to invalid distilled base BTF id [%d]\n",260 pr_warn("base BTF id [%d] maps to invalid distilled base BTF id [%d]\n",
271 id, dist_name_info->id);261 id, dist_info->id);
272 err = -EINVAL;262 err = -EINVAL;
273 goto done;263 goto done;
274 }264 }
275 dist_t = btf_type_by_id(r->dist_base_btf, dist_name_info->id);265 dist_t = btf_type_by_id(r->dist_base_btf, dist_info->id);
276 dist_kind = btf_kind(dist_t);266 dist_kind = btf_kind(dist_t);
277 267
278 /* Validate that the found distilled type is compatible.268 /* Validate that the found distilled type is compatible.
@@ -319,15 +309,15 @@ static int btf_relocate_map_distilled_base(struct btf_relocate *r) · 40 unmodified lines
319 /* size verification is required for embedded309 /* size verification is required for embedded
320 * struct/unions.310 * struct/unions.
321 */311 */
322 if (r->id_map[dist_name_info->id] == BTF_IS_EMBEDDED &&312 if (r->id_map[dist_info->id] == BTF_IS_EMBEDDED &&
323 base_t->size != dist_t->size)313 base_t->size != dist_t->size)
324 continue;314 continue;
325 break;315 break;
326 default:316 default:
327 continue;317 continue;
328 }318 }
329 if (r->id_map[dist_name_info->id] &&319 if (r->id_map[dist_info->id] &&
330 r->id_map[dist_name_info->id] != BTF_IS_EMBEDDED) {320 r->id_map[dist_info->id] != BTF_IS_EMBEDDED) {
331 /* we already have a match; this tells us that321 /* we already have a match; this tells us that
332 * multiple base types of the same name322 * multiple base types of the same name
333 * have the same size, since for cases where323 * have the same size, since for cases where
@@ -337,13 +327,13 @@ static int btf_relocate_map_distilled_base(struct btf_relocate *r) · 3 unmodified lines
337 * to in base BTF, so error out.327 * to in base BTF, so error out.
338 */328 */
339 pr_warn("distilled base BTF type '%s' [%u], size %u has multiple candidates of the same size (ids [%u, %u]) in base BTF\n",329 pr_warn("distilled base BTF type '%s' [%u], size %u has multiple candidates of the same size (ids [%u, %u]) in base BTF\n",
340 base_name_info.name, dist_name_info->id,330 base_info.name, dist_info->id,
341 base_t->size, id, r->id_map[dist_name_info->id]);331 base_t->size, id, r->id_map[dist_info->id]);
342 err = -EINVAL;332 err = -EINVAL;
343 goto done;333 goto done;
344 }334 }
345 /* map id and name */335 /* map id and name */
346 r->id_map[dist_name_info->id] = id;336 r->id_map[dist_info->id] = id;
347 r->str_map[dist_t->name_off] = base_t->name_off;337 r->str_map[dist_t->name_off] = base_t->name_off;
348 }338 }
349 }339 }
@@ -362,7 +352,7 @@ static int btf_relocate_map_distilled_base(struct btf_relocate *r) · 12 unmodified lines
362 }352 }
363done:353done:
364 free(base_name_cnt);354 free(base_name_cnt);
365 free(dist_base_info_sorted);355 free(info);
366 return err;356 return err;
367}357}
368 358