From: David Marchevsky <david.marchevsky@linux.dev>
To: Daniel Xu <dxu@dxuuu.xyz>,
acme@kernel.org, jolsa@kernel.org, quentin@isovalent.com
Cc: andrii.nakryiko@gmail.com, ast@kernel.org, daniel@iogearbox.net,
bpf@vger.kernel.org
Subject: Re: [PATCH dwarves] pahole: Inject kfunc decl tags into BTF
Date: Thu, 21 Dec 2023 17:57:18 -0500 [thread overview]
Message-ID: <98e76ea6-f45e-4ed5-9976-97f540032a55@linux.dev> (raw)
In-Reply-To: <421d18942d6ad28625530a8b3247595dc05eb100.1703110747.git.dxu@dxuuu.xyz>
On 12/20/23 5:19 PM, Daniel Xu wrote:
> This commit teaches pahole to parse symbols in .BTF_ids section in
> vmlinux and discover exported kfuncs. Pahole then takes the list of
> kfuncs and injects a BTF_KIND_DECL_TAG for each kfunc.
>
> This enables downstream users and tools to dynamically discover which
> kfuncs are available on a system by parsing vmlinux or module BTF, both
> available in /sys/kernel/btf.
>
> Example of encoding:
>
> $ bpftool btf dump file .tmp_vmlinux.btf | rg DECL_TAG | wc -l
> 388
>
> $ bpftool btf dump file .tmp_vmlinux.btf | rg 68940
> [68940] FUNC 'bpf_xdp_get_xfrm_state' type_id=68939 linkage=static
> [128124] DECL_TAG 'kfunc' type_id=68940 component_idx=-1
>
> Signed-off-by: Daniel Xu <dxu@dxuuu.xyz>
> ---
> btf_encoder.c | 202 ++++++++++++++++++++++++++++++++++++++++++++++++++
> 1 file changed, 202 insertions(+)
>
> diff --git a/btf_encoder.c b/btf_encoder.c
> index fd04008..2697214 100644
> --- a/btf_encoder.c
> +++ b/btf_encoder.c
> @@ -34,6 +34,9 @@
> #include <pthread.h>
>
> #define BTF_ENCODER_MAX_PROTO 512
> +#define BTF_IDS_SECTION ".BTF_ids"
> +#define BTF_ID_FUNC_PFX "__BTF_ID__func__"
> +#define BTF_KFUNC_TYPE_TAG "kfunc"
Can this be bpf_kfunc? Elaborated on elsewhere in this reply
>
> /* state used to do later encoding of saved functions */
> struct btf_encoder_state {
> @@ -1352,6 +1355,200 @@ out:
> return err;
> }
>
> +/*
> + * Parse BTF_ID symbol and return the kfunc name.
> + *
> + * Returns:
> + * Callee-owned string containing kfunc name if successful.
nit: Caller-owned, not callee-owned
> + * NULL if !kfunc or on error.
> + */
> +static char *get_kfunc_name(const char *sym)
> +{
> + char *kfunc, *end;
> +
> + if (strncmp(sym, BTF_ID_FUNC_PFX, sizeof(BTF_ID_FUNC_PFX) - 1))
> + return NULL;
> +
> + /* Strip prefix */
> + kfunc = strdup(sym + sizeof(BTF_ID_FUNC_PFX) - 1);
> +
> + /* Strip suffix */
> + end = strrchr(kfunc, '_');
> + if (!end || *(end - 1) != '_') {
> + free(kfunc);
> + return NULL;
> + }
> + *(end - 1) = '\0';
> +
> + return kfunc;
> +}
> +
> +static int btf_encoder__tag_kfunc(struct btf_encoder *encoder, const char *kfunc)
> +{
> + int nr_types, type_id, err = -1;
> + struct btf *btf = encoder->btf;
> +
> + nr_types = btf__type_cnt(btf);
> + for (type_id = 1; type_id < nr_types; type_id++) {
> + const struct btf_type *type;
> + const char *name;
> +
> + type = btf__type_by_id(btf, type_id);
> + if (!type) {
> + fprintf(stderr, "%s: malformed BTF, can't resolve type for ID %d\n",
> + __func__, type_id);
> + goto out;
> + }
> +
> + if (!btf_is_func(type))
> + continue;
> +
> + name = btf__name_by_offset(btf, type->name_off);
> + if (!name) {
> + fprintf(stderr, "%s: malformed BTF, can't resolve name for ID %d\n",
> + __func__, type_id);
> + goto out;
> + }
> +
> + if (strcmp(name, kfunc))
> + continue;
> +
> + err = btf__add_decl_tag(btf, BTF_KFUNC_TYPE_TAG, type_id, -1);
In an ideal world we'd just add this tag to __bpf_kfunc macro
definition, right? Then bpftool can generate fwd decls from generated
vmlinux w/o any pahole changes. But no gcc support for BTF tags, so need
to do this workaround.
With that in mind, instead of unconditionally adding BTF_KFUNC_TYPE_TAG
to funcs in btf id sets, can this code only do so if there isn't an
existing BTF_KFUNC_TYPE_TAG pointing to it? It'd require another loop
over btf types to built set of already-tagged funcs, but would
future-proof this work. Alternatively, if existing btf__dedup call after
btf_encoder__tag_kfuncs will get rid of these extraneous "tagged types"
in the scenario where one already exists, then a comment here to that
effect would be appreciated.
My nit about BTF_KFUNC_TYPE_TAG earlier was related: if we do want
__bpf_kfunc macro to add such a tag, might as well make the tag
'bpf_kfunc' so it's easier for unfamiliar folks to understand.
next prev parent reply other threads:[~2023-12-21 22:57 UTC|newest]
Thread overview: 21+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-12-20 22:19 [PATCH dwarves] pahole: Inject kfunc decl tags into BTF Daniel Xu
2023-12-21 6:37 ` Daniel Xu
2023-12-21 8:35 ` Jiri Olsa
2023-12-21 17:05 ` Alexei Starovoitov
2023-12-21 17:42 ` Alan Maguire
2023-12-21 18:07 ` Alexei Starovoitov
2023-12-21 18:18 ` Daniel Xu
2023-12-22 0:52 ` Alexei Starovoitov
2023-12-22 20:50 ` Daniel Xu
2023-12-22 9:55 ` Alan Maguire
2023-12-22 12:46 ` Jiri Olsa
2023-12-22 16:24 ` Alan Maguire
2023-12-22 20:55 ` Daniel Xu
2023-12-22 22:11 ` Alexei Starovoitov
2024-01-03 0:56 ` Daniel Xu
2024-01-03 8:48 ` Jiri Olsa
2024-01-03 20:19 ` Daniel Xu
2023-12-21 8:35 ` Jiri Olsa
2023-12-23 19:35 ` Daniel Xu
2023-12-21 22:57 ` David Marchevsky [this message]
2023-12-23 19:40 ` Daniel Xu
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=98e76ea6-f45e-4ed5-9976-97f540032a55@linux.dev \
--to=david.marchevsky@linux.dev \
--cc=acme@kernel.org \
--cc=andrii.nakryiko@gmail.com \
--cc=ast@kernel.org \
--cc=bpf@vger.kernel.org \
--cc=daniel@iogearbox.net \
--cc=dxu@dxuuu.xyz \
--cc=jolsa@kernel.org \
--cc=quentin@isovalent.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.