]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
resolve_btfids: Introduce enum btf_id_kind
authorIhor Solodrai <ihor.solodrai@linux.dev>
Fri, 19 Dec 2025 18:13:16 +0000 (10:13 -0800)
committerAndrii Nakryiko <andrii@kernel.org>
Fri, 19 Dec 2025 18:55:40 +0000 (10:55 -0800)
Instead of using multiple flags, make struct btf_id tagged with an
enum value indicating its kind in the context of resolve_btfids.

Signed-off-by: Ihor Solodrai <ihor.solodrai@linux.dev>
Signed-off-by: Andrii Nakryiko <andrii@kernel.org>
Tested-by: Alan Maguire <alan.maguire@oracle.com>
Acked-by: Eduard Zingerman <eddyz87@gmail.com>
Link: https://lore.kernel.org/bpf/20251219181321.1283664-4-ihor.solodrai@linux.dev
tools/bpf/resolve_btfids/main.c

index b4caae1170dd9282700ad1d1b4f58f912732bc7a..e721e20a2bbd8cd365fe70a2bbca05e62eb1d90a 100644 (file)
 # error "Unknown machine endianness!"
 #endif
 
+enum btf_id_kind {
+       BTF_ID_KIND_NONE,
+       BTF_ID_KIND_SYM,
+       BTF_ID_KIND_SET,
+       BTF_ID_KIND_SET8
+};
+
 struct btf_id {
        struct rb_node   rb_node;
        char            *name;
@@ -105,9 +112,8 @@ struct btf_id {
                int      id;
                int      cnt;
        };
+       enum btf_id_kind kind;
        int              addr_cnt;
-       bool             is_set;
-       bool             is_set8;
        Elf64_Addr       addr[ADDR_CNT];
 };
 
@@ -197,8 +203,10 @@ static struct btf_id *btf_id__find(struct rb_root *root, const char *name)
        return NULL;
 }
 
-static struct btf_id *
-btf_id__add(struct rb_root *root, char *name, bool unique)
+static struct btf_id *__btf_id__add(struct rb_root *root,
+                                   char *name,
+                                   enum btf_id_kind kind,
+                                   bool unique)
 {
        struct rb_node **p = &root->rb_node;
        struct rb_node *parent = NULL;
@@ -221,12 +229,23 @@ btf_id__add(struct rb_root *root, char *name, bool unique)
        if (id) {
                pr_debug("adding symbol %s\n", name);
                id->name = name;
+               id->kind = kind;
                rb_link_node(&id->rb_node, parent, p);
                rb_insert_color(&id->rb_node, root);
        }
        return id;
 }
 
+static inline struct btf_id *btf_id__add(struct rb_root *root, char *name, enum btf_id_kind kind)
+{
+       return __btf_id__add(root, name, kind, false);
+}
+
+static inline struct btf_id *btf_id__add_unique(struct rb_root *root, char *name, enum btf_id_kind kind)
+{
+       return __btf_id__add(root, name, kind, true);
+}
+
 static char *get_id(const char *prefix_end)
 {
        /*
@@ -260,22 +279,36 @@ static char *get_id(const char *prefix_end)
        return id;
 }
 
-static struct btf_id *add_set(struct object *obj, char *name, bool is_set8)
+static struct btf_id *add_set(struct object *obj, char *name, enum btf_id_kind kind)
 {
+       int len = strlen(name);
+       int prefixlen;
+       char *id;
+
        /*
         * __BTF_ID__set__name
         * name =    ^
         * id   =         ^
         */
-       char *id = name + (is_set8 ? sizeof(BTF_SET8 "__") : sizeof(BTF_SET "__")) - 1;
-       int len = strlen(name);
+       switch (kind) {
+       case BTF_ID_KIND_SET:
+               prefixlen = sizeof(BTF_SET "__") - 1;
+               break;
+       case BTF_ID_KIND_SET8:
+               prefixlen = sizeof(BTF_SET8 "__") - 1;
+               break;
+       default:
+               pr_err("Unexpected kind %d passed to %s() for symbol %s\n", kind, __func__, name);
+               return NULL;
+       }
 
+       id = name + prefixlen;
        if (id >= name + len) {
                pr_err("FAILED to parse set name: %s\n", name);
                return NULL;
        }
 
-       return btf_id__add(&obj->sets, id, true);
+       return btf_id__add_unique(&obj->sets, id, kind);
 }
 
 static struct btf_id *add_symbol(struct rb_root *root, char *name, size_t size)
