From: "Emil Tsalapatis" <emil@etsalapatis.com>
To: "Ihor Solodrai" <ihor.solodrai@linux.dev>,
"Alexei Starovoitov" <ast@kernel.org>,
"Andrii Nakryiko" <andrii@kernel.org>,
"Daniel Borkmann" <daniel@iogearbox.net>,
"Eduard Zingerman" <eddyz87@gmail.com>,
"Kumar Kartikeya Dwivedi" <memxor@gmail.com>
Cc: "Alan Maguire" <alan.maguire@oracle.com>,
"Jiri Olsa" <jolsa@kernel.org>, <bpf@vger.kernel.org>,
<linux-kbuild@vger.kernel.org>
Subject: Re: [PATCH bpf-next v1 05/14] resolve_btfids: Index BTF ID symbols by address
Date: Tue, 16 Jun 2026 14:45:56 -0400 [thread overview]
Message-ID: <DJAP3FDYA9GP.O5139CT1RYW3@etsalapatis.com> (raw)
In-Reply-To: <20260601221805.821394-6-ihor.solodrai@linux.dev>
On Mon Jun 1, 2026 at 6:17 PM EDT, Ihor Solodrai wrote:
> Keep an address-sorted index of parsed .BTF_ids symbols so code that
> the original BTF_ID symbol name can be recovered from an entry
> address.
>
> Use the index in find_kfunc_flags() to scan BTF_SET8_KFUNCS entries
> directly and match each entry back to the requested kfunc.
>
> Signed-off-by: Ihor Solodrai <ihor.solodrai@linux.dev>
Reviewed-by: Emil Tsalapatis <emil@etsalapatis.com>
Some notes on clarity below.
> ---
> tools/bpf/resolve_btfids/main.c | 103 +++++++++++++++++++++++++-------
> 1 file changed, 80 insertions(+), 23 deletions(-)
>
> diff --git a/tools/bpf/resolve_btfids/main.c b/tools/bpf/resolve_btfids/main.c
> index f8a91fa7584f..43512af13148 100644
> --- a/tools/bpf/resolve_btfids/main.c
> +++ b/tools/bpf/resolve_btfids/main.c
> @@ -119,6 +119,11 @@ struct btf_id {
> Elf64_Addr addr[ADDR_CNT];
> };
>
> +struct addr_sym {
> + Elf64_Addr addr;
> + const char *name;
> +};
> +
> struct object {
> const char *path;
> const char *btf_path;
> @@ -150,6 +155,10 @@ struct object {
> int nr_structs;
> int nr_unions;
> int nr_typedefs;
> +
> + struct addr_sym *addr_syms;
> + int nr_addr_syms;
> + int max_addr_syms;
> };
>
> #define KF_IMPLICIT_ARGS (1 << 16)
> @@ -480,6 +489,49 @@ static int elf_collect(struct object *obj)
> return 0;
> }
>
> +static int push_addr_sym(struct object *obj, Elf64_Addr addr, const char *name)
> +{
> + struct addr_sym *arr = obj->addr_syms;
> + int cap = obj->max_addr_syms;
> +
> + if (obj->nr_addr_syms + 1 > cap) {
> + cap = max(cap + 256, cap * 2);
> + arr = realloc(arr, sizeof(*arr) * cap);
> + if (!arr)
> + return -ENOMEM;
> + obj->max_addr_syms = cap;
> + obj->addr_syms = arr;
> + }
> +
> + obj->addr_syms[obj->nr_addr_syms].addr = addr;
> + obj->addr_syms[obj->nr_addr_syms].name = name;
> + obj->nr_addr_syms++;
> +
> + return 0;
> +}
> +
> +static int cmp_addr_sym(const void *a, const void *b)
> +{
> + Elf64_Addr aa = ((const struct addr_sym *)a)->addr;
> + Elf64_Addr ab = ((const struct addr_sym *)b)->addr;
> +
> + if (aa < ab)
> + return -1;
> + if (aa > ab)
> + return 1;
> + return 0;
> +}
> +
> +static const char *find_name_by_addr(struct object *obj, Elf64_Addr addr)
> +{
> + struct addr_sym key = { .addr = addr };
> + struct addr_sym *res;
> +
> + res = bsearch(&key, obj->addr_syms, obj->nr_addr_syms,
> + sizeof(*obj->addr_syms), cmp_addr_sym);
> + return res ? res->name : NULL;
> +}
> +
> static int symbols_collect(struct object *obj)
> {
> Elf_Scn *scn = NULL;
> @@ -573,8 +625,14 @@ static int symbols_collect(struct object *obj)
> return -1;
> }
> id->addr[id->addr_cnt++] = sym.st_value;
> +
> + if (push_addr_sym(obj, sym.st_value, id->name))
> + return -1;
> }
>
> + qsort(obj->addr_syms, obj->nr_addr_syms, sizeof(*obj->addr_syms),
> + cmp_addr_sym);
> +
> return 0;
> }
>
> @@ -946,43 +1004,41 @@ static int collect_decl_tags(struct btf2btf_context *ctx)
> }
>
> /*
> - * To find the kfunc flags having its struct btf_id (with ELF addresses)
> - * we need to find the address that is in range of a set8.
> - * If a set8 is found, then the flags are located at addr + 4 bytes.
> + * To find kfunc flags, scan BTF_SET8_KFUNCS entries and use the entry
> + * address to recover the corresponding BTF_ID symbol name.
> * Return 0 (no flags!) if not found.
> */
> static u32 find_kfunc_flags(struct object *obj, struct btf_id *kfunc_id)
> {
> const u32 *elf_data_ptr = obj->efile.idlist->d_buf;
> - u64 set_lower_addr, set_upper_addr, addr;
> struct btf_id *set_id;
> struct rb_node *next;
> - u32 flags;
> - u64 idx;
> + u64 idx, set_addr;
> + u32 set_flags;
>
> for (next = rb_first(&obj->sets); next; next = rb_next(next)) {
> set_id = rb_entry(next, struct btf_id, rb_node);
> if (set_id->kind != BTF_ID_KIND_SET8 || set_id->addr_cnt != 1)
> continue;
>
> - set_lower_addr = set_id->addr[0];
> - set_upper_addr = set_lower_addr + set_id->cnt * sizeof(u64);
> + set_addr = set_id->addr[0];
> + idx = (set_addr - obj->efile.idlist_addr) / sizeof(u32) + 1;
Is the +1 because the set8-global flags are in &((char *)btf_id_set8)[4]?
If that's the case, can you add a comment that you're checking the
set-global flags to decide whether to skip all of it?
> + set_flags = elf_data_ptr[idx];
> + if (!(set_flags & BTF_SET8_KFUNCS))
> + continue;
>
> - for (u32 i = 0; i < kfunc_id->addr_cnt; i++) {
> - addr = kfunc_id->addr[i];
> - /*
> - * Lower bound is exclusive to skip the 8-byte header of the set.
> - * Upper bound is inclusive to capture the last entry at offset 8*cnt.
> - */
> - if (set_lower_addr < addr && addr <= set_upper_addr) {
> - pr_debug("found kfunc %s in BTF_ID_FLAGS %s\n",
> - kfunc_id->name, set_id->name);
> - idx = addr - obj->efile.idlist_addr;
> - idx = idx / sizeof(u32) + 1;
> - flags = elf_data_ptr[idx];
> -
> - return flags;
> - }
> + for (u32 i = 0; i < set_id->cnt; i++) {
> + Elf64_Addr addr = set_addr + sizeof(u64) * (i + 1);
Same here, can you point out that the +1 is to skip the set header?
> + const char *name = find_name_by_addr(obj, addr);
> +
> + if (!name || strcmp(name, kfunc_id->name) != 0)
> + continue;
> +
> + pr_debug("found kfunc %s in BTF_ID_FLAGS %s\n",
> + kfunc_id->name, set_id->name);
> +
> + idx = (addr - obj->efile.idlist_addr) / sizeof(u32) + 1;
This seems to be the same calculation as we do for the whole set8 flag,
but AFAICT the context is different and here we're indexing into the pair.
Can you add a comment for this?
> + return elf_data_ptr[idx];
> }
> }
>
> @@ -1575,6 +1631,7 @@ int main(int argc, const char **argv)
> btf_id__free_all(&obj.typedefs);
> btf_id__free_all(&obj.funcs);
> btf_id__free_all(&obj.sets);
> + free(obj.addr_syms);
> if (obj.efile.elf) {
> elf_end(obj.efile.elf);
> close(obj.efile.fd);
next prev parent reply other threads:[~2026-06-16 18:45 UTC|newest]
Thread overview: 54+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-06-01 22:17 [PATCH bpf-next v1 00/14] resolve_btfids: Implement BTF tags emission for kfuncs Ihor Solodrai
2026-06-01 22:17 ` [PATCH bpf-next v1 01/14] tools/bpf: Sync btf_ids.h to tools Ihor Solodrai
2026-06-16 6:28 ` Emil Tsalapatis
2026-06-01 22:17 ` [PATCH bpf-next v1 02/14] selftests/bpf: Modernize resolve_btfids test scaffolding Ihor Solodrai
2026-06-02 13:02 ` Jiri Olsa
2026-06-02 18:30 ` Ihor Solodrai
2026-06-16 6:33 ` Emil Tsalapatis
2026-06-01 22:17 ` [PATCH bpf-next v1 03/14] selftests/bpf: Fix resolve_btfids test reads of BTF ID sets in PIE builds Ihor Solodrai
2026-06-03 23:45 ` Andrii Nakryiko
2026-06-16 20:15 ` Ihor Solodrai
2026-06-16 6:53 ` Emil Tsalapatis
2026-06-01 22:17 ` [PATCH bpf-next v1 04/14] selftests/bpf: Add kfunc set test to resolve_btfids Ihor Solodrai
2026-06-02 13:02 ` Jiri Olsa
2026-06-03 23:45 ` Andrii Nakryiko
2026-06-16 7:07 ` Emil Tsalapatis
2026-06-16 18:33 ` Alexei Starovoitov
2026-06-16 21:52 ` Ihor Solodrai
2026-06-01 22:17 ` [PATCH bpf-next v1 05/14] resolve_btfids: Index BTF ID symbols by address Ihor Solodrai
2026-06-01 22:28 ` sashiko-bot
2026-06-01 23:03 ` bot+bpf-ci
2026-06-02 13:01 ` Jiri Olsa
2026-06-02 18:28 ` Ihor Solodrai
2026-06-03 23:45 ` Andrii Nakryiko
2026-06-16 21:47 ` Ihor Solodrai
2026-06-16 18:45 ` Emil Tsalapatis [this message]
2026-06-16 21:53 ` Ihor Solodrai
2026-06-01 22:17 ` [PATCH bpf-next v1 06/14] resolve_btfids: Discover kfuncs from BTF ID sets Ihor Solodrai
2026-06-01 22:33 ` sashiko-bot
2026-06-02 18:36 ` Ihor Solodrai
2026-06-02 20:36 ` Jiri Olsa
2026-06-02 21:08 ` Ihor Solodrai
2026-06-03 23:45 ` Andrii Nakryiko
2026-06-03 23:45 ` Andrii Nakryiko
2026-06-16 21:49 ` Ihor Solodrai
2026-06-01 22:17 ` [PATCH bpf-next v1 07/14] resolve_btfids: Emit bpf_kfunc BTF decl tag for discovered kfuncs Ihor Solodrai
2026-06-03 23:45 ` Andrii Nakryiko
2026-06-01 22:17 ` [PATCH bpf-next v1 08/14] selftests/bpf: Verify bpf_kfunc decl tag emission in resolve_btfids Ihor Solodrai
2026-06-01 22:18 ` [PATCH bpf-next v1 09/14] resolve_btfids: Emit a decl tag for kfuncs with KF_FASTCALL Ihor Solodrai
2026-06-01 22:18 ` [PATCH bpf-next v1 10/14] selftests/bpf: Verify bpf_fastcall decl tags in resolve_btfids test Ihor Solodrai
2026-06-03 23:47 ` Andrii Nakryiko
2026-06-01 22:18 ` [PATCH bpf-next v1 11/14] resolve_btfids: Process KF_ARENA_* flags in resolve_btfids Ihor Solodrai
2026-06-03 23:47 ` Andrii Nakryiko
2026-06-16 19:51 ` Emil Tsalapatis
2026-06-16 20:36 ` Emil Tsalapatis
2026-06-16 21:58 ` Ihor Solodrai
2026-06-01 22:18 ` [PATCH bpf-next v1 12/14] selftests/bpf: Verify arena type tags in resolve_btfids test Ihor Solodrai
2026-06-01 22:29 ` sashiko-bot
2026-06-03 23:46 ` Andrii Nakryiko
2026-06-01 22:18 ` [PATCH bpf-next v1 13/14] kbuild: Drop decl_tag_kfuncs and attributes from pahole flags Ihor Solodrai
2026-06-03 23:48 ` Andrii Nakryiko
2026-06-01 22:18 ` [PATCH bpf-next v1 14/14] docs, resolve_btfids: Document kfunc BTF annotation emission Ihor Solodrai
2026-06-16 19:54 ` Emil Tsalapatis
2026-06-03 23:45 ` [PATCH bpf-next v1 00/14] resolve_btfids: Implement BTF tags emission for kfuncs Andrii Nakryiko
2026-06-16 20:10 ` Ihor Solodrai
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=DJAP3FDYA9GP.O5139CT1RYW3@etsalapatis.com \
--to=emil@etsalapatis.com \
--cc=alan.maguire@oracle.com \
--cc=andrii@kernel.org \
--cc=ast@kernel.org \
--cc=bpf@vger.kernel.org \
--cc=daniel@iogearbox.net \
--cc=eddyz87@gmail.com \
--cc=ihor.solodrai@linux.dev \
--cc=jolsa@kernel.org \
--cc=linux-kbuild@vger.kernel.org \
--cc=memxor@gmail.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.