Commit 2bce2c1c authored by Andrii Nakryiko's avatar Andrii Nakryiko Committed by Daniel Borkmann

libbpf: Make use of BTF field iterator in BPF linker code

Switch all BPF linker code dealing with iterating BTF type ID and string
offset fields to new btf_field_iter facilities.
Signed-off-by: default avatarAndrii Nakryiko <andrii@kernel.org>
Signed-off-by: default avatarDaniel Borkmann <daniel@iogearbox.net>
Tested-by: default avatarAlan Maguire <alan.maguire@oracle.com>
Acked-by: default avatarEduard Zingerman <eddyz87@gmail.com>
Acked-by: default avatarJiri Olsa <jolsa@kernel.org>
Link: https://lore.kernel.org/bpf/20240605001629.4061937-3-andrii@kernel.org
parent 68153bb2
...@@ -5267,7 +5267,7 @@ __u32 *btf_field_iter_next(struct btf_field_iter *it) ...@@ -5267,7 +5267,7 @@ __u32 *btf_field_iter_next(struct btf_field_iter *it)
return NULL; return NULL;
if (it->m_idx < 0) { if (it->m_idx < 0) {
if (it->off_idx < it->desc.t_cnt) if (it->off_idx < it->desc.t_off_cnt)
return it->p + it->desc.t_offs[it->off_idx++]; return it->p + it->desc.t_offs[it->off_idx++];
/* move to per-member iteration */ /* move to per-member iteration */
it->m_idx = 0; it->m_idx = 0;
...@@ -5281,7 +5281,7 @@ __u32 *btf_field_iter_next(struct btf_field_iter *it) ...@@ -5281,7 +5281,7 @@ __u32 *btf_field_iter_next(struct btf_field_iter *it)
return NULL; return NULL;
} }
if (it->off_idx >= it->desc.m_cnt) { if (it->off_idx >= it->desc.m_off_cnt) {
/* exhausted this member's fields, go to the next member */ /* exhausted this member's fields, go to the next member */
it->m_idx++; it->m_idx++;
it->p += it->desc.m_sz; it->p += it->desc.m_sz;
......
...@@ -515,11 +515,11 @@ enum btf_field_iter_kind { ...@@ -515,11 +515,11 @@ enum btf_field_iter_kind {
struct btf_field_desc { struct btf_field_desc {
/* once-per-type offsets */ /* once-per-type offsets */
int t_cnt, t_offs[2]; int t_off_cnt, t_offs[2];
/* member struct size, or zero, if no members */ /* member struct size, or zero, if no members */
int m_sz; int m_sz;
/* repeated per-member offsets */ /* repeated per-member offsets */
int m_cnt, m_offs[1]; int m_off_cnt, m_offs[1];
}; };
struct btf_field_iter { struct btf_field_iter {
......
...@@ -957,19 +957,33 @@ static int check_btf_str_off(__u32 *str_off, void *ctx) ...@@ -957,19 +957,33 @@ static int check_btf_str_off(__u32 *str_off, void *ctx)
static int linker_sanity_check_btf(struct src_obj *obj) static int linker_sanity_check_btf(struct src_obj *obj)
{ {
struct btf_type *t; struct btf_type *t;
int i, n, err = 0; int i, n, err;
if (!obj->btf) if (!obj->btf)
return 0; return 0;
n = btf__type_cnt(obj->btf); n = btf__type_cnt(obj->btf);
for (i = 1; i < n; i++) { for (i = 1; i < n; i++) {
struct btf_field_iter it;
__u32 *type_id, *str_off;
t = btf_type_by_id(obj->btf, i); t = btf_type_by_id(obj->btf, i);
err = err ?: btf_type_visit_type_ids(t, check_btf_type_id, obj->btf); err = btf_field_iter_init(&it, t, BTF_FIELD_ITER_IDS);
err = err ?: btf_type_visit_str_offs(t, check_btf_str_off, obj->btf);
if (err) if (err)
return err; return err;
while ((type_id = btf_field_iter_next(&it))) {
if (*type_id >= n)
return -EINVAL;
}
err = btf_field_iter_init(&it, t, BTF_FIELD_ITER_STRS);
if (err)
return err;
while ((str_off = btf_field_iter_next(&it))) {
if (!btf__str_by_offset(obj->btf, *str_off))
return -EINVAL;
}
} }
return 0; return 0;
...@@ -2234,26 +2248,10 @@ static int linker_fixup_btf(struct src_obj *obj) ...@@ -2234,26 +2248,10 @@ static int linker_fixup_btf(struct src_obj *obj)
return 0; return 0;
} }
static int remap_type_id(__u32 *type_id, void *ctx)
{
int *id_map = ctx;
int new_id = id_map[*type_id];
/* Error out if the type wasn't remapped. Ignore VOID which stays VOID. */
if (new_id == 0 && *type_id != 0) {
pr_warn("failed to find new ID mapping for original BTF type ID %u\n", *type_id);
return -EINVAL;
}
*type_id = id_map[*type_id];
return 0;
}
static int linker_append_btf(struct bpf_linker *linker, struct src_obj *obj) static int linker_append_btf(struct bpf_linker *linker, struct src_obj *obj)
{ {
const struct btf_type *t; const struct btf_type *t;
int i, j, n, start_id, id; int i, j, n, start_id, id, err;
const char *name; const char *name;
if (!obj->btf) if (!obj->btf)
...@@ -2324,9 +2322,25 @@ static int linker_append_btf(struct bpf_linker *linker, struct src_obj *obj) ...@@ -2324,9 +2322,25 @@ static int linker_append_btf(struct bpf_linker *linker, struct src_obj *obj)
n = btf__type_cnt(linker->btf); n = btf__type_cnt(linker->btf);
for (i = start_id; i < n; i++) { for (i = start_id; i < n; i++) {
struct btf_type *dst_t = btf_type_by_id(linker->btf, i); struct btf_type *dst_t = btf_type_by_id(linker->btf, i);
struct btf_field_iter it;
__u32 *type_id;
if (btf_type_visit_type_ids(dst_t, remap_type_id, obj->btf_type_map)) err = btf_field_iter_init(&it, dst_t, BTF_FIELD_ITER_IDS);
return -EINVAL; if (err)
return err;
while ((type_id = btf_field_iter_next(&it))) {
int new_id = obj->btf_type_map[*type_id];
/* Error out if the type wasn't remapped. Ignore VOID which stays VOID. */
if (new_id == 0 && *type_id != 0) {
pr_warn("failed to find new ID mapping for original BTF type ID %u\n",
*type_id);
return -EINVAL;
}
*type_id = obj->btf_type_map[*type_id];
}
} }
/* Rewrite VAR/FUNC underlying types (i.e., FUNC's FUNC_PROTO and VAR's /* Rewrite VAR/FUNC underlying types (i.e., FUNC's FUNC_PROTO and VAR's
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment