mirror of
git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2025-09-18 22:14:16 +00:00
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. Suggested-by: Andrii Nakryiko <andrii.nakryiko@gmail.com> Signed-off-by: Alan Maguire <alan.maguire@oracle.com> Signed-off-by: Andrii Nakryiko <andrii@kernel.org> Acked-by: Eduard Zingerman <eddyz87@gmail.com> Link: https://lore.kernel.org/bpf/20240620091733.1967885-2-alan.maguire@oracle.com
This commit is contained in:
parent
cd387ce548
commit
d1cf840854
1 changed files with 31 additions and 41 deletions
|
@ -160,7 +160,7 @@ static int btf_mark_embedded_composite_type_ids(struct btf_relocate *r, __u32 i)
|
||||||
*/
|
*/
|
||||||
static int btf_relocate_map_distilled_base(struct btf_relocate *r)
|
static int btf_relocate_map_distilled_base(struct btf_relocate *r)
|
||||||
{
|
{
|
||||||
struct btf_name_info *dist_base_info_sorted, *dist_base_info_sorted_end;
|
struct btf_name_info *info, *info_end;
|
||||||
struct btf_type *base_t, *dist_t;
|
struct btf_type *base_t, *dist_t;
|
||||||
__u8 *base_name_cnt = NULL;
|
__u8 *base_name_cnt = NULL;
|
||||||
int err = 0;
|
int err = 0;
|
||||||
|
@ -169,26 +169,24 @@ static int btf_relocate_map_distilled_base(struct btf_relocate *r)
|
||||||
/* generate a sort index array of name/type ids sorted by name for
|
/* generate a sort index array of name/type ids sorted by name for
|
||||||
* distilled base BTF to speed name-based lookups.
|
* distilled base BTF to speed name-based lookups.
|
||||||
*/
|
*/
|
||||||
dist_base_info_sorted = calloc(r->nr_dist_base_types, sizeof(*dist_base_info_sorted));
|
info = calloc(r->nr_dist_base_types, sizeof(*info));
|
||||||
if (!dist_base_info_sorted) {
|
if (!info) {
|
||||||
err = -ENOMEM;
|
err = -ENOMEM;
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
dist_base_info_sorted_end = dist_base_info_sorted + r->nr_dist_base_types;
|
info_end = info + r->nr_dist_base_types;
|
||||||
for (id = 0; id < r->nr_dist_base_types; id++) {
|
for (id = 0; id < r->nr_dist_base_types; id++) {
|
||||||
dist_t = btf_type_by_id(r->dist_base_btf, id);
|
dist_t = btf_type_by_id(r->dist_base_btf, id);
|
||||||
dist_base_info_sorted[id].name = btf__name_by_offset(r->dist_base_btf,
|
info[id].name = btf__name_by_offset(r->dist_base_btf, dist_t->name_off);
|
||||||
dist_t->name_off);
|
info[id].id = id;
|
||||||
dist_base_info_sorted[id].id = id;
|
info[id].size = dist_t->size;
|
||||||
dist_base_info_sorted[id].size = dist_t->size;
|
info[id].needs_size = true;
|
||||||
dist_base_info_sorted[id].needs_size = true;
|
|
||||||
}
|
}
|
||||||
qsort(dist_base_info_sorted, r->nr_dist_base_types, sizeof(*dist_base_info_sorted),
|
qsort(info, r->nr_dist_base_types, sizeof(*info), cmp_btf_name_size);
|
||||||
cmp_btf_name_size);
|
|
||||||
|
|
||||||
/* Mark distilled base struct/union members of split BTF structs/unions
|
/* Mark distilled base struct/union members of split BTF structs/unions
|
||||||
* in id_map with BTF_IS_EMBEDDED; this signals that these types
|
* in id_map with BTF_IS_EMBEDDED; this signals that these types
|
||||||
* need to match both name and size, otherwise embeddding the base
|
* need to match both name and size, otherwise embedding the base
|
||||||
* struct/union in the split type is invalid.
|
* struct/union in the split type is invalid.
|
||||||
*/
|
*/
|
||||||
for (id = r->nr_dist_base_types; id < r->nr_split_types; id++) {
|
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)
|
||||||
|
|
||||||
/* Now search base BTF for matching distilled base BTF types. */
|
/* Now search base BTF for matching distilled base BTF types. */
|
||||||
for (id = 1; id < r->nr_base_types; id++) {
|
for (id = 1; id < r->nr_base_types; id++) {
|
||||||
struct btf_name_info *dist_name_info, *dist_name_info_next = NULL;
|
struct btf_name_info *dist_info, base_info = {};
|
||||||
struct btf_name_info base_name_info = {};
|
|
||||||
int dist_kind, base_kind;
|
int dist_kind, base_kind;
|
||||||
|
|
||||||
base_t = btf_type_by_id(r->base_btf, id);
|
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)
|
||||||
if (!base_t->name_off)
|
if (!base_t->name_off)
|
||||||
continue;
|
continue;
|
||||||
base_kind = btf_kind(base_t);
|
base_kind = btf_kind(base_t);
|
||||||
base_name_info.id = id;
|
base_info.id = id;
|
||||||
base_name_info.name = btf__name_by_offset(r->base_btf, base_t->name_off);
|
base_info.name = btf__name_by_offset(r->base_btf, base_t->name_off);
|
||||||
switch (base_kind) {
|
switch (base_kind) {
|
||||||
case BTF_KIND_INT:
|
case BTF_KIND_INT:
|
||||||
case BTF_KIND_FLOAT:
|
case BTF_KIND_FLOAT:
|
||||||
case BTF_KIND_ENUM:
|
case BTF_KIND_ENUM:
|
||||||
case BTF_KIND_ENUM64:
|
case BTF_KIND_ENUM64:
|
||||||
/* These types should match both name and size */
|
/* These types should match both name and size */
|
||||||
base_name_info.needs_size = true;
|
base_info.needs_size = true;
|
||||||
base_name_info.size = base_t->size;
|
base_info.size = base_t->size;
|
||||||
break;
|
break;
|
||||||
case BTF_KIND_FWD:
|
case BTF_KIND_FWD:
|
||||||
/* No size considerations for fwds. */
|
/* No size considerations for fwds. */
|
||||||
|
@ -248,31 +245,24 @@ static int btf_relocate_map_distilled_base(struct btf_relocate *r)
|
||||||
* unless corresponding _base_ types to match them are
|
* unless corresponding _base_ types to match them are
|
||||||
* missing.
|
* missing.
|
||||||
*/
|
*/
|
||||||
base_name_info.needs_size = base_name_cnt[base_t->name_off] > 1;
|
base_info.needs_size = base_name_cnt[base_t->name_off] > 1;
|
||||||
base_name_info.size = base_t->size;
|
base_info.size = base_t->size;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
/* iterate over all matching distilled base types */
|
/* iterate over all matching distilled base types */
|
||||||
for (dist_name_info = search_btf_name_size(&base_name_info, dist_base_info_sorted,
|
for (dist_info = search_btf_name_size(&base_info, info, r->nr_dist_base_types);
|
||||||
r->nr_dist_base_types);
|
dist_info != NULL && dist_info < info_end &&
|
||||||
dist_name_info != NULL; dist_name_info = dist_name_info_next) {
|
cmp_btf_name_size(&base_info, dist_info) == 0;
|
||||||
/* Are there more distilled matches to process after
|
dist_info++) {
|
||||||
* this one?
|
if (!dist_info->id || dist_info->id >= r->nr_dist_base_types) {
|
||||||
*/
|
|
||||||
dist_name_info_next = dist_name_info + 1;
|
|
||||||
if (dist_name_info_next >= dist_base_info_sorted_end ||
|
|
||||||
cmp_btf_name_size(&base_name_info, dist_name_info_next))
|
|
||||||
dist_name_info_next = NULL;
|
|
||||||
|
|
||||||
if (!dist_name_info->id || dist_name_info->id > r->nr_dist_base_types) {
|
|
||||||
pr_warn("base BTF id [%d] maps to invalid distilled base BTF id [%d]\n",
|
pr_warn("base BTF id [%d] maps to invalid distilled base BTF id [%d]\n",
|
||||||
id, dist_name_info->id);
|
id, dist_info->id);
|
||||||
err = -EINVAL;
|
err = -EINVAL;
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
dist_t = btf_type_by_id(r->dist_base_btf, dist_name_info->id);
|
dist_t = btf_type_by_id(r->dist_base_btf, dist_info->id);
|
||||||
dist_kind = btf_kind(dist_t);
|
dist_kind = btf_kind(dist_t);
|
||||||
|
|
||||||
/* Validate that the found distilled type is compatible.
|
/* Validate that the found distilled type is compatible.
|
||||||
|
@ -319,15 +309,15 @@ static int btf_relocate_map_distilled_base(struct btf_relocate *r)
|
||||||
/* size verification is required for embedded
|
/* size verification is required for embedded
|
||||||
* struct/unions.
|
* struct/unions.
|
||||||
*/
|
*/
|
||||||
if (r->id_map[dist_name_info->id] == BTF_IS_EMBEDDED &&
|
if (r->id_map[dist_info->id] == BTF_IS_EMBEDDED &&
|
||||||
base_t->size != dist_t->size)
|
base_t->size != dist_t->size)
|
||||||
continue;
|
continue;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (r->id_map[dist_name_info->id] &&
|
if (r->id_map[dist_info->id] &&
|
||||||
r->id_map[dist_name_info->id] != BTF_IS_EMBEDDED) {
|
r->id_map[dist_info->id] != BTF_IS_EMBEDDED) {
|
||||||
/* we already have a match; this tells us that
|
/* we already have a match; this tells us that
|
||||||
* multiple base types of the same name
|
* multiple base types of the same name
|
||||||
* have the same size, since for cases where
|
* have the same size, since for cases where
|
||||||
|
@ -337,13 +327,13 @@ static int btf_relocate_map_distilled_base(struct btf_relocate *r)
|
||||||
* to in base BTF, so error out.
|
* to in base BTF, so error out.
|
||||||
*/
|
*/
|
||||||
pr_warn("distilled base BTF type '%s' [%u], size %u has multiple candidates of the same size (ids [%u, %u]) in base BTF\n",
|
pr_warn("distilled base BTF type '%s' [%u], size %u has multiple candidates of the same size (ids [%u, %u]) in base BTF\n",
|
||||||
base_name_info.name, dist_name_info->id,
|
base_info.name, dist_info->id,
|
||||||
base_t->size, id, r->id_map[dist_name_info->id]);
|
base_t->size, id, r->id_map[dist_info->id]);
|
||||||
err = -EINVAL;
|
err = -EINVAL;
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
/* map id and name */
|
/* map id and name */
|
||||||
r->id_map[dist_name_info->id] = id;
|
r->id_map[dist_info->id] = id;
|
||||||
r->str_map[dist_t->name_off] = base_t->name_off;
|
r->str_map[dist_t->name_off] = base_t->name_off;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -362,7 +352,7 @@ static int btf_relocate_map_distilled_base(struct btf_relocate *r)
|
||||||
}
|
}
|
||||||
done:
|
done:
|
||||||
free(base_name_cnt);
|
free(base_name_cnt);
|
||||||
free(dist_base_info_sorted);
|
free(info);
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue