mirror of
https://github.com/netdata/libbpf.git
synced 2026-04-04 23:59:07 +08:00
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: Andrii Nakryiko <andrii@kernel.org> Signed-off-by: Daniel Borkmann <daniel@iogearbox.net> Tested-by: Alan Maguire <alan.maguire@oracle.com> Acked-by: Eduard Zingerman <eddyz87@gmail.com> Acked-by: Jiri Olsa <jolsa@kernel.org> Link: https://lore.kernel.org/bpf/20240605001629.4061937-3-andrii@kernel.org
This commit is contained in:
committed by
Andrii Nakryiko
parent
cece3242fb
commit
13182b94f3
@@ -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)
|
|||||||
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 {
|
|||||||
|
|
||||||
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 {
|
||||||
|
|||||||
58
src/linker.c
58
src/linker.c
@@ -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)
|
|||||||
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)
|
|||||||
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
|
||||||
|
|||||||
Reference in New Issue
Block a user