@@ -288,7 +321,7 @@ static struct btf_id *add_symbol(struct rb_root *root, char *name, size_t size)
                return NULL;
        }
 
-       return btf_id__add(root, id, false);
+       return btf_id__add(root, id, BTF_ID_KIND_SYM);
 }
 
 /* Older libelf.h and glibc elf.h might not yet define the ELF compression types. */
@@ -491,35 +524,31 @@ static int symbols_collect(struct object *obj)
                        id = add_symbol(&obj->funcs, prefix, sizeof(BTF_FUNC) - 1);
                /* set8 */
                } else if (!strncmp(prefix, BTF_SET8, sizeof(BTF_SET8) - 1)) {
-                       id = add_set(obj, prefix, true);
+                       id = add_set(obj, prefix, BTF_ID_KIND_SET8);
                        /*
                         * SET8 objects store list's count, which is encoded
                         * in symbol's size, together with 'cnt' field hence
                         * that - 1.
                         */
-                       if (id) {
+                       if (id)
                                id->cnt = sym.st_size / sizeof(uint64_t) - 1;
-                               id->is_set8 = true;
-                       }
                /* set */
                } else if (!strncmp(prefix, BTF_SET, sizeof(BTF_SET) - 1)) {
-                       id = add_set(obj, prefix, false);
+                       id = add_set(obj, prefix, BTF_ID_KIND_SET);
                        /*
                         * SET objects store list's count, which is encoded
                         * in symbol's size, together with 'cnt' field hence
                         * that - 1.
                         */
-                       if (id) {
+                       if (id)
                                id->cnt = sym.st_size / sizeof(int) - 1;
-                               id->is_set = true;
-                       }
                } else {
                        pr_err("FAILED unsupported prefix %s\n", prefix);
                        return -1;
                }
 
                if (!id)
-                       return -ENOMEM;
+                       return -EINVAL;
 
                if (id->addr_cnt >= ADDR_CNT) {
                        pr_err("FAILED symbol %s crossed the number of allowed lists\n",
@@ -643,7 +672,7 @@ static int id_patch(struct object *obj, struct btf_id *id)
        int i;
 
        /* For set, set8, id->id may be 0 */
-       if (!id->id && !id->is_set && !id->is_set8) {
+       if (!id->id && id->kind != BTF_ID_KIND_SET && id->kind != BTF_ID_KIND_SET8) {
                pr_err("WARN: resolve_btfids: unresolved symbol %s\n", id->name);
                warnings++;
        }
@@ -696,6 +725,7 @@ static int sets_patch(struct object *obj)
 {
        Elf_Data *data = obj->efile.idlist;
        struct rb_node *next;
+       int cnt;
 
        next = rb_first(&obj->sets);
        while (next) {
@@ -715,11 +745,15 @@ static int sets_patch(struct object *obj)
                        return -1;
                }
 
-               if (id->is_set) {
+               switch (id->kind) {
+               case BTF_ID_KIND_SET:
                        set = data->d_buf + off;
+                       cnt = set->cnt;
                        qsort(set->ids, set->cnt, sizeof(set->ids[0]), cmp_id);
-               } else {
+                       break;
+               case BTF_ID_KIND_SET8:
                        set8 = data->d_buf + off;
+                       cnt = set8->cnt;
                        /*
                         * Make sure id is at the beginning of the pairs
                         * struct, otherwise the below qsort would not work.
@@ -744,10 +778,13 @@ static int sets_patch(struct object *obj)
                                                bswap_32(set8->pairs[i].flags);
                                }
                        }
+                       break;
+               default:
+                       pr_err("Unexpected btf_id_kind %d for set '%s'\n", id->kind, id->name);
+                       return -1;
                }
 
-               pr_debug("sorting  addr %5lu: cnt %6d [%s]\n",
-                        off, id->is_set ? set->cnt : set8->cnt, id->name);
+               pr_debug("sorting  addr %5lu: cnt %6d [%s]\n", off, cnt, id->name);
 
                next = rb_next(next);
        }