]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
libbpf: Make use of BTF field iterator in BTF handling code
authorAndrii Nakryiko <andrii@kernel.org>
Wed, 5 Jun 2024 00:16:27 +0000 (17:16 -0700)
committerDaniel Borkmann <daniel@iogearbox.net>
Wed, 5 Jun 2024 14:54:37 +0000 (16:54 +0200)
Use new BTF field iterator logic to replace all the callback-based
visitor calls. There is still a .BTF.ext callback-based visitor APIs
that should be converted, which will happens as a follow up.

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-4-andrii@kernel.org
tools/lib/bpf/btf.c

index d72260ac26a52f8d524eaf40bf92323910ebe8df..0190fd819f58b68abcb10af1bdeeac73281aef71 100644 (file)
@@ -1739,9 +1739,8 @@ struct btf_pipe {
        struct hashmap *str_off_map; /* map string offsets from src to dst */
 };
 
-static int btf_rewrite_str(__u32 *str_off, void *ctx)
+static int btf_rewrite_str(struct btf_pipe *p, __u32 *str_off)
 {
-       struct btf_pipe *p = ctx;
        long mapped_off;
        int off, err;
 
@@ -1774,7 +1773,9 @@ static int btf_rewrite_str(__u32 *str_off, void *ctx)
 int btf__add_type(struct btf *btf, const struct btf *src_btf, const struct btf_type *src_type)
 {
        struct btf_pipe p = { .src = src_btf, .dst = btf };
+       struct btf_field_iter it;
        struct btf_type *t;
+       __u32 *str_off;
        int sz, err;
 
        sz = btf_type_size(src_type);
@@ -1791,26 +1792,17 @@ int btf__add_type(struct btf *btf, const struct btf *src_btf, const struct btf_t
 
        memcpy(t, src_type, sz);
 
-       err = btf_type_visit_str_offs(t, btf_rewrite_str, &p);
+       err = btf_field_iter_init(&it, t, BTF_FIELD_ITER_STRS);
        if (err)
                return libbpf_err(err);
 
-       return btf_commit_type(btf, sz);
-}
-
-static int btf_rewrite_type_ids(__u32 *type_id, void *ctx)
-{
-       struct btf *btf = ctx;
-
-       if (!*type_id) /* nothing to do for VOID references */
-               return 0;
+       while ((str_off = btf_field_iter_next(&it))) {
+               err = btf_rewrite_str(&p, str_off);
+               if (err)
+                       return libbpf_err(err);
+       }
 
-       /* we haven't updated btf's type count yet, so
-        * btf->start_id + btf->nr_types - 1 is the type ID offset we should
-        * add to all newly added BTF types
-        */
-       *type_id += btf->start_id + btf->nr_types - 1;
-       return 0;
+       return btf_commit_type(btf, sz);
 }
 
 static size_t btf_dedup_identity_hash_fn(long key, void *ctx);
@@ -1858,6 +1850,9 @@ int btf__add_btf(struct btf *btf, const struct btf *src_btf)
        memcpy(t, src_btf->types_data, data_sz);
 
        for (i = 0; i < cnt; i++) {
+               struct btf_field_iter it;
+               __u32 *type_id, *str_off;
+
                sz = btf_type_size(t);
                if (sz < 0) {
                        /* unlikely, has to be corrupted src_btf */
@@ -1869,15 +1864,31 @@ int btf__add_btf(struct btf *btf, const struct btf *src_btf)
                *off = t - btf->types_data;
 
                /* add, dedup, and remap strings referenced by this BTF type */
-               err = btf_type_visit_str_offs(t, btf_rewrite_str, &p);
+               err = btf_field_iter_init(&it, t, BTF_FIELD_ITER_STRS);
                if (err)
                        goto err_out;
+               while ((str_off = btf_field_iter_next(&it))) {
+                       err = btf_rewrite_str(&p, str_off);
+                       if (err)
+                               goto err_out;
+               }
 
                /* remap all type IDs referenced from this BTF type */
-               err = btf_type_visit_type_ids(t, btf_rewrite_type_ids, btf);
+               err = btf_field_iter_init(&it, t, BTF_FIELD_ITER_IDS);
                if (err)
                        goto err_out;
 
+               while ((type_id = btf_field_iter_next(&it))) {
+                       if (!*type_id) /* nothing to do for VOID references */
+                               continue;
+
+                       /* we haven't updated btf's type count yet, so
+                        * btf->start_id + btf->nr_types - 1 is the type ID offset we should
+                        * add to all newly added BTF types
+                        */
+                       *type_id += btf->start_id + btf->nr_types - 1;
+               }
+
                /* go to next type data and type offset index entry */
                t += sz;
                off++;
@@ -3453,11 +3464,19 @@ static int btf_for_each_str_off(struct btf_dedup *d, str_off_visit_fn fn, void *
        int i, r;
 
        for (i = 0; i < d->btf->nr_types; i++) {
+               struct btf_field_iter it;
                struct btf_type *t = btf_type_by_id(d->btf, d->btf->start_id + i);
+               __u32 *str_off;
 
-               r = btf_type_visit_str_offs(t, fn, ctx);
+               r = btf_field_iter_init(&it, t, BTF_FIELD_ITER_STRS);
                if (r)
                        return r;
+
+               while ((str_off = btf_field_iter_next(&it))) {
+                       r = fn(str_off, ctx);
+                       if (r)
+                               return r;
+               }
        }
 
        if (!d->btf_ext)
@@ -4919,10 +4938,23 @@ static int btf_dedup_remap_types(struct btf_dedup *d)
 
        for (i = 0; i < d->btf->nr_types; i++) {
                struct btf_type *t = btf_type_by_id(d->btf, d->btf->start_id + i);
+               struct btf_field_iter it;
+               __u32 *type_id;
 
-               r = btf_type_visit_type_ids(t, btf_dedup_remap_type_id, d);
+               r = btf_field_iter_init(&it, t, BTF_FIELD_ITER_IDS);
                if (r)
                        return r;
+
+               while ((type_id = btf_field_iter_next(&it))) {
+                       __u32 resolved_id, new_id;
+
+                       resolved_id = resolve_type_id(d, *type_id);
+                       new_id = d->hypot_map[resolved_id];
+                       if (new_id > BTF_MAX_NR_TYPES)
+                               return -EINVAL;
+
+                       *type_id = new_id;
+               }
        }
 
        if (!d->btf_ext)